www.linuxtv.org下,有篇文档详细讲解了V4L2相关知识和体系结构。是V4L2方面最全面的文档。可以通过它学习V4L2的一些思路和想法。
最新文档则在:

文档包含的内容主要是Linux Kernel对 用户空间使用者提供的Video和Audio流Device. 包括video Cameras,模拟/数字电视接收器卡,AM/FM接受卡,流捕捉Device。


对V4L2 Device编程,通常包含以下步骤:
1. 打开Device。 
2. 改变devcie的特性,选择video或者audio 输入,video 标准,图像亮度等等。
3. 协商数据格式。
4. 协商输入/输入的方法。
5. 真实的输入/输出 Loop。
6. 关闭Device。


0.打开和关闭设备:
0.1: 设备名:
V4L2 driver以Kernel Modules形态实现,它在被root用户手动insmod 或者在设备首次被插入时被载入。driver 模块将被挂载在videodev模块下。

每个driver在载入是都会注册一个或多个主设备号为81,此设备号为0-255的device node.  如何分配次设备号,完全取决于root用户(SamInfo:其实不指定的话,系统也会自动分配没有被占用的次设备号)。这个方式的本意是为了解决device冲突。

模块的参数可以选择次设备号,此以设备名为前缀的的_nr中。例如:video_0表明/dev/video(0+Base). 
其中,video的base为0。radio的base则为64。
#insmod mydriver.ko video_nr=0,1 radio_nr=0,1


1. 关联设备:
Device可以支持几个相关的功能,例如video Capture,video overlay (注1)和 VBI
capturing相关联,因为其功能共享。video 输入设备和tuner也类似。V4L和早期版本的V4L2 对Video Capture 和Video Overlay采用同样的命名方式和同样范围的子设备号,但VBI设备则不同。这种方式有很多问题,更严重的是, V4L
videodev 禁止多重打开。


2. 设备的多次打开:
通常,V4L2设备可以被打开多次, 当驱动支持这个功能时,用户可以在其它应用程序捕捉Video或者Audio时,同时打开设备调节亮度或者音量.

多重打开功能是可选的,Driver至少应该支持用户在没有数据访问的情况下并发打开.
因为可以多重打开,所以理论上就应该可以设置优先级别(VIDIOC_G_PRIORITY和VIDIOC_S_PRIORITY),优先级高的应用程序可以成功修改一些设置,优先级低的设备去修改时,则会报失败EBUSY。



3. 共享数据流(Shared Data Streams)
V4L2 driver 不支持多个应用程序通过copy buffer读写Device的同一个数据流。非要这么干,可以使用在用户空间的代理程序。如果驱动支持流共享,那么其实现必须是透明的。V4L2 API 并没有列出产生冲突时要如何来解决。


4. 能力查询:(Querying Capabilites)
V4L2 包含很宽广的使用范围。 所以首先需要查询其设备能力集。
通常,使用ioctl VIDIOC_QUERYCAP
来查询当前driver是否合乎规范。因为V4L2要求所有driver 和Device都支持这个Ioctl。所以,可以通过这个ioctl是否成功来判断当前设备和dirver 是否支持V4L2规范。当然,这样同时还能够得到设备足够的能力信息。

struct v4l2_capability
{
 __u8 driver[16];   //驱动名。
 __u8 card[32];     // Device名
 __u8 bus_info[32];  //在Bus系统中存放位置
 __u32 version;      //driver 版本
 __u32 capabilities;  //能力集
 __u32 reserved[4];
};
能力集中包含:

V4L2_CAP_VIDEO_CAPTURE 0x00000001     The device supports the Video    Capture interface.

V4L2_CAP_VIDEO_OUTPUT   0x00000002     The device supports the Video    Output interface.

V4L2_CAP_VIDEO_OVERLAY 0x00000004     The device supports the Video    Overlay interface.

A video overlay device typically stores captured images directly in the video memory   of a graphics card,with hardware clipping
and scaling.

V4L2_CAP_VBI_CAPTURE     0x00000010 The device supports the Raw  VBI Capture interface, providing Teletext and Closed
Caption   data.

V4L2_CAP_VBI_OUTPUT     0x00000020      The device supports the Raw  VBI Output interface.

V4L2_CAP_SLICED_VBI_CAPTURE  0x00000040 The device supports the Sliced VBI Capture interface.

V4L2_CAP_SLICED_VBI_OUTPUT   0x00000080 The device supports the Sliced VBI Output interface.

