diff --git a/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudioaggregator.c b/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudioaggregator.c index d967a3295d..123cc78951 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudioaggregator.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudioaggregator.c @@ -1806,6 +1806,7 @@ gst_audio_aggregator_post_messages (GstAudioAggregator * aagg) * Replace the current buffer with input and update GstAudioAggregatorPadPrivate * values. */ +#define ABSDIFF(a, b) ((a) > (b) ? (a) - (b) : (b) - (a)) static gboolean gst_audio_aggregator_fill_buffer (GstAudioAggregator * aagg, GstAudioAggregatorPad * pad) @@ -1873,12 +1874,13 @@ gst_audio_aggregator_fill_buffer (GstAudioAggregator * aagg, pad->priv->new_segment = FALSE; } else { guint64 diff, max_sample_diff; + GstClockTime expected_time; /* Check discont, based on audiobasesink */ - if (start_offset <= pad->priv->next_offset) - diff = pad->priv->next_offset - start_offset; - else - diff = start_offset - pad->priv->next_offset; + diff = ABSDIFF (pad->priv->next_offset, start_offset); + + expected_time = + gst_util_uint64_scale (pad->priv->next_offset, GST_SECOND, rate); max_sample_diff = gst_util_uint64_scale_int (aagg->priv->alignment_threshold, rate, @@ -1888,8 +1890,11 @@ gst_audio_aggregator_fill_buffer (GstAudioAggregator * aagg, if (G_UNLIKELY (diff >= max_sample_diff)) { if (aagg->priv->discont_wait > 0) { if (pad->priv->discont_time == GST_CLOCK_TIME_NONE) { - pad->priv->discont_time = start_time; - } else if (start_time - pad->priv->discont_time >= + if (ABSDIFF (expected_time, start_time) >= aagg->priv->discont_wait) + discont = TRUE; + else + pad->priv->discont_time = expected_time; + } else if (ABSDIFF (start_time, pad->priv->discont_time) >= aagg->priv->discont_wait) { discont = TRUE; pad->priv->discont_time = GST_CLOCK_TIME_NONE; @@ -2046,6 +2051,8 @@ done: return TRUE; } +#undef ABSDIFF + /* Called with pad object lock held */ static gboolean diff --git a/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudiobasesink.c b/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudiobasesink.c index 1f843acf44..bc0b7c881f 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudiobasesink.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudiobasesink.c @@ -1728,6 +1728,7 @@ flushing: } } +#define ABSDIFF(a, b) ((a) > (b) ? (a) - (b) : (b) - (a)) static gint64 gst_audio_base_sink_get_alignment (GstAudioBaseSink * sink, GstClockTime sample_offset) @@ -1764,10 +1765,16 @@ gst_audio_base_sink_get_alignment (GstAudioBaseSink * sink, if (sink->priv->discont_wait > 0) { GstClockTime time = gst_util_uint64_scale_int (sample_offset, GST_SECOND, rate); + GstClockTime expected_time = gst_util_uint64_scale_int (sink->next_sample, + GST_SECOND, 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) { + if (ABSDIFF (expected_time, time) >= sink->priv->discont_wait) + discont = TRUE; + else + sink->priv->discont_time = expected_time; + } else if (ABSDIFF (time, + sink->priv->discont_time) >= sink->priv->discont_wait) { /* discont_wait expired, discontinuity detected */ discont = TRUE; sink->priv->discont_time = -1; @@ -1805,6 +1812,8 @@ gst_audio_base_sink_get_alignment (GstAudioBaseSink * sink, return align; } +#undef ABSDIFF + static GstFlowReturn gst_audio_base_sink_render (GstBaseSink * bsink, GstBuffer * buf) { diff --git a/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudiostreamalign.c b/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudiostreamalign.c index caabc842ed..89d9881069 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudiostreamalign.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudiostreamalign.c @@ -370,6 +370,7 @@ gst_audio_stream_align_process (GstAudioStreamAlign * align, discont = TRUE; } else { guint64 diff, max_sample_diff; + GstClockTime expected_time; /* Check discont */ if (align->rate > 0) { @@ -378,6 +379,10 @@ gst_audio_stream_align_process (GstAudioStreamAlign * align, diff = ABSDIFF (end_offset, align->next_offset); } + expected_time = + gst_util_uint64_scale (align->next_offset, GST_SECOND, + ABS (align->rate)); + max_sample_diff = gst_util_uint64_scale_int (align->alignment_threshold, ABS (align->rate), GST_SECOND); @@ -386,7 +391,14 @@ gst_audio_stream_align_process (GstAudioStreamAlign * align, if (G_UNLIKELY (diff >= max_sample_diff)) { if (align->discont_wait > 0) { if (align->discont_time == GST_CLOCK_TIME_NONE) { - align->discont_time = align->rate > 0 ? start_time : end_time; + if (align->rate > 0 + && ABSDIFF (expected_time, start_time) >= align->discont_wait) + discont = TRUE; + else if (align->rate < 0 + && ABSDIFF (expected_time, end_time) >= align->discont_wait) + discont = TRUE; + else + align->discont_time = expected_time; } else if ((align->rate > 0 && ABSDIFF (start_time, align->discont_time) >= align->discont_wait) diff --git a/subprojects/gst-plugins-base/tests/check/libs/audio.c b/subprojects/gst-plugins-base/tests/check/libs/audio.c index 7a01995e2d..1d570073f3 100644 --- a/subprojects/gst-plugins-base/tests/check/libs/audio.c +++ b/subprojects/gst-plugins-base/tests/check/libs/audio.c @@ -1005,17 +1005,17 @@ GST_START_TEST (test_stream_align) gst_audio_stream_align_process (align, discont, timestamp, 10, &out_timestamp, &out_duration, NULL); - fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); - fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); if (i == 0) fail_unless (discont); else fail_unless (!discont); + fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); + fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); } /* Drift forwards by 1ms per 10ms buffer for the first 40 buffers. * - after 40 buffers we're above alignment threshold - * - after 40 + 100 buffers we're at discont wait + * - after 40 + 96 buffers we're at discont wait */ for (i = 0; i < 500; i++) { timestamp = 10 * GST_MSECOND * i; @@ -1027,15 +1027,15 @@ GST_START_TEST (test_stream_align) gst_audio_stream_align_process (align, discont, timestamp, 10, &out_timestamp, &out_duration, NULL); - if (i < 140) { - fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); - fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); + if (i < 136) { if (i == 0) fail_unless (discont); else fail_unless (!discont); + fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); + fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); } else { - if (i == 140) + if (i == 136) fail_unless (discont); else fail_unless (!discont); @@ -1047,7 +1047,7 @@ GST_START_TEST (test_stream_align) /* Drift backwards by 1ms per 10ms buffer for the first 40 buffers. * - after 40 buffers we're above alignment threshold - * - after 40 + 100 buffers we're at discont wait + * - after 40 + 104 buffers we're at discont wait */ for (i = 0; i < 500; i++) { timestamp = 10 * GST_MSECOND * i; @@ -1059,15 +1059,15 @@ GST_START_TEST (test_stream_align) gst_audio_stream_align_process (align, discont, timestamp, 10, &out_timestamp, &out_duration, NULL); - if (i < 140) { - fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); - fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); + if (i < 144) { if (i == 0) fail_unless (discont); else fail_unless (!discont); + fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); + fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); } else { - if (i == 140) + if (i == 144) fail_unless (discont); else fail_unless (!discont); @@ -1080,7 +1080,7 @@ GST_START_TEST (test_stream_align) /* Shift all buffers but the first by 40ms * - after 1 buffers we're above alignment threshold - * - after 101 buffers we're at discont wait + * - after 97 buffers we're at discont wait */ for (i = 0; i < 500; i++) { timestamp = 10 * GST_MSECOND * i; @@ -1092,15 +1092,15 @@ GST_START_TEST (test_stream_align) gst_audio_stream_align_process (align, discont, timestamp, 10, &out_timestamp, &out_duration, NULL); - if (i < 101) { - fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); - fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); + if (i < 97) { if (i == 0) fail_unless (discont); else fail_unless (!discont); + fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); + fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); } else { - if (i == 101) + if (i == 97) fail_unless (discont); else fail_unless (!discont); @@ -1124,15 +1124,15 @@ GST_START_TEST (test_stream_align) gst_audio_stream_align_process (align, discont, timestamp, 10, &out_timestamp, &out_duration, NULL); - fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); - fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); if (i == 0) fail_unless (discont); else fail_unless (!discont); + fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); + fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); } - /* Shift every buffer 100 by 2: discont at buffer 200 + /* Shift every buffer after 100 by 2s: discont at buffer 100 */ for (i = 0; i < 500; i++) { timestamp = 10 * GST_MSECOND * i; @@ -1144,21 +1144,21 @@ GST_START_TEST (test_stream_align) gst_audio_stream_align_process (align, discont, timestamp, 10, &out_timestamp, &out_duration, NULL); - if (i < 200) { - fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); - fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); + if (i < 100) { if (i == 0) fail_unless (discont); else fail_unless (!discont); - } else { - fail_unless_equals_uint64 (out_timestamp, - 10 * GST_MSECOND * i + 2 * GST_SECOND); + fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); - if (i == 200) + } else { + if (i == 100) fail_unless (discont); else fail_unless (!discont); + fail_unless_equals_uint64 (out_timestamp, + 10 * GST_MSECOND * i + 2 * GST_SECOND); + fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); } } @@ -1185,12 +1185,12 @@ GST_START_TEST (test_stream_align_reverse) gst_audio_stream_align_process (align, discont, timestamp, 10, &out_timestamp, &out_duration, NULL); - fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); - fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); if (i == 499) fail_unless (discont); else fail_unless (!discont); + fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); + fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); } /* Drift forwards by 1ms per 10ms buffer for the first 40 buffers. @@ -1207,15 +1207,15 @@ GST_START_TEST (test_stream_align_reverse) gst_audio_stream_align_process (align, discont, timestamp, 10, &out_timestamp, &out_duration, NULL); - if (i >= 500 - 140) { - fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); - fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); + if (i >= 500 - 144) { if (i == 499) fail_unless (discont); else fail_unless (!discont); + fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); + fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); } else { - if (i == 499 - 140) + if (i == 499 - 144) fail_unless (discont); else fail_unless (!discont); @@ -1239,15 +1239,15 @@ GST_START_TEST (test_stream_align_reverse) gst_audio_stream_align_process (align, discont, timestamp, 10, &out_timestamp, &out_duration, NULL); - if (i >= 500 - 140) { - fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); - fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); + if (i >= 500 - 136) { if (i == 499) fail_unless (discont); else fail_unless (!discont); + fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); + fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); } else { - if (i == 499 - 140) + if (i == 499 - 136) fail_unless (discont); else fail_unless (!discont); @@ -1260,7 +1260,7 @@ GST_START_TEST (test_stream_align_reverse) /* Shift all buffers but the first by 40ms * - after 1 buffers we're above alignment threshold - * - after 101 buffers we're at discont wait + * - after 106 buffers we're at discont wait */ for (i = 499; i >= 0; i--) { timestamp = 10 * GST_MSECOND * i; @@ -1272,15 +1272,15 @@ GST_START_TEST (test_stream_align_reverse) gst_audio_stream_align_process (align, discont, timestamp, 10, &out_timestamp, &out_duration, NULL); - if (i >= 500 - 101) { - fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); - fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); + if (i >= 500 - 105) { if (i == 499) fail_unless (discont); else fail_unless (!discont); + fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); + fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); } else { - if (i == 499 - 101) + if (i == 499 - 105) fail_unless (discont); else fail_unless (!discont); @@ -1304,15 +1304,15 @@ GST_START_TEST (test_stream_align_reverse) gst_audio_stream_align_process (align, discont, timestamp, 10, &out_timestamp, &out_duration, NULL); - fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); - fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); if (i == 499) fail_unless (discont); else fail_unless (!discont); + fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); + fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); } - /* Shift buffer 100 by 2: discont at buffer 200 + /* Shift every buffer after 100 by 2s: discont at buffer 100 */ for (i = 499; i >= 0; i--) { timestamp = 10 * GST_MSECOND * i; @@ -1324,21 +1324,21 @@ GST_START_TEST (test_stream_align_reverse) gst_audio_stream_align_process (align, discont, timestamp, 10, &out_timestamp, &out_duration, NULL); - if (i >= 500 - 200) { - fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); - fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); + if (i >= 500 - 100) { if (i == 499) fail_unless (discont); else fail_unless (!discont); - } else { - fail_unless_equals_uint64 (out_timestamp, - 10 * GST_MSECOND * i + 2 * GST_SECOND); + fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i); fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); - if (i == 499 - 200) + } else { + if (i == 499 - 100) fail_unless (discont); else fail_unless (!discont); + fail_unless_equals_uint64 (out_timestamp, + 10 * GST_MSECOND * i + 2 * GST_SECOND); + fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND); } }