v4l2 spec 中文 Ch01

 

 

Video for Linux Two API Specification

Revision 0.24

 

 

 

 

 

 

 

Michael H Schimek

mschimek@gmx.at

 

 

 

 

 

 

Bill Dirks

Hans Verkuil

Martin Rubli

 

 

 

 

 

V4L2 中文版            Made by:鱼在飞(467350479)         个人翻译,转载申明

v4l2全五章下载地址

v4l2 中文pdf,Chapter all

Chapter 1. 通用API(Common API Elements)

编程以支持一个V4l2的设备包含以下步骤:

.打开设备

.改变设备的属性,选择音频和视频输入,视频的标准(编码格式?),图片的亮度等

.协商数据格式

.协商输入/输出的方法

.输入/输出循环

.关闭设备

1.1.  打开和关闭设备(Opening and Closing Devices)

1.1.1.  设备命名(Device Naming)

V4L2以模块的方式在内核中实现,可以被管理员手动的加载或者是当设备第一次打开时被加载。驱动模块被挂在内核模块"videodev"下。在这份文档中,提供了辅助函数和一个通用的应用程序接口规范。

每个驱动加载时都会用主设备号81和次设备号0-255来注册一个或多个设备节点。该如何分配次设备号给这些个V4L2设备,完全取决与系统管理员,这主要是为了解决设备间的冲突(为了区分不同的设备)1。当选定次设备号后,模块将会以"_nr"为前缀来命名特殊的设备文件名。举个例子来说,像"video_nr"就是代表视频采集设备的(在内核中表示为)/dev/video。数字则是和设备类型相关并基于次设备号的一个偏移2

当驱动支持同一型号的多个设备时,这时就可以赋予多个次设备号了,并以逗号隔开:

> insmod mydriver.o video_nr=0,1 radio_nr=0,1

 

在/etc/modules.conf 文件中,可能是显示如下:

 alias char-major-81-0 mydriver

 alias char-major-81-1 mydriver

 alias char-major-81-64 mydriver                        

Options mydriver video_nr=0,1 radio_nr=0,1             ‚

当应用程序试图打开主设备号81,次设备号0,1,64,时会加载驱动"mydriver"

‚注册前两个视频采集设备时是从主设备号0开始的,接着是1...一直到63,而音频设备则是从次设备64开始的。

    如果未显式给定次设备号,那么模块将提供一个默认值。第四章将阐述不同型号设备的起始次设备号。显然次设备号必须是独一无二的。假如所请求的设备号正在使用时,很明显起冲突的设备将不会被注册。

   安装惯例,系统管理员会根据主、次设备号在/dev目录下创建不同功用的特殊设备文件。文件名字则建议有别于列在第四章的V4L2设备名。

用命令mknod创建的字符设备,拥有特权操作并且这些设备是不能通过主、次设备号打开的。这就意味着应用程序是不能可靠的扫描已加载或者是安装的驱动的。用户必须键入设备名,或者应用程序会尝试默认的设备名。

在设备文件系统(devfs)下,次设备号是被忽略的(明显的在其下我们只要知道设备的功能,主设备号就提供这样的作用)。V4L2驱动会自动的在/dev/v4l目录下,用默认的设备名创建所请求的设备文件。

1.1.2.  相关设备(Related Devices)

驱动通常都能支持许多相关的功能。有个例子说,视频采集,直接传输视频,视频垂直消隐信号采集 ,

都有着千丝万缕的联系,这是因为这些功能都共享着,起码在他们之间,相同的视频输入(视频采集头,webcam)和高频头(可以看作是音视频采集头)。

 

注(V4L2所提供的接口):

1. 视频采集接口(video capture interface):这种应用的设备可以是高频头或者摄像头.V4L2的最初设计就是应用于这种功能的.         

2. 视频输出接口(video output interface):可以驱动计算机的外围视频图像设备--像可以输出电视信号格式的设备.         

3. 直接传输视频接口(video overlay interface):它的主要工作是把从视频采集设备采集过来的信号直接输出到输出设备之上,而不用经过系统的CPU.         

