summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2017-11-27 17:41:52 +0200
committerSebastian Dröge <sebastian@centricular.com>2017-12-14 10:37:20 +0200
commit3e70f00209520b3395a80fb2b69b2914885b6894 (patch)
tree8b1bdbecd8fd472dc167da691dc6dfb1f07fb579
parent118b2967e725eeb5102e73415cbaf5b05ad1eafc (diff)
decklinkaudiosink: Check also against the clock if we run ahead of the clock too much
The buffer level as reported by the Decklink driver is completely unreliable, and we could otherwise easily run ahead >1s if we're unlucky. https://bugzilla.gnome.org/show_bug.cgi?id=790114
-rw-r--r--sys/decklink/gstdecklinkaudiosink.cpp37
1 files changed, 33 insertions, 4 deletions
diff --git a/sys/decklink/gstdecklinkaudiosink.cpp b/sys/decklink/gstdecklinkaudiosink.cpp
index c97c07447..e39ee4544 100644
--- a/sys/decklink/gstdecklinkaudiosink.cpp
+++ b/sys/decklink/gstdecklinkaudiosink.cpp
@@ -585,6 +585,9 @@ gst_decklink_audio_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
self->info.rate);
guint32 buffered_samples;
GstClockTime buffered_time;
+ guint32 written = 0;
+ GstClock *clock;
+ GstClockTime clock_ahead;
if (GST_BASE_SINK_CAST (self)->flushing) {
flow_ret = GST_FLOW_FLUSHING;
@@ -619,6 +622,35 @@ gst_decklink_audio_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
else
running_time = 0;
+ clock = gst_element_get_clock (GST_ELEMENT_CAST (self));
+ clock_ahead = 0;
+ if (clock) {
+ GstClockTime clock_now = gst_clock_get_time (clock);
+ GstClockTime base_time =
+ gst_element_get_base_time (GST_ELEMENT_CAST (self));
+ gst_object_unref (clock);
+ clock = NULL;
+
+ if (clock_now != GST_CLOCK_TIME_NONE && base_time != GST_CLOCK_TIME_NONE) {
+ GST_DEBUG_OBJECT (self,
+ "Clock time %" GST_TIME_FORMAT ", base time %" GST_TIME_FORMAT
+ ", target running time %" GST_TIME_FORMAT,
+ GST_TIME_ARGS (clock_now), GST_TIME_ARGS (base_time),
+ GST_TIME_ARGS (running_time));
+ if (clock_now > base_time)
+ clock_now -= base_time;
+ else
+ clock_now = 0;
+
+ if (clock_now < running_time)
+ clock_ahead = running_time - clock_now;
+ }
+ }
+
+ GST_DEBUG_OBJECT (self,
+ "Ahead %" GST_TIME_FORMAT " of the clock running time",
+ GST_TIME_ARGS (clock_ahead));
+
if (self->output->
output->GetBufferedAudioSampleFrameCount (&buffered_samples) != S_OK)
buffered_samples = 0;
@@ -630,7 +662,7 @@ gst_decklink_audio_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
"Buffered %" GST_TIME_FORMAT " in the driver (%u samples)",
GST_TIME_ARGS (buffered_time), buffered_samples);
// We start waiting once we have more than buffer-time buffered
- if (buffered_time > self->buffer_time) {
+ if (buffered_time > self->buffer_time || clock_ahead > self->buffer_time) {
GstClockReturn clock_ret;
GstClockTime wait_time = running_time;
@@ -666,7 +698,6 @@ gst_decklink_audio_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
&schedule_time, &schedule_time_duration);
if (!self->output->started) {
- guint32 written = 0;
GST_LOG_OBJECT (self, "Writing audio frame synchronously because PAUSED");
ret =
@@ -695,8 +726,6 @@ gst_decklink_audio_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
else
written_all += written;
} else {
- guint32 written = 0;
-
GST_LOG_OBJECT (self, "Scheduling audio samples at %" GST_TIME_FORMAT
" with duration %" GST_TIME_FORMAT, GST_TIME_ARGS (schedule_time),
GST_TIME_ARGS (schedule_time_duration));