LINUX&UVC控制请求VIDIOC_QUERYCAP设备功能属性信息v4l2_capability
2024-03-29
128
0
VIDIOC_QUERYCAP请求使用api函数ioctl,最终进行LINUX&UVC驱动中,根据设备节点的不同,执行的回调函数不同。
VIDIOC_QUERYCAP请求用于返回设备支持的功能属性信息,其对应的结构体v4l2_capability。
struct v4l2_capability
{
u8 driver[16]; // 驱动名字
u8 card[32]; // 设备名字
u8 bus_info[32]; // 设备在系统中的位置
u32 version;// 驱动版本号
u32 capabilities;// 设备支持的操作
u32 reserved[4]; // 保留字段
};
UVC驱动
const struct v4l2_ioctl_ops uvc_ioctl_ops = {
.vidioc_querycap = uvc_ioctl_querycap,
...
}
具体代码为:
static int uvc_ioctl_querycap(struct file *file, void *fh,
struct v4l2_capability *cap)
{
struct video_device *vdev = video_devdata(file);
struct uvc_fh *handle = file->private_data;
struct uvc_video_chain *chain = handle->chain;
struct uvc_streaming *stream = handle->stream;
strscpy(cap->driver, "uvcvideo", sizeof(cap->driver));
strscpy(cap->card, vdev->name, sizeof(cap->card));
usb_make_path(stream->dev->udev, cap->bus_info, sizeof(cap->bus_info));
cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING | chain->caps;
return 0;
}
对于metadata节点,对应的函数为:
static const struct v4l2_ioctl_ops uvc_meta_ioctl_ops = {
.vidioc_querycap = uvc_meta_v4l2_querycap,
...
}
具体代码为:
static int uvc_meta_v4l2_querycap(struct file *file, void *fh,
struct v4l2_capability *cap)
{
struct v4l2_fh *vfh = file->private_data;
struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
struct uvc_video_chain *chain = stream->chain;
strscpy(cap->driver, "uvcvideo", sizeof(cap->driver));
strscpy(cap->card, vfh->vdev->name, sizeof(cap->card));
usb_make_path(stream->dev->udev, cap->bus_info, sizeof(cap->bus_info));
cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING | chain->caps;
return 0;
}
v4l2_capability
通过分析两个回调函数,可知:
- 对应驱动名称,因其都是usb video class设备节点,故驱动使用的是”uvcvideo”,其对应MakeFile编译后的模块uvcvideo.o
对于设备名称,则来源于usbCore的设备名称。
int uvc_register_video_device(...) { ... strscpy(vdev->name, dev->name, sizeof(vdev->name)); ... }
bus_info:其通过函数usb_make_path实现:
static inline int usb_make_path(struct usb_device *dev, char *buf, size_t size) { int actual; actual = snprintf(buf, size, "usb-%s-%s", dev->bus->bus_name,dev->devpath); return (actual >= (int)size) ? -1 : actual; }
capabilities:这里标识了设备的特征信息。其都包含V4L2_CAP_DEVICE_CAPS和V4L2_CAP_STREAMING,对于 chain->caps,则根据视频流描述符是输入还是输出设备不同而不同:
if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) stream->chain->caps |= V4L2_CAP_VIDEO_CAPTURE| V4L2_CAP_META_CAPTURE; else stream->chain->caps |= V4L2_CAP_VIDEO_OUTPUT;
其它相关的属性信息可详见:https://elixir.bootlin.com/linux/v5.5-rc2/source/include/uapi/linux/videodev2.h#L452
/* Values for 'capabilities' field */
#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */
#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */
#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */
#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture device */
#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output device */
#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */
#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */
#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */
#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000200 /* Can do video output overlay */
#define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */
#define V4L2_CAP_RDS_OUTPUT 0x00000800 /* Is an RDS encoder */
/* Is a video capture device that supports multiplanar formats */
#define V4L2_CAP_VIDEO_CAPTURE_MPLANE 0x00001000
/* Is a video output device that supports multiplanar formats */
#define V4L2_CAP_VIDEO_OUTPUT_MPLANE 0x00002000
/* Is a video mem-to-mem device that supports multiplanar formats */
#define V4L2_CAP_VIDEO_M2M_MPLANE 0x00004000
/* Is a video mem-to-mem device */
#define V4L2_CAP_VIDEO_M2M 0x00008000
#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */
#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */
#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */
#define V4L2_CAP_MODULATOR 0x00080000 /* has a modulator */
#define V4L2_CAP_SDR_CAPTURE 0x00100000 /* Is a SDR capture device */
#define V4L2_CAP_EXT_PIX_FORMAT 0x00200000 /* Supports the extended pixel format */
#define V4L2_CAP_SDR_OUTPUT 0x00400000 /* Is a SDR output device */
#define V4L2_CAP_META_CAPTURE 0x00800000 /* Is a metadata capture device */
#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */
#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */
#define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */
#define V4L2_CAP_META_OUTPUT 0x08000000 /* Is a metadata output device */
#define V4L2_CAP_TOUCH 0x10000000 /* Is a touch device */
#define V4L2_CAP_DEVICE_CAPS 0x80000000 /* sets device capabilities field */