diff options
author | Matthew Waters <matthew@centricular.com> | 2019-08-21 06:35:30 -0500 |
---|---|---|
committer | Tim-Philipp Müller <tim@centricular.com> | 2019-09-02 14:16:23 +0100 |
commit | df1140c3de904174d60cac10be856fa654014f53 (patch) | |
tree | be0b5e4d56405188940a053e3bd9a74e964bf3ff | |
parent | 01fc474ac2a273aef4266bf1fd8019ece4638bd7 (diff) | |
download | gstreamer-plugins-bad-df1140c3de904174d60cac10be856fa654014f53.tar.gz |
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.
-rw-r--r-- | sys/decklink/gstdecklinkaudiosink.cpp | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/sys/decklink/gstdecklinkaudiosink.cpp b/sys/decklink/gstdecklinkaudiosink.cpp index 8407f65a2..546072485 100644 --- a/sys/decklink/gstdecklinkaudiosink.cpp +++ b/sys/decklink/gstdecklinkaudiosink.cpp @@ -609,7 +609,7 @@ gst_decklink_audio_sink_render (GstBaseSink * bsink, GstBuffer * buffer) GstClockTime buffered_time; guint32 written = 0; GstClock *clock; - GstClockTime clock_ahead; + GstClockTimeDiff clock_ahead; if (GST_BASE_SINK_CAST (self)->flushing) { flow_ret = GST_FLOW_FLUSHING; @@ -664,14 +664,13 @@ gst_decklink_audio_sink_render (GstBaseSink * bsink, GstBuffer * buffer) else clock_now = 0; - if (clock_now < running_time) - clock_ahead = running_time - clock_now; + clock_ahead = running_time - clock_now; } } GST_DEBUG_OBJECT (self, - "Ahead %" GST_TIME_FORMAT " of the clock running time", - GST_TIME_ARGS (clock_ahead)); + "Ahead %" GST_STIME_FORMAT " of the clock running time", + GST_STIME_ARGS (clock_ahead)); if (self->output-> output->GetBufferedAudioSampleFrameCount (&buffered_samples) != S_OK) @@ -683,13 +682,35 @@ gst_decklink_audio_sink_render (GstBaseSink * bsink, GstBuffer * buffer) GST_DEBUG_OBJECT (self, "Buffered %" GST_TIME_FORMAT " in the driver (%u 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 - if (buffered_time > self->buffer_time || clock_ahead > self->buffer_time) { + if (((GstClockTime) clock_ahead) > self->buffer_time) { GstClockReturn clock_ret; GstClockTime wait_time = running_time; 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) wait_time = 0; |