4. 视频间隔消隐信号接口(VBI interface):它可以使应用可以访问传输消隐期的视频信号.           

5. 收音机接口(radio interface):可用来处理从AM或FM高频头设备接收来的音频流.

V4L和早前的V4L2版本,视频采集和overlay是使用相同的设备名,相同的次设备号,但是却有别于VBI(Vertial Blanking Interval)。实践表明,这种方法拥有众多问题3,更糟糕的是V4L的videodev模型是禁止同时多次打开设备的。

作为补救措施,当前的V4L2版本是通过特定的名字和次设备号放宽了设备类型的概念。为了保持和旧的应用程序的兼容性,驱动必须依旧注册不同的次设备号并制定一个默认的对应功能给这个设备(major代表一类设备,minor这是用来给内核区分一类设备的不同实例或者功能。这样,major代表一个班级,那么minor就是用来告诉校长这班级中的某个学生!)。但是,如果驱动支持相关功能,就必须在所注册的次设备号下实现这个功能(就是说为了支持老版应用像mjpg-server,你必须为这类设备提供一个minor以支持默认的功能;但他有新的作用,你也必须给予支持)。在第四章提及的一些功能可以在打开的时候进行选择。

想象一下,一个驱动支持视频采集,直接视频传输,视频间隔消隐信号和FM收音机。他用0,64,224(这种编码格式是为保兼容性从V4L API中继承下来的)次设备号注册了三个设备。不管/dev/video(81,0)或者/dev/vbi(81,224)是否处于打开状态,应用程序都可以从这三种设备中选择某项功能。不通过编程(就是说0直接用命令dd和cat)/dev/video就可采集视频图片,通过/dev/vbi来获得原始的视频间隔消隐信号。 /dev/radio(81,64)是一个不变的无线装置,因而和视频部分的功能并没有联系。但是,没有相互的关联并不意味着你可以同时使用它们。当你用open()调用时很有可能返回设备忙--EBUSY的错误代码。

除视频的输入输出外,硬件可能也支持抽样甚至是回放功能(VLC貌似就是这样的)。如果真是这样,那么这些功能会被实现为OSS(Open Sound System)或者ALSA (Advanced Linux Sound Architecture)PCM设备,最终可能是OSS或者ALSA的混合体。V4L2 API并未做任何假设来发现这些有相互关系的设备。

If you have an idea please write to the Video4Linux mailing list:

https://listman.redhat.com/mailman/listinfo/video4linux-list.

1.1.3.  并发打开(Multiple Opens)

    通常,V4l2设备可被多次打开的。当这被驱动支持时,用户可以,例子说嘛,你可以设计一个面板程序,比如有些按钮可以调节亮暗或者音量啊,而与此同时另一个应用程序却正在采集音视频。换句话说,面板程序就被比作了OSS或者ALSA混合应用了。当一个设备支持多项功能像采集啊且能同时直接接传输啊神马的,Multiple Opens允许fork出进程或特定的应用程序达到并发的使用设备。

Multiple Opens是可选的,驱动应该至少允许在没数据交换的情况下支持并发访问,例子就是,上面的面板程序。这意味着当设备正在使用中时open()可返回EBUSY错误代码,ioctl()函数的初始化数据交换(也就是VIDIOC_S_FMT ioctl),read(),write()函数亦是如此。

只不过打开一个V4L2设备并不允许互斥存取4。然而初始化数据交换赋予读和写数据的请求类型的权利。

也可以改变相关属性,文件描述符。应用程序可以通过在1.3节描述的优先级机制请求额外的访问权限。                          

1.1.4.  共享数据流(Shared Data Streams)

V4L2驱动不应该支持在一个设备上,通过拷贝缓冲对同一数据流进行多应用程序的读或写,或者是时分复用亦或是其他相似的方法。非要这么干,可以使用在用户空间的代理程序。如果驱动支持流共享,那么其实现必须是透明的。V4L2 API 并没有列出产生冲突时要如何来解决。

