GNOME Bugzilla – Bug 480557
[v4l2src] Nasty segfault (with broken driver?)
Last modified: 2007-11-15 23:29:11 UTC
I'm having a very nasty segfault when using the following pipeline. this was launched on an amd64 architecture : gst-launch v4l2src ! tee name=tee tee.src%d ! queue ! ffmpegcolorspace ! xvimagesink tee.src%d ! queue ! ffmpegcolorspace ! theoraenc ! rtptheorapay ! gdppay ! udpsink port=2000 However, there is no problem when setting sync=false on the udpsink. Launching a much more classical gst-launch v4l2src ! ffmpegcolorspace ! udpsink port=2000 is just fine. The webcam used is the logitech orbit : QuickCam Orbit/Sphere This particular webcam doesn't work at all in stable. When tested with stable version with the apple iSight, there was no problem. With the isight and CVS HEAD, the same command was launched (32bits architecture this time), and it worked perfectly. The backtrace I got is unusable with the gst-launch command. However, doing the same in python got me this : [New Thread 1082132800 (LWP 6921)] [Thread 1082132800 (LWP 6921) exited] [New Thread 1090525504 (LWP 6928)] [New Thread 1098918208 (LWP 6935)] [New Thread 1107310912 (LWP 6943)] [New Thread 1115703616 (LWP 6949)] Program received signal SIGSEGV, Segmentation fault.
+ Trace 165620
Thread 1107310912 (LWP 6943)
> The backtrace I got is unusable with the gst-launch command. > However, doing the same in python got me this (..) You need to run gdb or valgrind on gst-launch-0.10, since gst-launch is just a wrapper script/program (or, if you're using an uninstalled setup, gstreamer/tools/.libs/gst-launch-0.10 or gstreamer/tools/.libs/lt-gst-launch-0.10).
does it also crash if you remove gdppay from the pipeline?
Ping?
Created attachment 97366 [details] gdb backtrace
I did the attached backtrace with the following pipeline : The version is still CVS HEAD, on an Ubuntu Feisty i386 gst-launch v4l2src ! tee name=teee ! queue ! ffmpegcolorspace ! theoraenc ! gdppay ! udpsink teee. ! queue ! ffmpegcolorspace ! ximagesink Funnily enough, that same pipeline in Python doesn't cause trouble. I'm suspecting a threading problem, but that's just a hunch, and alas I don't know GStreamer enough to debug it myself. Tell me if anything else is needed.
Does it also happen with a simple: v4l2src ! ffmpegcolorspace ! xvimagesink It seem like the driver did not allocate the capture memory correctly. Can you attach a log made with GST_DEBUG=*v4l2*:5?
Created attachment 97411 [details] GST_DEBUG=*v4l2*:5 file with GST_DEBUG=*v4l2*:5
Created attachment 97423 [details] GST_DEBUG=*v4l2*:5 again
Hi Christophe Eymard, please try again....I've just committed I hope it Fixes this bug BR 2007-10-22 Edgard Lima <edgard.lima@indt.org.br> * sys/v4l2/v4l2src_calls.c: (gst_v4l2src_grab_frame): Fixes "v4l2src ! queue ! xvimagesink". The queue ask for buffer too early. It is temporary until we find something better.
Ok, the commit I pointed out above was really ugly. Lets have a look at the real bug we are facing (which is a bug in device driver side): gst_v4l2src_grab_frame { ... while (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_DQBUF, &buffer) < 0) It should never return true unless really there is a buffer available What happens to my device driver (pwc: Logitech QuickCam Orbit/Sphere USB webcam) is that when this function is called on third time, we have the following situation: buffer[0] is in use upstream buffer[1] is free ('cause for this buffer, the last one, we always copied) then the 'ioctl' above returns 0 with buffer.index = 0. which should be impossible 'cause the buffer[0] has not been finalized yet (so not available for the driver to write in it yet - means VIDIOC_QBUF not called yet for this buffer) So, we have two options 1- doesn't change anything (just rollback my last ugly commit) and report or send a patch to the device driver guys 2- make always copy for the time being (I vote 1) btw: Wim what do you think of make the default buffer pool size 4 instead current 2?
Well, there is a work around that at least works for me :-) the only change is in func -> gst_v4l2src_grab_frame - need_copy = v4l2src->pool->num_live_buffers == v4l2src->pool->buffer_count; + need_copy = index == 0; this way, the copy always happens to the first buffer (so it will always be available to the driver) and the other buffers are in use too. ....Well, since it is a driver bug, it is hard to say if the driver is really writing to pool->buffer[0] or it is writing to another buffer in pool and just returning buffer.index = 0 to us. Wim, what do you think? btw: I've tried to make my camera to use 4 buffer but it just uses 2 buffers (I have no idea about other drivers). BR, Edgard
If it's something we can safely catch or work around without side effects, we may just as well do that IMO. In any case, moving bug to the right component.
Bug fixed http://webcvs.freedesktop.org/gstreamer/gst-plugins-good/ChangeLog?r1=1.3170&r2=1.3171 By default the buffers are always copied (safer - bugged drivers - with performance penality) If the application knows the driver is well written, the property "always-copy" could be set to "false" to make mmap effectively used. BR, Edgard
Great! 2007-11-15 Edgard Lima <edgard.lima@indt.org.br> * sys/v4l2/gstv4l2src.c: (gst_v4l2src_class_init), (gst_v4l2src_init), (gst_v4l2src_set_property), (gst_v4l2src_get_property): * sys/v4l2/gstv4l2src.h: * sys/v4l2/v4l2src_calls.c: (gst_v4l2src_grab_frame): Always copy buffers by default (handle safer with bugged drivers) and added a property to make it possible to use mmap effectively (no copy if possible) when application wants to. Fixes: #480557.