首页 > 编程语言 >V4L2应用程序开发(1)

V4L2应用程序开发(1)

时间:2024-03-26 17:22:25浏览次数:29  
标签:__ V4L2 程序开发 ioctl VIDIOC u32 应用 v4l2

参考资料:韦东山第三期   v4l2应用程序开发分为两个部分,数据采集流程和控制流程两个部分   数据采集流程: 分为空闲链表和完成链表   驱动程序周而复始地做如下事情:

  • 从硬件采集到数据
  • 把"空闲链表"取出buffer,把数据存入buffer
  • 把含有数据的buffer放入"完成链表"
APP也会周而复始地做如下事情:
  • 监测"完成链表",等待它含有buffer
  • 从"完成链表"中取出buffer
  • 处理数据
  • 把buffer放入"空闲链表"
链表操作示意图: 0 摄像头的应用操作流程,如下:
  • open:打开设备节点/dev/videoX
  • ioctl VIDIOC_QUERYCAP:Query Capbility,查询能力,比如
    • 确认它是否是"捕获设备",因为有些节点是输出设备
    • 确认它是否支持mmap操作,还是仅支持read/write操作
  • ioctl VIDIOC_ENUM_FMT:枚举它支持的格式
  • ioctl VIDIOC_S_FMT:在上面枚举出来的格式里,选择一个来设置格式
  • ioctl VIDIOC_REQBUFS:申请buffer,APP可以申请很多个buffer,但是驱动程序不一定能申请到,requery申请
  • ioctl VIDIOC_QUERYBUF和mmap:查询buffer信息、映射
    • 如果申请到了N个buffer,这个ioctl就应该执行N次
    • 执行mmap后,APP就可以直接读写这些buffer
  • ioctl VIDIOC_QBUF:把buffer放入"空闲链表"
    • 如果申请到了N个buffer,这个ioctl就应该执行N次
  • ioctl VIDIOC_STREAMON:启动摄像头
  • 这里是一个循环:使用poll/select监测buffer,然后从"完成链表"中取出buffer,处理后再放入"空闲链表"
    • poll/select
    • ioctl VIDIOC_DQBUF:从"完成链表"中取出buffer
    • 处理:前面使用mmap映射了每个buffer的地址,处理时就可以直接使用地址来访问buffer
    • ioclt VIDIOC_QBUF:把buffer放入"空闲链表"
  • ioctl VIDIOC_STREAMOFF:停止摄像头
  控制流程: 应用程序接口

数据格式的枚举、获得和设置:

1、数据格式

枚举格式的时候,只是返回支持的pixelformat和描述
struct v4l2_fmtdesc fmtdesc;
fmtdesc.index = 0;  // 比如从0开始
fmtdesc.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;  // 指定type为"捕获"
ioctl(vd->fd, VIDIOC_ENUM_FMT, &fmtdesc);

// uapi/linux/videodev2.h
 struct v4l2_fmtdesc {
         __u32               index;             /* Format number      */
         __u32               type;              /* enum v4l2_buf_type */
         __u32               flags;
         __u8                description[32];   /* Description string */
         __u32               pixelformat;       /* Format fourcc      */
         __u32               reserved[4];
 };

 enum v4l2_buf_type {
         V4L2_BUF_TYPE_VIDEO_CAPTURE        = 1,            // 摄像头一般就为捕获设备
         V4L2_BUF_TYPE_VIDEO_OUTPUT         = 2,
         V4L2_BUF_TYPE_VIDEO_OVERLAY        = 3,
         V4L2_BUF_TYPE_VBI_CAPTURE          = 4,
         V4L2_BUF_TYPE_VBI_OUTPUT           = 5,
         V4L2_BUF_TYPE_SLICED_VBI_CAPTURE   = 6,
         V4L2_BUF_TYPE_SLICED_VBI_OUTPUT    = 7,
 #if 1
         /* Experimental */
         V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8,
 #endif
         V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 9,
         V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE  = 10,
         V4L2_BUF_TYPE_SDR_CAPTURE          = 11,
         /* Deprecated, do not use */
         V4L2_BUF_TYPE_PRIVATE              = 0x80,
 };

 

2、获取当前摄像头使用的格式

获取当前格式更加详细的信息,就需要使用VIDIOC_G_FRT
struct v4l2_format currentFormat;
memset(&currentFormat, 0, sizeof(struct v4l2_format));
currentFormat.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ioctl(vd->fd, VIDIOC_G_FMT, &currentFormat);

