GNOME Bugzilla – Bug 783049
v4l2src: buffer starvation prevent pipeline to run as expected fps
Last modified: 2017-06-29 19:15:57 UTC
We are using this pipeline to test the performance on our hardware: gst-launch-1.0 -v v4l2src device=/dev/video1 io-mode=4 ! video/x-raw,format=NV12,width=3840,height=2160,framerate=30/1 ! fpsdisplaysink name=fpssink text-overlay=false video-sink=kmssink sync=true -v The fps reported by the sink are around 20 fps instead of the 30 expected. This seems to be because not enough buffers are allocated by v4l2src leading to a starvation problem.
Created attachment 352510 [details] [review] v4l2: increase by one the number of allocated buffers 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.
Review of attachment 352510 [details] [review]: ::: sys/v4l2/gstv4l2object.c @@ +3941,1 @@ if (pushing_from_our_pool) { I guess we want to increase the number of buffers also when not pushing from our pool?
(In reply to Guillaume Desmottes from comment #2) > Review of attachment 352510 [details] [review] [review]: > > ::: sys/v4l2/gstv4l2object.c > @@ +3941,1 @@ > if (pushing_from_our_pool) { > > I guess we want to increase the number of buffers also when not pushing from > our pool? I would believe not. When not pushing from our own pool, we'll have 2 buffers allocated. The flow would be something like: 1. 2 buffer queued 2. 1 buffer queued, 1 being copied 3. 2 buffer queued, pushing So we give back the buffer before we start pushing. That should reduce the risk of starving the capture. In the end, we'll starve the driver only if the copy takes longer then 1 frame duration, which is fine.
Ok cool, I didn't realise we were copying in this code path. Then I think my patch is ready for review in its current form.
Thanks. Attachment 352510 [details] pushed as 47ca2ce - v4l2: increase by one the number of allocated buffers