mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 06:46:38 +00:00
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
This commit is contained in:
parent
2f9da0ab59
commit
6af863916a
2 changed files with 25 additions and 2 deletions
|
@ -707,6 +707,27 @@ retry:
|
||||||
|
|
||||||
// Detect gaps in stream time
|
// Detect gaps in stream time
|
||||||
self->processed += sample_count;
|
self->processed += sample_count;
|
||||||
|
if (self->expected_stream_time != GST_CLOCK_TIME_NONE
|
||||||
|
&& p.stream_timestamp == GST_CLOCK_TIME_NONE && !p.no_signal) {
|
||||||
|
/* 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 && !p.no_signal) {
|
||||||
|
/* 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) {
|
if (p.stream_timestamp != GST_CLOCK_TIME_NONE) {
|
||||||
GstClockTime start_stream_time, end_stream_time;
|
GstClockTime start_stream_time, end_stream_time;
|
||||||
|
@ -734,14 +755,15 @@ retry:
|
||||||
GST_FORMAT_TIME, timestamp);
|
GST_FORMAT_TIME, timestamp);
|
||||||
|
|
||||||
msg =
|
msg =
|
||||||
gst_message_new_qos (GST_OBJECT (self), TRUE, running_time, p.stream_timestamp,
|
gst_message_new_qos (GST_OBJECT (self), TRUE, running_time,
|
||||||
timestamp, duration);
|
p.stream_timestamp, timestamp, duration);
|
||||||
gst_message_set_qos_stats (msg, GST_FORMAT_DEFAULT, self->processed,
|
gst_message_set_qos_stats (msg, GST_FORMAT_DEFAULT, self->processed,
|
||||||
self->dropped);
|
self->dropped);
|
||||||
gst_element_post_message (GST_ELEMENT (self), msg);
|
gst_element_post_message (GST_ELEMENT (self), msg);
|
||||||
}
|
}
|
||||||
self->expected_stream_time = end_stream_time;
|
self->expected_stream_time = end_stream_time;
|
||||||
}
|
}
|
||||||
|
self->last_hardware_time = p.hardware_timestamp;
|
||||||
|
|
||||||
if (p.no_signal)
|
if (p.no_signal)
|
||||||
GST_BUFFER_FLAG_SET (*buffer, GST_BUFFER_FLAG_GAP);
|
GST_BUFFER_FLAG_SET (*buffer, GST_BUFFER_FLAG_GAP);
|
||||||
|
|
|
@ -75,6 +75,7 @@ struct _GstDecklinkAudioSrc
|
||||||
GstClockTime expected_stream_time;
|
GstClockTime expected_stream_time;
|
||||||
guint64 processed;
|
guint64 processed;
|
||||||
guint64 dropped;
|
guint64 dropped;
|
||||||
|
GstClockTime last_hardware_time;
|
||||||
|
|
||||||
/* Last time we noticed a discont */
|
/* Last time we noticed a discont */
|
||||||
GstClockTime discont_time;
|
GstClockTime discont_time;
|
||||||
|
|
Loading…
Reference in a new issue