decklink2: Validate video buffer size

This commit is contained in:
Seungha Yang 2023-12-14 19:27:50 +09:00
parent 26abbb73bc
commit e5ad448f47
2 changed files with 55 additions and 7 deletions

View file

@ -43,9 +43,12 @@ struct _GstDeckLink2Demux
GstPad *sink_pad;
GstPad *video_pad;
GstPad *audio_pad;
GstVideoInfo video_info;
GstFlowCombiner *flow_combiner;
GstCaps *audio_caps;
guint drop_count;
};
static void gst_decklink2_demux_finalize (GObject * object);
@ -132,6 +135,7 @@ gst_decklink2_demux_change_state (GstElement * element,
switch (transition) {
case GST_STATE_CHANGE_READY_TO_PAUSED:
gst_clear_caps (&self->audio_caps);
self->drop_count = 0;
break;
default:
break;
@ -163,6 +167,7 @@ gst_decklink2_demux_chain (GstPad * sinkpad, GstObject * parent,
GstDeckLink2AudioMeta *meta;
GstSample *audio_sample = NULL;
GstFlowReturn ret;
gsize buf_size;
meta = gst_buffer_get_decklink2_audio_meta (inbuf);
if (meta) {
@ -230,6 +235,23 @@ gst_decklink2_demux_chain (GstPad * sinkpad, GstObject * parent,
}
out:
buf_size = gst_buffer_get_size (inbuf);
if (buf_size < self->video_info.size) {
GST_WARNING_OBJECT (self, "Too small buffer size %" G_GSIZE_FORMAT
" < %" G_GSIZE_FORMAT, buf_size, self->video_info.size);
gst_buffer_unref (inbuf);
self->drop_count++;
if (self->drop_count > 30) {
GST_ERROR_OBJECT (self, "Too many buffers were dropped");
return GST_FLOW_ERROR;
}
return GST_FLOW_OK;
}
self->drop_count = 0;
GST_LOG_OBJECT (self, "Pushing video buffer %" GST_PTR_FORMAT, inbuf);
ret = gst_pad_push (self->video_pad, inbuf);
ret = gst_flow_combiner_update_pad_flow (self->flow_combiner,
@ -262,6 +284,8 @@ gst_decklink2_demux_sink_event (GstPad * sinkpad, GstObject * parent,
gst_event_parse_caps (event, &caps);
GST_DEBUG_OBJECT (self, "Forwarding %" GST_PTR_FORMAT, caps);
gst_video_info_from_caps (&self->video_info, caps);
return gst_pad_push_event (self->video_pad, event);
}
case GST_EVENT_FLUSH_STOP:

View file

@ -593,8 +593,15 @@ gst_decklink2_src_create (GstPushSrc * src, GstBuffer ** buffer)
GstDeckLink2SrcPrivate *priv = self->priv;
gboolean is_gap_buf = FALSE;
GstClockTimeDiff av_sync;
guint retry_count = 0;
gsize buf_size;
again:
if (retry_count > 30) {
GST_ERROR_OBJECT (self, "Too many buffers were dropped");
return GST_FLOW_ERROR;
}
if (!gst_decklink2_src_run (self)) {
GST_ELEMENT_ERROR (self, STREAM, FAILED, (NULL),
("Failed to start stream"));
@ -605,17 +612,26 @@ again:
if (ret != GST_FLOW_OK) {
if (ret == GST_DECKLINK2_INPUT_FLOW_STOPPED) {
GST_DEBUG_OBJECT (self, "Input was stopped for restarting");
retry_count++;
goto again;
}
return ret;
}
std::unique_lock < std::mutex > lk (priv->lock);
if (caps && !gst_caps_is_equal (caps, self->selected_caps)) {
if (!caps) {
GST_WARNING_OBJECT (self, "Buffer without caps");
gst_clear_buffer (&buf);
retry_count++;
goto again;
}
priv->lock.lock ();
if (!gst_caps_is_equal (caps, self->selected_caps)) {
GST_DEBUG_OBJECT (self, "Set updated caps %" GST_PTR_FORMAT, caps);
gst_caps_replace (&self->selected_caps, caps);
lk.unlock ();
gst_video_info_from_caps (&self->video_info, caps);
priv->lock.unlock ();
if (!gst_pad_set_caps (GST_BASE_SRC_PAD (self), caps)) {
GST_ERROR_OBJECT (self, "Couldn't set caps");
gst_clear_buffer (&buf);
@ -623,9 +639,9 @@ again:
return GST_FLOW_NOT_NEGOTIATED;
}
lk.lock ();
} else {
priv->lock.unlock ();
}
gst_clear_caps (&caps);
if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_GAP))
@ -633,11 +649,19 @@ again:
if (is_gap_buf != self->is_gap_buf) {
self->is_gap_buf = is_gap_buf;
lk.unlock ();
g_object_notify (G_OBJECT (self), "signal");
lk.lock ();
}
buf_size = gst_buffer_get_size (buf);
if (buf_size < self->video_info.size) {
GST_WARNING_OBJECT (self, "Too small buffer size %" G_GSIZE_FORMAT
" < %" G_GSIZE_FORMAT, buf_size, self->video_info.size);
gst_clear_buffer (&buf);
retry_count++;
goto again;
}
std::unique_lock < std::mutex > lk (priv->lock);
*buffer = buf;
if (self->desync_threshold != 0 &&