From a3cb4d493736157e96eb83d040352931875a2855 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 22 Nov 2005 18:32:09 +0000 Subject: [PATCH] gst-libs/gst/audio/gstaudioclock.c: This clock can be slaved to a master clock now. 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 | 23 ++++++++++ gst-libs/gst/audio/gstaudioclock.c | 1 + gst-libs/gst/audio/gstbaseaudiosink.c | 78 +++++++++++++++++++++++----------- gst-libs/gst/audio/gstbaseaudiosink.h | 3 +- gst-libs/gst/rtp/gstbasertpdepayload.c | 19 +-------- gst-libs/gst/rtp/gstbasertpdepayload.h | 2 - 6 files changed, 81 insertions(+), 45 deletions(-) diff --git a/ChangeLog b/ChangeLog index a93ff77..c36da40 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2005-11-22 Wim Taymans + + * 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 * docs/libs/tmpl/gstaudio.sgml: diff --git a/gst-libs/gst/audio/gstaudioclock.c b/gst-libs/gst/audio/gstaudioclock.c index c878f39..76a8d97 100644 --- a/gst-libs/gst/audio/gstaudioclock.c +++ b/gst-libs/gst/audio/gstaudioclock.c @@ -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 * diff --git a/gst-libs/gst/audio/gstbaseaudiosink.c b/gst-libs/gst/audio/gstbaseaudiosink.c index 3ae18dd..6881d90 100644 --- a/gst-libs/gst/audio/gstbaseaudiosink.c +++ b/gst-libs/gst/audio/gstbaseaudiosink.c @@ -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: diff --git a/gst-libs/gst/audio/gstbaseaudiosink.h b/gst-libs/gst/audio/gstbaseaudiosink.h index 86d8fe3..52bbf1e 100644 --- a/gst-libs/gst/audio/gstbaseaudiosink.h +++ b/gst-libs/gst/audio/gstbaseaudiosink.h @@ -84,7 +84,8 @@ struct _GstBaseAudioSink { guint64 next_sample; /* clock */ - GstClock *clock; + gboolean provide_clock; + GstClock *provided_clock; /*< private >*/ gpointer _gst_reserved[GST_PADDING]; diff --git a/gst-libs/gst/rtp/gstbasertpdepayload.c b/gst-libs/gst/rtp/gstbasertpdepayload.c index 8822c36..95256b4 100644 --- a/gst-libs/gst/rtp/gstbasertpdepayload.c +++ b/gst-libs/gst/rtp/gstbasertpdepayload.c @@ -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) diff --git a/gst-libs/gst/rtp/gstbasertpdepayload.h b/gst-libs/gst/rtp/gstbasertpdepayload.h index 320da07..3dd0242 100644 --- a/gst-libs/gst/rtp/gstbasertpdepayload.h +++ b/gst-libs/gst/rtp/gstbasertpdepayload.h @@ -78,8 +78,6 @@ struct _GstBaseRTPDepayload */ GQueue *queue; - GstClock *clock; - /*< private >*/ union { gboolean need_newsegment; -- 2.7.4