After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 753372 - v4l2src: io-mode=rw not always releasing video0 on v4l2_close
v4l2src: io-mode=rw not always releasing video0 on v4l2_close
Status: RESOLVED NOTGNOME
Product: GStreamer
Classification: Platform
Component: gst-plugins-good
1.4.5
Other Linux
: Normal normal
: git master
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2015-08-07 23:11 UTC by g
Modified: 2016-03-31 01:48 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
A hack that seems to work (1.95 KB, patch)
2015-08-07 23:11 UTC, g
none Details | Review
Code to see the problem (2.75 KB, text/plain)
2015-08-07 23:12 UTC, g
  Details
Output with patch (479.33 KB, text/plain)
2015-08-07 23:12 UTC, g
  Details
Output without patch (219.04 KB, text/plain)
2015-08-07 23:13 UTC, g
  Details
Makefile (317 bytes, text/plain)
2015-08-07 23:14 UTC, g
  Details

Description g 2015-08-07 23:11:45 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
Comment 1 g 2015-08-07 23:12:27 UTC
Created attachment 308927 [details]
Code to see the problem
Comment 2 g 2015-08-07 23:12:54 UTC
Created attachment 308928 [details]
Output with patch
Comment 3 g 2015-08-07 23:13:10 UTC
Created attachment 308929 [details]
Output without patch
Comment 4 g 2015-08-07 23:14:18 UTC
Created attachment 308930 [details]
Makefile

Not sure if this will be useful or not
Comment 5 Nicolas Dufresne (ndufresne) 2016-03-31 01:47:39 UTC
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.
Comment 6 Nicolas Dufresne (ndufresne) 2016-03-31 01:48:21 UTC
Please reopen if you found information that show otherwise.