1.1.5.  函数(Functions)

应用程序可以使用open()和close()函数来打开、关闭V4L2设备(都是雷同的)。下面几小节将介绍设备编程所用到的ioctl()方法。

1.2.  功能查询(Querying Capabilities)

因为啊,人都想做大嘛!这个V4l2 涉及了各式各样的设备,但是呢,这个API接口却并不能都适合这些个繁杂的设备。因此,相同类型的设备就可能拥有完全不一样的能力,所以这份规范也允许忽略一些复杂且不那么重要的API接口。

ioctl的VIDIOC_QUERYCAP选项是用来检查内核设备是不是和这份规范相兼容滴,也可以顺便看看这些设备所能够支持的函数和I/O方法,一举两得。其他的特性嘛,也可以依葫芦画瓢,调用各自的ioctl方法,例子么,想知道设备上的视频连接头的名字啊,型号和数量神马的,就可以调用ioctl的VIDIOC_ENUMINPUT方法.尽管API主要功用是--抽象(模糊)底层硬件,但是,ioctl方法是允许驱动特定的应用程序来可靠的辨识相应的驱动的。

但是,所有的V4l2驱动都必须支持VIDIOC_QUERYCAP这个方法(显而易见的)。应用程序都应该在打开设备之后就调用这个方法。

1.3.  应用程序的优先级(Application Priority)

当多个程序共享一个设备时,你可能就希望分配给他们不同的优先级(想想为什么封建社会的把人分成三六九等,虽然不人道但有一方面:执政者是希望管理起来方便)。不同于传统"rm -rf /"(移除根目录下的一切,系统需要内核+文件系统,这么做告诉你:不存在阻塞?)思想,视频记录程序可能阻止其他的应用程序,使他们失去对视频的控制,不能换电视台(一个劲的放广告,这搁谁他也受不鸟啊!)。

另一个目的就是,允许被用户控制的应用程序对可工作在后台的低优先级的应用进行抢占,然后(被抢占的)在稍后一点的时间重新获得对设备的控制权。

鉴于这些个特性是不可能都在用户空间中实现的,V4L2就定义了ioctl的VIDIOC_G_PRIORITY和VIDIOC_S_PRIORITY方法来请求和查询访问文件描述符的优先级。因为有些个驱动并不支持这俩个方法,为保持和V4L2的早期版本的兼容性,会在打开设备时默认的给他们个中间的优先级。再通过VIDIOC_QUERYCAP后应用程序通常会调用VIDIOC_S_PRIORITY请求一个其他的优先级。

如果ioctls在其他程序拥有更高的优先级时,用诸如VIDIOC_S_INPUT方法去改变驱动的属性,会返回EBUSY的错误代码。事件机制(如:U盘的热插拔,他会在用户空间中弹出个东东,告诉你US13来了)会通知应用程序有人在别的地方想篡改属性,但是还没添加呢(您老给看看怎么办呗)!

1.4.  视频输入/输出(Video Inputs and Outputs)

视频的输入和输出就是设备上的物理连接头。例子是:RF红外头,复合视频头(不知是啥玩意),w-Video或者RGB连接头。收音机就没有视频输入、输出了。

如果想去了解可用数量的输入和输出属性,应用程序可以分别使用ioctl的VIDIOC_ENUMINPUT和VIDIOC_ENUMOUTPUT方法来枚举来查看。当当前的视频输入被查询的时候,Ioctl的VIDIOC_ENUMINPUT方法会返回v4l2_input结构体,它包含了可用的信号状态信息。

Ioctl的VIDIOC_G_INPUT和VIDIOC_G_OUTPUT方法会返回当前视频的输入、输出索引。为选择不同的输入、输出,应用程序可以使用ioctl的VIDIOC_S_INPUT和VIDOC_S_OUTPUT方法。当设备有一个或多个输入时,驱动就必须实现所有的输入类ioctl方法,对于输出也是同样的。

 

Example 1-1. Information about the current video input

struct v4l2_input input;

int index;

