decklinkaudiosink: Drop late buffers

Asking decklink to render audio data seems to be based entirely on
the sample counts which completely disregards the timestamps
we pass to decklink.  As a result, we need to explicitly check
for late buffers and drop them ourselves.
This commit is contained in:
Matthew Waters 2019-08-21 06:35:30 -05:00 committed by Sebastian Dröge
parent e31c1423b7
commit 82e23a27f7

View file

@ -609,7 +609,7 @@ gst_decklink_audio_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
GstClockTime buffered_time; GstClockTime buffered_time;
guint32 written = 0; guint32 written = 0;
GstClock *clock; GstClock *clock;
GstClockTime clock_ahead; GstClockTimeDiff clock_ahead;
if (GST_BASE_SINK_CAST (self)->flushing) { if (GST_BASE_SINK_CAST (self)->flushing) {
flow_ret = GST_FLOW_FLUSHING; flow_ret = GST_FLOW_FLUSHING;
@ -664,14 +664,13 @@ gst_decklink_audio_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
else else
clock_now = 0; clock_now = 0;
if (clock_now < running_time)
clock_ahead = running_time - clock_now; clock_ahead = running_time - clock_now;
} }
} }
GST_DEBUG_OBJECT (self, GST_DEBUG_OBJECT (self,
"Ahead %" GST_TIME_FORMAT " of the clock running time", "Ahead %" GST_STIME_FORMAT " of the clock running time",
GST_TIME_ARGS (clock_ahead)); GST_STIME_ARGS (clock_ahead));
if (self->output-> if (self->output->
output->GetBufferedAudioSampleFrameCount (&buffered_samples) != S_OK) output->GetBufferedAudioSampleFrameCount (&buffered_samples) != S_OK)
@ -683,13 +682,35 @@ gst_decklink_audio_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
GST_DEBUG_OBJECT (self, GST_DEBUG_OBJECT (self,
"Buffered %" GST_TIME_FORMAT " in the driver (%u samples)", "Buffered %" GST_TIME_FORMAT " in the driver (%u samples)",
GST_TIME_ARGS (buffered_time), buffered_samples); GST_TIME_ARGS (buffered_time), buffered_samples);
{
GstClockTimeDiff buffered_ahead_of_clock_ahead = GST_CLOCK_DIFF (clock_ahead, buffered_time);
GST_DEBUG_OBJECT (self, "driver is %" GST_STIME_FORMAT " ahead of the "
"expected clock", GST_STIME_ARGS (buffered_ahead_of_clock_ahead));
/* we don't want to store too much data in the driver as decklink
* doesn't seem to actually use our provided timestamps to perform its
* own synchronisation. It seems to count samples instead. */
/* FIXME: do we need to split buffers? */
if (buffered_ahead_of_clock_ahead > 0 &&
buffered_ahead_of_clock_ahead > gst_base_sink_get_max_lateness (bsink)) {
GST_DEBUG_OBJECT (self, "Dropping buffer that is %" GST_STIME_FORMAT
" too late", GST_STIME_ARGS (buffered_ahead_of_clock_ahead));
if (self->resampler)
gst_audio_resampler_reset (self->resampler);
flow_ret = GST_FLOW_OK;
break;
}
}
// We start waiting once we have more than buffer-time buffered // We start waiting once we have more than buffer-time buffered
if (buffered_time > self->buffer_time || clock_ahead > self->buffer_time) { if (((GstClockTime) clock_ahead) > self->buffer_time) {
GstClockReturn clock_ret; GstClockReturn clock_ret;
GstClockTime wait_time = running_time; GstClockTime wait_time = running_time;
GST_DEBUG_OBJECT (self, GST_DEBUG_OBJECT (self,
"Buffered enough, wait for preroll or the clock or flushing"); "Buffered enough, wait for preroll or the clock or flushing. "
"Configured buffer time: %" GST_TIME_FORMAT, GST_TIME_ARGS (self->buffer_time));
if (wait_time < self->buffer_time) if (wait_time < self->buffer_time)
wait_time = 0; wait_time = 0;