Set DISCONT flag after signal loss or frame drop

This commit is contained in:
Sebastian Dröge 2023-06-14 12:02:51 +03:00
parent 002437f37d
commit 63b1e261b2

View file

@ -2156,7 +2156,7 @@ static void capture_thread_func(AJAThread *thread, void *data) {
GstClock *clock = NULL; GstClock *clock = NULL;
AUTOCIRCULATE_TRANSFER transfer; AUTOCIRCULATE_TRANSFER transfer;
guint64 frames_dropped_last = G_MAXUINT64; guint64 frames_dropped_last = G_MAXUINT64;
gboolean have_signal = TRUE; gboolean have_signal = TRUE, discont = TRUE;
guint iterations_without_frame = 0; guint iterations_without_frame = 0;
NTV2VideoFormat last_detected_video_format = ::NTV2_FORMAT_UNKNOWN; NTV2VideoFormat last_detected_video_format = ::NTV2_FORMAT_UNKNOWN;
@ -2228,6 +2228,7 @@ restart:
gst_queue_array_push_tail_struct(self->queue, &item); gst_queue_array_push_tail_struct(self->queue, &item);
g_cond_signal(&self->queue_cond); g_cond_signal(&self->queue_cond);
have_signal = FALSE; have_signal = FALSE;
discont = TRUE;
} }
self->device->device->WaitForInputVerticalInterrupt(self->channel); self->device->device->WaitForInputVerticalInterrupt(self->channel);
continue; continue;
@ -2351,6 +2352,7 @@ restart:
gst_queue_array_push_tail_struct(self->queue, &item); gst_queue_array_push_tail_struct(self->queue, &item);
g_cond_signal(&self->queue_cond); g_cond_signal(&self->queue_cond);
have_signal = FALSE; have_signal = FALSE;
discont = TRUE;
} }
self->device->device->WaitForInputVerticalInterrupt(self->channel); self->device->device->WaitForInputVerticalInterrupt(self->channel);
g_mutex_lock(&self->queue_lock); g_mutex_lock(&self->queue_lock);
@ -2387,6 +2389,7 @@ restart:
gst_queue_array_push_tail_struct(self->queue, &item); gst_queue_array_push_tail_struct(self->queue, &item);
g_cond_signal(&self->queue_cond); g_cond_signal(&self->queue_cond);
have_signal = FALSE; have_signal = FALSE;
discont = TRUE;
} }
self->device->device->WaitForInputVerticalInterrupt(self->channel); self->device->device->WaitForInputVerticalInterrupt(self->channel);
g_mutex_lock(&self->queue_lock); g_mutex_lock(&self->queue_lock);
@ -2436,6 +2439,7 @@ restart:
g_cond_signal(&self->queue_cond); g_cond_signal(&self->queue_cond);
frames_dropped_last = status.acFramesDropped; frames_dropped_last = status.acFramesDropped;
discont = TRUE;
} }
if (status.IsRunning() && status.acBufferLevel > 1) { if (status.IsRunning() && status.acBufferLevel > 1) {
@ -2589,6 +2593,7 @@ restart:
else else
now_gst = 0; now_gst = 0;
// TODO: Drift detection and compensation
GST_BUFFER_PTS(video_buffer) = now_gst; GST_BUFFER_PTS(video_buffer) = now_gst;
GST_BUFFER_DURATION(video_buffer) = gst_util_uint64_scale( GST_BUFFER_DURATION(video_buffer) = gst_util_uint64_scale(
GST_SECOND, self->configured_info.fps_d, self->configured_info.fps_n); GST_SECOND, self->configured_info.fps_d, self->configured_info.fps_n);
@ -2596,22 +2601,6 @@ restart:
GST_BUFFER_DURATION(audio_buffer) = gst_util_uint64_scale( GST_BUFFER_DURATION(audio_buffer) = gst_util_uint64_scale(
GST_SECOND, self->configured_info.fps_d, self->configured_info.fps_n); GST_SECOND, self->configured_info.fps_d, self->configured_info.fps_n);
// TODO: Drift detection and compensation
QueueItem item = {
.type = QUEUE_ITEM_TYPE_FRAME,
.frame = {.capture_time = now_gst,
.video_buffer = video_buffer,
.audio_buffer = audio_buffer,
.anc_buffer = anc_buffer,
.anc_buffer2 = anc_buffer2,
.tc = time_code,
.detected_format =
(self->quad_mode
? ::GetQuadSizedVideoFormat(current_video_format)
: current_video_format),
.vpid = vpid_a}};
while (self->queue_num_frames >= self->queue_size) { while (self->queue_num_frames >= self->queue_size) {
guint n = gst_queue_array_get_length(self->queue); guint n = gst_queue_array_get_length(self->queue);
@ -2636,12 +2625,33 @@ restart:
gst_queue_array_drop_struct(self->queue, i, NULL); gst_queue_array_drop_struct(self->queue, i, NULL);
gst_queue_array_push_tail_struct(self->queue, &item); gst_queue_array_push_tail_struct(self->queue, &item);
self->queue_num_frames -= 1; self->queue_num_frames -= 1;
discont = TRUE;
g_cond_signal(&self->queue_cond); g_cond_signal(&self->queue_cond);
break; break;
} }
} }
} }
if (discont) {
GST_BUFFER_FLAG_SET(video_buffer, GST_BUFFER_FLAG_DISCONT);
GST_BUFFER_FLAG_SET(audio_buffer, GST_BUFFER_FLAG_DISCONT);
discont = FALSE;
}
QueueItem item = {
.type = QUEUE_ITEM_TYPE_FRAME,
.frame = {.capture_time = now_gst,
.video_buffer = video_buffer,
.audio_buffer = audio_buffer,
.anc_buffer = anc_buffer,
.anc_buffer2 = anc_buffer2,
.tc = time_code,
.detected_format =
(self->quad_mode
? ::GetQuadSizedVideoFormat(current_video_format)
: current_video_format),
.vpid = vpid_a}};
GST_TRACE_OBJECT(self, "Queuing frame %" GST_TIME_FORMAT, GST_TRACE_OBJECT(self, "Queuing frame %" GST_TIME_FORMAT,
GST_TIME_ARGS(now_gst)); GST_TIME_ARGS(now_gst));
gst_queue_array_push_tail_struct(self->queue, &item); gst_queue_array_push_tail_struct(self->queue, &item);
@ -2668,6 +2678,7 @@ restart:
gst_queue_array_push_tail_struct(self->queue, &item); gst_queue_array_push_tail_struct(self->queue, &item);
g_cond_signal(&self->queue_cond); g_cond_signal(&self->queue_cond);
have_signal = FALSE; have_signal = FALSE;
discont = TRUE;
} }
} }