Video for linux 2 example (v4l2 demo)

本文介绍了V4L2(Video For Linux Two)API的使用,详细讲解了如何打开和关闭设备、查询设备属性、设置视频制式和帧格式、图像缩放以及缓冲区管理等步骤,提供了相应的示例代码,适用于Linux下的视频处理和开发。
摘要由CSDN通过智能技术生成

                       V4L2 API讲解附demo

(注:从他人博客整理修正而来)

(看完本文后,更简便的api请移步至video for linux 2 API

1. 定义


V4L2(Video For Linux Two) 是内核提供给应用程序访问音、视频驱动的统一接口。


2. 工作流程:


打开设备-> 检查和设置设备属性-> 设置帧格式-> 设置一种输入输出方法(缓冲 区管理)-> 循环获取数据-> 关闭设备。


3. 设备的打开和关闭:


#include <fcntl.h>

int open(const char *device_name, int flags);

#include <unistd.h>

int clo se(int fd);

例:


int fd=open(“/dev/video0”,O_RDWR); // 打开设备

close(fd); // 关闭设备

注意:V4L2 的相关定义包含在头文件<linux/videodev2.h> 中.


4. 查询设备属性: VIDIOC_QUERYCAP


相关函数:


int ioctl(int fd, int request, struct v4l2_capability *argp);

相关结构体:


struct v4l2_capability

{

u8 driver[16]; // 驱动名字

u8 card[32]; // 设备名字

u8 bus_info[32]; // 设备在系统中的位置

u32 version; // 驱动版本号

u32 capabilities; // 设备支持的操作

u32 reserved[4]; // 保留字段

};

capabilities 常用值:

V4L2_CAP_VIDEO_CAPTURE // 是否支持图像获取

例:显示设备信息


struct v4l2_capability cap;

ioctl(fd,VIDIOC_QUERYCAP,&cap);

printf(“Driver Name:%s\nCard Name:%s\nBus info:%s\nDriver Version:%u.%u.%u\n”,cap.driver,cap.card,cap.bus_info,(cap.version>>16)&0XFF, (cap.version>>8)&0XFF,cap.version&0XFF);

5. 设置视频的制式和帧格式


制式包括PAL,NTSC,帧的格式个包括宽度和高度等。

相关函数:


int ioctl(int fd, int request, struct v4l2_fmtdesc *argp);

int ioctl(int fd, int request, struct v4l2_format *argp);

相关结构体:

v4l2_cropcap 结构体用来设置摄像头的捕捉能力,在捕捉上视频时应先先设置

v4l2_cropcap 的 type 域,再通过 VIDIO_CROPCAP 操作命令获取设备捕捉能力的参数,保存于 v4l2_cropcap 结构体中,包括 bounds(最大捕捉方框的左上角坐标和宽高),defrect

(默认捕捉方框的左上角坐标和宽高)等。

v4l2_format 结构体用来设置摄像头的视频制式、帧格式等,在设置这个参数时应先填 好 v4l2_format 的各个域,如 type(传输流类型),fmt.pix.width(宽),

fmt.pix.heigth(高),fmt.pix.field(采样区域,如隔行采样),fmt.pix.pixelformat(采

样类型,如 YUV4:2:2),然后通过 VIDIO_S_FMT 操作命令设置视频捕捉格式。如下图所示:

clip_image004



5.1 查询并显示所有支持的格式:VIDIOC_ENUM_FMT


相关函数:


int ioctl(int fd, int request, struct v4l2_fmtdesc *argp);


相关结构体:


struct v4l2_fmtdesc

{

u32 index; // 要查询的格式序号,应用程序设置

enum v4l2_buf_type type; // 帧类型,应用程序设置

u32 flags; // 是否为压缩格式

u8 description[32]; // 格式名称

u32 pixelformat; // 格式

u32 reserved[4]; // 保留

};

例:显示所有支持的格式


struct v4l2_fmtdesc fmtdesc; fmtdesc.index=0; fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; printf("Support format:\n");

while(ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) != -1)

