v4l2: Handle corrupted buffer with empty payload
This allow skipping buffer flagged with ERROR that has no payload.
This is typical behaviour when a recovererable error occured during
capture in the driver, but that no valid data was ever written into that
buffer. This patch also translate V4L2_BUF_FLAG_ERROR into
GST_BUFFER_FLAG_CORRUPTED. Hence decoding error produce
by decoder due to missing frames will now be correctly marked. Finally,
this fixes a buffer leak when EOS is reached.
https://bugzilla.gnome.org/show_bug.cgi?id=740040
diff --git a/sys/v4l2/gstv4l2transform.c b/sys/v4l2/gstv4l2transform.c
index f645532..cfcc3dd 100644
--- a/sys/v4l2/gstv4l2transform.c
+++ b/sys/v4l2/gstv4l2transform.c
@@ -468,20 +468,23 @@
if (G_UNLIKELY (ret != GST_FLOW_OK))
goto beach;
- pool = gst_base_transform_get_buffer_pool (trans);
+ do {
+ pool = gst_base_transform_get_buffer_pool (trans);
- if (!gst_buffer_pool_set_active (pool, TRUE))
- goto activate_failed;
+ if (!gst_buffer_pool_set_active (pool, TRUE))
+ goto activate_failed;
- GST_DEBUG_OBJECT (self, "Dequeue output buffer");
- ret = gst_buffer_pool_acquire_buffer (pool, outbuf, NULL);
- g_object_unref (pool);
+ GST_DEBUG_OBJECT (self, "Dequeue output buffer");
+ ret = gst_buffer_pool_acquire_buffer (pool, outbuf, NULL);
+ g_object_unref (pool);
- if (ret != GST_FLOW_OK)
- goto alloc_failed;
+ if (ret != GST_FLOW_OK)
+ goto alloc_failed;
- pool = self->v4l2capture->pool;
- ret = gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL (pool), outbuf);
+ pool = self->v4l2capture->pool;
+ ret = gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL (pool), outbuf);
+
+ } while (ret == GST_V4L2_FLOW_CORRUPTED_BUFFER);
if (ret != GST_FLOW_OK) {
gst_buffer_unref (*outbuf);