V4L2_CAP_RDS_CAPTURE    0x00000100          [to be defined]

#define V4L2_CAP_TUNER 0x00010000  
#define V4L2_CAP_AUDIO 0x00020000  
#define V4L2_CAP_RADIO 0x00040000  

#define V4L2_CAP_READWRITE 0x01000000  
#define V4L2_CAP_ASYNCIO 0x02000000  
#define V4L2_CAP_STREAMING 0x04000000  

看起来很熟悉吧,其实就是Driver里面的Type。


5.格式查选和设置:
这里的格式,其实是指抓到的每一帧数据的相关格式.例如: 长,宽,像素,field等。
5.1:得到当前格式:
VIDIOC_G_FMT。
ioctl(Handle, VIDIOC_G_FMT, &Format)
参数三:
与很多ioctl类似, 它是个in/out参数。

struct v4l2_format
{
 enum v4l2_buf_type type;
 union
 {
 struct v4l2_pix_format pix;
 struct v4l2_window win;
 struct v4l2_vbi_format vbi;
 struct v4l2_sliced_vbi_format sliced;
 __u8 raw_data[200];
 } fmt;
};

v4l2_buf_type  type; 输入信息,让用户选择是哪种类型的设备。这里又与Driver中对应起来了。

struct v4l2_pix_format pix;
struct v4l2_pix_format
{
 __u32 width;   //抓取桢的宽度
 __u32 height;   //桢高度
 __u32 pixelformat;  //像素格式。例如:V4L2_PIX_FMT_YUYV,V4L2_PIX_FMT_RGB332等。
 enum v4l2_field field; //image包含逐行数据还是隔行数据。如果是隔行数据,是奇行还是偶行(下一篇详细讲述)
 __u32 bytesperline; //每行多少字节,通过width,height,pixelformat可以算出
 __u32 sizeimage;    //每桢多少字节。也可以算出。但需要加入field信息才能算出
 enum v4l2_colorspace colorspace;
 __u32 priv;
};

好像首次取 sizeimage,可能会取到不正确的值。

5.2:设置Format:
VIDIOC_S_FMT:
io_rel = ioctl(Handle, VIDIOC_S_FMT, &Format);
在设置之前,需要填写参数3Format内容.
例如;
Format.fmt.pix.width =  Width;
Format.fmt.pix.height = Height;
Format.fmt.pix.pixelformat= pixelformat;//V4L2_PIX_FMT_YUYV;
Format.fmt.pix.field = V4L2_FIELD_INTERLACED;


6. Streaming 信息得到和设置
前面Format是单帧数据的设置。现在咱们需要设置和流有关的信息。如桢数。
6.1:得到当前Stream信息:
利用ioctl:
memset(&Stream_Parm, 0, sizeof(struct v4l2_streamparm));
Stream_Parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 

io_rel = ioctl(Handle, VIDIOC_G_PARM, &Stream_Parm);
与之前类似,关键还是在参数三:
struct v4l2_streamparm
{
 enum v4l2_buf_type type;
 union
 {
 struct v4l2_captureparm capture;
 struct v4l2_outputparm output;
 __u8 raw_data[200];
 } parm;
};

type是个in/out参数,咱们是Camera捕捉设备,所以选用V4L2_BUF_TYPE_VIDEO_CAPTURE。

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

调节的关键在 struct v4l2_fract timeperframe;
struct v4l2_fract {
 __u32 numerator;   //FPS的分子
 __u32 denominator; // FPS的分母
};
例如: numerator=1, denominator= 30. 则表明每秒30帧。



6.2:设置Stream Setting
memset(&Stream_Parm, 0, sizeof(struct v4l2_streamparm));
Stream_Parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 

Stream_Parm.parm.capture.timeperframe.denominator =Denominator;;
Stream_Parm.parm.capture.timeperframe.numerator = Numerator;

io_rel = ioctl(Handle, VIDIOC_S_PARM, &Stream_Parm);







注1:
Video Capture(视频捕捉)和Video overlay的区别:
vieo overlay不同于video
capture,是指不需要对video信号的帧进行copy,直接将视频信号转化成显卡的VGA信号或者将捕获到的视频帧直接存放在显卡的内存中

