docs/libs/gstreamer-libs-sections.txt: Add new methods to docs.
authorWim Taymans <wim.taymans@gmail.com>
Thu, 30 Aug 2007 17:50:54 +0000 (17:50 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Thu, 30 Aug 2007 17:50:54 +0000 (17:50 +0000)
Original commit message from CVS:
* docs/libs/gstreamer-libs-sections.txt:
Add new methods to docs.
* libs/gst/base/gstbasesink.c: (gst_base_sink_class_init),
(gst_base_sink_init), (gst_base_sink_set_ts_offset),
(gst_base_sink_get_ts_offset), (gst_base_sink_set_property),
(gst_base_sink_get_property), (gst_base_sink_wait_clock):
* libs/gst/base/gstbasesink.h:
Add ts-offset property to fine-tune the synchronisation.
API: GstBaseSink::ts-offset property
API: gst_base_sink_set_ts_offset()
API: gst_base_sink_get_ts_offset()

ChangeLog
docs/libs/gstreamer-libs-sections.txt
libs/gst/base/gstbasesink.c
libs/gst/base/gstbasesink.h

index 5ec0513..8f85fda 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2007-08-30  Wim Taymans  <wim.taymans@gmail.com>
+
+       * docs/libs/gstreamer-libs-sections.txt:
+       Add new methods to docs.
+
+       * libs/gst/base/gstbasesink.c: (gst_base_sink_class_init),
+       (gst_base_sink_init), (gst_base_sink_set_ts_offset),
+       (gst_base_sink_get_ts_offset), (gst_base_sink_set_property),
+       (gst_base_sink_get_property), (gst_base_sink_wait_clock):
+       * libs/gst/base/gstbasesink.h:
+       Add ts-offset property to fine-tune the synchronisation.
+       API: GstBaseSink::ts-offset property
+       API: gst_base_sink_set_ts_offset()
+       API: gst_base_sink_get_ts_offset()
+
 2007-08-29  Wim Taymans  <wim.taymans@gmail.com>
 
        * libs/gst/base/gstbasesink.c: (gst_base_sink_class_init),
index 21dd3ad..1639a2a 100644 (file)
@@ -262,8 +262,12 @@ gst_base_sink_set_sync
 gst_base_sink_get_sync
 gst_base_sink_set_max_lateness
 gst_base_sink_get_max_lateness
-gst_base_sink_is_qos_enabled
 gst_base_sink_set_qos_enabled
+gst_base_sink_is_qos_enabled
+gst_base_sink_set_async_enabled
+gst_base_sink_is_async_enabled
+gst_base_sink_set_ts_offset
+gst_base_sink_get_ts_offset
 
 GST_BASE_SINK_PAD
 
index 88327a6..ef8eb90 100644 (file)
@@ -159,6 +159,7 @@ struct _GstBaseSinkPrivate
 {
   gint qos_enabled;             /* ATOMIC */
   gboolean async_enabled;
+  GstClockTimeDiff ts_offset;
 
   /* start, stop of current buffer, stream time, used to report position */
   GstClockTime current_sstart;
@@ -227,6 +228,7 @@ struct _GstBaseSinkPrivate
 #define DEFAULT_MAX_LATENESS           -1
 #define DEFAULT_QOS                    FALSE
 #define DEFAULT_ASYNC                  TRUE
+#define DEFAULT_TS_OFFSET              0
 
 enum
 {
@@ -235,7 +237,8 @@ enum
   PROP_SYNC,
   PROP_MAX_LATENESS,
   PROP_QOS,
-  PROP_ASYNC
+  PROP_ASYNC,
+  PROP_TS_OFFSET
 };
 
 static GstElementClass *parent_class = NULL;
@@ -363,6 +366,19 @@ gst_base_sink_class_init (GstBaseSinkClass * klass)
   g_object_class_install_property (gobject_class, PROP_ASYNC,
       g_param_spec_boolean ("async", "Async",
           "Go asynchronously to PAUSED", DEFAULT_ASYNC, G_PARAM_READWRITE));
+  /**
+   * GstBaseSink:ts-offset
+   *
+   * Controls the final synchronisation, a negative value will render the buffer
+   * earlier while a positive value delays playback. This property can be 
+   * used to fix synchronisation in bad files.
+   *
+   * Since: 0.10.15
+   */
+  g_object_class_install_property (gobject_class, PROP_TS_OFFSET,
+      g_param_spec_int64 ("ts-offset", "TS Offset",
+          "Timestamp offset in nanoseconds", G_MININT64, G_MAXINT64,
+          DEFAULT_TS_OFFSET, G_PARAM_READWRITE));
 
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_base_sink_change_state);
@@ -514,6 +530,7 @@ gst_base_sink_init (GstBaseSink * basesink, gpointer g_class)
   basesink->abidata.ABI.max_lateness = DEFAULT_MAX_LATENESS;
   gst_atomic_int_set (&priv->qos_enabled, DEFAULT_QOS);
   priv->async_enabled = DEFAULT_ASYNC;
+  priv->ts_offset = DEFAULT_TS_OFFSET;
 
   GST_OBJECT_FLAG_SET (basesink, GST_ELEMENT_IS_SINK);
 }
