v4l2架构专题模块handler分析 -- ioctl分析

前面分析了handler的创建以及添加ctrl的过程,对于ctrl来说,ctrl的类型有很多,这里仅仅分析了一个而已,其他的基本也是这个套路。既然handler创建了,ctrl添加了,那么如何通过ioctl去操作呢?

这里贴一个ctrl实例

h_flip = v4l2_ctrl_new_std(handler, &xxx_ctrl_ops,
                  V4L2_CID_HFLIP, 0, 1, 1, 0);

通过id V4L2_CID_HFLIP可以知道,这是一个操作水平镜像的ctrl

我们可以通过v4l2-ctl查看

# v4l2-ctl -l -d /dev/v4l-subdev3

User Controls

       ...
   horizontal_flip 0x00980914 (bool)   : default=0 value=0
     vertical_flip 0x00980915 (bool)   : default=0 value=0

...

可以看出当前值为0

下面写个程序通过ioctl操作

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <asm/types.h>
#include <linux/videodev2.h>
#include <sys/mman.h>
#include <errno.h>

int main(int argc, char **argv)
{
    int fd; 
    int ret;

    struct v4l2_control ctrl;
    struct v4l2_queryctrl qctrl;

    if (argc != 3) {
        printf("Usage: v4l2_ctrl_test <device> <value>\n");
        printf("example: v4l2_ctrl_test /dev/video0 1\n");

        goto err1;
    }

    fd = open(argv[1], O_RDWR);
    if (fd < 0) {
        printf("open device: %s fail\n", argv[1]);
        goto err1;
    }

    ctrl.id = V4L2_CID_HFLIP;
    if (ioctl(fd, VIDIOC_G_CTRL, &ctrl) < 0) {
        printf("ioctl G V4L2_CID_HFLIP error!\n");
        goto err;
    }

    printf("value = %d\n", ctrl.value);
    ctrl.value = atoi(argv[2]);
    if (ioctl(fd, VIDIOC_S_CTRL, &ctrl) < 0) {
        printf("ioctl S V4L2_CID_HFLIP error!\n");
        goto err;
    }


err:
    close(fd);
err1:
    return -1;
}

首次通过VIDIOC_G_CTRL,获取ctrl到值,然后通过VIDIOC_S_CTRL设置ctrl的值

# v4l2_ctrl_test /dev/v4l-subdev3 1
value = 0
# v4l2-ctl -l -d /dev/v4l-subdev3

User Controls
            ...
      horizontal_flip 0x00980914 (bool)   : default=0 value=1
        vertical_flip 0x00980915 (bool)   : default=0 value=0
            ...

操作后可以看到值从0变成了1

对于一个ctrl,如果不知道其最大最小这些信息,可以通过下面的ioctl去获取

    qctrl.id = V4L2_CID_HFLIP;
    if (ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) < 0) {
        printf("ioctl Q V4L2_CID_HFLIP error!\n");
        goto err;
    }   
    
    printf("name          : %s\n", qctrl.name);
    printf("type          : 0x%08x\n", qctrl.type);
    printf("minimum       : %d\n", qctrl.minimum);
    printf("maximum       : %d\n", qctrl.maximum);
    printf("step          : %d\n", qctrl.step);
    printf("default_value : %d\n", qctrl.default_value);

得到如下的 打印信息:

name          : Horizontal Flip
type          : 0x00000002
minimum       : 0
maximum       : 1
step          : 1
default_value : 0

对于ioctl的调用过程这里不再去跟进分析,内核对应下面的这3个函数

v4l_g_ctrl

v4l_s_ctrl

v4l_queryctrl

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

dianlong_lee

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

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

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

打赏作者

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

抵扣说明:

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

余额充值