From 95bab882253e8a368f72e5cb19a7ac1e489b8417 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 21 Jan 2015 18:09:03 +0100 Subject: [PATCH] gstv4l2bufferpool: handle -EPIPE from DQBUF to signal EOS The V4L2 decoder signals EOS by returning -EPIPE from DQBUF after the last buffer. https://bugzilla.gnome.org/show_bug.cgi?id=743338 --- sys/v4l2/gstv4l2allocator.c | 19 +++++++++++++------ sys/v4l2/gstv4l2allocator.h | 3 ++- sys/v4l2/gstv4l2bufferpool.c | 10 ++++++++-- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/sys/v4l2/gstv4l2allocator.c b/sys/v4l2/gstv4l2allocator.c index b3d02eb..6dd39bf 100644 --- a/sys/v4l2/gstv4l2allocator.c +++ b/sys/v4l2/gstv4l2allocator.c @@ -1269,8 +1269,9 @@ done: return ret; } -GstV4l2MemoryGroup * -gst_v4l2_allocator_dqbuf (GstV4l2Allocator * allocator) +GstFlowReturn +gst_v4l2_allocator_dqbuf (GstV4l2Allocator * allocator, + GstV4l2MemoryGroup ** group_out) { struct v4l2_buffer buffer = { 0 }; struct v4l2_plane planes[VIDEO_MAX_PLANES] = { {0} }; @@ -1278,7 +1279,7 @@ gst_v4l2_allocator_dqbuf (GstV4l2Allocator * allocator) GstV4l2MemoryGroup *group = NULL; - g_return_val_if_fail (g_atomic_int_get (&allocator->active), FALSE); + g_return_val_if_fail (g_atomic_int_get (&allocator->active), GST_FLOW_ERROR); buffer.type = allocator->type; buffer.memory = allocator->memory; @@ -1296,7 +1297,7 @@ gst_v4l2_allocator_dqbuf (GstV4l2Allocator * allocator) if (!IS_QUEUED (group->buffer)) { GST_ERROR_OBJECT (allocator, "buffer %i was not queued, this indicate a driver bug.", buffer.index); - return NULL; + return GST_FLOW_ERROR; } group->buffer = buffer; @@ -1334,9 +1335,15 @@ gst_v4l2_allocator_dqbuf (GstV4l2Allocator * allocator) for (i = 0; i < group->n_mem; i++) gst_memory_unref (group->mem[i]); - return group; + *group_out = group; + return GST_FLOW_OK; error: + if (errno == EPIPE) { + GST_DEBUG_OBJECT (allocator, "broken pipe signals last buffer"); + return GST_FLOW_EOS; + } + GST_ERROR_OBJECT (allocator, "failed dequeuing a %s buffer: %s", memory_type_to_str (allocator->memory), g_strerror (errno)); @@ -1378,7 +1385,7 @@ error: break; } - return NULL; + return GST_FLOW_ERROR; } void diff --git a/sys/v4l2/gstv4l2allocator.h b/sys/v4l2/gstv4l2allocator.h index 71c64a4..a260389 100644 --- a/sys/v4l2/gstv4l2allocator.h +++ b/sys/v4l2/gstv4l2allocator.h @@ -148,7 +148,8 @@ void gst_v4l2_allocator_flush (GstV4l2Allocator * alloc gboolean gst_v4l2_allocator_qbuf (GstV4l2Allocator * allocator, GstV4l2MemoryGroup * group); -GstV4l2MemoryGroup* gst_v4l2_allocator_dqbuf (GstV4l2Allocator * allocator); +GstFlowReturn gst_v4l2_allocator_dqbuf (GstV4l2Allocator * allocator, + GstV4l2MemoryGroup ** group); void gst_v4l2_allocator_reset_group (GstV4l2Allocator * allocator, GstV4l2MemoryGroup * group); diff --git a/sys/v4l2/gstv4l2bufferpool.c b/sys/v4l2/gstv4l2bufferpool.c index 7c963cc..bcf167d 100644 --- a/sys/v4l2/gstv4l2bufferpool.c +++ b/sys/v4l2/gstv4l2bufferpool.c @@ -1139,8 +1139,10 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2BufferPool * pool, GstBuffer ** buffer) GST_LOG_OBJECT (pool, "dequeueing a buffer"); - group = gst_v4l2_allocator_dqbuf (pool->vallocator); - if (group == NULL) + res = gst_v4l2_allocator_dqbuf (pool->vallocator, &group); + if (res == GST_FLOW_EOS) + goto eos; + if (res != GST_FLOW_OK) goto dqbuf_failed; /* get our GstBuffer with that index from the pool, if the buffer was @@ -1261,6 +1263,10 @@ poll_failed: GST_DEBUG_OBJECT (pool, "poll error %s", gst_flow_get_name (res)); return res; } +eos: + { + return GST_FLOW_EOS; + } dqbuf_failed: { return GST_FLOW_ERROR; -- 2.7.4