1

The presenting problem and symptoms: I've found that for each individual physical USB web camera I attach in Raspbian, a pair of such /dev/video devices is created. When I try to capture an image from that 1 physical camera with fswebcam by specifying one of the /dev/video devices in the pair, one will fails with an ioctl error and the other will succeed.

The help I am wanting: I'm looking for a way to probe / pre-determine which of the pair will fail so I can avoid generating errors and only call fswebcam against the member of the /dev/video pair that will work.

Background: I have some USB web cams I am using in a multi-camera array. I want to capture one image from each of the cameras in a loop. I tried looping across every /dev/video device and discovered this paired phenomenon where one /dev/video device name will succeed and the other will fail, for each camera.

The fswebcam calls that fail (i.e. throw ioctl errors) generate the following messages:

Unable to query input 0.

VIDIOC_ENUMINPUT: Inappropriate ioctl for device

FULL REQUEST: Can anyone provide me with a simple way to grep or find all the "valid" devices in the /dev/video* or /sys/class/video4linux// trees or a simple shell command I can use to tell me without throwing an error when this is not a valid device for fswebcam requests?

Additional info: Below I show the output that v4l2-ctl shows when it queries each device.

The v4l2-ctl output from the /dev/video* that will succeed:

$ v4l2-ctl --device=/dev/video0 --all
Driver Info (not using libv4l2):
    Driver name   : uvcvideo
    Card type     : UNIQUESKY_CAR_CAMERA: Integrate
    Bus info      : usb-3f980000.usb-1.2.1
    Driver version: 4.19.58
    Capabilities  : 0x84A00001
        Video Capture
        Streaming
        Extended Pix Format
        Device Capabilities
    Device Caps   : 0x04200001
        Video Capture
        Streaming
        Extended Pix Format
Priority: 2
Video input : 0 (Camera 1: ok)
Format Video Capture:
    Width/Height      : 1920/1080
    Pixel Format      : 'MJPG'
    Field             : None
    Bytes per Line    : 0
    Size Image        : 4147200
    Colorspace        : sRGB
    Transfer Function : Default
    YCbCr/HSV Encoding: Default
    Quantization      : Default
    Flags             : 
Crop Capability Video Capture:
    Bounds      : Left 0, Top 0, Width 1920, Height 1080
    Default     : Left 0, Top 0, Width 1920, Height 1080
    Pixel Aspect: 1/1
Selection: crop_default, Left 0, Top 0, Width 1920, Height 1080
Selection: crop_bounds, Left 0, Top 0, Width 1920, Height 1080
Streaming Parameters Video Capture:
    Capabilities     : timeperframe
    Frames per second: 30.000 (30/1)
    Read buffers     : 0
                     brightness (int)    : min=-64 max=64 step=1 default=-8193 value=0
                       contrast (int)    : min=0 max=95 step=1 default=57343 value=0
                     saturation (int)    : min=0 max=100 step=1 default=57343 value=80
                            hue (int)    : min=-2000 max=2000 step=1 default=-8193 value=0
 white_balance_temperature_auto (bool)   : default=1 value=1
                          gamma (int)    : min=64 max=300 step=1 default=57343 value=84
                           gain (int)    : min=1 max=8 step=1 default=57343 value=1
           power_line_frequency (menu)   : min=0 max=2 default=1 value=1
      white_balance_temperature (int)    : min=2800 max=6500 step=1 default=57343 value=3980 flags=inactive
                      sharpness (int)    : min=1 max=7 step=1 default=57343 value=2
         backlight_compensation (int)    : min=0 max=128 step=0 default=20478 value=0
                  exposure_auto (menu)   : min=0 max=3 default=0 value=3
              exposure_absolute (int)    : min=10 max=626 step=1 default=156 value=156 flags=inactive

Here's what is returned if I try the alternate device that causes the ioctl error fail:

$ v4l2-ctl --device=/dev/video1 --all
Driver Info (not using libv4l2):
    Driver name   : uvcvideo
    Card type     : UNIQUESKY_CAR_CAMERA: Integrate
    Bus info      : usb-3f980000.usb-1.2.1
    Driver version: 4.19.58
    Capabilities  : 0x84A00001
        Video Capture
        Streaming
        Extended Pix Format
        Device Capabilities
    Device Caps   : 0x04A00000
        Streaming
        Extended Pix Format
Priority: 2
 .

The important difference between the two v4l2-ctl outputs are that the "Video Capture" capability is NOT PRESENT under "Device Caps" in the 2nd /dev/video* object, but it IS PRESENT under the first devices's "Device Caps". Apparently fswebcam makes a request that expects that the "video capture" capability to be present for a device, and when that "Device Cap" is NOT present if throw the IOCTL error.

Unfortunately the v4l2-cntl output is very verbose, and the words "Video Capture" appear in BOTH listings under "Capabilities". But to appears again under "Device Caps" in only one case.

This makes it more challenging to write a test using something like grep, and I worry that changes to the formatting of these reports could make any test based on them fragile. Is there a way to search out ONLY the Device Caps?

I'd love to generate a list of JUST the cameras with that capability, but I am unsure how to do it. At present, My best solution is to look for "Video Capture" listed twice

2
  • The output of v4l2-ctl is for human, not for computer-processing. The root of this question is one physical device is not expected to have two different device nodes, but this is more likely to be a kernel driver bug which may not be easy to fix. As workaround, you should call v4l2 APIs on the two nodes to query their capabilities. Go read v4l2 docs to find correct ways to check the capabilities that fswebcam requires (which is the ability to support VIDIOC_ENUMINPUT ioctl in your case) Feb 22, 2020 at 16:09
  • Thanks roaima. This link is helpful to me in understanding why I am seeing two /dev/videos for each usb camera, and now I now understand how to determine which one I want to request images from! Feb 5, 2021 at 5:49

1 Answer 1

2

with one camera generally the first device is the real space for capturing.
so ls /dev/video generates a list, capture the first item on it.

Not the answer you're looking for? Browse other questions tagged or ask your own question.