if(-1 == ioctl(fd, VIDIOC_G_INPUT, &index)){

    perror("VIDIOC_G_INPUT");

    exit(EXIT_FAILURE);

}

memset(&input, 0, sizeof(input));

input.index = index;

if(-1 == ioctl(fd, VIDIOC_ENUMINPUT, &input)){

    perror("VIDIOC_ENUMINPUT");

    exit(EXIT_FAILURE);

}

printf("Current input: %s\n", input.name);

 

Example 1-2. Switching to the first video input

int index;

index = 0;

if(-1 == ioctl(fd, VIDIOC_S_INPUT, &index)){

    perror("VIDIOC_S_INPUT");

    exit(EXIT_FAILURE);

}

1.5.  音频输入/输出(Audio Inputs and Outputs)

音频的输入输出也是一个设备的物理连接头。 视频采集设备有输入(必须的),(若有输出就有输出?既是0个或多个的意思?)输出设备有输出(这...)。无线接收装置是没有音频输入或输出的(就是个电磁信号)。他们必定拥有一个调频头,这也是他们的音频信号来源!但是对于本API,调频头只是相对于视频的输入、输出的,音频设备是没有这些个的。TV卡上的回环接头,就是接收音频信号并将它们发到声卡上变成声音,却没有被当成音频输出。

音视频的输入输出是有联系的。想想也是,视频源通常夹杂音频信号。当视频和音频源是个高频头(可参见百科)时,这就更加明显了。假设存在有两个混合视频输入,两个音频输入,可以想见会有4种组合状况。视频和音频接头间的关系,分别定义在结构体v4l2_input(源码在Videodev2.h中)和v4l2_output的audioset域中,其每一位(从零开始)都代表着是输入还是输出的索引。

struct v4l2_input{

__u32    index;          Identifies the input, set by the                           application.

__u8     name[32];           Name of the video input, a                                     NUL-terminated ASCII string, for                               example: "Vin (Composite 2)".

                            This information is intended for the                           user, preferably the connector label on                           the device itself.   

__u32    type;           /*  Type of input */

   __u32    audioset;       /*  Associated audios (bitfield) */

                                Drivers can enumerate up to 32 video   and audio inputs. This field shows which          audio inputs were selectable as audio source if this was the currently                       selected video input. It is a bit mask.       The LSB corresponds to audio input 0,   the MSB to input 31. Any number of bits   can be set, or none.

                                When the driver does not enumerate     audio inputs no bits must be set.                    Applications shall not interpret this as lack of audio support. Some drivers                    automatically select audio sources and    do not enumerate them since there is no               choice anyway.

                            For details on audio inputs and how    to select the current input see Section           1.5.

   __u32    tuner;             /*  Associated tuner */

                                Capture devices can have zero or more tuners (RF demodulators). When the type    is set to V4L2_INPUT_TYPE_TUNER this is   an RF connector and this field                      identifies the tuner. It corresponds to   struct v4l2_tuner field index. For                details on tuners see Section 1.6.

    v4l2_std_id   std;          Every video input supports one or more different video standards. This                 field is a set of all supported standards.    For details on video standards and how         to switch see Section 1.7.

    __u32      status;         This   field provides status    information about the input. See Table                       3 for flags. Status is only valid when    this is the current input.

    __u32    reserved[4];       Reserved for future extensions.    Drivers must set the array to zero.

};

 

如果想去知道可用的输入、输出数量和属性,应用程序可以分别通过使用ioctl的VIDIOC_ENUMAUDIO和VIDIOC_ENUMAUDOUT方法来枚举他们。当正在使用中的设备被查询时,由VIDIOC_ENUMAUDOUT方法返回的v4l2_audio结构中包含了可用的信号状态信息。

 

struct v4l2_audio{

   __u32   index;            Identifies the audio input, set by the                                 driver or Application.

 

   __u8  name[32];          Name of the audio input, a                                         NUL-terminated ASCII string, for                                   example: "Line In". This information is                              intended for the user, preferably the                              connector label on the device itself.

 

