From b5ff71fc3cbdf7ca868b3a3379dd39da436c6473 Mon Sep 17 00:00:00 2001 From: Vivia Nikolaidou Date: Fri, 29 Dec 2017 15:14:54 +0200 Subject: [PATCH] decklinkaudiosrc: Extrapolate stream/hw reference timestamps when video frame is missing Sometimes we might get an audio packet without a corresponding video frame. In these cases, the stream and hardware reference timestamps would be missing, because they're called on the video frame. Instead of potentially breaking stuff downstream that might depend on these, we now extrapolate them. https://bugzilla.gnome.org/show_bug.cgi?id=792042 --- sys/decklink/gstdecklinkaudiosrc.cpp | 26 ++++++++++++++++++++++++-- sys/decklink/gstdecklinkaudiosrc.h | 1 + 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/sys/decklink/gstdecklinkaudiosrc.cpp b/sys/decklink/gstdecklinkaudiosrc.cpp index efd42206d1..3abbc5081e 100644 --- a/sys/decklink/gstdecklinkaudiosrc.cpp +++ b/sys/decklink/gstdecklinkaudiosrc.cpp @@ -707,6 +707,27 @@ retry: // Detect gaps in stream time self->processed += sample_count; + if (self->expected_stream_time != GST_CLOCK_TIME_NONE + && p.stream_timestamp == GST_CLOCK_TIME_NONE) { + /* We missed a frame. Extrapolate the timestamps */ + p.stream_timestamp = self->expected_stream_time; + p.stream_duration = + gst_util_uint64_scale_int (sample_count, GST_SECOND, self->info.rate); + } + if (self->last_hardware_time != GST_CLOCK_TIME_NONE + && p.hardware_timestamp == GST_CLOCK_TIME_NONE) { + /* This should always happen when the previous one also does, but let's + * have two separate checks just in case */ + GstClockTime start_hw_offset, end_hw_offset; + start_hw_offset = + gst_util_uint64_scale (self->last_hardware_time, self->info.rate, + GST_SECOND); + end_hw_offset = start_hw_offset + sample_count; + p.hardware_timestamp = + gst_util_uint64_scale_int (end_hw_offset, GST_SECOND, self->info.rate); + /* Will be the same as the stream duration - reuse it */ + p.hardware_duration = p.stream_duration; + } if (p.stream_timestamp != GST_CLOCK_TIME_NONE) { GstClockTime start_stream_time, end_stream_time; @@ -738,14 +759,15 @@ retry: GST_FORMAT_TIME, timestamp); msg = - gst_message_new_qos (GST_OBJECT (self), TRUE, running_time, p.stream_timestamp, - timestamp, duration); + gst_message_new_qos (GST_OBJECT (self), TRUE, running_time, + p.stream_timestamp, timestamp, duration); gst_message_set_qos_stats (msg, GST_FORMAT_DEFAULT, self->processed, self->dropped); gst_element_post_message (GST_ELEMENT (self), msg); } self->expected_stream_time = end_stream_time; } + self->last_hardware_time = p.hardware_timestamp; if (p.no_signal) GST_BUFFER_FLAG_SET (*buffer, GST_BUFFER_FLAG_GAP); diff --git a/sys/decklink/gstdecklinkaudiosrc.h b/sys/decklink/gstdecklinkaudiosrc.h index c631d39e61..405da7ae50 100644 --- a/sys/decklink/gstdecklinkaudiosrc.h +++ b/sys/decklink/gstdecklinkaudiosrc.h @@ -75,6 +75,7 @@ struct _GstDecklinkAudioSrc GstClockTime expected_stream_time; guint64 processed; guint64 dropped; + GstClockTime last_hardware_time; /* Last time we noticed a discont */ GstClockTime discont_time;