GNOME Bugzilla – Bug 670257
[v4l2src] fails to renegotiate from ready to paused
Last modified: 2012-06-29 13:15:06 UTC
Created attachment 207829 [details] Test app In the following pipeline: v4l2src ! capsfilter ! fakesink If we set the capsfilter to a 640x480 video format and start the pipeline, it should negotiate successfully. Then, we set the v4l2src to ready and change the capsfilter to 320x240 and set the v4l2src to playing. The problem is that the v4l2src fails to go to playing this second time. AFAIK, caps negotiation happens from ready to paused and the v4l2src should configure the new format and stream successfully. I'm attaching a test case.
Thanks Thiago, I'm having the same issue. Wanted to report the bug and found yours. I can confirm I'm having the exact same problem. Not sure what's causing it or how it could be fixed. I'll add that when going from READY to PAUSED state, libv4l2 prints the error: libv4l2: error setting pixformat: Device or resource busy and v4l2src sends WARNING messages : gst_v4l2_object_set_format:<v4l2src0> error: Device '/dev/video1' cannot capture at 320x240 gst_v4l2_object_set_format:<v4l2src0> error: Call to S_FMT failed for MJPG @ 320x240: Device or resource busy Showing that the VIDIOC_S_FMT does indeed get called and with the right width/height but for some reason it fails. Also, this happens when v4l2src is compiled with and without libv4l2.
If GST_STATE_READY is replaced with GST_STATE_PAUSED in the attached test code, the second GST_STATE_PLAYING is successful...hmmm...
I mean the test application attached when this bug report was opened.
That's because it doesn't check the new caps and it still captures using 640x480. Set the GST_DEBUG=v4l2*:5 env var to see what resolution it tries to use, you'll notice that when it switches the caps, v4l2src doesn't try to set the new format or anything (which makes me wonder why the capsfilter isn't throwing an error for incompatible caps).
If I place a GST_STATE_PAUSED and GST_STATE_NULL on either side of GST_STATE_READY then the second GST_STATE_PLAYING is successful as well... gst_element_set_state (src, GST_STATE_PAUSED); gst_element_set_state (src, GST_STATE_READY); gst_element_set_state (src, GST_STATE_NULL);
OK, but this works...it sets the caps to 320x240... gst_element_set_state (src, GST_STATE_PAUSED); gst_element_set_state (src, GST_STATE_READY); gst_element_set_state (src, GST_STATE_NULL); 0:00:05.227880823 [335m 4402[00m 0x1409b80 [31;01mERROR [00m [00;04m default test.c:62:reset_src_caps:[00m ### Setting to playing 0:00:05.231827510 [335m 4402[00m 0x1409b80 [36mDEBUG [00m [00m v4l2src gstv4l2src.c:640:gst_v4l2src_get_caps:<src>[00m unknown format 875967048 0:00:05.231860462 [335m 4402[00m 0x1409b80 [32;01mINFO [00m [00m v4l2src gstv4l2src.c:646:gst_v4l2src_get_caps:<src>[00m probed caps: video/x-raw-yuv, format=(fourcc)YUY2, width=(int)2304, height=(int)1536, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 2/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)2304, height=(int)1296, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 2/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)1920, height=(int)1080, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)1600, height=(int)896, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)1280, height=(int)720, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)960, height=(int)720, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)1024, height=(int)576, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)800, height=(int)600, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)864, height=(int)480, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)800, height=(int)448, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)640, height=(int)480, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)640, height=(int)360, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)432, height=(int)240, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)352, height=(int)288, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)320, height=(int)240, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)320, height=(int)180, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)176, height=(int)144, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)160, height=(int)120, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)160, height=(int)90, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)1920, height=(int)1080, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)1600, height=(int)896, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)1280, height=(int)720, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)960, height=(int)720, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)1024, height=(int)576, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)800, height=(int)600, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)864, height=(int)480, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)800, height=(int)448, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)640, height=(int)480, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)640, height=(int)360, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)432, height=(int)240, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)352, height=(int)288, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)320, height=(int)240, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)320, height=(int)180, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)176, height=(int)144, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)160, height=(int)120, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)160, height=(int)90, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 } 0:00:05.234189598 [335m 4402[00m 0x1409b80 [36mDEBUG [00m [00m v4l2src gstv4l2src.c:483:gst_v4l2src_negotiate:<src>[00m caps of src: video/x-raw-yuv, format=(fourcc)YUY2, width=(int)2304, height=(int)1536, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 2/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)2304, height=(int)1296, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 2/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)1920, height=(int)1080, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)1600, height=(int)896, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)1280, height=(int)720, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)960, height=(int)720, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)1024, height=(int)576, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)800, height=(int)600, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)864, height=(int)480, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)800, height=(int)448, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)640, height=(int)480, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)640, height=(int)360, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)432, height=(int)240, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)352, height=(int)288, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)320, height=(int)240, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)320, height=(int)180, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)176, height=(int)144, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)160, height=(int)120, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)160, height=(int)90, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)1920, height=(int)1080, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)1600, height=(int)896, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)1280, height=(int)720, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)960, height=(int)720, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)1024, height=(int)576, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)800, height=(int)600, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)864, height=(int)480, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)800, height=(int)448, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)640, height=(int)480, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)640, height=(int)360, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)432, height=(int)240, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)352, height=(int)288, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)320, height=(int)240, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)320, height=(int)180, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)176, height=(int)144, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)160, height=(int)120, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)160, height=(int)90, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 } 0:00:05.235135354 [335m 4402[00m 0x1409b80 [36mDEBUG [00m [00m v4l2src gstv4l2src.c:484:gst_v4l2src_negotiate:<src>[00m thiscaps: video/x-raw-yuv, format=(fourcc)YUY2, width=(int)2304, height=(int)1536, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 2/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)2304, height=(int)1296, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 2/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)1920, height=(int)1080, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)1600, height=(int)896, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)1280, height=(int)720, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)960, height=(int)720, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)1024, height=(int)576, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)800, height=(int)600, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)864, height=(int)480, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)800, height=(int)448, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)640, height=(int)480, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)640, height=(int)360, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)432, height=(int)240, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)352, height=(int)288, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)320, height=(int)240, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)320, height=(int)180, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)176, height=(int)144, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)160, height=(int)120, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; video/x-raw-yuv, format=(fourcc)YUY2, width=(int)160, height=(int)90, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)1920, height=(int)1080, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)1600, height=(int)896, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)1280, height=(int)720, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)960, height=(int)720, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)1024, height=(int)576, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)800, height=(int)600, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)864, height=(int)480, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)800, height=(int)448, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)640, height=(int)480, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)640, height=(int)360, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)432, height=(int)240, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)352, height=(int)288, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)320, height=(int)240, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)320, height=(int)180, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)176, height=(int)144, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)160, height=(int)120, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 }; image/jpeg, width=(int)160, height=(int)90, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 24/1, 20/1, 15/1, 10/1, 15/2, 5/1 } 0:00:05.236105490 [335m 4402[00m 0x1409b80 [36mDEBUG [00m [00m v4l2src gstv4l2src.c:492:gst_v4l2src_negotiate:<src>[00m caps of peer: video/x-raw-yuv, format=(fourcc)YUY2, width=(int)320, height=(int)240, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1 0:00:05.236153258 [335m 4402[00m 0x1409b80 [36mDEBUG [00m [00m v4l2src gstv4l2src.c:493:gst_v4l2src_negotiate:<src>[00m peercaps: video/x-raw-yuv, format=(fourcc)YUY2, width=(int)320, height=(int)240, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1 0:00:05.236202443 [335m 4402[00m 0x1409b80 [36mDEBUG [00m [00m v4l2src gstv4l2src.c:503:gst_v4l2src_negotiate:<src>[00m peer: video/x-raw-yuv, format=(fourcc)YUY2, width=(int)320, height=(int)240, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1 0:00:05.236244167 [335m 4402[00m 0x1409b80 [36mDEBUG [00m [00m v4l2src gstv4l2src.c:504:gst_v4l2src_negotiate:<src>[00m ipcaps: video/x-raw-yuv, format=(fourcc)YUY2, width=(int)320, height=(int)240, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1 0:00:05.236379671 [335m 4402[00m 0x1409b80 [36mDEBUG [00m [00m v4l2src gstv4l2src.c:516:gst_v4l2src_negotiate:<src>[00m intersect: video/x-raw-yuv, format=(fourcc)YUY2, width=(int)320, height=(int)240, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1 0:00:05.236422208 [335m 4402[00m 0x1409b80 [36mDEBUG [00m [00m v4l2src gstv4l2src.c:517:gst_v4l2src_negotiate:<src>[00m icaps: video/x-raw-yuv, format=(fourcc)YUY2, width=(int)320, height=(int)240, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1 0:00:05.236545947 [335m 4402[00m 0x1409b80 [36mDEBUG [00m [00m v4l2src gstv4l2src.c:572:gst_v4l2src_negotiate:<src>[00m fixated to: video/x-raw-yuv, format=(fourcc)YUY2, width=(int)320, height=(int)240, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1 0:00:05.236588014 [335m 4402[00m 0x1409b80 [36mDEBUG [00m [00m v4l2src gstv4l2src.c:573:gst_v4l2src_negotiate:<src>[00m caps: video/x-raw-yuv, format=(fourcc)YUY2, width=(int)320, height=(int)240, interlaced=(boolean)false, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1 0:00:05.236641419 [335m 4402[00m 0x1409b80 [36mDEBUG [00m [00m v4l2src gstv4l2src.c:685:gst_v4l2src_set_caps:<src>[00m trying to set_capture 320x240 at 30/1 fps, format YUV 4:2:2 (YUYV) 0:00:05.237733656 [335m 4402[00m 0x1409b80 [36mDEBUG [00m [00m v4l2src v4l2src_calls.c:231:gst_v4l2src_set_capture:<src>[00m Desired framerate: 30/1 0:00:05.237773363 [335m 4402[00m 0x1409b80 [37mLOG [00m [00m v4l2src v4l2src_calls.c:255:gst_v4l2src_set_capture:<src>[00m Setting framerate to 30/1 0:00:05.238482555 [335m 4402[00m 0x1409b80 [32;01mINFO [00m [00m v4l2src v4l2src_calls.c:281:gst_v4l2src_set_capture:<src>[00m Set framerate to 30/1 and duration to 0:00:00.033333333 0:00:05.238514550 [335m 4402[00m 0x1409b80 [36mDEBUG [00m [00m v4l2src v4l2src_calls.c:295:gst_v4l2src_capture_init:<src>[00m initializing the capture system 0:00:05.238544754 [335m 4402[00m 0x1409b80 [37mLOG [00m [00m v4l2src v4l2src_calls.c:303:gst_v4l2src_capture_init:<src>[00m initiating buffer pool 0:00:05.238862599 [335m 4402[00m 0x1409b80 [32;01mINFO [00m [00m v4l2src v4l2src_calls.c:310:gst_v4l2src_capture_init:<src>[00m capturing buffers via mmap() 0:00:05.238892076 [335m 4402[00m 0x1409b80 [36mDEBUG [00m [00m v4l2src v4l2src_calls.c:357:gst_v4l2src_capture_start:<src>[00m starting the capturing 0:00:05.385905344 [335m 4402[00m 0x1409b80 [37mLOG [00m [00m v4l2src gstv4l2src.c:799:gst_v4l2src_unlock_stop:<src>[00m No longer flushing 0:00:05.386124083 [335m 4402[00m 0x1409b80 [37mLOG [00m [00m v4l2src gstv4l2src.c:799:gst_v4l2src_unlock_stop:<src>[00m No longer flushing 0:00:05.386178257 [335m 4402[00m 0x1409b80 [31;01mERROR [00m [00;04m default test.c:67:reset_src_caps:[00m ### SUCCESS 0:00:05.386194666 [335m 4402[00m 0x1405450 [36mDEBUG [00m [00m v4l2src v4l2src_calls.c:110:gst_v4l2src_grab_frame:<src>[00m grab frame 0:00:05.386400599 [335m 4402[00m 0x1409b80 [37mLOG [00m [00m v4l2src gstv4l2src.c:788:gst_v4l2src_unlock:<src>[00m Flushing 0:00:05.386467089 [335m 4402[00m 0x1405450 [36mDEBUG [00m [00m v4l2src v4l2src_calls.c:191:gst_v4l2src_grab_frame:[00m stop called 0:00:05.386886497 [335m 4402[00m 0x1409b80 [37mLOG [00m [00m v4l2src gstv4l2src.c:788:gst_v4l2src_unlock:<src>[00m Flushing 0:00:05.386916960 [335m 4402[00m 0x1409b80 [37mLOG [00m [00m v4l2src gstv4l2src.c:799:gst_v4l2src_unlock_stop:<src>[00m No longer flushing 0:00:05.387093286 [335m 4402[00m 0x1409b80 [36mDEBUG [00m [00m v4l2src v4l2src_calls.c:386:gst_v4l2src_capture_stop:<src>[00m stopping capturing 0:00:05.438542593 [335m 4402[00m 0x1409b80 [36mDEBUG [00m [00m v4l2src v4l2src_calls.c:420:gst_v4l2src_capture_deinit:<src>[00m deinitting capture system
Yeah, that's normal, as soon as you go to NULL state it will close the fd, and it reopens it when it goes back to READY, so it's technically the same as if you restarted the application. It will definitely work if you go to NULL, the bug here is that you should not need to go to NULL, it must work when you go to READY (going to NULL (== closing the fd) might cause a race condition).
True...just trying variations...
This is all that I see in uvcvideo with the trace set... uvcvideo: uvc_v4l2_ioctl(VIDIOC_G_FMT) uvcvideo: uvc_v4l2_ioctl(VIDIOC_S_FMT) uvcvideo: Trying format 0x56595559 (YUYV): 320x240. uvcvideo: Using default frame interval 33333.3 us (30.0 fps). uvcvideo: uvc_v4l2_release
Bug in uvcvideo?
Hummm... possibly, can you trace whether uvcvideo is the one rejecting the new format, and if it is, why ? In the log you pasted, I don't see uvcvideo saying it's "Device busy" or showing any error. it's very probably that it's a bug from uvc, maybe the best way is to bisect it, see if it worked with an old version of v4l2src, or with an older kernel. Tracing where the error originates from would also be a good help.
In uvc_v4l2_set_format() the call to uvc_queue_allocated() is failing and returning -EBUSY. I put trace printk around it... if (uvc_queue_allocated(&stream->queue)) { ret = -EBUSY; goto done; }
Trace: uvcvideo: uvc_v4l2_ioctl(VIDIOC_G_FMT) uvcvideo: uvc_v4l2_ioctl(VIDIOC_S_FMT) uvcvideo: Trying format 0x56595559 (YUYV): 320x240. uvcvideo: Using default frame interval 33333.3 us (30.0 fps). uvcvideo: ***************** uvc_probe_video() uvcvideo: ***************** ret = 0 uvc_probe_video() uvcvideo: ***************** uvc_queue_allocated() uvcvideo: uvc_v4l2_release [root@devkrakorar test]# Debug Code: uvc_trace(UVC_TRACE_FORMAT, "***************** uvc_queue_allocated()\n"); if (uvc_queue_allocated(&stream->queue)) { ret = -EBUSY; goto done; } uvc_trace(UVC_TRACE_FORMAT, "***************** ret = %d - uvc_queue_allocated()\n", ret);
If I comment this code out... #if 0 if (uvc_queue_allocated(&stream->queue)) { ret = -EBUSY; goto done; } #endif ...then setting the format is successful... I don't know the ramifications nor the reason that this code is even in uvc_v4l2_set_format(). There is probably a good reason.
It looks like the code was added to ensure that a frame of the wrong format is not delivered after the calling application has successfully set a new format???
Thanks Robert, good find! The bug is not in uvc, it's in v4l2src. The uvc_queue_allocated only checks if the queue->count is != 0. The queue->count is set with the VIDIOC_REQBUFS ioctl, which itself is called when the gst_v4l2_bufferpool is created : v4l2 gstv4l2bufferpool.c:350:gst_v4l2_buffer_pool_new:<src> STREAMING, requesting 2 MMAP buffers And when we go to READY, the buffer pool is destroyed : v4l2 gstv4l2bufferpool.c:447:gst_v4l2_buffer_pool_destroy:<src> destroy pool So when we do the set_format, the driver finds that there are no buffers allocated, so it returns that error... The issue though is that v4l2src does the set_format *then* it creates the buffers. that's why it fails. I think the driver starts with a pre-initialized buffer, the set-format works, then new buffers get created. When we go to ready, those buffes are destroyed, and the uvc driver has 0 buffers left in the queue, so when we try to set format, it fails. The issue is that if I try to make it allocate the buffers before setting the format, v4l2src will complain that we shouldn't have buffers allocated when trying to set the format... since i'm not too familiar with v4l2, I don't really know what should be done here.
OK, but when I look at the code it looks like the underlying function tests if num_buffers > 0. The only way the test fails is if this function returns TRUE to uvc_queue_allocated() which is just a wrapper function that passes the return value back to the caller. It looks like the uvc_v4l2_set_format() function does not want allocated buffers? It looks to me like buffers are still allocated when uvc_v4l2_set_format() is called and this is the failure. Then again, I have only a few hours of sleep...;-)
I am thinking that GST_STATE_READY has not completed on v4l2src prior to the attempt to set a new format so there are still buffers hanging around?
Oh, you're right, I've read it wrong, it doesn't want buffers to be allocated, I thought it wanted buffers to be pre-allocated. So there's a memleak somewhere causing this. Actually.. I've read the VIDIOC_REQBUFS ioctl docs and it says it must be called with count=0 in order to free the buffers, but it's not called anywhere when the bufferpool gets destroyed. I've made it free the buffers kernel side when the bufferpool is destroyed and I can confirm that it fixed the bug! :) Thanks Robert for the help in figuring out the cause of this bug!
Here is a fix for the 0.10 branch : http://cgit.collabora.com/git/user/kakaroto/gst-plugins-good.git/commit/?h=0.10&id=ad756fb18f9371739f3c16960f06ddc1d5959106 I looked at the master branch but it's very different the way it works, I'd prefer someone else just ports my fix to it.
commit fd694682be04b9f179de9bd45a019bcf081ef871 Author: Youness Alaoui <youness.alaoui@collabora.co.uk> Date: Wed Jun 20 21:18:56 2012 +0000 v4l2: Free the kernel buffers when the bufferpool is destroyed The uvc driver will reject a set_format if there are still buffers allocated kernel-side. This means that doing a PLAYING->READY->PLAYING will fail if we don't free the buffers (also, memleak, etc..) This fixes bug #670257 : https://bugzilla.gnome.org/show_bug.cgi?id=670257
Thanks Wim, I noticed you also committed it to the master branch, then reverted it because libv4l was complaining. I think the solution is not to free them before we allocate buffers, but rather to free the buffers when the bufferpool is destroyed (or whatever pool configuration gets set when the state drops to READY). Should the bug be reopened until a fix is pushed into master ?
(In reply to comment #22) > Thanks Wim, > > I noticed you also committed it to the master branch, then reverted it because > libv4l was complaining. > I think the solution is not to free them before we allocate buffers, but rather > to free the buffers when the bufferpool is destroyed (or whatever pool > configuration gets set when the state drops to READY). I tried that with the same errors as a result, I don't really understand.
Hi Wim, I apply Youness patch to the latest "released" v4l2src and the problem goes away, if I remove it then the problem resurfaces. Would you please post the code from which you are working so that we can have a look? Post the source file and the diff. Thanks in advance. Best Regards, Rob
@Robert: Yes, my patch works but it's for the 0.10 branch only. What Wim did is to port it to the 1.0 branch of Gstreamer with this patch : http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=1b09bc609a578e731f0dbc8f6e698e25d8f4c5f8 But it failed so he reverted it here : http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=77f33e591fc0cbf2fbcb6cddc5803be766f206de The reason for the revert being : "Seems to make libv4l2 complain, maybe because we call REQBUFS with 0 buffers before we allocated buffers." @Wim: Humm.. I just tried the same as you on the 0.10 branch, I added a call to REQBUFS with count=0 before the allocation happens and the driver didn't complain, so that's not it. Also note that the fix you had (freeing the buffers right before allocating new ones) wouldn't fix the bug here because the renegotiation has to happen when no buffers are allocated on the kernel side. So the REQBUFS with count=0 has to happen before the VIDIOC_S_FMT happens (which itself happens before the bufferpool is allocated/configured).
Wow, the 11.xx code looks different from the 10.xx code. So, I see a function where the buffer pool is released in the 11.xx code, why not just start by placing the code to release the v4l2 buffers there and see what happens?
Unless the buffer pool is not released in 11.xx on PLAYING->READY...