From: Felipe Contreras Date: Mon, 2 May 2011 10:05:28 +0000 (+0300) Subject: baseaudiosink: make discont-wait configurable X-Git-Tag: 1.19.3~511^2~6555^2~348 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3df415d4c7d142cf07f805464ab9f41d098b505f;p=platform%2Fupstream%2Fgstreamer.git baseaudiosink: make discont-wait configurable Now we can configure how much time to wait before deciding that a discont has happened. Also, adds getter and setter to allow derived implementations to set this value upon construction. Suggestions and several improvements by Havard Graff. Signed-off-by: Felipe Contreras --- diff --git a/gst-libs/gst/audio/gstbaseaudiosink.c b/gst-libs/gst/audio/gstbaseaudiosink.c index dd531c9..eb4a0a3 100644 --- a/gst-libs/gst/audio/gstbaseaudiosink.c +++ b/gst-libs/gst/audio/gstbaseaudiosink.c @@ -62,12 +62,15 @@ struct _GstBaseAudioSinkPrivate * before resyncing */ guint64 drift_tolerance; - /* time of the previous detected discont candidate */ - GstClockTime discont_time; - /* number of nanoseconds we allow timestamps to drift * before resyncing */ GstClockTime alignment_threshold; + + /* time of the previous detected discont candidate */ + GstClockTime discont_time; + + /* number of nanoseconds to wait until creating a discontinuity */ + GstClockTime discont_wait; }; /* BaseAudioSink signals and args */ @@ -86,13 +89,17 @@ enum /* FIXME, enable pull mode when clock slaving and trick modes are figured out */ #define DEFAULT_CAN_ACTIVATE_PULL FALSE +/* when timestamps drift for more than 40ms we resync. This should + * be anough to compensate for timestamp rounding errors. */ +#define DEFAULT_ALIGNMENT_THRESHOLD (40 * GST_MSECOND) + /* when clock slaving drift for more than 40ms we resync. This is * a reasonable default */ #define DEFAULT_DRIFT_TOLERANCE ((40 * GST_MSECOND) / GST_USECOND) -/* when timestamps drift for more than 40ms we resync. This should - * be anough to compensate for timestamp rounding errors. */ -#define DEFAULT_ALIGNMENT_THRESHOLD (40 * GST_MSECOND) +/* allow for one second before resyncing to see if the timestamps drift will + * fix itself, or is a permanent offset */ +#define DEFAULT_DISCONT_WAIT (1 * GST_SECOND) enum { @@ -103,8 +110,9 @@ enum PROP_PROVIDE_CLOCK, PROP_SLAVE_METHOD, PROP_CAN_ACTIVATE_PULL, - PROP_DRIFT_TOLERANCE, PROP_ALIGNMENT_THRESHOLD, + PROP_DRIFT_TOLERANCE, + PROP_DISCONT_WAIT, PROP_LAST }; @@ -252,6 +260,19 @@ gst_base_audio_sink_class_init (GstBaseAudioSinkClass * klass) G_MAXINT64, DEFAULT_ALIGNMENT_THRESHOLD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstBaseAudioSink:discont-wait + * + * A window of time in nanoseconds to wait before creating a discontinuity as + * a result of breaching the drift-tolerance. + */ + g_object_class_install_property (gobject_class, PROP_DISCONT_WAIT, + g_param_spec_int64 ("discont-wait", "Discont Wait", + "Window of time in nanoseconds to wait before " + "creating a discontinuity", 0, + G_MAXINT64, DEFAULT_DISCONT_WAIT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_base_audio_sink_change_state); gstelement_class->provide_clock = @@ -292,6 +313,7 @@ gst_base_audio_sink_init (GstBaseAudioSink * baseaudiosink, baseaudiosink->priv->slave_method = DEFAULT_SLAVE_METHOD; baseaudiosink->priv->drift_tolerance = DEFAULT_DRIFT_TOLERANCE; baseaudiosink->priv->alignment_threshold = DEFAULT_ALIGNMENT_THRESHOLD; + baseaudiosink->priv->discont_wait = DEFAULT_DISCONT_WAIT; baseaudiosink->provided_clock = gst_audio_clock_new ("GstAudioSinkClock", (GstAudioClockGetTimeFunc) gst_base_audio_sink_get_time, baseaudiosink); @@ -729,6 +751,50 @@ gst_base_audio_sink_get_alignment_threshold (GstBaseAudioSink * sink) return result; } +/** + * gst_base_audio_sink_set_discont_wait: + * @sink: a #GstBaseAudioSink + * @discont_wait: the new discont wait in nanoseconds + * + * Controls how long the sink will wait before creating a discontinuity. + * + * Since: 0.10.31 + */ +void +gst_base_audio_sink_set_discont_wait (GstBaseAudioSink * sink, + GstClockTime discont_wait) +{ + g_return_if_fail (GST_IS_BASE_AUDIO_SINK (sink)); + + GST_OBJECT_LOCK (sink); + sink->priv->discont_wait = discont_wait; + GST_OBJECT_UNLOCK (sink); +} + +/** + * gst_base_audio_sink_get_discont_wait + * @sink: a #GstBaseAudioSink + * + * Get the current discont wait, in nanoseconds, used by @sink. + * + * Returns: The current discont wait used by @sink. + * + * Since: 0.10.31 + */ +GstClockTime +gst_base_audio_sink_get_discont_wait (GstBaseAudioSink * sink) +{ + GstClockTime result; + + g_return_val_if_fail (GST_IS_BASE_AUDIO_SINK (sink), -1); + + GST_OBJECT_LOCK (sink); + result = sink->priv->discont_wait; + GST_OBJECT_UNLOCK (sink); + + return result; +} + static void gst_base_audio_sink_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) @@ -760,6 +826,9 @@ gst_base_audio_sink_set_property (GObject * object, guint prop_id, gst_base_audio_sink_set_alignment_threshold (sink, g_value_get_uint64 (value)); break; + case PROP_DISCONT_WAIT: + gst_base_audio_sink_set_discont_wait (sink, g_value_get_uint64 (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -797,6 +866,9 @@ gst_base_audio_sink_get_property (GObject * object, guint prop_id, g_value_set_uint64 (value, gst_base_audio_sink_get_alignment_threshold (sink)); break; + case PROP_DISCONT_WAIT: + g_value_set_uint64 (value, gst_base_audio_sink_get_discont_wait (sink)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1443,17 +1515,21 @@ gst_base_audio_sink_get_alignment (GstBaseAudioSink * sink, if (sample_diff > headroom && align < 0) allow_align = FALSE; - /* wait before deciding to make a discontinuity */ if (G_UNLIKELY (sample_diff >= max_sample_diff)) { - GstClockTime time = gst_util_uint64_scale_int (sample_offset, - GST_SECOND, ringbuf->spec.rate); - if (sink->priv->discont_time == -1) { - /* discont candidate */ - sink->priv->discont_time = time; - } else if (time - sink->priv->discont_time >= GST_SECOND) { - /* one second passed, discontinuity detected */ + /* wait before deciding to make a discontinuity */ + if (sink->priv->discont_wait > 0) { + GstClockTime time = gst_util_uint64_scale_int (sample_offset, + GST_SECOND, ringbuf->spec.rate); + if (sink->priv->discont_time == -1) { + /* discont candidate */ + sink->priv->discont_time = time; + } else if (time - sink->priv->discont_time >= sink->priv->discont_wait) { + /* discont_wait expired, discontinuity detected */ + discont = TRUE; + sink->priv->discont_time = -1; + } + } else { discont = TRUE; - sink->priv->discont_time = -1; } } else if (G_UNLIKELY (sink->priv->discont_time != -1)) { /* we have had a discont, but are now back on track! */ diff --git a/gst-libs/gst/audio/gstbaseaudiosink.h b/gst-libs/gst/audio/gstbaseaudiosink.h index 0da0a15..e41a46a 100644 --- a/gst-libs/gst/audio/gstbaseaudiosink.h +++ b/gst-libs/gst/audio/gstbaseaudiosink.h @@ -185,6 +185,11 @@ void gst_base_audio_sink_set_alignment_threshold (GstBaseAudioSink * sink, GstClockTime gst_base_audio_sink_get_alignment_threshold (GstBaseAudioSink * sink); +void gst_base_audio_sink_set_discont_wait (GstBaseAudioSink * sink, + GstClockTime discont_wait); +GstClockTime + gst_base_audio_sink_get_discont_wait (GstBaseAudioSink * sink); + G_END_DECLS #endif /* __GST_BASE_AUDIO_SINK_H__ */