mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-23 04:20:17 +00:00
decklink2: Validate video buffer size
This commit is contained in:
parent
26abbb73bc
commit
e5ad448f47
2 changed files with 55 additions and 7 deletions
|
@ -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:
|
||||
|
|
|
@ -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 &&
|
||||
|
|
Loading…
Reference in a new issue