mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-23 12:30:11 +00:00
decklink2src: Implement soft restart
Instead of stopping stream, do pause, flush, and reset time mapping.
This commit is contained in:
parent
e5ad448f47
commit
7c4cae61b9
3 changed files with 33 additions and 16 deletions
|
@ -339,6 +339,7 @@ struct GstDeckLink2InputPrivate
|
||||||
signal = false;
|
signal = false;
|
||||||
was_restarted = false;
|
was_restarted = false;
|
||||||
stopping = false;
|
stopping = false;
|
||||||
|
need_restart = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::mutex lock;
|
std::mutex lock;
|
||||||
|
@ -346,6 +347,7 @@ struct GstDeckLink2InputPrivate
|
||||||
std::atomic < bool >signal;
|
std::atomic < bool >signal;
|
||||||
std::atomic < bool >was_restarted;
|
std::atomic < bool >was_restarted;
|
||||||
std::atomic <bool> stopping;
|
std::atomic <bool> stopping;
|
||||||
|
std::atomic <bool> need_restart;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstDeckLink2Input
|
struct _GstDeckLink2Input
|
||||||
|
@ -1503,20 +1505,27 @@ gst_decklink2_input_update_time_mapping (GstDeckLink2Input * self,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Must be called with lock taken */
|
||||||
static void
|
static void
|
||||||
gst_decklink2_input_do_restart (GstDeckLink2Input * self)
|
gst_decklink2_input_do_restart (GstDeckLink2Input * self)
|
||||||
{
|
{
|
||||||
GstDeckLink2InputPrivate *priv = self->priv;
|
GstDeckLink2InputPrivate *priv = self->priv;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (self, "Restaring input");
|
||||||
|
|
||||||
priv->was_restarted = true;
|
priv->was_restarted = true;
|
||||||
gst_decklink2_input_reset_time_mapping (self);
|
priv->need_restart = false;
|
||||||
gst_decklink2_input_stop_streams (self);
|
priv->lock.unlock ();
|
||||||
|
gst_decklink2_input_pause_streams (self);
|
||||||
gst_decklink2_input_flush_streams (self);
|
gst_decklink2_input_flush_streams (self);
|
||||||
|
gst_decklink2_input_start_streams (self);
|
||||||
|
priv->lock.lock ();
|
||||||
|
|
||||||
|
gst_decklink2_input_reset_time_mapping (self);
|
||||||
gst_adapter_clear (self->audio_buf);
|
gst_adapter_clear (self->audio_buf);
|
||||||
|
gst_queue_array_clear (self->queue);
|
||||||
self->audio_offset = INVALID_AUDIO_OFFSET;
|
self->audio_offset = INVALID_AUDIO_OFFSET;
|
||||||
self->next_audio_offset = INVALID_AUDIO_OFFSET;
|
self->next_audio_offset = INVALID_AUDIO_OFFSET;
|
||||||
|
|
||||||
gst_decklink2_input_start_streams (self);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1538,6 +1547,7 @@ gst_decklink2_input_on_frame_arrived (GstDeckLink2Input * self,
|
||||||
BMDTimeValue stream_dur;
|
BMDTimeValue stream_dur;
|
||||||
BMDFrameFlags flags = bmdFrameFlagDefault;
|
BMDFrameFlags flags = bmdFrameFlagDefault;
|
||||||
|
|
||||||
|
std::unique_lock < std::mutex > lk (priv->lock);
|
||||||
if (frame) {
|
if (frame) {
|
||||||
gboolean has_signal;
|
gboolean has_signal;
|
||||||
flags = frame->GetFlags ();
|
flags = frame->GetFlags ();
|
||||||
|
@ -1566,7 +1576,13 @@ gst_decklink2_input_on_frame_arrived (GstDeckLink2Input * self,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_lock < std::mutex > lk (priv->lock);
|
/* Restart requested, flush everything */
|
||||||
|
if (priv->need_restart) {
|
||||||
|
GST_DEBUG_OBJECT (self, "Restring as requested");
|
||||||
|
gst_decklink2_input_do_restart (self);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
hr = gst_decklink2_input_get_reference_clock (self, GST_SECOND,
|
hr = gst_decklink2_input_get_reference_clock (self, GST_SECOND,
|
||||||
&hw_now, &dummy, &dummy2);
|
&hw_now, &dummy, &dummy2);
|
||||||
if (!gst_decklink2_result (hr)) {
|
if (!gst_decklink2_result (hr)) {
|
||||||
|
@ -1622,7 +1638,6 @@ gst_decklink2_input_on_frame_arrived (GstDeckLink2Input * self,
|
||||||
|
|
||||||
pixel_format = frame->GetPixelFormat ();
|
pixel_format = frame->GetPixelFormat ();
|
||||||
if (pixel_format != self->pixel_format) {
|
if (pixel_format != self->pixel_format) {
|
||||||
lk.unlock ();
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "Unexpected pixel format change %d -> %d",
|
GST_DEBUG_OBJECT (self, "Unexpected pixel format change %d -> %d",
|
||||||
self->pixel_format, pixel_format);
|
self->pixel_format, pixel_format);
|
||||||
|
@ -1635,7 +1650,6 @@ gst_decklink2_input_on_frame_arrived (GstDeckLink2Input * self,
|
||||||
auto frame_height = frame->GetHeight ();
|
auto frame_height = frame->GetHeight ();
|
||||||
if (self->video_info.width != (gint) frame_width ||
|
if (self->video_info.width != (gint) frame_width ||
|
||||||
self->video_info.height != (gint) frame_height) {
|
self->video_info.height != (gint) frame_height) {
|
||||||
lk.unlock ();
|
|
||||||
|
|
||||||
GST_WARNING_OBJECT (self, "Unexpected resolution change %dx%d -> %dx%d",
|
GST_WARNING_OBJECT (self, "Unexpected resolution change %dx%d -> %dx%d",
|
||||||
self->video_info.width, self->video_info.height,
|
self->video_info.width, self->video_info.height,
|
||||||
|
@ -1958,6 +1972,7 @@ gst_decklink2_input_stop_unlocked (GstDeckLink2Input * self)
|
||||||
gst_clear_caps (&self->selected_audio_caps);
|
gst_clear_caps (&self->selected_audio_caps);
|
||||||
priv->signal = false;
|
priv->signal = false;
|
||||||
priv->was_restarted = false;
|
priv->was_restarted = false;
|
||||||
|
priv->need_restart = false;
|
||||||
self->skip_first_time = GST_CLOCK_TIME_NONE;
|
self->skip_first_time = GST_CLOCK_TIME_NONE;
|
||||||
self->start_time = GST_CLOCK_TIME_NONE;
|
self->start_time = GST_CLOCK_TIME_NONE;
|
||||||
self->started = FALSE;
|
self->started = FALSE;
|
||||||
|
@ -2145,6 +2160,12 @@ error:
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_decklink2_input_schedule_restart (GstDeckLink2Input * input)
|
||||||
|
{
|
||||||
|
input->priv->need_restart = true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_decklink2_input_stop (GstDeckLink2Input * input)
|
gst_decklink2_input_stop (GstDeckLink2Input * input)
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,6 +67,8 @@ HRESULT gst_decklink2_input_start (GstDeckLink2Input * input,
|
||||||
const GstDeckLink2InputVideoConfig * video_config,
|
const GstDeckLink2InputVideoConfig * video_config,
|
||||||
const GstDeckLink2InputAudioConfig * audio_config);
|
const GstDeckLink2InputAudioConfig * audio_config);
|
||||||
|
|
||||||
|
void gst_decklink2_input_schedule_restart (GstDeckLink2Input * input);
|
||||||
|
|
||||||
void gst_decklink2_input_stop (GstDeckLink2Input * input);
|
void gst_decklink2_input_stop (GstDeckLink2Input * input);
|
||||||
|
|
||||||
void gst_decklink2_input_set_flushing (GstDeckLink2Input * input,
|
void gst_decklink2_input_set_flushing (GstDeckLink2Input * input,
|
||||||
|
|
|
@ -680,12 +680,7 @@ again:
|
||||||
GST_STIME_FORMAT ", threshold %" GST_TIME_FORMAT,
|
GST_STIME_FORMAT ", threshold %" GST_TIME_FORMAT,
|
||||||
GST_STIME_ARGS (av_sync), GST_TIME_ARGS (self->desync_threshold));
|
GST_STIME_ARGS (av_sync), GST_TIME_ARGS (self->desync_threshold));
|
||||||
|
|
||||||
self->running = FALSE;
|
gst_decklink2_input_schedule_restart (self->input);
|
||||||
gst_decklink2_input_stop (self->input);
|
|
||||||
if (!gst_decklink2_src_run_unlocked (self, TRUE)) {
|
|
||||||
GST_ERROR_OBJECT (self, "Couldn't restart input");
|
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -801,8 +796,7 @@ gst_decklink2_src_restart (GstDeckLink2Src * self)
|
||||||
std::lock_guard < std::mutex > lk (priv->lock);
|
std::lock_guard < std::mutex > lk (priv->lock);
|
||||||
|
|
||||||
if (self->input && self->running) {
|
if (self->input && self->running) {
|
||||||
GST_INFO_OBJECT (self, "Stopping input for restart");
|
GST_INFO_OBJECT (self, "Scheduling restart");
|
||||||
self->running = FALSE;
|
gst_decklink2_input_schedule_restart (self->input);
|
||||||
gst_decklink2_input_stop (self->input);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue