I'm coming to the conclusion that v4l2 and gstreamer is fatally flawed. Every time I get a new v4l2 capture device something breaks.<br><br>I've a new device (Sensoray 2255S) and it was simple to get it to work, but not with code that doesn't break when using some other v4l2 device!<br>
<br>At the end of the day I need a 640x480 grayscale buffer coming out of my appsink. The problem is how do I define a pipeline to work around the various conversions I need when I don't get a error until the pipeline tries to play?<br>
<br>I was expecting link_ok = gst_element_link_filtered (source, capsfilter, caps_gray) to fail on a card that doesn't support grayscale, when the caps filter is set to caps_gray, but it doesn't. I don't know anything is wrong until I set the pipeline to playing but then its too late!<br>
<br>Perhaps I can best illustrate the problem with a few gst-launch examples, although without the same hardware you likely can't duplicate the problems.<br><br><br>For the device that can't do gray scale directly, this pipeline works:<br>
gst-launch -v v4l2src device=/dev/video6 ! ffmpegcolorspace ! video/x-raw-gray, framerate=\(fraction\)30000/1001, width=640, height=480 ! ffmpegcolorspace ! xvimagesink<br><br>It negotiates:<br> ffmpegcsp0.GstPad:sink: caps = video/x-raw-yuv, format=(fourcc)I420, framerate=(fraction)30000/1001, width=(int)640, height=(int)480<br>
<br>ffmpegcsp0.GstPad:src: caps = video/x-raw-gray, width=(int)640, height=(int)480, framerate=(fraction)30000/1001, bpp=(int)8, depth=(int)8<br><br>The second ffmpegcolor space just fixes the fact that xvimagesink can't do grayscale, but is not relevant to my programmatic appsink pipeline. <br>
<br><br><br>For the Sensoray device:<br>gst-launch -v v4l2src device=/dev/video2 ! ffmpegcolorspace ! video/x-raw-gray, framerate=\(fraction\)30000/1001, width=640, height=480 ! ffmpegcolorspace ! xvimagesink<br><br>negotiates:<br>
ffmpegcsp0.GstPad:sink: caps = video/x-raw-yuv, format=(fourcc)I420, framerate=(fraction)30000/1001, width=(int)640, height=(int)480 and all would seem well, except the video has a black bar in the middle because of a bug in either the Sensoray drive, v4l2, or gstreamer the negotiation is incorrect because I420 is not supported in the driver according to v4l-info:<br>
<br>inputs<br> VIDIOC_ENUMINPUT(0)<br> index : 0<br> name : "Composite"<br> type : CAMERA<br> audioset : 0<br> tuner : 0<br>
std : 0xb0ff [PAL_B,PAL_B1,PAL_G,PAL_H,PAL_I,PAL_D,PAL_D1,PAL_K,NTSC_M,NTSC_M_JP,?]<br> status : 0x0 []<br><br>video capture<br> VIDIOC_ENUM_FMT(0,VIDEO_CAPTURE)<br> index : 0<br>
type : VIDEO_CAPTURE<br> flags : 0<br> description : "4:2:2, planar, YUV422P"<br> pixelformat : 0x50323234 [422P]<br> VIDIOC_ENUM_FMT(1,VIDEO_CAPTURE)<br>
index : 1<br> type : VIDEO_CAPTURE<br> flags : 0<br> description : "4:2:2, packed, YUYV"<br> pixelformat : 0x56595559 [YUYV]<br>
VIDIOC_ENUM_FMT(2,VIDEO_CAPTURE)<br> index : 2<br> type : VIDEO_CAPTURE<br> flags : 0<br> description : "4:2:2, packed, UYVY"<br>
pixelformat : 0x59565955 [UYVY]<br> VIDIOC_ENUM_FMT(3,VIDEO_CAPTURE)<br> index : 3<br> type : VIDEO_CAPTURE<br> flags : 0<br> description : "8bpp GREY"<br>
pixelformat : 0x59455247 [GREY]<br> VIDIOC_ENUM_FMT(4,VIDEO_CAPTURE)<br> index : 4<br> type : VIDEO_CAPTURE<br> flags : 0<br> description : "JPG"<br>
pixelformat : 0x4745504a [JPEG]<br> VIDIOC_ENUM_FMT(5,VIDEO_CAPTURE)<br> index : 5<br> type : VIDEO_CAPTURE<br> flags : 0<br> description : "MJPG"<br>
pixelformat : 0x47504a4d [MJPG]<br> VIDIOC_G_FMT(VIDEO_CAPTURE)<br> type : VIDEO_CAPTURE<br> fmt.pix.width : 640<br> fmt.pix.height : 480<br> fmt.pix.pixelformat : 0x4745504a [JPEG]<br>
fmt.pix.field : INTERLACED<br> fmt.pix.bytesperline : 1920<br> fmt.pix.sizeimage : 921600<br> fmt.pix.colorspace : unknown<br> fmt.pix.priv : 0<br><br><br><br>Now if I simply do:<br>
<br> gst-launch -v v4l2src device=/dev/video2 ! xvimagesink<br><br>it correctly negotiates a 4:2:2 yuv format and works correctly. Other of my capture devices don't support support any 4:2:2 formats, so this is not a "common" format I could force the captures to.<br>
<br>So how can I detect this problem before I run the pipeline and adjust the pipeline around it?<br>Or how do I recover from the "can't negotiate" error when setting the pipeline to playing?<br><br><br>