mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
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 <felipe.contreras@gmail.com>
This commit is contained in:
parent
0a111bf26e
commit
3df415d4c7
2 changed files with 97 additions and 16 deletions
|
@ -62,12 +62,15 @@ struct _GstBaseAudioSinkPrivate
|
||||||
* before resyncing */
|
* before resyncing */
|
||||||
guint64 drift_tolerance;
|
guint64 drift_tolerance;
|
||||||
|
|
||||||
/* time of the previous detected discont candidate */
|
|
||||||
GstClockTime discont_time;
|
|
||||||
|
|
||||||
/* number of nanoseconds we allow timestamps to drift
|
/* number of nanoseconds we allow timestamps to drift
|
||||||
* before resyncing */
|
* before resyncing */
|
||||||
GstClockTime alignment_threshold;
|
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 */
|
/* BaseAudioSink signals and args */
|
||||||
|
@ -86,13 +89,17 @@ enum
|
||||||
/* FIXME, enable pull mode when clock slaving and trick modes are figured out */
|
/* FIXME, enable pull mode when clock slaving and trick modes are figured out */
|
||||||
#define DEFAULT_CAN_ACTIVATE_PULL FALSE
|
#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
|
/* when clock slaving drift for more than 40ms we resync. This is
|
||||||
* a reasonable default */
|
* a reasonable default */
|
||||||
#define DEFAULT_DRIFT_TOLERANCE ((40 * GST_MSECOND) / GST_USECOND)
|
#define DEFAULT_DRIFT_TOLERANCE ((40 * GST_MSECOND) / GST_USECOND)
|
||||||
|
|
||||||
/* when timestamps drift for more than 40ms we resync. This should
|
/* allow for one second before resyncing to see if the timestamps drift will
|
||||||
* be anough to compensate for timestamp rounding errors. */
|
* fix itself, or is a permanent offset */
|
||||||
#define DEFAULT_ALIGNMENT_THRESHOLD (40 * GST_MSECOND)
|
#define DEFAULT_DISCONT_WAIT (1 * GST_SECOND)
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -103,8 +110,9 @@ enum
|
||||||
PROP_PROVIDE_CLOCK,
|
PROP_PROVIDE_CLOCK,
|
||||||
PROP_SLAVE_METHOD,
|
PROP_SLAVE_METHOD,
|
||||||
PROP_CAN_ACTIVATE_PULL,
|
PROP_CAN_ACTIVATE_PULL,
|
||||||
PROP_DRIFT_TOLERANCE,
|
|
||||||
PROP_ALIGNMENT_THRESHOLD,
|
PROP_ALIGNMENT_THRESHOLD,
|
||||||
|
PROP_DRIFT_TOLERANCE,
|
||||||
|
PROP_DISCONT_WAIT,
|
||||||
|
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
};
|
};
|
||||||
|
@ -252,6 +260,19 @@ gst_base_audio_sink_class_init (GstBaseAudioSinkClass * klass)
|
||||||
G_MAXINT64, DEFAULT_ALIGNMENT_THRESHOLD,
|
G_MAXINT64, DEFAULT_ALIGNMENT_THRESHOLD,
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
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 =
|
gstelement_class->change_state =
|
||||||
GST_DEBUG_FUNCPTR (gst_base_audio_sink_change_state);
|
GST_DEBUG_FUNCPTR (gst_base_audio_sink_change_state);
|
||||||
gstelement_class->provide_clock =
|
gstelement_class->provide_clock =
|
||||||
|
@ -292,6 +313,7 @@ gst_base_audio_sink_init (GstBaseAudioSink * baseaudiosink,
|
||||||
baseaudiosink->priv->slave_method = DEFAULT_SLAVE_METHOD;
|
baseaudiosink->priv->slave_method = DEFAULT_SLAVE_METHOD;
|
||||||
baseaudiosink->priv->drift_tolerance = DEFAULT_DRIFT_TOLERANCE;
|
baseaudiosink->priv->drift_tolerance = DEFAULT_DRIFT_TOLERANCE;
|
||||||
baseaudiosink->priv->alignment_threshold = DEFAULT_ALIGNMENT_THRESHOLD;
|
baseaudiosink->priv->alignment_threshold = DEFAULT_ALIGNMENT_THRESHOLD;
|
||||||
|
baseaudiosink->priv->discont_wait = DEFAULT_DISCONT_WAIT;
|
||||||
|
|
||||||
baseaudiosink->provided_clock = gst_audio_clock_new ("GstAudioSinkClock",
|
baseaudiosink->provided_clock = gst_audio_clock_new ("GstAudioSinkClock",
|
||||||
(GstAudioClockGetTimeFunc) gst_base_audio_sink_get_time, baseaudiosink);
|
(GstAudioClockGetTimeFunc) gst_base_audio_sink_get_time, baseaudiosink);
|
||||||
|
@ -729,6 +751,50 @@ gst_base_audio_sink_get_alignment_threshold (GstBaseAudioSink * sink)
|
||||||
return result;
|
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
|
static void
|
||||||
gst_base_audio_sink_set_property (GObject * object, guint prop_id,
|
gst_base_audio_sink_set_property (GObject * object, guint prop_id,
|
||||||
const GValue * value, GParamSpec * pspec)
|
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,
|
gst_base_audio_sink_set_alignment_threshold (sink,
|
||||||
g_value_get_uint64 (value));
|
g_value_get_uint64 (value));
|
||||||
break;
|
break;
|
||||||
|
case PROP_DISCONT_WAIT:
|
||||||
|
gst_base_audio_sink_set_discont_wait (sink, g_value_get_uint64 (value));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -797,6 +866,9 @@ gst_base_audio_sink_get_property (GObject * object, guint prop_id,
|
||||||
g_value_set_uint64 (value,
|
g_value_set_uint64 (value,
|
||||||
gst_base_audio_sink_get_alignment_threshold (sink));
|
gst_base_audio_sink_get_alignment_threshold (sink));
|
||||||
break;
|
break;
|
||||||
|
case PROP_DISCONT_WAIT:
|
||||||
|
g_value_set_uint64 (value, gst_base_audio_sink_get_discont_wait (sink));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -1443,17 +1515,21 @@ gst_base_audio_sink_get_alignment (GstBaseAudioSink * sink,
|
||||||
if (sample_diff > headroom && align < 0)
|
if (sample_diff > headroom && align < 0)
|
||||||
allow_align = FALSE;
|
allow_align = FALSE;
|
||||||
|
|
||||||
/* wait before deciding to make a discontinuity */
|
|
||||||
if (G_UNLIKELY (sample_diff >= max_sample_diff)) {
|
if (G_UNLIKELY (sample_diff >= max_sample_diff)) {
|
||||||
GstClockTime time = gst_util_uint64_scale_int (sample_offset,
|
/* wait before deciding to make a discontinuity */
|
||||||
GST_SECOND, ringbuf->spec.rate);
|
if (sink->priv->discont_wait > 0) {
|
||||||
if (sink->priv->discont_time == -1) {
|
GstClockTime time = gst_util_uint64_scale_int (sample_offset,
|
||||||
/* discont candidate */
|
GST_SECOND, ringbuf->spec.rate);
|
||||||
sink->priv->discont_time = time;
|
if (sink->priv->discont_time == -1) {
|
||||||
} else if (time - sink->priv->discont_time >= GST_SECOND) {
|
/* discont candidate */
|
||||||
/* one second passed, discontinuity detected */
|
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;
|
discont = TRUE;
|
||||||
sink->priv->discont_time = -1;
|
|
||||||
}
|
}
|
||||||
} else if (G_UNLIKELY (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! */
|
/* we have had a discont, but are now back on track! */
|
||||||
|
|
|
@ -185,6 +185,11 @@ void gst_base_audio_sink_set_alignment_threshold (GstBaseAudioSink * sink,
|
||||||
GstClockTime
|
GstClockTime
|
||||||
gst_base_audio_sink_get_alignment_threshold (GstBaseAudioSink * sink);
|
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
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GST_BASE_AUDIO_SINK_H__ */
|
#endif /* __GST_BASE_AUDIO_SINK_H__ */
|
||||||
|
|
Loading…
Reference in a new issue