GNOME Bugzilla – Bug 753372
v4l2src: io-mode=rw not always releasing video0 on v4l2_close
Last modified: 2016-03-31 01:48:21 UTC
Created attachment 308926 [details] [review] A hack that seems to work When stopping a pipeline having v4l2src with io-mode=1 by setting it to NULL and then setting it back to PLAYING, I frequently cannot reopen /dev/video0 on the Raspberry Pi if Gstreamer didn't free all the buffers in the pool. When putting the bcm2835-v4l2 driver in debug mode, these messages are output to dmesg when it frees all the buffers properly: [17972.593172] bcm2835-v4l2: stopping capturing [17973.587120] bcm2835-v4l2: error 0 waiting for frame completion [17973.587150] bcm2835-v4l2: disabling connection [17973.589468] bcm2835-v4l2: Disabling camera [17973.608569] bcm2835-v4l2: Camera refcount now 0 When it doesn't free the buffers, nothing is output to dmesg on the v4l2_close, and then Gstreamer can't reopen /dev/video0. Looking at sys/v4l2/gstv4l2bufferpool.c, when Gstreamer doesn't free the buffers, in gst_v4l2_buffer_pool_flush_start it calls gst_poll_set_flushing before we've finished the v4l2_read in gst_v4l2_do_read, so the next gst_poll_wait will return EBUSY and we'll end up breaking out of the do while loop in gst_v4l2_do_read before the read is completed. If we just wait until that read completes, then it frees all the buffers and we apparently don't have any issues. However, why is the v4l2_close function, which is always called when setting the pipeline to NULL as shown with GST_DEBUG=v4l2*:9 printing "v4l2 v4l2_calls.c:710:gst_v4l2_close:<vidsrc> Trying to close /dev/video0", not calling the vb2_fop_release resulting in vb2_is_busy returning true as num_buffers is not zero? Shouldn't the v4l2_close clear those buffers even if they were in the middle of a read? I attached a patch to Gstreamer that appears to make this work, but this might be an issue in the video driver. I'm not entirely sure where to look from here. When running the demo application with the patch, it outputs (see works.log file, note "outstanding buffers 1" and a few "freeing buffer" messages after it): 0) Setting pipeline to PLAYING Pipeline state changed from NULL to READY, pending PLAYING: Pipeline state changed from READY to PAUSED, pending PLAYING: Pipeline state changed from PAUSED to PLAYING, pending VOID_PENDING: 0) Setting pipeline to NULL 1) Setting pipeline to PLAYING Pipeline state changed from NULL to READY, pending PLAYING: Pipeline state changed from READY to PAUSED, pending PLAYING: Pipeline state changed from PAUSED to PLAYING, pending VOID_PENDING: 1) Setting pipeline to NULL When running the demo application without the patch, it outputs (see doesnotwork.log file, note "outstanding buffers 1" and no "freeing buffer" messages): 0) Setting pipeline to PLAYING Pipeline state changed from NULL to READY, pending PLAYING: Pipeline state changed from READY to PAUSED, pending PLAYING: Pipeline state changed from PAUSED to PLAYING, pending VOID_PENDING: 0) Setting pipeline to NULL 1) Setting pipeline to PLAYING Pipeline state changed from NULL to READY, pending PLAYING: Pipeline state changed from READY to PAUSED, pending PLAYING: ERROR: Device '/dev/video0' is busy [Debug details: /home/leo/raspberry-pi/rpi-build/tmp/work/cortexa7hf-vfp-vfpv4-neon-poky-linux-gnueabi/gstreamer1.0-plugins-good/1.4.5-r0/gst-plugins-good-1.4.5/sys/v4l2/gstv4l2object.c(2838): gst_v4l2_object_set_format (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Call to S_FMT failed for YU12 @ 1280x720: Device or resource busy] 1) Setting pipeline to NULL
Created attachment 308927 [details] Code to see the problem
Created attachment 308928 [details] Output with patch
Created attachment 308929 [details] Output without patch
Created attachment 308930 [details] Makefile Not sure if this will be useful or not
Review of attachment 308926 [details] [review]: This does not sounds like not a GStreamer bug to me. In this case, the driver does not seem to support RW. That RW mode get emulated by libv4l2. The leak seems to be in that library.
Please reopen if you found information that show otherwise.