gst-libs/gst/audio/gstaudioclock.c: This clock can be slaved to a master clock now.
authorWim Taymans <wim.taymans@gmail.com>
Tue, 22 Nov 2005 18:32:09 +0000 (18:32 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Tue, 22 Nov 2005 18:32:09 +0000 (18:32 +0000)
Original commit message from CVS:
* gst-libs/gst/audio/gstaudioclock.c: (gst_audio_clock_init):
This clock can be slaved to a master clock now.

* gst-libs/gst/audio/gstbaseaudiosink.c:
(gst_base_audio_sink_class_init), (gst_base_audio_sink_init),
(gst_base_audio_sink_dispose), (gst_base_audio_sink_provide_clock),
(gst_base_audio_sink_set_clock),
(gst_base_audio_sink_set_property),
(gst_base_audio_sink_get_property), (gst_base_audio_sink_preroll),
(gst_base_audio_sink_render), (gst_base_audio_sink_change_state):
* gst-libs/gst/audio/gstbaseaudiosink.h:
Handle slaving the internal clock to the clock selected in the
pipeline.
Add property to make the basesink not provide a clock.

* gst-libs/gst/rtp/gstbasertpdepayload.c:
(gst_base_rtp_depayload_class_init), (gst_base_rtp_depayload_init),
(gst_base_rtp_depayload_wait):
* gst-libs/gst/rtp/gstbasertpdepayload.h:
We can use the clock in GstElement, no need to store it ourselves.

ChangeLog
gst-libs/gst/audio/gstaudioclock.c
gst-libs/gst/audio/gstbaseaudiosink.c
gst-libs/gst/audio/gstbaseaudiosink.h
gst-libs/gst/rtp/gstbasertpdepayload.c
gst-libs/gst/rtp/gstbasertpdepayload.h

index a93ff77..c36da40 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2005-11-22  Wim Taymans  <wim@fluendo.com>
+
+       * gst-libs/gst/audio/gstaudioclock.c: (gst_audio_clock_init):
+       This clock can be slaved to a master clock now.
+
+       * gst-libs/gst/audio/gstbaseaudiosink.c:
+       (gst_base_audio_sink_class_init), (gst_base_audio_sink_init),
+       (gst_base_audio_sink_dispose), (gst_base_audio_sink_provide_clock),
+       (gst_base_audio_sink_set_clock),
+       (gst_base_audio_sink_set_property),
+       (gst_base_audio_sink_get_property), (gst_base_audio_sink_preroll),
+       (gst_base_audio_sink_render), (gst_base_audio_sink_change_state):
+       * gst-libs/gst/audio/gstbaseaudiosink.h:
+       Handle slaving the internal clock to the clock selected in the
+       pipeline.
+       Add property to make the basesink not provide a clock.
+
+       * gst-libs/gst/rtp/gstbasertpdepayload.c:
+       (gst_base_rtp_depayload_class_init), (gst_base_rtp_depayload_init),
+       (gst_base_rtp_depayload_wait):
+       * gst-libs/gst/rtp/gstbasertpdepayload.h:
+       We can use the clock in GstElement, no need to store it ourselves.
+
 2005-11-22  Thomas Vander Stichele  <thomas at apestaart dot org>
 
        * docs/libs/tmpl/gstaudio.sgml:
index c878f39..76a8d97 100644 (file)
@@ -83,6 +83,7 @@ gst_audio_clock_init (GstAudioClock * clock)
   gst_object_set_name (GST_OBJECT (clock), "GstAudioClock");
 
   clock->last_time = 0;
+  GST_OBJECT_FLAG_SET (clock, GST_CLOCK_FLAG_CAN_SET_MASTER);
 }
 
 GstClock *
index 3ae18dd..6881d90 100644 (file)
@@ -41,11 +41,15 @@ enum
 
 #define DEFAULT_BUFFER_TIME    500 * GST_USECOND
 #define DEFAULT_LATENCY_TIME   10 * GST_USECOND
+//#define DEFAULT_PROVIDE_CLOCK TRUE
+#define DEFAULT_PROVIDE_CLOCK  FALSE
+
 enum
 {
   PROP_0,
   PROP_BUFFER_TIME,
   PROP_LATENCY_TIME,
+  PROP_PROVIDE_CLOCK,
 };
 
 #define _do_init(bla) \
@@ -65,7 +69,8 @@ static GstStateChangeReturn gst_base_audio_sink_change_state (GstElement *
     element, GstStateChange transition);
 
 static GstClock *gst_base_audio_sink_provide_clock (GstElement * elem);