#if 0
struct v4l2_format {
    __u32     type;            // 表示捕获设备
    union {
        struct v4l2_pix_format        pix;     /* V4L2_BUF_TYPE_VIDEO_CAPTURE */
        struct v4l2_pix_format_mplane    pix_mp;  /* V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */
        struct v4l2_window        win;     /* V4L2_BUF_TYPE_VIDEO_OVERLAY */
        struct v4l2_vbi_format        vbi;     /* V4L2_BUF_TYPE_VBI_CAPTURE */
        struct v4l2_sliced_vbi_format    sliced;  /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
        struct v4l2_sdr_format        sdr;     /* V4L2_BUF_TYPE_SDR_CAPTURE */
        __u8    raw_data[200];                   /* user-defined */
    } fmt;
};

/*
 *    V I D E O   I M A G E   F O R M A T
 */
struct v4l2_pix_format {
    __u32                 width;
    __u32            height;
    __u32            pixelformat;
    __u32            field;        /* enum v4l2_field */
    __u32                bytesperline;    /* for padding, zero if unused */
    __u32                  sizeimage;
    __u32            colorspace;    /* enum v4l2_colorspace */
    __u32            priv;        /* private data, depends on pixelformat */
    __u32            flags;        /* format flags (V4L2_PIX_FMT_FLAG_*) */
    __u32            ycbcr_enc;    /* enum v4l2_ycbcr_encoding */
    __u32            quantization;    /* enum v4l2_quantization */
    __u32            xfer_func;    /* enum v4l2_xfer_func */
};
#endif

 

3、设置当前格式

使用VIDIOC_S_FMT
struct v4l2_format fmt;
memset(&fmt, 0, sizeof(struct v4l2_format));
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = 1024;
fmt.fmt.pix.height = 768;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
fmt.fmt.pix.field = V4L2_FIELD_ANY;
int ret = ioctl(vd->fd, VIDIOC_S_FMT, &fmt);
 

选择输入源:

int value;
ioctl(h->fd,VIDIOC_G_INPUT,&value);  // 读到的value从0开始, 0表示第1个input源

int value = 0;  // 0表示第1个input源
ioctl(h->fd,VIDIOC_S_INPUT,&value)
 

其他参数:

如果每一参数都提供一系列的ioctl cmd,那使用起来很不方便。 对于这些参数,APP使用对应ID来选中它,然后使用VIDIOC_QUERYCTRL、VIDIOC_G_CTRL、VIDIOC_S_CTRL来操作它。 不同参数的ID值不同。以亮度Brightness为例,有如下调用方法:

1、查询

struct v4l2_queryctrl   qctrl;
memset(&qctrl, 0, sizeof(qctrl));
qctrl.id = V4L2_CID_BRIGHTNESS; // V4L2_CID_BASE+0;
ioctl(fd, VIDIOC_QUERYCTRL, &qctrl);

/*  Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
struct v4l2_queryctrl {
    __u32             id;
    __u32             type;    /* enum v4l2_ctrl_type */
    __u8             name[32];    /* Whatever */
    __s32             minimum;    /* Note signedness */
    __s32             maximum;
    __s32             step;
    __s32             default_value;
    __u32                flags;
    __u32             reserved[2];
};

 

2、获得当前值

struct v4l2_control c;
c.id = V4L2_CID_BRIGHTNESS; // V4L2_CID_BASE+0;
ioctl(h->fd, VIDIOC_G_CTRL, &c);


/*
 *    C O N T R O L S
 */
struct v4l2_control {
    __u32             id;
    __s32             value;
};

 

3、设置

struct v4l2_control c;
c.id = V4L2_CID_BRIGHTNESS; // V4L2_CID_BASE+0;
c.value = 99;
ioctl(h->fd, VIDIOC_S_CTRL, &c);
   

理解接口:

0 SU:select unit,选择输入源 PU:processiong unit,用于调整亮度、对比度、色度等 EU:encoding unit,对采集到的数据进行个性化处理的功能 0 ID会传递给PU app->驱动->(id, val)->硬件  

操作方法:

使用ioctl操作设备节点/dev/video0时,不同的ioctl操作可能是video control接口,或者video streaming接口 跟视频流相关的操作,比如VIDIOC_ENUM_FMT,VIDIOC_G_FMT,VIDIOC_S_FMT,VIDIOC_STREAMON,VIDIOC_STREAMOFF,是操作video streaming的接口   其他的接口,大多是video control接口 从驱动和硬件角度来看,要操作video control接口,需要指明: 1、entity:要操作的是那个terminal或者unit,比如PU 2、control selector:要操作entity里面的那个控制项,比如亮度 3、控制项里面的哪些位:比如camera terminal里的CT_PANTILT_RELATIVE_CONTROL控制项对应的32位数据,其中前16位对应PAN控制(左右转动),后16位对应TILE控制(上下转动) 但是应用程序不关心这些,使用一个ID来指定entity、control selector、哪些位:
struct v4l2_control c;
c.id = V4L2_CID_BRIGHTNESS;    // V4L2_CID_BASE+0;
c.value = 99;
ioctl(h->fd, VIDIOC_S_CTRL, &c);

/*
 *    C O N T R O L S
 */
struct v4l2_control {
    __u32             id;
    __s32             value;
};

 

支持V4L2_CAP_STREAMING就可以用mmap函数,不支持的话就只能用V4L2_CAP_READWRITE了

 

 

标签:__,V4L2,程序开发,ioctl,VIDIOC,u32,应用,v4l2
From: https://www.cnblogs.com/lethe1203/p/18097134

相关文章

  • 无人机反制:低空目标监测预警打击系统之应用场景【知语云智能科技】
    随着科技的不断发展,低空目标监测预警打击系统已成为现代军事与民用安全领域的重要组成部分。知语云智能科技在这一领域深耕多年,凭借其先进的技术实力和创新能力,为众多应用场景提供了高效、精准的解决方案。以下,将详细探讨低空目标监测预警打击系统在20种不同场景中的应用。军......
  • Java面试题:请解释Java中的集合框架?并详细说明各个集合的应用场景
    Java中的集合框架(CollectionFramework)是一组用来存储和管理对象的类和接口的集合,它为开发中常见的数据结构和算法提供了一种统一的、可重用的实现。Java集合框架的主要目的是提供一种灵活、可扩展的方式来存储和操作对象集合,而无需关心底层数据的存储细节。Java集合框架主......
  • 【附源码】Node.js毕业设计个人健康信息记录移动应用app(Express)
    本系统(程序+源码)带文档lw万字以上  文末可获取本课题的源码和程序系统程序文件列表系统的选题背景和意义选题背景:随着科技的进步和互联网的普及,移动应用已经成为人们日常生活中不可或缺的一部分。在健康管理领域,个人健康信息记录移动应用APP的开发和应用也日益受到关注......
  • 打车代驾app软件小程序开发定制
       打车代驾APP软件和小程序软件功能开发,除了基本的功能外还需要添加一些自己的想法,还有按照用户的使用习惯添加功能。   智能调度系统:打车软件会按照市场规律调整,例如用户需求、司机位置和交通状况,实现智能派单,提高效率。   语音导航:为司机提供语音导航功能,方便......
  • 探索计算机视觉的前沿:研究方向与应用前景
    引言计算机视觉作为人工智能领域的一个重要分支,近年来取得了显著的进展。它旨在使计算机能够从图像或多维数据中理解和解释视觉信息。随着深度学习技术的突破,计算机视觉的应用范围不断扩大,从自动驾驶到医疗诊断,其影响力日益增强。本文将探讨计算机视觉的几个主要研究方向及其......
  • C# 退出应用程序
    常见的有如下几种退出的方式this.Close关闭当前窗口如果我们操作的对象是Form时可以采用这种方式退出对应的Form,若不是主窗体的话,是无法退出程序的另外若有托管线程(非主线程),也无法干净地退出privatevoidbtnClose_Click(objectsender,EventArgse){this.close();......
  • 专注驱动器芯片,包括MASTERGAN1TR、VNQ860SP、VNH9013YTR、VN5160STR用于汽车应用
    1、MASTERGAN1TR——半桥驱动器通用DMOS31QFN输出配置:半桥应用:通用接口:-负载类型:容性,感性技术:DMOS导通电阻(典型值):150毫欧电流-输出/通道:10A电流-峰值输出:17A电压-供电:4.75V~9.5V电压-负载:600V(最大)工作温度:-40°C~150°C(TJ)特性:自举电路故障保护:超温,UVLO安装类型......
  • 大模型落地实战指南:从选择到训练,深度解析显卡选型、模型训练技、模型选择巧及AI未来展
    https://www.cnblogs.com/ting1/p/18096103 0.前言大模型发展史早期阶段(1950s~1980s)在1950年代初期,人们开始尝试使用计算机处理自然语言文本。然而,由于当时的计算机处理能力非常有限,很难处理自然语言中的复杂语法和语义。随着技术的发展,自然语言处理领域在20世纪60年代和70......
  • 产品可靠性设计、分析与试验在工程中的应用
    随着科技发展和信息化程度的不断推进,电子技术的复杂程度越来越高,发展速度越来越快,可靠性问题也越来越尖锐。一、典型的可靠性工作流程1、可靠性工作的常用工作流程2、某系统可靠性工作计划二、可靠性指标制定1、典型的可靠性指标2、建立工作剖面案例:无人机电子系统和动......
  • 大模型落地实战指南:从选择到训练,深度解析显卡选型、模型训练技、模型选择巧及AI未来展
    大模型落地实战指南:从选择到训练,深度解析显卡选型、模型训练技、模型选择巧及AI未来展望---打造AI应用新篇章0.前言大模型发展史早期阶段(1950s~1980s)在1950年代初期,人们开始尝试使用计算机处理自然语言文本。然而,由于当时的计算机处理能力非常有限,很难处理自然语言中的复杂语......