From a9b40eebc018de6133b1af7d92582166df3bafc7 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Sun, 8 Jul 2018 09:54:04 -0500 Subject: [PATCH] decklink: keep the internal time we send to decklink always increasing Otherwise decklink seems to hold onto the latest frame and may cause a flash in the output if the played sequence has a framerate less than the video output. Scenario is play for N seconds, pause, flushing seek to some other position, play again. Each of the play sequences would normally start at 0 with the decklink time. As a result, the latest frame from the previous sequence is kept alive waiting for it's timestamp to pass before either dropping (if a subsequent frame in the new sequence overrides it) or displayed causing the out of place frame to be displayed. This is also supported by the debug logs from the decklink video sink element where a ScheduledFrameCompleted() callback would not occur for the frame until the above had happened. It was timing related as to whether the frame was displayed based on the decklink refresh cycle (which seems to be 16ms here), when the frame was scheduled by the sink and the difference between the 'time since vblank' of the two play requests (and thus start times of scheduled playback). --- sys/decklink/gstdecklinkvideosink.cpp | 4 ++++ sys/decklink/gstdecklinkvideosink.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/sys/decklink/gstdecklinkvideosink.cpp b/sys/decklink/gstdecklinkvideosink.cpp index cf8b42ced1..b7c969c691 100644 --- a/sys/decklink/gstdecklinkvideosink.cpp +++ b/sys/decklink/gstdecklinkvideosink.cpp @@ -605,6 +605,7 @@ gst_decklink_video_sink_convert_to_internal_clock (GstDecklinkVideoSink * self, } else { GST_LOG_OBJECT (self, "No clock conversion needed, same clocks"); } + *timestamp += self->scheduled_stop_time; } static GstFlowReturn @@ -956,6 +957,7 @@ gst_decklink_video_sink_start_scheduled_playback (GstElement * element) self->output->started = TRUE; self->output->clock_restart = TRUE; + self->output->clock_offset = self->scheduled_stop_time; // Need to unlock to get the clock time g_mutex_unlock (&self->output->lock); @@ -1024,6 +1026,8 @@ gst_decklink_video_sink_stop_scheduled_playback (GstDecklinkVideoSink * self) self->output->output->IsScheduledPlaybackRunning (&active); } while (active); } + if (start_time > 0) + self->scheduled_stop_time = start_time; self->internal_base_time = GST_CLOCK_TIME_NONE; self->external_base_time = GST_CLOCK_TIME_NONE; g_mutex_unlock (&self->output->lock); diff --git a/sys/decklink/gstdecklinkvideosink.h b/sys/decklink/gstdecklinkvideosink.h index 08eb0a0ecb..86108ece7f 100644 --- a/sys/decklink/gstdecklinkvideosink.h +++ b/sys/decklink/gstdecklinkvideosink.h @@ -61,6 +61,8 @@ struct _GstDecklinkVideoSink GstClockTime internal_base_time; GstClockTime external_base_time; + GstClockTime scheduled_stop_time; + GstDecklinkOutput *output; };