{

printf("\t%d.%s\n",fmtdesc.index+1,fmtdesc.description);

fmtdesc.index++;

}

5.2 查看或设置当前格式: VIDIOC_G_FMT, VIDIOC_S_FMT


检查是否支持某种格式:VIDIOC_TRY_FMT

相关函数:


int ioctl(int fd, int request, struct v4l2_format *argp);

相关结构体:


struct v4l2_format
{

enum v4l2_buf_type type; // 帧类型,应用程序设置

union fmt
    {

        struct v4l2_pix_format pix; // 视频设备使用

        struct v4l2_window win;

        struct v4l2_vbi_format vbi;

        struct v4l2_sliced_vbi_format sliced;

        u8 raw_data[200];

    };
};

struct v4l2_pix_format

{

    u32 width; // 帧宽,单位像素

    u32 height; // 帧高,单位像素

    u32 pixelformat; // 帧格式

    enum v4l2_field field;

    u32 bytesperline;

    u32 sizeimage;

    enum v4l2_colorspace colorspace;

    u32 priv;

};

例:显示当前帧的相关信息


struct v4l2_format fmt;

fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

ioctl(fd, VIDIOC_G_FMT, &fmt);

printf(“Current data format information:\n\twidth:%d\n\theight:%d\n”, fmt.fmt.pix.width,fmt.fmt.pix.height);

struct v4l2_fmtdesc fmtdesc;

fmtdesc.index = 0;

fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc) != -1)
{

    if(fmtdesc.pixelformat & fmt.fmt.pix.pixelformat)
    {

        printf(“\tformat:%s\n”,fmtdesc.description);

        break;

    }
    fmtdesc.index++;

}



例:检查是否支持某种帧格式


struct v4l2_format fmt; 

fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 

fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB32; 

if(ioctl(fd,VIDIOC_TRY_FMT,&fmt) == -1) 
{
    if(errno==EINVAL)
    {
        printf(“not support format RGB32!\n”);
    }
}


6. 图像的缩放 VIDIOC_CROPCAP


相关函数:


int ioctl(int fd, int request, struct v4l2_cropcap *argp);

int ioctl(int fd, int request, struct v4l2_crop *argp);

int ioctl(int fd, int request, const struct v4l2_crop *argp);

相关结构体:

v4l2_cropcap 结构体用来设置摄像头的捕捉能力,在捕捉上视频时应先先设置v4l2_cropcap 的 type 域,再通过 VIDIO_CROPCAP 操作命令获取设备捕捉能力的参数,保存于 v4l2_cropcap 结构体中,包括 bounds(最大捕捉方框的左上角坐标和宽高),defrect(默认捕捉方框的左上角坐标和宽高)等。

Cropping 和 scaling 主要指的是图像的取景范围及图片的比例缩放的支持。Crop 就 是把得到的数据作一定的裁剪和伸缩,裁剪可以只取样我们可以得到的图像大小的一部分, 剪裁的主要参数是位置、长度、宽度。而 scale 的设置是通过 VIDIOC_G_FMT 和 VIDIOC_S_FMT 来获得和设置当前的 image 的长度,宽度来实现的。看下图

image

我们可以假设 bounds 是 sensor 最大能捕捉到的图像范围,而 defrect 是设备默认 的最大取样范围,这个可以通过 VIDIOC_CROPCAP 的 ioctl 来获得设备的 crap 相关的属 性 v4l2_cropcap,其中的 bounds 就是这个 bounds,其实就是上限。每个设备都有个默 认的取样范围,就是 defrect,就是 default rect 的意思,它比 bounds 要小一些。这 个范围也是通过 VIDIOC_CROPCAP 的 ioctl 来获得的 v4l2_cropcap 结构中的 defrect 来表示的,我们可以通过 VIDIOC_G_CROP 和 VIDIOC_S_CROP 来获取和设置设备当前的 crop 设置。


6.1 设置设备捕捉能力的参数


相关函数:


int ioctl(int fd, int request, struct v4l2_cropcap *argp);


相关结构体:


struct v4l2_cropcap
{
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值