-static void gst_base_audio_sink_set_clock (GstElement * elem, GstClock * clock);
+static gboolean gst_base_audio_sink_set_clock (GstElement * elem,
+    GstClock * clock);
 static GstClockTime gst_base_audio_sink_get_time (GstClock * clock,
     GstBaseAudioSink * sink);
 static void gst_base_audio_sink_callback (GstRingBuffer * rbuf, guint8 * data,
@@ -114,6 +119,10 @@ gst_base_audio_sink_class_init (GstBaseAudioSinkClass * klass)
       g_param_spec_int64 ("latency-time", "Latency Time",
           "Audio latency in milliseconds (-1 = default)",
           -1, G_MAXINT64, DEFAULT_LATENCY_TIME, G_PARAM_READWRITE));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PROVIDE_CLOCK,
+      g_param_spec_boolean ("provide-clock", "Provide Clock",
+          "Provide a clock to be used as the global pipeline clock",
+          DEFAULT_PROVIDE_CLOCK, G_PARAM_READWRITE));
 
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_base_audio_sink_change_state);
@@ -136,8 +145,9 @@ gst_base_audio_sink_init (GstBaseAudioSink * baseaudiosink,
 {
   baseaudiosink->buffer_time = DEFAULT_BUFFER_TIME;
   baseaudiosink->latency_time = DEFAULT_LATENCY_TIME;
+  baseaudiosink->provide_clock = DEFAULT_PROVIDE_CLOCK;
 
-  baseaudiosink->clock = gst_audio_clock_new ("clock",
+  baseaudiosink->provided_clock = gst_audio_clock_new ("clock",
       (GstAudioClockGetTimeFunc) gst_base_audio_sink_get_time, baseaudiosink);
 }
 
@@ -148,9 +158,9 @@ gst_base_audio_sink_dispose (GObject * object)
 
   sink = GST_BASE_AUDIO_SINK (object);
 
-  if (sink->clock)
-    gst_object_unref (sink->clock);
-  sink->clock = NULL;
+  if (sink->provided_clock)
+    gst_object_unref (sink->provided_clock);
+  sink->provided_clock = NULL;
 
   if (sink->ringbuffer)
     gst_object_unref (sink->ringbuffer);
@@ -167,25 +177,31 @@ gst_base_audio_sink_provide_clock (GstElement * elem)
 
   sink = GST_BASE_AUDIO_SINK (elem);
 
-  clock = GST_CLOCK_CAST (gst_object_ref (sink->clock));
+  if (sink->provide_clock)
+    clock = GST_CLOCK_CAST (gst_object_ref (sink->provided_clock));
+  else
+    clock = NULL;
 
   return clock;
 }
 
-static void
+static gboolean
 gst_base_audio_sink_set_clock (GstElement * elem, GstClock * clock)
 {
   GstBaseAudioSink *sink;
+  gboolean ret;
 
   sink = GST_BASE_AUDIO_SINK (elem);
 
   GST_OBJECT_LOCK (sink);
-  if (clock != sink->clock) {
-    gst_clock_set_master (sink->clock, clock);
+  if (clock != sink->provided_clock) {
+    ret = gst_clock_set_master (sink->provided_clock, clock);
   } else {
-    gst_clock_set_master (sink->clock, NULL);
+    ret = gst_clock_set_master (sink->provided_clock, NULL);
   }
   GST_OBJECT_UNLOCK (sink);
+
+  return ret;
 }
 
 static GstClockTime
@@ -220,6 +236,9 @@ gst_base_audio_sink_set_property (GObject * object, guint prop_id,
     case PROP_LATENCY_TIME:
       sink->latency_time = g_value_get_int64 (value);
       break;
+    case PROP_PROVIDE_CLOCK:
+      sink->provide_clock = g_value_get_boolean (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -241,6 +260,9 @@ gst_base_audio_sink_get_property (GObject * object, guint prop_id,
     case PROP_LATENCY_TIME:
       g_value_set_int64 (value, sink->latency_time);
       break;
+    case PROP_PROVIDE_CLOCK:
+      g_value_set_boolean (value, sink->provide_clock);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -350,8 +372,8 @@ wrong_state:
   {
     GST_DEBUG ("ringbuffer in wrong state");
     GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND,
-        ("sink not negotiated."), (NULL));
-    return GST_FLOW_ERROR;
+        ("sink not negotiated."), ("sink not negotiated."));
+    return GST_FLOW_NOT_NEGOTIATED;
   }
 }
 
@@ -441,7 +463,8 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
   if (render_diff < 0)
     goto out_of_segment;
 
-  gst_clock_get_calibration (sink->clock, &cinternal, &cexternal, &crate);
+  gst_clock_get_calibration (sink->provided_clock, &cinternal, &cexternal,
+      &crate);
   GST_DEBUG_OBJECT (sink,
       "internal %" G_GUINT64_FORMAT ", %" G_GUINT64_FORMAT ", rate %g",
       cinternal, cexternal, crate);
@@ -567,18 +590,23 @@ gst_base_audio_sink_change_state (GstElement * element,
       break;
     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
     {
-      GstClockTime time;
-      gdouble rate;
-
-      time = gst_clock_get_internal_time (sink->clock);
-
-      GST_DEBUG_OBJECT (sink, "time: %" GST_TIME_FORMAT, GST_TIME_ARGS (time));
-
-      gst_clock_get_calibration (sink->clock, NULL, NULL, &rate);
-      /* Does not work yet.
-         gst_clock_set_calibration (sink->clock, 
-         time, element->base_time, rate);
-       */
+      /* if we are slaved to a clock, we need to set the initial
+       * calibration */
+      /* FIXME, this is not yet accurate enough for smooth playback */
+      if (gst_clock_get_master (sink->provided_clock)) {
+        GstClockTime time;
+        gdouble rate;
+
+        time = gst_clock_get_internal_time (sink->provided_clock);
+
+        GST_DEBUG_OBJECT (sink, "time: %" GST_TIME_FORMAT,
+            GST_TIME_ARGS (time));
+
+        gst_clock_get_calibration (sink->provided_clock, NULL, NULL, &rate);
+        /* Does not work yet. */
+        gst_clock_set_calibration (sink->provided_clock,
+            time, element->base_time, rate);
+      }
       break;
     }
     case GST_STATE_CHANGE_PAUSED_TO_READY:
index 86d8fe3..52bbf1e 100644 (file)
@@ -84,7 +84,8 @@ struct _GstBaseAudioSink {
   guint64       next_sample;
 
   /* clock */
-  GstClock     *clock;
+  gboolean       provide_clock;
+  GstClock     *provided_clock;
 
   /*< private >*/
   gpointer _gst_reserved[GST_PADDING];
index 8822c36..95256b4 100644 (file)
@@ -80,8 +80,6 @@ static gboolean gst_base_rtp_depayload_setcaps (GstPad * pad, GstCaps * caps);
 static GstFlowReturn gst_base_rtp_depayload_chain (GstPad * pad,
     GstBuffer * in);
 
-static void gst_base_rtp_depayload_set_clock (GstElement * element,
-    GstClock * clock);
 static GstStateChangeReturn gst_base_rtp_depayload_change_state (GstElement *
     element, GstStateChange transition);
 static GstFlowReturn gst_base_rtp_depayload_add_to_queue (GstBaseRTPDepayload *
@@ -118,8 +116,6 @@ gst_base_rtp_depayload_class_init (GstBaseRTPDepayloadClass * klass)
 
   gobject_class->finalize = gst_base_rtp_depayload_finalize;
 
-  gstelement_class->set_clock =
-      GST_DEBUG_FUNCPTR (gst_base_rtp_depayload_set_clock);
   gstelement_class->change_state = gst_base_rtp_depayload_change_state;
 
   klass->add_to_queue = gst_base_rtp_depayload_add_to_queue;
@@ -158,7 +154,6 @@ gst_base_rtp_depayload_init (GstBaseRTPDepayload * filter, gpointer g_class)
 
   /* this one needs to be overwritten by child */
   filter->clock_rate = 0;
-  filter->clock = NULL;
 }
 
 static void
@@ -399,27 +394,17 @@ gst_base_rtp_depayload_wait (GstBaseRTPDepayload * filter, GstClockTime time)
   GstClockID id;
 
   g_return_if_fail (GST_CLOCK_TIME_IS_VALID (time));
-  if (filter->clock == NULL) {
+  if (GST_ELEMENT_CLOCK (filter) == NULL) {
     GST_DEBUG_OBJECT (filter, "No clock given yet");
     return;
   }
 
-  id = gst_clock_new_single_shot_id (filter->clock, time);
+  id = gst_clock_new_single_shot_id (GST_ELEMENT_CLOCK (filter), time);
 
   gst_clock_id_wait (id, NULL);
   gst_clock_id_unref (id);
 }
 
-static void
-gst_base_rtp_depayload_set_clock (GstElement * element, GstClock * clock)
-{
-  GstBaseRTPDepayload *sink;
-
-  sink = GST_BASE_RTP_DEPAYLOAD (element);
-
-  sink->clock = clock;
-}
-
 static GstStateChangeReturn
 gst_base_rtp_depayload_change_state (GstElement * element,
     GstStateChange transition)
index 320da07..3dd0242 100644 (file)
@@ -78,8 +78,6 @@ struct _GstBaseRTPDepayload
    */
   GQueue *queue;
 
-  GstClock *clock;
-
   /*< private >*/
   union {
     gboolean need_newsegment;