v4l2: increase by one the number of allocated buffers
authorGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>
Wed, 24 May 2017 13:07:51 +0000 (15:07 +0200)
committerNicolas Dufresne <nicolas.dufresne@collabora.com>
Thu, 29 Jun 2017 19:13:18 +0000 (15:13 -0400)
Increasing this number fix a buffer starvation problem I'm hitting
with a "v4l2src ! kmssink" pipeline.

kmssink requests 2 buffer as it keeps a reference on the last rendered
one. So we were allocating 3 buffers for the pipeline.
Once the first 2 buffers have been pushed we ended up with:
- one buffer queued in v4l2
- one being pushed
- one kept as last rendered

If this 3rd buffer is released after that v4l2 used the first one to
capture we end up with a buffer starvation problem as no buffer is currently
queued in v4l2 for capture.

Fixing this by adding one extra buffer to the pipeline so when one
buffer is being pushed downstream the other can already be queued to
capture the next frame.

We were already adding 3 buffers if downstream didn't reply to the
allocation query. I reduced this number to 2 to compensate the extra
buffer which is now always added.

https://bugzilla.gnome.org/show_bug.cgi?id=783049

sys/v4l2/gstv4l2object.c

index b7ab4ab..ec7a9e2 100644 (file)
@@ -4092,14 +4092,16 @@ gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query)
   if (pushing_from_our_pool) {
     /* When pushing from our own pool, we need what downstream one, to be able
      * to fill the pipeline, the minimum required to decoder according to the
-     * driver and 1 more, so we don't endup up with everything downstream or
-     * held by the decoder. */
-    own_min = min + obj->min_buffers + 1;
+     * driver and 2 more, so we don't endup up with everything downstream or
+     * held by the decoder. We account 2 buffers for v4l2 so when one is being
+     * pushed downstream the other one can already be queued for the next
+     * frame. */
+    own_min = min + obj->min_buffers + 2;
 
     /* If no allocation parameters where provided, allow for a little more
      * buffers and enable copy threshold */
     if (!update) {
-      own_min += 3;
+      own_min += 2;
       gst_v4l2_buffer_pool_copy_at_threshold (GST_V4L2_BUFFER_POOL (pool),
           TRUE);
     } else {