0
votes

I have been playing around with a userspace application based on uvc driver based on v4l2. I have been trying to get the capabilities of my integrated webcam (this is a laptop), and then I got into one problem. My driver does not set any video standard flags against VIDIOC_ENUMINPUT ioctl. Following is my code.

struct v4l2_capability caps;
memset(&caps, 0, sizeof(caps));

if(-1 == ioctl(fd, VIDIOC_QUERYCAP, &caps)) {
    perror("Unable to query capabilities");
    return errno;
}

printf(
        "--------  VIDIOC_QUERYCAP  --------\n"
        "Driver       = %s\n"
        "Card         = %s\n"
        "Bus Info     = %s\n"
        "Version      = %d\n"
        "Capabilities = %#x\n"
        "Device Caps  = %#x\n",
        caps.driver,
        caps.card,
        caps.bus_info,
        caps.version,
        caps.capabilities,
        caps.device_caps);


int index;

if(-1 == ioctl(fd, VIDIOC_G_INPUT, &index)) {
    perror("Unable to get current input index");
    return errno;
}

struct v4l2_input input;
memset(&input, 0, sizeof(input));
input.index = index;

if(-1 == ioctl(fd, VIDIOC_ENUMINPUT, &input)) {
    perror("Unabel to query attributes of video input");
    return errno;
}

printf(
        "--------- VIDIOC_ENUMINPUT ---------\n"
        "Index        = %d\n"
        "Name         = %s\n"
        "Type         = %d\n"
        "Audio Set    = %d\n"
        "Video Stds   = %lld\n"
        "Status       = %d\n"
        "Capabilities = %d\n",
        input.index,
        input.name,
        input.type,
        input.audioset,
        input.std,
        input.status,
        input.capabilities);

And the output looks like the following.

--------  VIDIOC_QUERYCAP  --------
Driver       = uvcvideo
Card         = Integrated_Webcam_HD: Integrate
Bus Info     = usb-0000:00:1d.0-1.6
Version      = 266001
Capabilities = 0x84200001
Device Caps  = 0x4200001
--------- VIDIOC_ENUMINPUT ---------
Index        = 0
Name         = Camera 1
Type         = 2
Audio Set    = 0
Video Stds   = 0    // <--- Problem here.
Status       = 0
Capabilities = 0

Notice that the video standards flag is set to 0. To further drill down the problem, I tried VIDIOC_G_STD ioctl, as follows,

struct v4l2_standard std;
memset(&std, 0, sizeof(std));
if(-1 == ioctl(fd, VIDIOC_G_STD, &std)) {
    perror("Error");
    return errno;
}

But receives the following error.

Error: Inappropriate ioctl for device

What could be the conclusion? Am I doing anything wrong here?

Platform Details

  • Linux linux 4.15.0-20-generic #21-Ubuntu SMP Tue Apr 24 06:16:15 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
  • Driver version: 4.15.17
  • Device node : /dev/video0 (only one device)
1

1 Answers

1
votes

I think I found the answer myself. On closer evaluation, I have found that the integrated webcam on my laptop is on the USB bus internally. USB class devices are an exception for v4l2 video standard ioctl. As per the documentation,

Special rules apply to devices such as USB cameras where the notion of video standards makes little sense. More generally for any capture or output device which is incapable of capturing fields or frames at the nominal rate of the video standard, or that does not support the video standard formats at all. Here the driver shall set the std field of struct v4l2_input and struct v4l2_output to zero and the VIDIOC_G_STD, VIDIOC_S_STD, ioctl VIDIOC_QUERYSTD and ioctl VIDIOC_ENUMSTD ioctls shall return the ENOTTY error code or the EINVAL error code.

Thus, I think my camera falls into one of these categories, and STD query is not really applicable in my case. I'm not sure if this is true for MIPI or Parallel buses. I will update once I do a little more experiment with those hardware.