   __u32   capability;      Audio capability flags, see Table 2.

        __u32  mode;             Audio mode flags set by drivers and                                    applications (on VIDIOC_S_AUDIO ioctl),                               see Table 3.

 

   __u32   reserved[2];     Reserved for future extensions. Drivers   and applications must set the array to                zero.

};

 

Ioctl的VIDIOC_G_AUDIO和VIDIOC_G_AUDOUT方法会分别返回当前音频的输入和输出。和VIDIOC_G_INPUT,VIDIOC_G_OUTPUT不同,他们不仅仅返回个索引,而是类似VIDIOC_ENUMAUDIO和VIDIOC_ENUMDOUT返回的结构体。

意欲选择音频的输入或者是改变其属性,应用程序可以调用ioctl的VIDIOC_S_AUDIO方法。同样的如果想选择音频输出(要知道他们是没有可变属性的),则可以调用VIDIOC_S_AUDOUT方法。

当设备具有一个或多个输入、输出时,驱动就必须实现所有相应的ioctl方法!如果设备具有任何音频输入或者输出,驱动就必须设置由VIDIOC_QUERYCAP方法返回的v4l2_capability结构中V4L2_CAP_AUDIO标志位。

 

struct v4l2_capability{

       __u8   driver[16];          Name of the driver, a unique                                   NUL-terminated ASCII string. For                                   example: "bttv". Driver specific                                  applications can use this information to                             verify the driver identity.

                                   It is also useful to work around                                   known bugs, or to identify drivers in                              errorr eports.

                                   The driver version is stored in the                                version field. Storing strings in fixed                               sized arrays is bad practice but                                  unavoidable here. Drivers and                                      applications should take precautions to                               never read or write beyond the end of the                                 array and to make sure the strings are                               properly NUL-terminated.

 

        __u8   card[32];            Name of the device, a NUL-terminated                               ASCII string. For example: "Yoyodyne                                  TV/FM". One driver may support different                                brands or models of video hardware. This                               information is intended for users, for                                example in a menu of available devices.

                                   Since multiple TV cards of the same                                brand may  be installed which are                                  supported by the same driver, this name                               should be combined with the character                             device file name (e. g. /dev/video2) or                               the bus_info string to avoid                                       ambiguities.

 

       __u8   bus_info[32];        Location of the device in the system,                              a NUL-terminated ASCII string. For                                    example: "PCI Slot 4". This information                               is intended for users, to distinguish                                 multiple identical devices. If no such                                 information is available the field may                                simply count the devices controlled by                               the driver, or contain the empty string                                 (bus_info[0] = 0).

 

       __u32   version;            Version number of the driver.                                  Together with the driver field this                                   identifies a particular driver.

                                    The version number is formatted                                     using the KERNEL_VERSION() macro:

    #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) __u32         version = KERNEL_VERSION

   __u32  capabilities;        Device capabilities, see Table 2.

 

       __u32  reserved[4];             Reserved for future extensions.                                    Drivers must set this array to zero.

};    

#define V4L2_CAP_AUDIO          0x00020000  /* has audio support */

 

Table 2. Device Capabilities Flags

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]

 

Example 1-3. Information about the current audio input

struct v4l2_audio audio;

memset (&audio, 0, sizeof (audio));

if (-1 == ioctl (fd, VIDIOC_G_AUDIO, &audio)) {

    perror ("VIDIOC_G_AUDIO");

    exit (EXIT_FAILURE);

}

printf ("Current input: %s\n", audio.name);

 

Example 1-4. Switching to the first audio input

struct v4l2_audio audio;

memset (&audio, 0, sizeof (audio)); /* clear audio.mode, audio.reserved */

audio.index = 0;

if (-1 == ioctl (fd, VIDIOC_S_AUDIO, &audio)) {

    perror ("VIDIOC_S_AUDIO");

    exit (EXIT_FAILURE);

}

1.6.  高频头和调制器(Tuners and Modulators)

1.6.1.  高频头(Tuners)

