v4l_id: use device_caps if available
authorMichael Olbrich <m.olbrich@pengutronix.de>
Sun, 3 Feb 2019 09:52:02 +0000 (10:52 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 15 Feb 2019 11:14:05 +0000 (12:14 +0100)
According to the specification[1] the 'capabilities' describe the physical
device as a whole and the 'device_caps' describe the current device node.
The existence of 'device_caps' is indicated by the V4L2_CAP_DEVICE_CAPS
capability flag.
Use the 'device_caps' if available to generate the correct
ID_V4L_CAPABILITIES for the current device node.

This is relevant for UVC devices with current kernels: Two /dev/videoX
devices exist for those. One for video and one for metadata. The
 V4L2_CAP_VIDEO_CAPTURE flag is present in the 'capabilities' for both
device nodes but only in the 'device_caps' of the video device node.

Without this, the ID_V4L_CAPABILITIES of the metadata device node
incorrectly contains 'capture'.

[1] https://www.linuxtv.org/downloads/v4l-dvb-apis-new/uapi/v4l/vidioc-querycap.html

src/udev/v4l_id/v4l_id.c

index 4d48289..4d60ee3 100644 (file)
@@ -64,22 +64,27 @@ int main(int argc, char *argv[]) {
                 return 3;
 
         if (ioctl(fd, VIDIOC_QUERYCAP, &v2cap) == 0) {
+                int capabilities;
                 printf("ID_V4L_VERSION=2\n");
                 printf("ID_V4L_PRODUCT=%s\n", v2cap.card);
                 printf("ID_V4L_CAPABILITIES=:");
-                if ((v2cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) > 0 ||
-                    (v2cap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE) > 0)
+                if (v2cap.capabilities & V4L2_CAP_DEVICE_CAPS)
+                        capabilities = v2cap.device_caps;
+                else
+                        capabilities = v2cap.capabilities;
+                if ((capabilities & V4L2_CAP_VIDEO_CAPTURE) > 0 ||
+                    (capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE) > 0)
                         printf("capture:");
-                if ((v2cap.capabilities & V4L2_CAP_VIDEO_OUTPUT) > 0 ||
-                    (v2cap.capabilities & V4L2_CAP_VIDEO_OUTPUT_MPLANE) > 0)
+                if ((capabilities & V4L2_CAP_VIDEO_OUTPUT) > 0 ||
+                    (capabilities & V4L2_CAP_VIDEO_OUTPUT_MPLANE) > 0)
                         printf("video_output:");
-                if ((v2cap.capabilities & V4L2_CAP_VIDEO_OVERLAY) > 0)
+                if ((capabilities & V4L2_CAP_VIDEO_OVERLAY) > 0)
                         printf("video_overlay:");
-                if ((v2cap.capabilities & V4L2_CAP_AUDIO) > 0)
+                if ((capabilities & V4L2_CAP_AUDIO) > 0)
                         printf("audio:");
-                if ((v2cap.capabilities & V4L2_CAP_TUNER) > 0)
+                if ((capabilities & V4L2_CAP_TUNER) > 0)
                         printf("tuner:");
-                if ((v2cap.capabilities & V4L2_CAP_RADIO) > 0)
+                if ((capabilities & V4L2_CAP_RADIO) > 0)
                         printf("radio:");
                 printf("\n");
         }