mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-12 02:15:31 +00:00
decklinkvideosrc: Notify about signal loss even when dropping no-signal frames
Otherwise the application has no way of knowing that signal loss happened other than noticing a gap between actual frames.
This commit is contained in:
parent
dcff70d6bf
commit
5e4d10e296
1 changed files with 45 additions and 26 deletions
|
@ -190,6 +190,7 @@ typedef struct
|
||||||
static void
|
static void
|
||||||
capture_frame_clear (CaptureFrame * frame)
|
capture_frame_clear (CaptureFrame * frame)
|
||||||
{
|
{
|
||||||
|
if (frame->frame)
|
||||||
frame->frame->Release ();
|
frame->frame->Release ();
|
||||||
if (frame->tc)
|
if (frame->tc)
|
||||||
gst_video_time_code_free (frame->tc);
|
gst_video_time_code_free (frame->tc);
|
||||||
|
@ -823,9 +824,6 @@ gst_decklink_video_src_got_frame (GstElement * element,
|
||||||
GST_TIME_FORMAT "), no signal: %d", GST_TIME_ARGS (capture_time),
|
GST_TIME_FORMAT "), no signal: %d", GST_TIME_ARGS (capture_time),
|
||||||
GST_TIME_ARGS (stream_time), GST_TIME_ARGS (stream_duration), no_signal);
|
GST_TIME_ARGS (stream_time), GST_TIME_ARGS (stream_duration), no_signal);
|
||||||
|
|
||||||
if (self->drop_no_signal_frames && no_signal)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_mutex_lock (&self->lock);
|
g_mutex_lock (&self->lock);
|
||||||
if (self->first_time == GST_CLOCK_TIME_NONE)
|
if (self->first_time == GST_CLOCK_TIME_NONE)
|
||||||
self->first_time = stream_time;
|
self->first_time = stream_time;
|
||||||
|
@ -840,6 +838,18 @@ gst_decklink_video_src_got_frame (GstElement * element,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self->drop_no_signal_frames && no_signal) {
|
||||||
|
CaptureFrame f;
|
||||||
|
memset (&f, 0, sizeof (f));
|
||||||
|
|
||||||
|
/* Notify the streaming thread about the signal loss */
|
||||||
|
gst_queue_array_push_tail_struct (self->current_frames, &f);
|
||||||
|
g_cond_signal (&self->cond);
|
||||||
|
g_mutex_unlock (&self->lock);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
gst_decklink_video_src_update_time_mapping (self, capture_time, stream_time);
|
gst_decklink_video_src_update_time_mapping (self, capture_time, stream_time);
|
||||||
if (self->output_stream_time) {
|
if (self->output_stream_time) {
|
||||||
timestamp = stream_time;
|
timestamp = stream_time;
|
||||||
|
@ -871,10 +881,12 @@ gst_decklink_video_src_got_frame (GstElement * element,
|
||||||
self->buffer_size) {
|
self->buffer_size) {
|
||||||
CaptureFrame *tmp = (CaptureFrame *)
|
CaptureFrame *tmp = (CaptureFrame *)
|
||||||
gst_queue_array_pop_head_struct (self->current_frames);
|
gst_queue_array_pop_head_struct (self->current_frames);
|
||||||
|
if (tmp->frame) {
|
||||||
if (skipped_frames == 0)
|
if (skipped_frames == 0)
|
||||||
from_timestamp = tmp->timestamp;
|
from_timestamp = tmp->timestamp;
|
||||||
skipped_frames++;
|
skipped_frames++;
|
||||||
to_timestamp = tmp->timestamp;
|
to_timestamp = tmp->timestamp;
|
||||||
|
}
|
||||||
capture_frame_clear (tmp);
|
capture_frame_clear (tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1198,6 +1210,7 @@ gst_decklink_video_src_create (GstPushSrc * bsrc, GstBuffer ** buffer)
|
||||||
GST_STATIC_CAPS ("timestamp/x-decklink-hardware");
|
GST_STATIC_CAPS ("timestamp/x-decklink-hardware");
|
||||||
|
|
||||||
g_mutex_lock (&self->lock);
|
g_mutex_lock (&self->lock);
|
||||||
|
retry:
|
||||||
while (gst_queue_array_is_empty (self->current_frames) && !self->flushing) {
|
while (gst_queue_array_is_empty (self->current_frames) && !self->flushing) {
|
||||||
g_cond_wait (&self->cond, &self->lock);
|
g_cond_wait (&self->cond, &self->lock);
|
||||||
}
|
}
|
||||||
|
@ -1209,11 +1222,33 @@ gst_decklink_video_src_create (GstPushSrc * bsrc, GstBuffer ** buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
f = *(CaptureFrame *) gst_queue_array_pop_head_struct (self->current_frames);
|
f = *(CaptureFrame *) gst_queue_array_pop_head_struct (self->current_frames);
|
||||||
g_mutex_unlock (&self->lock);
|
|
||||||
|
// We will have no frame if frames without signal are dropped immediately
|
||||||
|
// but we still have to signal that it's lost here.
|
||||||
|
if (f.no_signal || !f.frame) {
|
||||||
|
if (!self->no_signal) {
|
||||||
|
self->no_signal = TRUE;
|
||||||
|
g_object_notify (G_OBJECT (self), "signal");
|
||||||
|
GST_ELEMENT_WARNING (GST_ELEMENT (self), RESOURCE, READ, ("No signal"),
|
||||||
|
("No input source was detected - video frames invalid"));
|
||||||
|
}
|
||||||
|
// If we have no frame here, simply retry until we got one
|
||||||
|
if (!f.frame) {
|
||||||
|
capture_frame_clear (&f);
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (self->no_signal) {
|
||||||
|
self->no_signal = FALSE;
|
||||||
|
g_object_notify (G_OBJECT (self), "signal");
|
||||||
|
GST_ELEMENT_INFO (GST_ELEMENT (self), RESOURCE, READ, ("Signal found"),
|
||||||
|
("Input source detected"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If we're not flushing, we should have a valid frame from the queue
|
// If we're not flushing, we should have a valid frame from the queue
|
||||||
g_assert (f.frame != NULL);
|
g_assert (f.frame != NULL);
|
||||||
|
|
||||||
g_mutex_lock (&self->lock);
|
|
||||||
if (self->caps_mode != f.mode) {
|
if (self->caps_mode != f.mode) {
|
||||||
if (self->mode == GST_DECKLINK_MODE_AUTO) {
|
if (self->mode == GST_DECKLINK_MODE_AUTO) {
|
||||||
GST_DEBUG_OBJECT (self, "Mode changed from %d to %d", self->caps_mode,
|
GST_DEBUG_OBJECT (self, "Mode changed from %d to %d", self->caps_mode,
|
||||||
|
@ -1304,22 +1339,6 @@ gst_decklink_video_src_create (GstPushSrc * bsrc, GstBuffer ** buffer)
|
||||||
vf->input = self->input->input;
|
vf->input = self->input->input;
|
||||||
vf->input->AddRef ();
|
vf->input->AddRef ();
|
||||||
|
|
||||||
if (f.no_signal) {
|
|
||||||
if (!self->no_signal) {
|
|
||||||
self->no_signal = TRUE;
|
|
||||||
g_object_notify (G_OBJECT (self), "signal");
|
|
||||||
GST_ELEMENT_WARNING (GST_ELEMENT (self), RESOURCE, READ, ("No signal"),
|
|
||||||
("No input source was detected - video frames invalid"));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (self->no_signal) {
|
|
||||||
self->no_signal = FALSE;
|
|
||||||
g_object_notify (G_OBJECT (self), "signal");
|
|
||||||
GST_ELEMENT_INFO (GST_ELEMENT (self), RESOURCE, READ, ("Signal found"),
|
|
||||||
("Input source detected"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mode = gst_decklink_get_mode (self->mode);
|
mode = gst_decklink_get_mode (self->mode);
|
||||||
|
|
||||||
// If we have a format that supports VANC and we are asked to extract CC,
|
// If we have a format that supports VANC and we are asked to extract CC,
|
||||||
|
|
Loading…
Reference in a new issue