嵌入式-v4l2摄像头的工作流程及ioctl功能详解

本文详细介绍了嵌入式系统中V4L2摄像头的工作流程,包括打开设备、设置参数、帧缓冲区管理、视频流控制等步骤,并对关键ioctl命令如VIDIOC_S_PARM、VIDIOC_S_INPUT、VIDIOC_S_CROP等的功能进行了深入解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.摄像头的工作流程
1.打开设备文件

int fd=open("/dev/video0",O_RDWR);

2.取得设备的capability,看看设备具体支持哪些功能,比如是否具有视频的输入或者音频的输入等等ioctl(fd_v4l, VIDIOC_QUERYCAP, &cap)
3. 设置视频采集的参数:
设置视频的制式,制式包括PAL/NTSC,使用 ioctl(fd_v4l, VIDIOC_S_STD, &std_id)
设置视频图像的采集窗口的大小,使用 ioctl(fd_v4l, VIDIOC_S_CROP, &crop)
设置视频帧格式,包括帧的点阵格式,宽度和高度等,使用 ioctl(fd_v4l, VIDIOC_S_FMT, &fmt)
设置视频的帧率,使用 ioctl(fd_v4l, VIDIOC_S_PARM, &parm)
设置视频的旋转方式,使用 ioctl(fd_v4l, VIDIOC_S_CTRL, &ctrl)
4.向驱动申请视频的帧缓冲区,一般不会超过5个ioctl(fd_v4l, VIDIOC_REQBUFS, &req)
查询帧缓冲区在内核空间中的长度和偏移量 ioctl(fd_v4l, VIDIOC_QUERYBUF, &buf)
5.物理内存映射
将帧缓冲区的地址映射到用户空间,这样就可以直接操作采集到的帧了,而不必去复制。
buffers[i].start = mmap (NULL, buffers[i].length, PROT_READ | PROT_WRITE, MAP_SHARED, fd_v4l, buffers[i].offset);
6. 将申请到的帧缓冲全部放入视频采集输出队列,以便存放采集的数据。ioctl (fd_v4l, VIDIOC_QBUF, &buf)
7. 开始视频流数据的采集。 ioctl (fd_v4l, VIDIOC_STREAMON, &type)
8. 驱动将采集到的一帧视频数据存入输入队列第一个帧缓冲区,存完后将该帧缓冲区移至视频采集输出队列。
9. 应用程序从视频采集输出队列中取出已含有采集数据的帧缓冲区。ioctl (fd_v4l, VIDIOC_DQBUF, &buf) ,应用程序处理该帧缓冲区的原始视频数据。
10. 处理完后,应用程序的将该帧缓冲区重新排入输入队列,这样便可以循环采集数据。ioctl (fd_v4l, VIDIOC_QBUF, &buf)重复上述步骤8到10,直到停止采集数据。
11. 停止视频的采集。ioctl (fd_v4l, VIDIOC_STREAMOFF, &type)
12. 释放申请的视频帧缓冲区 unmap,关闭视频设备文件 close(fd_v4l)。

二.摄像头ioctl功能详解
1.ioctl(fd_v4l, VIDIOC_S_PARM, &parm)
功能:获取或设置数据流的参数,一般设置帧率等参数(帧率(Frame rate)是用于测量显示帧数的量度。所谓的测量单位为每秒显示帧数(Frames per Second,简称:FPS)或”赫兹”(Hz)。)
参数:
(1)fd_v4l:打开设备文件
(2)VIDIOC_S_PARM:cmd传参
(3)&parm:struct v4l2_streamparm currentparm;

 struct v4l2_streamparm {
       __u32     type;/*type 涉及的操作的类型,对于视频捕获设备,应该为V4L2_BUF_TYPE_VIDEO_CAPTURE;对于输出设备应该为 V4L2_BUF_TYPE_VIDEO_OUTPUT。 它的值也可以是V4L2_BUF_TYPE_PRIVATE,在这种情况下,raw_data字 段用来传递一些私有的,不可移植的,甚至是不鼓励的数据给内核 。*/
      union {
        struct v4l2_captureparm capture;/*对于捕获设备而言,parm.capture字段是要关注的内容*/
        struct v4l2_outputparm  output;
        __u8    raw_data[200];  /* user-defined */
    } parm;
};

    struct v4l2_captureparm {
    __u32          capability;    /*  capability 一组功能标签,目前为止已经定义的只有一个V4L2_CAP_TIMEPERFRAME,它代表可以改变帧频率 */
    __u32          capturemode;  /*  capturemode也是一个只定义了一个标签的字段:V4L2_MODE_HIGHQUALITY,这个标签意在使硬件在高清模式下工作,实现单帧的捕获。
    这个模式可以做出任何的牺牲 (包括支持的格式,曝光时间等),以达到设备可以处理的最佳图片质量。 */
    struct v4l2_fract  timeperframe;  /*  timeperframe字段用于指定想要使用的帧频率 */
    __u32          extendedmode;  /* extendedmode,它在API中没有明确的意义。 */
    __u32              readbuffers;   /* readbuffers字段是read()操作被调用时内核应为输入的帧准备的缓冲区数量。 */
    __u32          reserved[4];
};

 struct v4l2_fract {
        __u32   numerator;
        __u32   denominator;
    };
/*numerator和denominator所描述的系数给出的是成功的帧之间的时间间隔。*/

struct v4l2_outputparm {
    __u32          capability;   /*  capability 一组功能标签,目前为止已经定义的只有一个V4L2_CAP_TIMEPERFRAME,它代表可以改变帧频率 */
    __u32          outputmode;   /*  capturemode也是一个只定义了一个标签的字段:V4L2_MODE_HIGHQUALITY,这个标签意在使硬件在高清模式下工作,实现单帧的捕获。
    这个模式可以做出任何的牺牲 ࿰
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值