summaryrefslogtreecommitdiff
path: root/sys/decklink
diff options
context:
space:
mode:
authorMatthew Waters <matthew@centricular.com>2019-08-21 06:35:30 -0500
committerSebastian Dröge <slomo@coaxion.net>2019-09-02 11:09:02 +0000
commit82e23a27f7d85f77adf9f15c0cb20be3028607dd (patch)
treeb42d985397be6ddbbba97fa6b9c6d52a9a1c8a4f /sys/decklink
parente31c1423b7587db3c867d2a0385978a2c0d201db (diff)
downloadgstreamer-plugins-bad-82e23a27f7d85f77adf9f15c0cb20be3028607dd.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.
Diffstat (limited to 'sys/decklink')
-rw-r--r--sys/decklink/gstdecklinkaudiosink.cpp35
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;