gstv4l2bufferpool: handle -EPIPE from DQBUF to signal EOS
authorPhilipp Zabel <p.zabel@pengutronix.de>
Wed, 21 Jan 2015 17:09:03 +0000 (18:09 +0100)
committerNicolas Dufresne <nicolas.dufresne@collabora.co.uk>
Wed, 10 Jun 2015 01:56:40 +0000 (21:56 -0400)
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
sys/v4l2/gstv4l2allocator.h
sys/v4l2/gstv4l2bufferpool.c

index b3d02eb..6dd39bf 100644 (file)
@@ -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
index 71c64a4..a260389 100644 (file)
@@ -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);
index 7c963cc..bcf167d 100644 (file)
@@ -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;