【Qt开发】V4L2 API详解 背景知识 打开设备设置参数的更多相关文章

  1. 【Qt开发】V4L2 API详解 Camera详细设置

    Camera的可设置项极多,V4L2 支持了不少.但Sam之前对这些设置的用法和涵义都是在看videodev2.h中边看边理解,感觉非常生涩.直到写这篇blog时,才发现v4l2有专门的SPEC来说明 ...

  2. 【Qt开发】V4L2 API详解 Buffer的准备和数据读取

    前面主要介绍的是:V4L2 的一些设置接口,如亮度,饱和度,曝光时间,帧数,增益,白平衡等.今天看看V4L2 得到数据的几个关键ioctl,Buffer的申请和数据的抓取. 1. 初始化 Memory ...

  3. V4L2 API详解 <二> Camera详细设置【转】

    转自:http://blog.sina.com.cn/s/blog_602f87700101bf36.html 作者: Sam (甄峰)  sam_code@hotmail.com   Camera的 ...

  4. V4L2 API详解 Buffer的准备和数据读取

    1. 初始化 Memory Mapping 或 User Pointer I/O. int ioctl(int fd, int requestbuf, struct v4l2_requestbuffe ...

  5. Android Developer -- Bluetooth篇 开发实例之四 API详解

    http://www.open-open.com/lib/view/open1390879771695.html 这篇文章将会详细解析BluetoothAdapter的详细api, 包括隐藏方法, 每 ...

  6. canvas绘图API详解

    canvas绘图API详解 1.context的状态 矩阵变换属性 当前剪辑区域 context的其他状态属性: strokeStyle, fillStyle, globalAlpha, lineWi ...

  7. 网络编程socket基本API详解(转)

    网络编程socket基本API详解   socket socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信. socket ...

  8. 转】Mahout推荐算法API详解

    原博文出自于: http://blog.fens.me/mahout-recommendation-api/ 感谢! Posted: Oct 21, 2013 Tags: itemCFknnMahou ...

  9. 【转】【Android UI设计与开发】之详解ActionBar的使用,androidactionbar

    原文网址:http://www.bkjia.com/Androidjc/895966.html [Android UI设计与开发]之详解ActionBar的使用,androidactionbar 详解 ...

随机推荐

  1. 深入理解JAVA虚拟机 自动内存管理机制

    运行时数据区域 其中右侧三个一起的部分是每个线程一份,左侧两个是所有线程共享的. 程序计数器(Program Counter Register) 英文名称叫Program Counter Regist ...

  2. mybatis 的 DefaultVFS 日志乱码问题

    mybatis 的 DefaultVFS 日志乱码问题 mybatis  DefaultVFS 乱码  1. 问题描述 今天在启动同事搭建的工程时,发现 console 中乱码,细看下,是 mybat ...

  3. Java中CharSet字符集

    java.nio.charset包中提供了Charset类,它继承了Comparable接口:还有CharsetDecoder.CharsetEncoder编码和解码的类,它们都是继承Object类. ...

  4. h5页面弹窗时页面固定(弹窗下面的页面不滑动)

    页面出现弹窗时,底部页面不能随之滑动怎么解决? 只需将页面的body增加一个样式 overflow:hidden;就能解决 jq: //开启弹窗 $('body').attr('style','ove ...

  5. netty之IO演进之路

    常见IO类型: 传统的同步阻塞I/O编程<BIO> 基于NIO的非阻塞编程 基于NIO2.0的异步非阻塞AIO编程 BIO缺点: 没有数据缓冲区,I/O性能存在问题 没有Channel概念 ...

  6. 初识Python,利用turtle画图

    目录 我的第三篇博客 一.初识Python 1.变量 2.注释 3.turtle库 我的第三篇博客 一.初识Python 1.变量 变量就是可变的的量,用来描述某个事物的属性.本质作用就是描述和接收变 ...

  7. redis开发使用规范

    redis开发使用规范 1.冷热数据分离,不要将所有数据全部都放在Redis中 根据业务只将高频热数据存储到Redis中[QPS大于5000],对于低频冷数据可以使用mysql等基于磁盘的存储方式. ...

  8. Python模块之-OS模块

    一.os模块概述 Python os模块包含普遍的操作系统功能.如果你希望你的程序能够与平台无关的话,这个模块是尤为重要的.(一语中的) 二.常用方法 1.os.name 输出字符串指示正在使用的平台 ...

  9. 箭头函数详解()=>{}

    摘要:箭头函数有几个使用注意点. (1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象,箭头函数继承而来的this指向永远不变. (2)不可以当作构造函数,也就是说,不可以使用n ...

  10. architecture 20190628

    https://abp.io/  --ABP v2 官网 https://grpc.io/ --gRPC官网 https://devblogs.microsoft.com/dotnet/introdu ...