summaryrefslogtreecommitdiffstats
path: root/ext/mimic
diff options
context:
space:
mode:
Diffstat (limited to 'ext/mimic')
-rw-r--r--ext/mimic/gstmimdec.c112
-rw-r--r--ext/mimic/gstmimdec.h2
-rw-r--r--ext/mimic/gstmimenc.c10
3 files changed, 110 insertions, 14 deletions
diff --git a/ext/mimic/gstmimdec.c b/ext/mimic/gstmimdec.c
index 6a0abce5..a0878a13 100644
--- a/ext/mimic/gstmimdec.c
+++ b/ext/mimic/gstmimdec.c
@@ -68,6 +68,8 @@ static GstFlowReturn gst_mimdec_chain (GstPad * pad, GstBuffer * in);
static GstStateChangeReturn
gst_mimdec_change_state (GstElement * element, GstStateChange transition);
+static gboolean gst_mimdec_sink_event (GstPad * pad, GstEvent * event);
+
GST_BOILERPLATE (GstMimDec, gst_mimdec, GstElement, GST_TYPE_ELEMENT);
@@ -111,15 +113,12 @@ gst_mimdec_class_init (GstMimDecClass * klass)
static void
gst_mimdec_init (GstMimDec * mimdec, GstMimDecClass * klass)
{
- mimdec->sinkpad =
- gst_pad_new_from_template (gst_static_pad_template_get (&sink_factory),
- "sink");
+ mimdec->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
gst_element_add_pad (GST_ELEMENT (mimdec), mimdec->sinkpad);
gst_pad_set_chain_function (mimdec->sinkpad, gst_mimdec_chain);
+ gst_pad_set_event_function (mimdec->sinkpad, gst_mimdec_sink_event);
- mimdec->srcpad =
- gst_pad_new_from_template (gst_static_pad_template_get (&src_factory),
- "src");
+ mimdec->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
gst_element_add_pad (GST_ELEMENT (mimdec), mimdec->srcpad);
mimdec->adapter = gst_adapter_new ();
@@ -138,6 +137,8 @@ gst_mimdec_finalize (GObject * object)
gst_adapter_clear (mimdec->adapter);
g_object_unref (mimdec->adapter);
+
+ GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
}
static GstFlowReturn
@@ -213,6 +214,9 @@ gst_mimdec_chain (GstPad * pad, GstBuffer * in)
(guchar *) gst_adapter_peek (mimdec->adapter, mimdec->payload_size);
if (mimdec->dec == NULL) {
+ GstEvent *event = NULL;
+ gboolean result = TRUE;
+
/* Check if its a keyframe, otherwise skip it */
if (GUINT32_FROM_LE (*((guint32 *) (frame_body + 12))) != 0) {
gst_adapter_flush (mimdec->adapter, mimdec->payload_size);
@@ -254,6 +258,20 @@ gst_mimdec_chain (GstPad * pad, GstBuffer * in)
res = GST_FLOW_ERROR;
goto out;
}
+
+ if (mimdec->need_newsegment)
+ event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME,
+ mimdec->current_ts * GST_MSECOND, -1, 0);
+ mimdec->need_newsegment = FALSE;
+ GST_OBJECT_UNLOCK (mimdec);
+ if (event)
+ result = gst_pad_push_event (mimdec->srcpad, event);
+ GST_OBJECT_LOCK (mimdec);
+ if (!result) {
+ GST_WARNING_OBJECT (mimdec, "gst_pad_push_event failed");
+ res = GST_FLOW_ERROR;
+ goto out;
+ }
}
out_buf = gst_buffer_new_and_alloc (mimdec->buffer_size);
@@ -270,7 +288,10 @@ gst_mimdec_chain (GstPad * pad, GstBuffer * in)
goto out;
}
- GST_BUFFER_TIMESTAMP (out_buf) = in_time;
+ if (GST_CLOCK_TIME_IS_VALID (in_time))
+ GST_BUFFER_TIMESTAMP (out_buf) = in_time;
+ else
+ GST_BUFFER_TIMESTAMP (out_buf) = mimdec->current_ts * GST_MSECOND;
mimic_get_property (mimdec->dec, "width", &width);
mimic_get_property (mimdec->dec, "height", &height);
@@ -312,6 +333,7 @@ gst_mimdec_change_state (GstElement * element, GstStateChange transition)
switch (transition) {
case GST_STATE_CHANGE_READY_TO_NULL:
+ GST_OBJECT_LOCK (element);
if (mimdec->dec != NULL) {
mimic_close (mimdec->dec);
mimdec->dec = NULL;
@@ -319,8 +341,13 @@ gst_mimdec_change_state (GstElement * element, GstStateChange transition)
mimdec->have_header = FALSE;
mimdec->payload_size = -1;
mimdec->current_ts = -1;
- GST_OBJECT_UNLOCK (element);
}
+ GST_OBJECT_UNLOCK (element);
+ break;
+ case GST_STATE_CHANGE_READY_TO_PAUSED:
+ GST_OBJECT_LOCK (element);
+ mimdec->need_newsegment = TRUE;
+ GST_OBJECT_UNLOCK (element);
break;
default:
break;
@@ -328,3 +355,72 @@ gst_mimdec_change_state (GstElement * element, GstStateChange transition)
return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
}
+
+static gboolean
+gst_mimdec_sink_event (GstPad * pad, GstEvent * event)
+{
+ gboolean res = TRUE;
+ GstMimDec *mimdec = GST_MIMDEC (gst_pad_get_parent (pad));
+
+ /*
+ * Ignore upstream newsegment event, its EVIL, we should implement
+ * proper seeking instead
+ */
+ switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_NEWSEGMENT:
+ {
+ gboolean update;
+ GstFormat format;
+ gdouble rate, arate;
+ gint64 start, stop, time;
+
+ gst_event_parse_new_segment_full (event, &update, &rate, &arate,
+ &format, &start, &stop, &time);
+
+ /* we need TIME and a positive rate */
+ if (format != GST_FORMAT_TIME)
+ goto newseg_wrong_format;
+
+ if (rate <= 0.0)
+ goto newseg_wrong_rate;
+
+ GST_OBJECT_LOCK (mimdec);
+ mimdec->need_newsegment = FALSE;
+ GST_OBJECT_UNLOCK (mimdec);
+
+ res = gst_pad_push_event (mimdec->srcpad, event);
+ }
+ break;
+ case GST_EVENT_FLUSH_STOP:
+ GST_OBJECT_LOCK (mimdec);
+ mimdec->need_newsegment = TRUE;
+ GST_OBJECT_UNLOCK (mimdec);
+
+ res = gst_pad_push_event (mimdec->srcpad, event);
+ break;
+ default:
+ res = gst_pad_push_event (mimdec->srcpad, event);
+ break;
+ }
+
+done:
+
+ gst_object_unref (mimdec);
+
+ return res;
+
+newseg_wrong_format:
+ {
+ GST_DEBUG_OBJECT (mimdec, "received non TIME newsegment");
+ gst_event_unref (event);
+ goto done;
+ }
+newseg_wrong_rate:
+ {
+ GST_DEBUG_OBJECT (mimdec, "negative rates not supported yet");
+ gst_event_unref (event);
+ goto done;
+ }
+
+
+}
diff --git a/ext/mimic/gstmimdec.h b/ext/mimic/gstmimdec.h
index 7db6b1b8..e1db38d1 100644
--- a/ext/mimic/gstmimdec.h
+++ b/ext/mimic/gstmimdec.h
@@ -57,6 +57,8 @@ struct _GstMimDec
gboolean have_header;
guint32 payload_size;
guint32 current_ts;
+
+ gboolean need_newsegment;
};
struct _GstMimDecClass
diff --git a/ext/mimic/gstmimenc.c b/ext/mimic/gstmimenc.c
index 2418e7c8..4a65b9fd 100644
--- a/ext/mimic/gstmimenc.c
+++ b/ext/mimic/gstmimenc.c
@@ -142,17 +142,13 @@ gst_mimenc_class_init (GstMimEncClass * klass)
static void
gst_mimenc_init (GstMimEnc * mimenc, GstMimEncClass * klass)
{
- mimenc->sinkpad =
- gst_pad_new_from_template (gst_static_pad_template_get (&sink_factory),
- "sink");
+ mimenc->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
gst_element_add_pad (GST_ELEMENT (mimenc), mimenc->sinkpad);
gst_pad_set_setcaps_function (mimenc->sinkpad, gst_mimenc_setcaps);
gst_pad_set_chain_function (mimenc->sinkpad, gst_mimenc_chain);
gst_pad_set_event_function (mimenc->sinkpad, gst_mimenc_event);
- mimenc->srcpad =
- gst_pad_new_from_template (gst_static_pad_template_get (&src_factory),
- "src");
+ mimenc->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
gst_element_add_pad (GST_ELEMENT (mimenc), mimenc->srcpad);
mimenc->enc = NULL;
@@ -538,6 +534,8 @@ paused_mode_task (gpointer data)
GST_OBJECT_LOCK (mimenc);
mimenc->clock_id = NULL;
GST_OBJECT_UNLOCK (mimenc);
+
+ gst_clock_id_unref (id);
}
return;