I&#39;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&#39;ve a new device (Sensoray 2255S) and it was simple to get it to work, but not with code that doesn&#39;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&#39;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&#39;t support grayscale, when the caps filter is set to caps_gray, but it doesn&#39;t.  I don&#39;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&#39;t duplicate the problems.<br><br><br>For the device that can&#39;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&#39;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                    : &quot;Composite&quot;<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             : &quot;4:2:2, planar, YUV422P&quot;<br>    pixelformat             : 0x50323234 [422P]<br>    VIDIOC_ENUM_FMT(1,VIDEO_CAPTURE)<br>
    index                   : 1<br>    type                    : VIDEO_CAPTURE<br>    flags                   : 0<br>    description             : &quot;4:2:2, packed, YUYV&quot;<br>    pixelformat             : 0x56595559 [YUYV]<br>
    VIDIOC_ENUM_FMT(2,VIDEO_CAPTURE)<br>    index                   : 2<br>    type                    : VIDEO_CAPTURE<br>    flags                   : 0<br>    description             : &quot;4:2:2, packed, UYVY&quot;<br>
    pixelformat             : 0x59565955 [UYVY]<br>    VIDIOC_ENUM_FMT(3,VIDEO_CAPTURE)<br>    index                   : 3<br>    type                    : VIDEO_CAPTURE<br>    flags                   : 0<br>    description             : &quot;8bpp GREY&quot;<br>
    pixelformat             : 0x59455247 [GREY]<br>    VIDIOC_ENUM_FMT(4,VIDEO_CAPTURE)<br>    index                   : 4<br>    type                    : VIDEO_CAPTURE<br>    flags                   : 0<br>    description             : &quot;JPG&quot;<br>
    pixelformat             : 0x4745504a [JPEG]<br>    VIDIOC_ENUM_FMT(5,VIDEO_CAPTURE)<br>    index                   : 5<br>    type                    : VIDEO_CAPTURE<br>    flags                   : 0<br>    description             : &quot;MJPG&quot;<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&#39;t support support any 4:2:2 formats, so this is not a &quot;common&quot; 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 &quot;can&#39;t negotiate&quot; error when setting the pipeline to playing?<br><br><br>