diff options
author | Sebastian Dröge <sebastian@centricular.com> | 2017-11-27 17:41:52 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2017-12-14 10:37:20 +0200 |
commit | 3e70f00209520b3395a80fb2b69b2914885b6894 (patch) | |
tree | 8b1bdbecd8fd472dc167da691dc6dfb1f07fb579 | |
parent | 118b2967e725eeb5102e73415cbaf5b05ad1eafc (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.cpp | 37 |
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)); |