From 646876105fe1799355715839477958adf1d096fd Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Sun, 3 Feb 2019 10:52:02 +0100 Subject: [PATCH] v4l_id: use device_caps if available 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 | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/udev/v4l_id/v4l_id.c b/src/udev/v4l_id/v4l_id.c index 4d48289..4d60ee3 100644 --- a/src/udev/v4l_id/v4l_id.c +++ b/src/udev/v4l_id/v4l_id.c @@ -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"); } -- 2.7.4