gst/base/: Implement clock sync in base class.
authorWim Taymans <wim.taymans@gmail.com>
Thu, 10 Nov 2005 14:45:27 +0000 (14:45 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Thu, 10 Nov 2005 14:45:27 +0000 (14:45 +0000)
Original commit message from CVS:
* gst/base/gstbasesink.c: (gst_base_sink_do_sync):
* gst/base/gstbasesrc.c: (gst_base_src_wait),
(gst_base_src_do_sync), (gst_base_src_get_range):
Implement clock sync in base class.

ChangeLog
gst/base/gstbasesink.c
gst/base/gstbasesrc.c
libs/gst/base/gstbasesink.c
libs/gst/base/gstbasesrc.c

index 1a7784f..5d59f55 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2005-11-10  Wim Taymans  <wim@fluendo.com>
+
+       * gst/base/gstbasesink.c: (gst_base_sink_do_sync):
+       * gst/base/gstbasesrc.c: (gst_base_src_wait),
+       (gst_base_src_do_sync), (gst_base_src_get_range):
+       Implement clock sync in base class.
+
 2005-11-10  Thomas Vander Stichele  <thomas at apestaart dot org>
 
        patch by: Tim-Philipp Müller <tim at centricular dot net>
index bbc2525..3cd2735 100644 (file)
@@ -1063,8 +1063,13 @@ gst_base_sink_do_sync (GstBaseSink * basesink, GstBuffer * buffer)
   if (end_valid)
     stream_end += basesink->segment_accum;
 
+  if (!basesink->sync) {
+    GST_DEBUG_OBJECT (basesink, "no need to sync");
+    goto done;
+  }
+
   /* now do clocking */
-  if (basesink->clock && basesink->sync) {
+  if (basesink->clock) {
     GstClockTime base_time;
 
     GST_LOCK (basesink);
index 999c7c6..5231e38 100644 (file)
@@ -782,6 +782,84 @@ gst_base_src_get_property (GObject * object, guint prop_id, GValue * value,
   }
 }
 
+/* with STREAM_LOCK and LOCK*/
+static GstClockReturn
+gst_base_src_wait (GstBaseSrc * basesrc, GstClockTime time)
+{
+  GstClockReturn ret;
+  GstClockID id;
+  GstClock *clock;
+
+  if ((clock = GST_ELEMENT_CLOCK (basesrc)) == NULL)
+    return GST_CLOCK_OK;
+
+  /* clock_id should be NULL outside of this function */
+  g_assert (basesrc->clock_id == NULL);
+  g_assert (GST_CLOCK_TIME_IS_VALID (time));
+
+  id = gst_clock_new_single_shot_id (clock, time);
+
+  basesrc->clock_id = id;
+  /* release the object lock while waiting */
+  GST_UNLOCK (basesrc);
+
+  ret = gst_clock_id_wait (id, NULL);
+
+  GST_LOCK (basesrc);
+  gst_clock_id_unref (id);
+  basesrc->clock_id = NULL;
+
+  return ret;
+}
+
+
+/* perform synchronisation on a buffer
+ */
+static GstClockReturn
+gst_base_src_do_sync (GstBaseSrc * basesrc, GstBuffer * buffer)
+{
+  GstClockReturn result = GST_CLOCK_OK;
+  GstClockTime start, end;
+  GstBaseSrcClass *bclass;
+  gboolean start_valid;
+  GstClockTime base_time;
+
+  bclass = GST_BASE_SRC_GET_CLASS (basesrc);
+
+  start = end = -1;
+  if (bclass->get_times)
+    bclass->get_times (basesrc, buffer, &start, &end);
+
+  start_valid = GST_CLOCK_TIME_IS_VALID (start);
+
+  /* if we don't have a timestamp, we don't sync */
+  if (!start_valid) {
+    GST_DEBUG_OBJECT (basesrc, "get_times returned invalid start");
+    goto done;
+  }
+
+  GST_DEBUG_OBJECT (basesrc, "got times start: %" GST_TIME_FORMAT
+      ", end: %" GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (end));
+
+  /* now do clocking */
+  GST_LOCK (basesrc);
+  base_time = GST_ELEMENT_CAST (basesrc)->base_time;
+
+  GST_LOG_OBJECT (basesrc,
+      "waiting for clock, base time %" GST_TIME_FORMAT
+      ", stream_start %" GST_TIME_FORMAT,
+      GST_TIME_ARGS (base_time), GST_TIME_ARGS (start));
+
+  result = gst_base_src_wait (basesrc, start + base_time);
+  GST_UNLOCK (basesrc);
+
+  GST_LOG_OBJECT (basesrc, "clock entry done: %d", result);
+
+done:
+  return result;
+}
+
+
 static GstFlowReturn
 gst_base_src_get_range (GstBaseSrc * src, guint64 offset, guint length,
     GstBuffer ** buf)
@@ -789,6 +867,7 @@ gst_base_src_get_range (GstBaseSrc * src, guint64 offset, guint length,
   GstFlowReturn ret;
   GstBaseSrcClass *bclass;
   gint64 maxsize;
+  GstClockReturn status;
 
   bclass = GST_BASE_SRC_GET_CLASS (src);
 
@@ -858,7 +937,26 @@ gst_base_src_get_range (GstBaseSrc * src, guint64 offset, guint length,
   }
 
   ret = bclass->create (src, offset, length, buf);
-
+  if (ret != GST_FLOW_OK)
+    goto done;
+
+  /* now sync before pushing the buffer */
+  status = gst_base_src_do_sync (src, *buf);
+  switch (status) {
+    case GST_CLOCK_EARLY:
+      GST_DEBUG_OBJECT (src, "buffer too late!, returning anyway");
+      break;
+    case GST_CLOCK_OK:
+      GST_DEBUG_OBJECT (src, "buffer ok");
+      break;
+    default:
+      GST_DEBUG_OBJECT (src, "clock returned %d, not returning", status);
+      gst_buffer_unref (*buf);
+      *buf = NULL;
+      ret = GST_FLOW_WRONG_STATE;
+      break;
+  }
+done:
   return ret;
 
   /* ERROR */
index bbc2525..3cd2735 100644 (file)
@@ -1063,8 +1063,13 @@ gst_base_sink_do_sync (GstBaseSink * basesink, GstBuffer * buffer)
   if (end_valid)
     stream_end += basesink->segment_accum;
 
+  if (!basesink->sync) {
+    GST_DEBUG_OBJECT (basesink, "no need to sync");
+    goto done;
+  }
+
   /* now do clocking */
-  if (basesink->clock && basesink->sync) {
+  if (basesink->clock) {
     GstClockTime base_time;
 
     GST_LOCK (basesink);
index 999c7c6..5231e38 100644 (file)
@@ -782,6 +782,84 @@ gst_base_src_get_property (GObject * object, guint prop_id, GValue * value,
   }
 }
 
+/* with STREAM_LOCK and LOCK*/
+static GstClockReturn
+gst_base_src_wait (GstBaseSrc * basesrc, GstClockTime time)
+{
+  GstClockReturn ret;
+  GstClockID id;
+  GstClock *clock;
+
+  if ((clock = GST_ELEMENT_CLOCK (basesrc)) == NULL)
+    return GST_CLOCK_OK;
+
+  /* clock_id should be NULL outside of this function */
+  g_assert (basesrc->clock_id == NULL);
+  g_assert (GST_CLOCK_TIME_IS_VALID (time));
+
+  id = gst_clock_new_single_shot_id (clock, time);
+
+  basesrc->clock_id = id;
+  /* release the object lock while waiting */
+  GST_UNLOCK (basesrc);
+
+  ret = gst_clock_id_wait (id, NULL);
+
+  GST_LOCK (basesrc);
+  gst_clock_id_unref (id);
+  basesrc->clock_id = NULL;
+
+  return ret;
+}
+
+
+/* perform synchronisation on a buffer
+ */
+static GstClockReturn
+gst_base_src_do_sync (GstBaseSrc * basesrc, GstBuffer * buffer)
+{
+  GstClockReturn result = GST_CLOCK_OK;
+  GstClockTime start, end;
+  GstBaseSrcClass *bclass;
+  gboolean start_valid;
+  GstClockTime base_time;
+
+  bclass = GST_BASE_SRC_GET_CLASS (basesrc);
+
+  start = end = -1;
+  if (bclass->get_times)
+    bclass->get_times (basesrc, buffer, &start, &end);
+
+  start_valid = GST_CLOCK_TIME_IS_VALID (start);
+
+  /* if we don't have a timestamp, we don't sync */
+  if (!start_valid) {
+    GST_DEBUG_OBJECT (basesrc, "get_times returned invalid start");
+    goto done;
+  }
+
+  GST_DEBUG_OBJECT (basesrc, "got times start: %" GST_TIME_FORMAT
+      ", end: %" GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (end));
+
+  /* now do clocking */
+  GST_LOCK (basesrc);
+  base_time = GST_ELEMENT_CAST (basesrc)->base_time;
+
+  GST_LOG_OBJECT (basesrc,
+      "waiting for clock, base time %" GST_TIME_FORMAT
+      ", stream_start %" GST_TIME_FORMAT,
+      GST_TIME_ARGS (base_time), GST_TIME_ARGS (start));
+
+  result = gst_base_src_wait (basesrc, start + base_time);
+  GST_UNLOCK (basesrc);
+
+  GST_LOG_OBJECT (basesrc, "clock entry done: %d", result);
+
+done:
+  return result;
+}
+
+
 static GstFlowReturn
 gst_base_src_get_range (GstBaseSrc * src, guint64 offset, guint length,
     GstBuffer ** buf)
@@ -789,6 +867,7 @@ gst_base_src_get_range (GstBaseSrc * src, guint64 offset, guint length,
   GstFlowReturn ret;
   GstBaseSrcClass *bclass;
   gint64 maxsize;
+  GstClockReturn status;
 
   bclass = GST_BASE_SRC_GET_CLASS (src);
 
@@ -858,7 +937,26 @@ gst_base_src_get_range (GstBaseSrc * src, guint64 offset, guint length,
   }
 
   ret = bclass->create (src, offset, length, buf);
-
+  if (ret != GST_FLOW_OK)
+    goto done;
+
+  /* now sync before pushing the buffer */
+  status = gst_base_src_do_sync (src, *buf);
+  switch (status) {
+    case GST_CLOCK_EARLY:
+      GST_DEBUG_OBJECT (src, "buffer too late!, returning anyway");
+      break;
+    case GST_CLOCK_OK:
+      GST_DEBUG_OBJECT (src, "buffer ok");
+      break;
+    default:
+      GST_DEBUG_OBJECT (src, "clock returned %d, not returning", status);
+      gst_buffer_unref (*buf);
+      *buf = NULL;
+      ret = GST_FLOW_WRONG_STATE;
+      break;
+  }
+done:
   return ret;
 
   /* ERROR */