从应用调用vivi驱动分析v4l2 -- 应用查询(VIDIOC_QUERYCAP)过程分析

Linux v4l2架构学习总链接

应用测试代码如下:

v4l2测试代码

vivi驱动分析如下:

从vivi虚拟摄像头驱动分析v4l2

step 2 : 查询设备功能

struct v4l2_capability cap;
ioctl(fd, VIDIOC_QUERYCAP, &cap)

video注册的时候fops是v4l2_fops,所以会调用到v4l2_fops.unlocked_ioctl 也就是 v4l2_ioctl

v4l2_ioctl中 调用到 vdev->fops->unlocked_ioctl,vdev->fops对于vivi驱动的vivi_fops,所以unlocked_ioctl就是video_ioctl2

其中VIDIOC_QUERYCAP对应 v4l_querycap

static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
				struct file *file, void *fh, void *arg)
{
	struct v4l2_capability *cap = (struct v4l2_capability *)arg;
	struct video_device *vfd = video_devdata(file);
	int ret;

	cap->version = LINUX_VERSION_CODE;
	cap->device_caps = vfd->device_caps;
	cap->capabilities = vfd->device_caps | V4L2_CAP_DEVICE_CAPS;


        /*
         * 对应vivi驱动的 vidioc_querycap
         */


	ret = ops->vidioc_querycap(file, fh, cap);

	cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT;
	/*
	 * Drivers MUST fill in device_caps, so check for this and
	 * warn if it was forgotten.
	 */
	WARN(!(cap->capabilities & V4L2_CAP_DEVICE_CAPS) ||
		!cap->device_caps, "Bad caps for driver %s, %x %x",
		cap->driver, cap->capabilities, cap->device_caps);
	cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT;

	return ret;
}

vivi驱动vidioc_querycap源码如下

static int vidioc_querycap(struct file *file, void  *priv,
					struct v4l2_capability *cap)
{
	struct vivi_dev *dev = video_drvdata(file);

	strcpy(cap->driver, "vivi");
	strcpy(cap->card, "vivi");


        /*
         * 这里加深一下理解
         * dev->v4l2_dev.name 是什么?
         * vivi驱动中有这样一句代码
         * snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),
			"%s-%03d", VIVI_MODULE_NAME, inst);
         * "vivi-000" "vivi-001" 这种名字
         */

	strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
	cap->version = VIVI_VERSION;

        
        /*
         * 驱动表示支持capture,streaming及read write
         */    
    

	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | \
			    V4L2_CAP_READWRITE;
	return 0;
}

VIDIOC_QUERYCAP的过程比较简单

这里要注意,linux4.9.11中 struct v4l2_capability 中不仅仅有capabilities还新增了 device_caps。

    物理设备 整体功能
  * @capabilities: capabilities of the physical device as a whole
    通过此特定设备(节点)访问的功能 
  * @device_caps:  capabilities accessed via this particular device (node)

通俗的解释是:比如有个设备支持audio和capture,但是硬件上音频相关的线路没有连接,从当前的驱动上只支持capture,而无法支持audio。

这里我也写了一个测试程序v4l2_test测试vivi注册的video节点

int main(int argc, char **argv)
{
        int fd;
        struct v4l2_capability cap;

        if (argc != 2) {
                printf("Usage: v4l2_test <device>\n");
                printf("example: v4l2_test /dev/video0\n");
                return -1;
        }

        fd = open(argv[1], O_RDWR);

        if (fd < 0) {
                printf("open video device fail\n");
                return -1;
        }


        if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) {
                printf("Get video capability error!\n");
                return -1;
        }

        if (!(cap.device_caps & V4L2_CAP_VIDEO_CAPTURE)) {
                printf("Video device not support capture!\n");
                close(fd);
                return -1;
        }

        printf("Support capture!\n");

        close(fd);

        return 0;
}

通常在v4l2应用开发中,VIDIOC_QUERYCAP主要目的就是判断当前设备是否支持我们想要的功能,仅此而已。

代码放在了码云上

https://gitee.com/ldl17/v4l2-learn/blob/master/v4l2_test.c

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dianlong_lee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值