@@ -717,6 +734,52 @@ gst_base_sink_is_async_enabled (GstBaseSink * sink)
 }
 
 /**
+ * gst_base_sink_set_ts_offset:
+ * @sink: the sink
+ * @offset: the new offset
+ *
+ * Adjust the synchronisation of @sink with @offset. A negative value will
+ * render buffers earlier than their timestamp. A positive value will delay
+ * rendering. This function can be used to fix playback of badly timestamped
+ * buffers.
+ *
+ * Since: 0.10.15
+ */
+void
+gst_base_sink_set_ts_offset (GstBaseSink * sink, GstClockTimeDiff offset)
+{
+  g_return_if_fail (GST_IS_BASE_SINK (sink));
+
+  GST_OBJECT_LOCK (sink);
+  sink->priv->ts_offset = offset;
+  GST_OBJECT_UNLOCK (sink);
+}
+
+/**
+ * gst_base_sink_get_ts_offset:
+ * @sink: the sink
+ *
+ * Get the synchronisation offset of @sink.
+ *
+ * Returns: The synchronisation offset.
+ *
+ * Since: 0.10.15
+ */
+GstClockTimeDiff
+gst_base_sink_get_ts_offset (GstBaseSink * sink)
+{
+  GstClockTimeDiff res;
+
+  g_return_val_if_fail (GST_IS_BASE_SINK (sink), 0);
+
+  GST_OBJECT_LOCK (sink);
+  res = sink->priv->ts_offset;
+  GST_OBJECT_UNLOCK (sink);
+
+  return res;
+}
+
+/**
  * gst_base_sink_get_latency:
  * @sink: the sink
  *
@@ -845,6 +908,9 @@ gst_base_sink_set_property (GObject * object, guint prop_id,
     case PROP_ASYNC:
       gst_base_sink_set_async_enabled (sink, g_value_get_boolean (value));
       break;
+    case PROP_TS_OFFSET:
+      gst_base_sink_set_ts_offset (sink, g_value_get_int64 (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -875,6 +941,9 @@ gst_base_sink_get_property (GObject * object, guint prop_id, GValue * value,
     case PROP_ASYNC:
       g_value_set_boolean (value, gst_base_sink_is_async_enabled (sink));
       break;
+    case PROP_TS_OFFSET:
+      g_value_set_int64 (value, gst_base_sink_get_ts_offset (sink));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1247,6 +1316,7 @@ gst_base_sink_wait_clock (GstBaseSink * basesink, GstClockTime time,
   GstClockID id;
   GstClockReturn ret;
   GstClock *clock;
+  GstClockTimeDiff ts_offset;
 
   if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (time)))
     goto invalid_time;
@@ -1262,6 +1332,17 @@ gst_base_sink_wait_clock (GstBaseSink * basesink, GstClockTime time,
   time += GST_ELEMENT_CAST (basesink)->base_time;
   time += basesink->priv->latency;
 
+  /* apply offset, be carefull for underflows */
+  ts_offset = basesink->priv->ts_offset;
+  if (ts_offset < 0) {
+    ts_offset = -ts_offset;
+    if (ts_offset < time)
+      time -= ts_offset;
+    else
+      time = 0;
+  } else
+    time += ts_offset;
+
   id = gst_clock_new_single_shot_id (clock, time);
   GST_OBJECT_UNLOCK (basesink);
 
index 000f179..438adf4 100644 (file)
@@ -205,6 +205,10 @@ gboolean   gst_base_sink_is_qos_enabled    (GstBaseSink *sink);
 void           gst_base_sink_set_async_enabled (GstBaseSink *sink, gboolean enabled);
 gboolean       gst_base_sink_is_async_enabled  (GstBaseSink *sink);
 
+/* tuning synchronisation */
+void           gst_base_sink_set_ts_offset     (GstBaseSink *sink, GstClockTimeDiff offset);
+GstClockTimeDiff gst_base_sink_get_ts_offset   (GstBaseSink *sink);
+
 /* latency */
 gboolean       gst_base_sink_query_latency     (GstBaseSink *sink, gboolean *live, gboolean *upstream_live,
                                                 GstClockTime *min_latency, GstClockTime *max_latency);