GNOME Bugzilla – Bug 563574
v4l2src should capture in non-blocking mode
Last modified: 2009-03-25 08:09:54 UTC
My webcam (hardware/kernel?) has a nasty bug where the streaming seems to fail to start. Causing the v4l2src element to block on a VIDEOC_DQBUFF ioctl forever. While this is obviously a bug on a lower level, it does reveal the issue that gst open the v4l2 device in blocking mode. cameras can potentially capture at very low rates (capture time of second or more), it's quite annoying that in the worst case setting the element to state NULL would then cost of the order of seconds..
gst-plugins-good/sys/v4l2$ grep -C1 -Hn " open (" *.c gstv4l2object.c-108- gstv4l2object.c:109: if ((fd = open (device, O_RDWR | O_NONBLOCK)) > 0 || errno == EBUSY) { gstv4l2object.c-110- if (fd > 0) -- v4l2_calls.c-422- v4l2object->video_fd = v4l2_calls.c:423: open (v4l2object->videodev, O_RDWR /* | O_NONBLOCK */ ); v4l2_calls.c-424- So I removed the uncommented /* | O_NONBLOCK */ in v4l2_calls.c:423 and that leads to: 0:00:00.241962456 16029 0x88d7058 WARN v4l2src v4l2src_calls.c:998:gst_v4l2src_grab_frame:<v4l2src0> problem grabbing frame 0 (ix=0), trials=50, pool-ct=3, buf.flags=0 0:00:00.242056393 16029 0x88d7058 WARN v4l2src v4l2src_calls.c:1006:gst_v4l2src_grab_frame:<v4l2src0> Non-blocking I/O has been selected using O_NONBLOCK and no buffer was in the outgoing queue. device /dev/video0 The commented O_NONBLOCK was added in http://webcvs.freedesktop.org/gstreamer/gst-plugins-good/sys/v4l2/v4l2_calls.c?r1=1.23&r2=1.24 by alima saying "Just make few things more robust and also some identation." No idea how much changes it would need to support it.
If O_NONBLOCK is used the gst_v4l2src_grab_frame need to poll the video_fd for it to become readable and only then do VIDIOC_DQBUF. And also to fix the issue of it not being able to stop when waiting for a frame, the unlock method in the src needs to be implemented. the tcpsrc element should have a good exmample of how to do this
I think we should bump the severity of this. It's very visible doing recording with pitivi on ubuntu intrepid using a logitech uvcvideo camera. The driver seems to be racy. After the STREAMON and QBUF ioctls, the device isn't always ready to produce data and the first gst_v4l2src_grab_frame justs hangs indefinitely. I understand this is partly due to broken drivers / hardware, but uvcvideo cameras are pretty common and the fact that the pipeline blocks forever is just wrong.
(In reply to comment #3) > I think we should bump the severity of this. It's very visible doing recording > with pitivi on ubuntu intrepid using a logitech uvcvideo camera. The driver > seems to be racy. After the STREAMON and QBUF ioctls, the device isn't always > ready to produce data and the first gst_v4l2src_grab_frame justs hangs > indefinitely. Just for the record, the same happens almost always with the uvcvideo cam built into the Dell M1330.
Totally agree, but its best done by someone who can actually reproduce it.
Created attachment 129750 [details] [review] v4l2src: Wait for a frame to become available before capturing
commit cff3f46760eac74c9bbd7a36aca44fedf327424b Author: Sjoerd Simons <sjoerd.simons@collabora.co.uk> Date: Sun Mar 1 19:55:26 2009 +0100 v4l2: Wait for a frame to become available before capturing it Use GstPoll to wait for the fd of the video device to become readable before trying to capture a frame. This speeds up stopping v4l2src a lot as it no longer has to wait for the next frame, especially when capturing with low framerates or when the video device just never generates a frame (which seem common issue for uvcvideo devices) Fixes bug #563574.
Sjörd, I wonder about the addition of #ifdef G_OS_WIN32 if (WSAGetLastError () != WSAEINTR) goto select_error; #else if (errno != EAGAIN && errno != EINTR) goto select_error; #endif in your patch. Imho v4l2src is linux only (it's under ./sys). is seems also unrelated to the problem. Should we remove that again?
Changed in git.