视频输入设备可能有一个或多个高频头来解调RF(射频)信号。VIDIOC_ENUMINPUT方法会返回type域被设置成V4L2_INPUT_TYPE_TUNER的v4l2_input结构体,且其中的tuner域也包含着tuner的索引号码。

无线发射设备通常只有索引号为0的这么一个tuner,同时没有任何视频输入。

应用程序可以分别通过使用VIDIOC_G_TUNER和VIDIOC_S_TUNER方法来查询和改变tuner的属性。当正在使用中的设备被查询时,由VIDIOC_G_TUNER方法返回的v4l2_tuner结构中包含了可用的信号状态信息。需要注意的是,当拥有多个tuner时VIDIOC_S_TUNER并不会切换当前的tuner。其实这个tuner是由当前的视频输入唯一确定的。当设备含有一个或多个tuner时,驱动就必须支持ioctl方法和提供设置由VIDIOC_QUERYCAP返回的v4l2_capability中V4L2_CAP_TUNER标志。

...

#define VIDIOC_G_TUNER      _IOWR(‘V’, 29, struct v4l2_tuner)

#define VIDIOC_S_TUNER      _IOW(‘V’, 30,  struct v4l2_tuner)

...

1.6.2.  调制器(Modulators)

视频输出设备可以有一个或多个调制器,他可以将视频信号调制成TV电线的解说信号,或者是视频记录器的。每个调制器是和一个或多个视频输出相关联的,而关联的数量取决于RF射频连接头的数量。

VIDIOC_ENUMOUTPUT方法返回的v4l2_output结构中的type域会被设置成V4L2_OUTPUT_TYPE_MODULATOR,而他的modulator域包含了modulator的索引号。规范并没有定义无线输出设备。

   

struct v4l2_output {

    __u32        index;     /*  Which output */

    __u8         name[32];  /*  Label */

    __u32        type;          /*  Type of output */

    __u32        audioset;  /*  Associated audios (bitfield) */

    __u32        modulator;     /*  Associated modulator */

    v4l2_std_id  std;

    __u32        reserved[4];

};

应用程序可以使用VIDIOC_G_MODULATOR和VIDIOC_S_MODULATOR方法来查询和改变modulator的属性。需要注意的是,当拥有多个tuner时VIDIOC_S_MODULATOR并不会切换当前的modulator。其实这个modulator是由当前的视频输入唯一确定的.当设备含有一个或多个modulator时,驱动就必须支持ioctl方法和提供设置由VIDIOC_QUERYCAP返回的v4l2_capability中V4L2_CAP_MODULATOR标志。

1.6.3.  无线频率(Radio Frequency)

struct v4l2_frequency {

__u32    tuner;             The tuner or modulator index number. This is the same value as in the struct v4l2_input tuner field and the struct v4l2_tuner index field, or the struct v4l2_output modulator field and the

                           struct v4l2_modulator index field.

 

enum v4l2_tuner_type  type;     The tuner type. This is the same value as in the struct v4l2_tuner type field. The field is not applicable to modulators, i.e.ignored by drivers.

 

__u32    frequency;         Tuning frequency in units of 62.5 kHz, or if the struct v4l2_tuner or struct v4l2_modulator capabilities flag V4L2_TUNER_CAP_LOW is set, in units of 62.5 Hz.

 

__u32    reserved[8];        Reserved for future extensions. Drivers and applications must set the array to zero.

};

 

应用程序可以使用VIDIOC_G_FREQUENCY和VIDIOC_S_FREQUENCY方法来获得和设置tuner或者modulator的无线频率。这些个方法同样适用于TV和无线设备。当提供tuner和modulator的ioctl方法时,驱动就必须实现相关方法。

1.6.4.  卫星接收器(Satellite Receivers)

    将要讨论。可以参见Peter Schlaf的建议,位于邮件列表:video4linux-list@redhat.com上,发表于2002年10月23号,主题是:"Re: [V4L] Re: v4l2 api"。

  • 0
    点赞
  • 2
    收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 2
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值