[farsight2/master] Initial timestamp-merging work for funnel

Olivier Crête olivier.crete at collabora.co.uk
Tue Dec 23 15:24:08 PST 2008


---
 gst/funnel/gstfsfunnel.c |   96 ++++++++++++++++++++++++++++++++++++++++++++--
 gst/funnel/gstfsfunnel.h |    2 +
 2 files changed, 94 insertions(+), 4 deletions(-)

diff --git a/gst/funnel/gstfsfunnel.c b/gst/funnel/gstfsfunnel.c
index 66fb59e..6aa3377 100644
--- a/gst/funnel/gstfsfunnel.c
+++ b/gst/funnel/gstfsfunnel.c
@@ -65,9 +65,12 @@ static GstPad *fs_funnel_request_new_pad (GstElement * element,
   GstPadTemplate * templ, const gchar * name);
 static void fs_funnel_release_pad (GstElement * element, GstPad * pad);
 static GstFlowReturn fs_funnel_chain (GstPad * pad, GstBuffer * buffer);
+static gboolean fs_funnel_event (GstPad * pad, GstEvent * event);
 
 
-
+typedef struct {
+  GstSegment segment;
+} FsFunnelPadPrivate;
 
 static void
 fs_funnel_base_init (gpointer g_class)
@@ -123,14 +126,17 @@ fs_funnel_request_new_pad (GstElement * element, GstPadTemplate * templ,
 {
   GstPad *sinkpad;
   FsFunnel *funnel = FS_FUNNEL (element);
+  FsFunnelPadPrivate *priv = g_slice_alloc0 (sizeof(FsFunnelPadPrivate));
 
   GST_DEBUG_OBJECT (funnel, "requesting pad");
 
   sinkpad = gst_pad_new_from_template (templ, name);
 
-  //  gst_pad_set_setcaps_function ()
-
   gst_pad_set_chain_function (sinkpad, GST_DEBUG_FUNCPTR (fs_funnel_chain));
+  gst_pad_set_event_function (sinkpad, GST_DEBUG_FUNCPTR (fs_funnel_event));
+
+  gst_segment_init (&priv->segment, GST_FORMAT_UNDEFINED);
+  gst_pad_set_element_private (sinkpad, priv);
 
   gst_pad_set_active (sinkpad, TRUE);
 
@@ -143,11 +149,15 @@ static void
 fs_funnel_release_pad (GstElement * element, GstPad * pad)
 {
   FsFunnel *funnel = FS_FUNNEL (element);
+  FsFunnelPadPrivate *priv = gst_pad_get_element_private (pad);
 
   GST_DEBUG_OBJECT (funnel, "releasing pad");
 
   gst_pad_set_active (pad, FALSE);
 
+  if (priv)
+    g_slice_free1 (sizeof(FsFunnelPadPrivate), priv);
+
   gst_element_remove_pad (GST_ELEMENT_CAST (funnel), pad);
 }
 
@@ -156,19 +166,97 @@ fs_funnel_chain (GstPad * pad, GstBuffer * buffer)
 {
   GstFlowReturn res;
   FsFunnel *funnel = FS_FUNNEL (gst_pad_get_parent (pad));
+  FsFunnelPadPrivate *priv = gst_pad_get_element_private (pad);
+  GstEvent *event = NULL;
 
   GST_DEBUG_OBJECT (funnel, "received buffer %p", buffer);
 
+  GST_OBJECT_LOCK (funnel);
+  if (priv->segment.format == GST_FORMAT_UNDEFINED) {
+    GST_WARNING_OBJECT (funnel, "Got buffer without segment,"
+        " setting segment [0,inf[");
+     gst_segment_set_newsegment_full (&priv->segment, FALSE, 1.0, 1.0,
+         GST_FORMAT_TIME, 0, -1, 0);
+  }
+
+  if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buffer)))
+    gst_segment_set_last_stop (&priv->segment, priv->segment.format,
+        GST_BUFFER_TIMESTAMP (buffer));
+
+  buffer = gst_buffer_make_metadata_writable (buffer);
+  GST_BUFFER_TIMESTAMP (buffer) = gst_segment_to_running_time (&priv->segment,
+      priv->segment.format, GST_BUFFER_TIMESTAMP (buffer));
+
+  if (!funnel->has_segment)
+  {
+    event = gst_event_new_new_segment_full (FALSE, 1.0, 1.0, GST_FORMAT_TIME,
+        0, -1, 0);
+    funnel->has_segment = TRUE;
+  }
+  GST_OBJECT_UNLOCK (funnel);
+
+  if (event) {
+    if (!gst_pad_push_event (funnel->srcpad, event)) {
+      GST_WARNING_OBJECT (funnel, "Could not push out newsegment event");
+      res = GST_FLOW_ERROR;
+      goto out;
+    }
+  }
+
   res = gst_pad_push (funnel->srcpad, buffer);
 
-  GST_DEBUG_OBJECT (funnel, "handled buffer %s", gst_flow_get_name (res));
+  GST_LOG_OBJECT (funnel, "handled buffer %s", gst_flow_get_name (res));
 
+ out:
   gst_object_unref (funnel);
 
   return res;
 }
 
+static gboolean
+fs_funnel_event (GstPad * pad, GstEvent * event)
+{
+  FsFunnel *funnel = FS_FUNNEL (gst_pad_get_parent (pad));
+  FsFunnelPadPrivate *priv = gst_pad_get_element_private (pad);
+  gboolean forward = TRUE;
+  gboolean res = TRUE;
+
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_NEWSEGMENT:
+      {
+        gboolean update;
+        gdouble rate, arate;
+        GstFormat format;
+        gint64 start;
+        gint64 stop;
+        gint64 time;
+
+        gst_event_parse_new_segment_full (event, &update, &rate, &arate,
+            &format, &start, &stop, &time);
+
+
+        GST_OBJECT_LOCK (funnel);
+        gst_segment_set_newsegment_full (&priv->segment, update, rate, arate,
+            format, start, stop, time);
+        GST_OBJECT_UNLOCK (funnel);
+
+        forward = FALSE;
+        gst_event_unref (event);
+      }
+      break;
+    default:
+      forward = TRUE;
+      break;
+  }
+
+
+  if (forward)
+    res = gst_pad_push_event (funnel->srcpad, event);
+
+  gst_object_unref (funnel);
 
+  return res;
+}
 
 static gboolean plugin_init (GstPlugin * plugin)
 {
diff --git a/gst/funnel/gstfsfunnel.h b/gst/funnel/gstfsfunnel.h
index adb26a6..f22082e 100644
--- a/gst/funnel/gstfsfunnel.h
+++ b/gst/funnel/gstfsfunnel.h
@@ -54,6 +54,8 @@ struct _FsFunnel {
 
   /*< private >*/
   GstPad         *srcpad;
+
+  gboolean has_segment;
 };
 
 struct _FsFunnelClass {
-- 
1.5.6.5




More information about the farsight-commits mailing list