79
93
/* FIXME, enable pull mode when clock slaving and trick modes are figured out */
80
94
#define DEFAULT_CAN_ACTIVATE_PULL FALSE
82
/* when timestamps or clock slaving drift for more than 40ms we resync. This is
96
/* when timestamps drift for more than 40ms we resync. This should
97
* be anough to compensate for timestamp rounding errors. */
98
#define DEFAULT_ALIGNMENT_THRESHOLD (40 * GST_MSECOND)
100
/* when clock slaving drift for more than 40ms we resync. This is
83
101
* a reasonable default */
84
102
#define DEFAULT_DRIFT_TOLERANCE ((40 * GST_MSECOND) / GST_USECOND)
104
/* allow for one second before resyncing to see if the timestamps drift will
105
* fix itself, or is a permanent offset */
106
#define DEFAULT_DISCONT_WAIT (1 * GST_SECOND)
217
241
* GstBaseAudioSink:drift-tolerance
219
* Controls the amount of time in milliseconds that timestamps or clocks are allowed
243
* Controls the amount of time in microseconds that clocks are allowed
220
244
* to drift before resynchronisation happens.
224
248
g_object_class_install_property (gobject_class, PROP_DRIFT_TOLERANCE,
225
249
g_param_spec_int64 ("drift-tolerance", "Drift Tolerance",
226
"Tolerance for timestamp and clock drift in microseconds", 1,
250
"Tolerance for clock drift in microseconds", 1,
227
251
G_MAXINT64, DEFAULT_DRIFT_TOLERANCE,
228
252
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
254
* GstBaseAudioSink:alignment_threshold
256
* Controls the amount of time in nanoseconds that timestamps are allowed
257
* to drift from their ideal time before choosing not to align them.
261
g_object_class_install_property (gobject_class, PROP_ALIGNMENT_THRESHOLD,
262
g_param_spec_uint64 ("alignment-threshold", "Alignment Threshold",
263
"Timestamp alignment threshold in nanoseconds", 1,
264
G_MAXUINT64 - 1, DEFAULT_ALIGNMENT_THRESHOLD,
265
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
268
* GstBaseAudioSink:discont-wait
270
* A window of time in nanoseconds to wait before creating a discontinuity as
271
* a result of breaching the drift-tolerance.
275
g_object_class_install_property (gobject_class, PROP_DISCONT_WAIT,
276
g_param_spec_uint64 ("discont-wait", "Discont Wait",
277
"Window of time in nanoseconds to wait before "
278
"creating a discontinuity", 0,
279
G_MAXUINT64 - 1, DEFAULT_DISCONT_WAIT,
280
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
230
282
gstelement_class->change_state =
231
283
GST_DEBUG_FUNCPTR (gst_base_audio_sink_change_state);
435
489
basesink->priv->us_latency = min_l;
438
492
gst_util_uint64_scale_int (spec->seglatency * spec->segsize,
439
493
GST_SECOND, spec->rate * spec->bytes_per_sample);
440
494
GST_OBJECT_UNLOCK (basesink);
442
496
/* we cannot go lower than the buffer size and the min peer latency */
443
min_latency = min_latency + min_l;
497
min_latency = base_latency + min_l;
444
498
/* the max latency is the max of the peer, we can delay an infinite
445
499
* amount of time. */
446
max_latency = min_latency + (max_l == -1 ? 0 : max_l);
500
max_latency = (max_l == -1) ? -1 : (base_latency + max_l);
448
502
GST_DEBUG_OBJECT (basesink,
449
503
"peer min %" GST_TIME_FORMAT ", our min latency: %"
450
504
GST_TIME_FORMAT, GST_TIME_ARGS (min_l),
451
505
GST_TIME_ARGS (min_latency));
506
GST_DEBUG_OBJECT (basesink,
507
"peer max %" GST_TIME_FORMAT ", our max latency: %"
508
GST_TIME_FORMAT, GST_TIME_ARGS (max_l),
509
GST_TIME_ARGS (max_latency));
453
511
GST_DEBUG_OBJECT (basesink,
454
512
"peer or we are not live, don't care about latency");
717
* gst_base_audio_sink_set_alignment_threshold:
718
* @sink: a #GstBaseAudioSink
719
* @alignment_threshold: the new alignment threshold in nanoseconds
721
* Controls the sink's alignment threshold.
726
gst_base_audio_sink_set_alignment_threshold (GstBaseAudioSink * sink,
727
GstClockTime alignment_threshold)
729
g_return_if_fail (GST_IS_BASE_AUDIO_SINK (sink));
731
GST_OBJECT_LOCK (sink);
732
sink->priv->alignment_threshold = alignment_threshold;
733
GST_OBJECT_UNLOCK (sink);
737
* gst_base_audio_sink_get_alignment_threshold
738
* @sink: a #GstBaseAudioSink
740
* Get the current alignment threshold, in nanoseconds, used by @sink.
742
* Returns: The current alignment threshold used by @sink.
747
gst_base_audio_sink_get_alignment_threshold (GstBaseAudioSink * sink)
751
g_return_val_if_fail (GST_IS_BASE_AUDIO_SINK (sink), -1);
753
GST_OBJECT_LOCK (sink);
754
result = sink->priv->alignment_threshold;
755
GST_OBJECT_UNLOCK (sink);
761
* gst_base_audio_sink_set_discont_wait:
762
* @sink: a #GstBaseAudioSink
763
* @discont_wait: the new discont wait in nanoseconds
765
* Controls how long the sink will wait before creating a discontinuity.
770
gst_base_audio_sink_set_discont_wait (GstBaseAudioSink * sink,
771
GstClockTime discont_wait)
773
g_return_if_fail (GST_IS_BASE_AUDIO_SINK (sink));
775
GST_OBJECT_LOCK (sink);
776
sink->priv->discont_wait = discont_wait;
777
GST_OBJECT_UNLOCK (sink);
781
* gst_base_audio_sink_get_discont_wait
782
* @sink: a #GstBaseAudioSink
784
* Get the current discont wait, in nanoseconds, used by @sink.
786
* Returns: The current discont wait used by @sink.
791
gst_base_audio_sink_get_discont_wait (GstBaseAudioSink * sink)
795
g_return_val_if_fail (GST_IS_BASE_AUDIO_SINK (sink), -1);
797
GST_OBJECT_LOCK (sink);
798
result = sink->priv->discont_wait;
799
GST_OBJECT_UNLOCK (sink);
659
805
gst_base_audio_sink_set_property (GObject * object, guint prop_id,
660
806
const GValue * value, GParamSpec * pspec)
765
926
gst_ring_buffer_activate (sink->ringbuffer, TRUE);
929
/* due to possible changes in the spec file we should recalibrate the clock */
930
gst_clock_get_calibration (sink->provided_clock, NULL, NULL,
931
&crate_num, &crate_denom);
932
gst_clock_set_calibration (sink->provided_clock,
933
gst_clock_get_internal_time (sink->provided_clock), now, crate_num,
768
936
/* calculate actual latency and buffer times.
769
937
* FIXME: In 0.11, store the latency_time internally in ns */
770
938
spec->latency_time = gst_util_uint64_scale (spec->segsize,
1323
gst_base_audio_sink_get_alignment (GstBaseAudioSink * sink, GstClockTime sample_offset)
1493
gst_base_audio_sink_get_alignment (GstBaseAudioSink * sink,
1494
GstClockTime sample_offset)
1325
1496
GstRingBuffer *ringbuf = sink->ringbuffer;
1499
gint64 max_sample_diff;
1329
1500
gint segdone = g_atomic_int_get (&ringbuf->segdone) - ringbuf->segbase;
1330
1501
gint64 samples_done = segdone * ringbuf->samples_per_seg;
1331
1502
gint64 headroom = sample_offset - samples_done;
1332
1503
gboolean allow_align = TRUE;
1504
gboolean discont = FALSE;
1334
1506
/* now try to align the sample to the previous one, first see how big the
1335
1507
* difference is. */
1336
1508
if (sample_offset >= sink->next_sample)
1337
diff = sample_offset - sink->next_sample;
1509
sample_diff = sample_offset - sink->next_sample;
1339
diff = sink->next_sample - sample_offset;
1511
sample_diff = sink->next_sample - sample_offset;
1341
/* calculate the max allowed drift in units of samples. By default this is
1342
* 20ms and should be anough to compensate for timestamp rounding errors. */
1343
maxdrift = (ringbuf->spec.rate * sink->priv->drift_tolerance) / GST_MSECOND;
1513
/* calculate the max allowed drift in units of samples. */
1514
max_sample_diff = gst_util_uint64_scale_int (sink->priv->alignment_threshold,
1515
ringbuf->spec.rate, GST_SECOND);
1345
1517
/* calc align with previous sample */
1346
1518
align = sink->next_sample - sample_offset;
1348
1520
/* don't align if it means writing behind the read-segment */
1349
if (diff > headroom && align < 0)
1521
if (sample_diff > headroom && align < 0)
1350
1522
allow_align = FALSE;
1352
if (G_LIKELY (diff < maxdrift && allow_align)) {
1524
if (G_UNLIKELY (sample_diff >= max_sample_diff)) {
1525
/* wait before deciding to make a discontinuity */
1526
if (sink->priv->discont_wait > 0) {
1527
GstClockTime time = gst_util_uint64_scale_int (sample_offset,
1528
GST_SECOND, ringbuf->spec.rate);
1529
if (sink->priv->discont_time == -1) {
1530
/* discont candidate */
1531
sink->priv->discont_time = time;
1532
} else if (time - sink->priv->discont_time >= sink->priv->discont_wait) {
1533
/* discont_wait expired, discontinuity detected */
1535
sink->priv->discont_time = -1;
1540
} else if (G_UNLIKELY (sink->priv->discont_time != -1)) {
1541
/* we have had a discont, but are now back on track! */
1542
sink->priv->discont_time = -1;
1545
if (G_LIKELY (!discont && allow_align)) {
1353
1546
GST_DEBUG_OBJECT (sink,
1354
1547
"align with prev sample, ABS (%" G_GINT64_FORMAT ") < %"
1355
G_GINT64_FORMAT, align, maxdrift);
1548
G_GINT64_FORMAT, align, max_sample_diff);
1550
gint64 diff_s G_GNUC_UNUSED;
1357
1552
/* calculate sample diff in seconds for error message */
1358
gint64 diff_s = gst_util_uint64_scale_int (diff, GST_SECOND, ringbuf->spec.rate);
1554
gst_util_uint64_scale_int (sample_diff, GST_SECOND, ringbuf->spec.rate);
1359
1556
/* timestamps drifted apart from previous samples too much, we need to
1360
1557
* resync. We log this as an element warning. */
1361
1558
GST_WARNING_OBJECT (sink,
1362
1559
"Unexpected discontinuity in audio timestamps of "
1363
1560
"%s%" GST_TIME_FORMAT ", resyncing",
1364
sample_offset > sink->next_sample ? "+" : "-",
1365
GST_TIME_ARGS (diff_s));
1561
sample_offset > sink->next_sample ? "+" : "-", GST_TIME_ARGS (diff_s));
1706
1928
"dropping sample out of segment time %" GST_TIME_FORMAT ", start %"
1707
1929
GST_TIME_FORMAT, GST_TIME_ARGS (time),
1708
1930
GST_TIME_ARGS (bsink->segment.start));
1936
GST_DEBUG_OBJECT (sink, "dropping late sample");
1709
1937
return GST_FLOW_OK;
1942
GST_ELEMENT_ERROR (sink, STREAM, FORMAT, (NULL), ("failed to payload."));
1943
ret = GST_FLOW_ERROR;
1714
1948
GST_DEBUG_OBJECT (sink, "ringbuffer not negotiated");
1715
1949
GST_ELEMENT_ERROR (sink, STREAM, FORMAT, (NULL), ("sink not negotiated."));
1716
return GST_FLOW_NOT_NEGOTIATED;
1950
ret = GST_FLOW_NOT_NEGOTIATED;
1720
1955
GST_DEBUG_OBJECT (sink, "wrong size");
1721
1956
GST_ELEMENT_ERROR (sink, STREAM, WRONG_TYPE,
1722
1957
(NULL), ("sink received buffer of wrong size."));
1723
return GST_FLOW_ERROR;
1958
ret = GST_FLOW_ERROR;
1727
1963
GST_DEBUG_OBJECT (sink, "preroll got interrupted: %d (%s)", ret,
1728
1964
gst_flow_get_name (ret));
1731
1967
sync_latency_failed:
1733
1969
GST_DEBUG_OBJECT (sink, "failed waiting for latency");