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