baseaudiosink: split drift-tolerance into alignment-threshold

So that drift-tolerance is used for clock slaving resync, and
alignment-threshold is for timestamp drift.
This commit is contained in:
Felipe Contreras 2011-05-21 15:49:20 +03:00 committed by Wim Taymans
parent 58b9818853
commit 369cf3f14a
2 changed files with 86 additions and 7 deletions

View file

@ -58,9 +58,13 @@ struct _GstBaseAudioSinkPrivate
GstClockTime eos_time; GstClockTime eos_time;
gboolean do_time_offset; gboolean do_time_offset;
/* number of microseconds we allow timestamps or clock slaving to drift /* number of microseconds we allow clock slaving to drift
* before resyncing */ * before resyncing */
guint64 drift_tolerance; guint64 drift_tolerance;
/* number of nanoseconds we allow timestamps to drift
* before resyncing */
GstClockTime alignment_threshold;
}; };
/* BaseAudioSink signals and args */ /* BaseAudioSink signals and args */
@ -79,10 +83,14 @@ 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 or 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
* be anough to compensate for timestamp rounding errors. */
#define DEFAULT_ALIGNMENT_THRESHOLD (40 * GST_MSECOND)
enum enum
{ {
PROP_0, PROP_0,
@ -93,6 +101,7 @@ enum
PROP_SLAVE_METHOD, PROP_SLAVE_METHOD,
PROP_CAN_ACTIVATE_PULL, PROP_CAN_ACTIVATE_PULL,
PROP_DRIFT_TOLERANCE, PROP_DRIFT_TOLERANCE,
PROP_ALIGNMENT_THRESHOLD,
PROP_LAST PROP_LAST
}; };
@ -216,16 +225,29 @@ gst_base_audio_sink_class_init (GstBaseAudioSinkClass * klass)
/** /**
* GstBaseAudioSink:drift-tolerance * GstBaseAudioSink:drift-tolerance
* *
* Controls the amount of time in microseconds that timestamps or clocks are allowed * Controls the amount of time in microseconds that clocks are allowed
* to drift before resynchronisation happens. * to drift before resynchronisation happens.
* *
* Since: 0.10.26 * Since: 0.10.26
*/ */
g_object_class_install_property (gobject_class, PROP_DRIFT_TOLERANCE, g_object_class_install_property (gobject_class, PROP_DRIFT_TOLERANCE,
g_param_spec_int64 ("drift-tolerance", "Drift Tolerance", g_param_spec_int64 ("drift-tolerance", "Drift Tolerance",
"Tolerance for timestamp and clock drift in microseconds", 1, "Tolerance for clock drift in microseconds", 1,
G_MAXINT64, DEFAULT_DRIFT_TOLERANCE, G_MAXINT64, DEFAULT_DRIFT_TOLERANCE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GstBaseAudioSink:alignment_threshold
*
* Controls the amount of time in nanoseconds that timestamps are allowed
* to drift from their ideal time before choosing not to align them.
*
* Since: 0.10.26
*/
g_object_class_install_property (gobject_class, PROP_ALIGNMENT_THRESHOLD,
g_param_spec_int64 ("alignment-threshold", "Alignment Threshold",
"Timestamp alignment threshold in nanoseconds", 1,
G_MAXINT64, DEFAULT_ALIGNMENT_THRESHOLD,
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);
@ -266,6 +288,7 @@ gst_base_audio_sink_init (GstBaseAudioSink * baseaudiosink,
baseaudiosink->provide_clock = DEFAULT_PROVIDE_CLOCK; baseaudiosink->provide_clock = DEFAULT_PROVIDE_CLOCK;
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->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);
@ -659,6 +682,50 @@ gst_base_audio_sink_get_drift_tolerance (GstBaseAudioSink * sink)
return result; return result;
} }
/**
* gst_base_audio_sink_set_alignment_threshold:
* @sink: a #GstBaseAudioSink
* @alignment_threshold: the new alignment threshold in nanoseconds
*
* Controls the sink's alignment threshold.
*
* Since: 0.10.31
*/
void
gst_base_audio_sink_set_alignment_threshold (GstBaseAudioSink * sink,
GstClockTime alignment_threshold)
{
g_return_if_fail (GST_IS_BASE_AUDIO_SINK (sink));
GST_OBJECT_LOCK (sink);
sink->priv->alignment_threshold = alignment_threshold;
GST_OBJECT_UNLOCK (sink);
}
/**
* gst_base_audio_sink_get_alignment_threshold
* @sink: a #GstBaseAudioSink
*
* Get the current alignment threshold, in nanoseconds, used by @sink.
*
* Returns: The current alignment threshold used by @sink.
*
* Since: 0.10.31
*/
GstClockTime
gst_base_audio_sink_get_alignment_threshold (GstBaseAudioSink * sink)
{
gint64 result;
g_return_val_if_fail (GST_IS_BASE_AUDIO_SINK (sink), -1);
GST_OBJECT_LOCK (sink);
result = sink->priv->alignment_threshold;
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)
@ -686,6 +753,10 @@ gst_base_audio_sink_set_property (GObject * object, guint prop_id,
case PROP_DRIFT_TOLERANCE: case PROP_DRIFT_TOLERANCE:
gst_base_audio_sink_set_drift_tolerance (sink, g_value_get_int64 (value)); gst_base_audio_sink_set_drift_tolerance (sink, g_value_get_int64 (value));
break; break;
case PROP_ALIGNMENT_THRESHOLD:
gst_base_audio_sink_set_alignment_threshold (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;
@ -719,6 +790,10 @@ gst_base_audio_sink_get_property (GObject * object, guint prop_id,
case PROP_DRIFT_TOLERANCE: case PROP_DRIFT_TOLERANCE:
g_value_set_int64 (value, gst_base_audio_sink_get_drift_tolerance (sink)); g_value_set_int64 (value, gst_base_audio_sink_get_drift_tolerance (sink));
break; break;
case PROP_ALIGNMENT_THRESHOLD:
g_value_set_uint64 (value,
gst_base_audio_sink_get_alignment_threshold (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;
@ -1351,9 +1426,8 @@ gst_base_audio_sink_get_alignment (GstBaseAudioSink * sink,
else else
diff = sink->next_sample - sample_offset; diff = sink->next_sample - sample_offset;
/* calculate the max allowed drift in units of samples. By default this is /* calculate the max allowed drift in units of samples. */
* 40ms and should be anough to compensate for timestamp rounding errors. */ maxdrift = (ringbuf->spec.rate * sink->priv->alignment_threshold) / GST_MSECOND;
maxdrift = (ringbuf->spec.rate * sink->priv->drift_tolerance) / GST_MSECOND;
/* calc align with previous sample */ /* calc align with previous sample */
align = sink->next_sample - sample_offset; align = sink->next_sample - sample_offset;

View file

@ -180,6 +180,11 @@ void gst_base_audio_sink_set_drift_tolerance (GstBaseAudioSink *sink,
gint64 drift_tolerance); gint64 drift_tolerance);
gint64 gst_base_audio_sink_get_drift_tolerance (GstBaseAudioSink *sink); gint64 gst_base_audio_sink_get_drift_tolerance (GstBaseAudioSink *sink);
void gst_base_audio_sink_set_alignment_threshold (GstBaseAudioSink * sink,
GstClockTime alignment_threshold);
GstClockTime
gst_base_audio_sink_get_alignment_threshold (GstBaseAudioSink * sink);
G_END_DECLS G_END_DECLS
#endif /* __GST_BASE_AUDIO_SINK_H__ */ #endif /* __GST_BASE_AUDIO_SINK_H__ */