6.1. V4L 和 V4L2 之间的差异

Linux 2.1 中首次引入了 Video For Linux API,以统一并取代早期驱动程序编写者独立开发的各种电视和无线电设备相关接口。从 Linux 2.5 开始,改进后的 V4L2 API 取代了 V4L API。对旧 V4L 调用的支持已从内核中删除,但库Libv4l 用户空间库支持将 V4L API 系统调用转换为 V4L2 系统调用。

6.1.1. 打开和关闭设备

出于兼容性原因,建议用于 V4L2 视频捕获、叠加、无线电和原始 vbi 捕获设备的字符设备文件名与 V4L 使用的文件名相同。它们在 接口中列出,并在下面的 V4L 设备类型、名称和编号中列出。

V4L2 中已删除图文电视设备(次要范围 192-223),并且不再存在。不再有用于处理纯图文电视的硬件。而是使用原始或分片 VBI。

V4L 的 videodev 模块根据注册的设备类型,在加载顺序中自动为驱动程序分配次要编号。我们建议 V4L2 驱动程序默认注册具有相同编号的设备,但系统管理员可以使用驱动程序模块选项分配任意次要编号。主设备编号仍然是 81。

V4L 设备类型、名称和编号

设备类型

文件名

次要编号

视频捕获和叠加

/dev/video/dev/bttv0 [1], /dev/video0/dev/video63

0-63

无线电接收器

/dev/radio [2], /dev/radio0/dev/radio63

64-127

原始 VBI 捕获

/dev/vbi, /dev/vbi0/dev/vbi31

224-255

V4L 禁止(或曾经禁止)多次打开设备文件。V4L2 驱动程序可以支持多次打开,有关详细信息和后果,请参阅 打开和关闭设备

V4L 驱动程序使用 EINVAL 错误代码响应 V4L2 ioctl。

6.1.2. 查询功能

V4L 的 VIDIOCGCAP ioctl 等效于 V4L2 的 ioctl VIDIOC_QUERYCAP

结构 video_capability 中的 name 字段在结构 v4l2_capability 中变为 cardtypecapabilities 替换。请注意,V4L2 不会像这样区分设备类型,最好将基本视频输入、视频输出和无线电设备视为支持一组相关功能(如视频捕获、视频叠加和 VBI 捕获)的设备。有关介绍,请参阅 打开和关闭设备

struct video_capability type

结构 v4l2_capability capabilities 标志

目的

VID_TYPE_CAPTURE

V4L2_CAP_VIDEO_CAPTURE

支持视频捕获接口。

VID_TYPE_TUNER

V4L2_CAP_TUNER

该设备具有调谐器或调制器

VID_TYPE_TELETEXT

V4L2_CAP_VBI_CAPTURE

支持原始 VBI 捕获接口。

VID_TYPE_OVERLAY

V4L2_CAP_VIDEO_OVERLAY

支持视频叠加接口。

VID_TYPE_CHROMAKEY

结构 v4l2_framebuffercapability 字段中的 V4L2_FBUF_CAP_CHROMAKEY

是否支持色键叠加。有关叠加的更多信息,请参阅视频叠加接口

VID_TYPE_CLIPPING

结构 v4l2_framebuffercapability 字段中的 V4L2_FBUF_CAP_LIST_CLIPPINGV4L2_FBUF_CAP_BITMAP_CLIPPING

是否支持裁剪叠加图像,请参阅视频叠加接口

VID_TYPE_FRAMERAM

结构 v4l2_framebuffercapability 字段中未设置V4L2_FBUF_CAP_EXTERNOVERLAY

叠加是否会覆盖帧缓冲区内存,请参阅视频叠加接口

VID_TYPE_SCALES

-

此标志指示硬件是否可以缩放图像。V4L2 API 通过使用 VIDIOC_S_CROPVIDIOC_S_FMT ioctl 设置裁剪尺寸和图像大小来暗示缩放因子。驱动程序返回最接近的可能大小。有关裁剪和缩放的更多信息,请参阅 图像裁剪、插入和缩放 - CROP API

VID_TYPE_MONOCHROME

-

应用程序可以使用 ioctl VIDIOC_ENUM_FMT ioctl 枚举支持的图像格式,以确定设备是否仅支持灰度捕获。有关图像格式的更多信息,请参阅图像格式

VID_TYPE_SUBCAPTURE

-

应用程序可以调用 VIDIOC_G_CROP ioctl 来确定设备是否支持捕获完整图片的一部分(在 V4L2 中为“裁剪”)。如果不支持,则 ioctl 返回 EINVAL 错误代码。有关裁剪和缩放的更多信息,请参阅图像裁剪、插入和缩放 - CROP API

VID_TYPE_MPEG_DECODER

-

应用程序可以使用 ioctl VIDIOC_ENUM_FMT ioctl 枚举支持的图像格式,以确定设备是否支持 MPEG 流。

VID_TYPE_MPEG_ENCODER

-

参见上文。

VID_TYPE_MJPEG_DECODER

-

参见上文。

VID_TYPE_MJPEG_ENCODER

-

参见上文。

audios 字段被 capabilities 标志 V4L2_CAP_AUDIO 替换,指示设备是否有任何音频输入或输出。要确定它们的数量,应用程序可以使用 VIDIOC_G_AUDIO ioctl 枚举音频输入。音频 ioctl 在 音频输入和输出中描述。

已删除 maxwidthmaxheightminwidthminheight 字段。使用所需尺寸调用 VIDIOC_S_FMTVIDIOC_TRY_FMT ioctl 会返回最接近的可能大小,同时考虑到当前的视频标准、裁剪和缩放限制。

6.1.3. 视频源

V4L 使用结构体 video_channel,通过 VIDIOCGCHANVIDIOCSCHAN ioctl 来枚举 V4L 设备的视频输入。等效的 V4L2 ioctl 是 ioctl VIDIOC_ENUMINPUTVIDIOC_G_INPUTVIDIOC_S_INPUT,它们使用结构体 v4l2_input,如 视频输入和输出 中所述。

用于计数输入的 channel 字段被重命名为 index,视频输入类型被重命名如下:

结构体 video_channel type

结构体 v4l2_input type

VIDEO_TYPE_TV

V4L2_INPUT_TYPE_TUNER

VIDEO_TYPE_CAMERA

V4L2_INPUT_TYPE_CAMERA

与表示此输入调谐器数量的 tuners 字段不同,V4L2 假定每个视频输入最多连接到一个调谐器。但是,一个调谐器可以有多个输入,即射频连接器,并且一个设备可以有多个调谐器。与输入关联的调谐器的索引号(如果有)存储在结构体 v4l2_inputtuner 字段中。调谐器的枚举在 调谐器和调制器 中讨论。

冗余的 VIDEO_VC_TUNER 标志被删除。与调谐器关联的视频输入类型为 V4L2_INPUT_TYPE_TUNERVIDEO_VC_AUDIO 标志被 audioset 字段替换。V4L2 认为设备最多有 32 个音频输入。 audioset 字段中的每个置位都代表此视频输入与之组合的一个音频输入。有关音频输入以及如何在它们之间切换的信息,请参阅 音频输入和输出

描述支持的视频标准的 norm 字段被 std 替换。 V4L 规范提到一个标志 VIDEO_VC_NORM,表示是否可以更改标准。此标志是稍后与 norm 字段一起添加的,并且在此期间已被删除。 V4L2 对视频标准采用了类似但更全面的方法,有关更多信息,请参阅 视频标准

6.1.4. 调谐

可以使用 V4L VIDIOCGTUNERVIDIOCSTUNER ioctl 和结构体 video_tuner 来枚举 V4L 电视或无线电设备的调谐器。等效的 V4L2 ioctl 是 VIDIOC_G_TUNERVIDIOC_S_TUNER,它们使用结构体 v4l2_tuner。调谐器在 调谐器和调制器 中介绍。

用于计数调谐器的 tuner 字段被重命名为 indexnamerangelowrangehigh 字段保持不变。

指示支持的视频标准的 VIDEO_TUNER_PALVIDEO_TUNER_NTSCVIDEO_TUNER_SECAM 标志被删除。此信息现在包含在关联的结构体 v4l2_input 中。对于指示是否可以切换视频标准的 VIDEO_TUNER_NORM 标志,没有替代项。mode 字段用于选择不同的视频标准,已被 视频标准 中描述的全新 ioctl 和结构集所取代。由于其普遍性,应该提到 BTTV 驱动程序除了常规的 VIDEO_MODE_PAL (0)、 VIDEO_MODE_NTSCVIDEO_MODE_SECAMVIDEO_MODE_AUTO (3) 之外,还支持多种标准。即 N/PAL Argentina、M/PAL、N/PAL 和 NTSC Japan,编号为 3-6(原文如此)。

指示立体声接收的 VIDEO_TUNER_STEREO_ON 标志在字段 rxsubchans 中变为 V4L2_TUNER_SUB_STEREO。此字段还允许检测单声道和双语音频,有关详细信息,请参阅结构体 v4l2_tuner 的定义。目前,对于 VIDEO_TUNER_RDS_ONVIDEO_TUNER_MBS_ON 标志,没有替代项。

VIDEO_TUNER_LOW 标志在结构体 v4l2_tunercapability 字段中被重命名为 V4L2_TUNER_CAP_LOW

用于更改调谐器频率的 VIDIOCGFREQVIDIOCSFREQ ioctl 被重命名为 VIDIOC_G_FREQUENCYVIDIOC_S_FREQUENCY。它们接受指向结构体 v4l2_frequency 的指针,而不是 unsigned long integer。

6.1.5. 图像属性

V4L2 没有与 VIDIOCGPICTVIDIOCSPICT ioctl 和结构体 video_picture 等效的项。以下字段被 V4L2 控件替换,这些控件可以通过 ioctl VIDIOC_QUERYCTRL、VIDIOC_QUERY_EXT_CTRL 和 VIDIOC_QUERYMENUVIDIOC_G_CTRLVIDIOC_S_CTRL ioctl 访问。

结构体 video_picture

V4L2 控制 ID

亮度

V4L2_CID_BRIGHTNESS

色调

V4L2_CID_HUE

颜色

V4L2_CID_SATURATION

对比度

V4L2_CID_CONTRAST

白度

V4L2_CID_WHITENESS

V4L 图片控件的范围被假定为 0 到 65535,没有特定的重置值。 V4L2 API 允许任意限制和默认值,可以使用 ioctl VIDIOC_QUERYCTRL、VIDIOC_QUERY_EXT_CTRL 和 VIDIOC_QUERYMENU ioctl 查询。有关控件的常规信息,请参阅 用户控件

视频图像的 depth(每个像素的平均位数)由选定的图像格式暗示。 V4L2 没有明确提供此类信息,假定识别格式的应用程序知道图像深度,而其他应用程序不需要知道。palette 字段移动到了结构体 v4l2_pix_format

结构体 video_picture palette

结构体 v4l2_pix_format pixfmt

VIDEO_PALETTE_GREY

V4L2_PIX_FMT_GREY

VIDEO_PALETTE_HI240

V4L2_PIX_FMT_HI240 [3]

VIDEO_PALETTE_RGB565

V4L2_PIX_FMT_RGB565

VIDEO_PALETTE_RGB555

V4L2_PIX_FMT_RGB555

VIDEO_PALETTE_RGB24

V4L2_PIX_FMT_BGR24

VIDEO_PALETTE_RGB32

V4L2_PIX_FMT_BGR32 [4]

VIDEO_PALETTE_YUV422

V4L2_PIX_FMT_YUYV

VIDEO_PALETTE_YUYV [5]

V4L2_PIX_FMT_YUYV

VIDEO_PALETTE_UYVY

V4L2_PIX_FMT_UYVY

VIDEO_PALETTE_YUV420

VIDEO_PALETTE_YUV411

V4L2_PIX_FMT_Y41P [6]

VIDEO_PALETTE_RAW

[7]

VIDEO_PALETTE_YUV422P

V4L2_PIX_FMT_YUV422P

VIDEO_PALETTE_YUV411P

V4L2_PIX_FMT_YUV411P [8]

VIDEO_PALETTE_YUV420P

V4L2_PIX_FMT_YVU420

VIDEO_PALETTE_YUV410P

V4L2_PIX_FMT_YVU410

V4L2 图像格式在 图像格式 中定义。可以使用 VIDIOC_S_FMT ioctl 来选择图像格式。

6.1.6. 音频

VIDIOCGAUDIOVIDIOCSAUDIO ioctl 以及结构体 video_audio 用于枚举 V4L 设备的音频输入。等效的 V4L2 ioctl 是 VIDIOC_G_AUDIOVIDIOC_S_AUDIO,它们使用结构体 v4l2_audio,如 音频输入和输出 中所述。

用于计算音频输入的 audio “通道号”字段已重命名为 index

VIDIOCSAUDIO 上,mode 字段选择 VIDEO_SOUND_MONOVIDEO_SOUND_STEREOVIDEO_SOUND_LANG1VIDEO_SOUND_LANG2 音频解调模式中的一种。当当前音频标准为 BTSC 时,VIDEO_SOUND_LANG2 指的是 SAP,而 VIDEO_SOUND_LANG1 没有意义。此外,在 V4L 规范中没有记录,也没有办法查询所选模式。在 VIDIOCGAUDIO 上,驱动程序在此字段中返回实际接收到的音频节目。在 V4L2 API 中,此信息分别存储在结构体 v4l2_tunerrxsubchansaudmode 字段中。有关调谐器的更多信息,请参阅 调谐器和调制器。与音频模式相关,结构体 v4l2_audio 还会报告这是单声道还是立体声输入,无论源是否为调谐器。

以下字段被可以使用 ioctls VIDIOC_QUERYCTRL、VIDIOC_QUERY_EXT_CTRL 和 VIDIOC_QUERYMENUVIDIOC_G_CTRLVIDIOC_S_CTRL ioctl 访问的 V4L2 控件所替换

结构体 video_audio

V4L2 控制 ID

音量

V4L2_CID_AUDIO_VOLUME

低音

V4L2_CID_AUDIO_BASS

高音

V4L2_CID_AUDIO_TREBLE

平衡

V4L2_CID_AUDIO_BALANCE

为了确定驱动程序支持哪些控件,V4L 提供了 flags VIDEO_AUDIO_VOLUMEVIDEO_AUDIO_BASSVIDEO_AUDIO_TREBLEVIDEO_AUDIO_BALANCE。在 V4L2 API 中,ioctls VIDIOC_QUERYCTRL、VIDIOC_QUERY_EXT_CTRL 和 VIDIOC_QUERYMENU ioctl 报告是否支持相应的控件。因此,VIDEO_AUDIO_MUTABLEVIDEO_AUDIO_MUTE 标志被布尔值 V4L2_CID_AUDIO_MUTE 控件所替换。

所有 V4L2 控件都有一个 step 属性,用于替换结构体 video_audiostep 字段。V4L 音频控件被假定为从 0 到 65535,没有特定的重置值。V4L2 API 允许任意限制和默认值,可以使用 ioctls VIDIOC_QUERYCTRL、VIDIOC_QUERY_EXT_CTRL 和 VIDIOC_QUERYMENU ioctl 查询。有关控件的常规信息,请参阅 用户控件

6.1.7. 帧缓冲区覆盖

VIDIOCGFBUFVIDIOCSFBUF 等效的 V4L2 ioctl 是 VIDIOC_G_FBUFVIDIOC_S_FBUF。结构体 video_bufferbase 字段保持不变,除了 V4L2 定义了一个标志来指示非破坏性覆盖而不是 NULL 指针。所有其他字段都移动到结构体 v4l2_pix_formatfmt 子结构体中,该结构体位于结构体 v4l2_framebuffer 中。depth 字段被 pixelformat 替换。有关 RGB 格式及其各自的颜色深度的列表,请参阅 RGB 格式

V4L2 使用通用的数据格式协商 ioctl VIDIOC_G_FMTVIDIOC_S_FMT 来代替特殊的 ioctl VIDIOCGWINVIDIOCSWIN。它们采用指向结构体 v4l2_format 的指针作为参数。这里使用 fmt 联合的 win 成员,一个结构体 v4l2_window

结构体 video_windowxywidthheight 字段移动到结构体 v4l2_rect 子结构体 w 中,该子结构体位于结构体 v4l2_window 中。chromakeyclipsclipcount 字段保持不变。结构体 video_clip 被重命名为结构体 v4l2_clip,该结构体还包含一个结构体 v4l2_rect,但语义仍然相同。

VIDEO_WINDOW_INTERLACE 标志被删除。相反,应用程序必须将 field 字段设置为 V4L2_FIELD_ANYV4L2_FIELD_INTERLACEDVIDEO_WINDOW_CHROMAKEY 标志移动到结构体 v4l2_framebuffer 中,其新名称为 V4L2_FBUF_FLAG_CHROMAKEY

在 V4L 中,将位图指针存储在 clips 中,并将 clipcount 设置为 VIDEO_CLIP_BITMAP (-1) 会请求位图剪切,使用 1024 × 625 位的固定大小位图。结构体 v4l2_window 有一个单独的 bitmap 指针字段用于此目的,并且位图大小由 w.widthw.height 确定。

用于启用或禁用覆盖的 VIDIOCCAPTURE ioctl 重命名为 ioctl VIDIOC_OVERLAY

6.1.8. 裁剪

为了仅捕获完整图片的一部分,V4L 定义了使用结构体 video_captureVIDIOCGCAPTUREVIDIOCSCAPTURE ioctl。等效的 V4L2 ioctl 是 VIDIOC_G_CROPVIDIOC_S_CROP,它们使用结构体 v4l2_crop,以及相关的 ioctl VIDIOC_CROPCAP ioctl。这是一个相当复杂的问题,有关详细信息,请参阅 图像裁剪、插入和缩放 -- CROP API

字段 xywidthheight 已移至结构体 v4l2_rect 的子结构体 c 中,该结构体为 v4l2_crop。字段 decimation 已被删除。在 V4L2 API 中,缩放因子由裁剪矩形的大小以及捕获或叠加图像的大小隐含表示。

捕获奇数场或偶数场的标志 VIDEO_CAPTURE_ODDVIDEO_CAPTURE_EVEN 已被结构体 v4l2_pix_format 和结构体 v4l2_window 的名为 field 的字段中的 V4L2_FIELD_TOPV4L2_FIELD_BOTTOM 取代。这些结构体用于使用 VIDIOC_S_FMT ioctl 选择捕获或叠加格式。

6.1.9. 读取图像,内存映射

6.1.9.1. 使用 read 方法捕获

使用 read() 函数从 V4L 或 V4L2 设备读取图像没有本质区别,但是 V4L2 驱动程序不需要支持此 I/O 方法。应用程序可以使用 ioctl VIDIOC_QUERYCAP ioctl 确定该函数是否可用。所有与应用程序交换数据的 V4L2 设备都必须支持 select()poll() 函数。

要选择图像格式和大小,V4L 提供 VIDIOCSPICTVIDIOCSWIN ioctl。V4L2 使用通用的数据格式协商 ioctl VIDIOC_G_FMTVIDIOC_S_FMT。它们接受指向结构体 v4l2_format 的指针作为参数,这里使用其 fmt 联合中的名为 pix 的结构体 v4l2_pix_format

有关 V4L2 读取接口的更多信息,请参阅 读取/写入

6.1.9.2. 使用内存映射捕获

应用程序可以通过将设备内存中的缓冲区(或者更常见的是在 DMA 可寻址的系统内存中分配的缓冲区)映射到它们的地址空间来从 V4L 设备读取。这避免了读取方法的数据复制开销。V4L2 也支持内存映射,但有一些差异。

V4L

V4L2

必须在分配缓冲区之前使用 VIDIOC_S_FMT ioctl 选择图像格式。如果未选择格式,驱动程序可能会使用上次的格式,可能是由另一个应用程序请求的格式。

应用程序无法更改缓冲区数量。它内置在驱动程序中,除非它有一个模块选项可以在加载驱动程序模块时更改数量。

ioctl VIDIOC_REQBUFS ioctl 分配所需数量的缓冲区,这是初始化序列中的必需步骤。

驱动程序将所有缓冲区映射为一段连续的内存范围。VIDIOCGMBUF ioctl 可用于查询缓冲区数量、每个缓冲区相对于虚拟文件起点的偏移量以及使用的总内存量,这些可以作为 mmap() 函数的参数。

缓冲区是单独映射的。可以使用 ioctl VIDIOC_QUERYBUF ioctl 确定每个缓冲区的偏移量和大小。

VIDIOCMCAPTURE ioctl 准备一个缓冲区用于捕获。它还确定此缓冲区的图像格式。ioctl 立即返回,如果未检测到视频信号,则最终返回 EAGAIN 错误代码。当驱动程序支持多个缓冲区时,应用程序可以多次调用该 ioctl,从而具有多个未完成的捕获请求。

VIDIOCSYNC ioctl 暂停执行,直到某个特定缓冲区被填充。

驱动程序维护一个传入队列和一个传出队列。ioctl VIDIOC_QBUF, VIDIOC_DQBUF 将任何空缓冲区排队到传入队列中。使用 VIDIOC_DQBUF ioctl 将填充的缓冲区从传出队列中出列。要等待直到填充的缓冲区可用,可以使用此函数、select()poll()。在将一个或多个缓冲区排队后,必须调用一次 ioctl VIDIOC_STREAMON, VIDIOC_STREAMOFF ioctl 以开始捕获。它的对应项 VIDIOC_STREAMOFF 停止捕获并将所有缓冲区从两个队列中出列。如果已知,应用程序可以使用 ioctl VIDIOC_ENUMINPUT ioctl 查询信号状态。

有关内存映射和示例的更深入讨论,请参阅 流式 I/O(内存映射)

6.1.10. 读取原始 VBI 数据

最初,V4L API 未指定原始 VBI 捕获接口,仅保留设备文件 /dev/vbi 用于此目的。唯一支持此接口的驱动程序是 BTTV 驱动程序,它实际上定义了 V4L VBI 接口。从设备读取会产生具有以下参数的原始 VBI 图像

结构体 v4l2_vbi_format

V4L,BTTV 驱动程序

sampling_rate

28636363 Hz NTSC(或任何其他 525 行标准);35468950 Hz PAL 和 SECAM(625 行标准)

offset

?

samples_per_line

2048

sample_format

V4L2_PIX_FMT_GREY。最后四个字节(一个机器字节序整数)包含一个帧计数器。

start[]

10、273 NTSC;22、335 PAL 和 SECAM

count[]

16, 16 [9]

flags

0

V4L 规范中没有记录,在 Linux 2.3 中,添加了使用结构体 vbi_formatVIDIOCGVBIFMTVIDIOCSVBIFMT ioctl,以确定 VBI 图像参数。这些 ioctl 与 原始 VBI 数据接口 中指定的 V4L2 VBI 接口仅部分兼容。

不存在 offset 字段,sample_format 应该为 VIDEO_PALETTE_RAW,等同于 V4L2_PIX_FMT_GREY。其余字段可能等同于结构体 v4l2_vbi_format

显然只有 Zoran (ZR 36120) 驱动程序实现了这些 ioctl。其语义与 V4L2 中指定的语义在两个方面有所不同。参数在 open() 时重置,并且如果参数无效,VIDIOCSVBIFMT 始终返回 EINVAL 错误代码。

6.1.11. 其他

V4L2 没有与 VIDIOCGUNIT ioctl 等效的命令。应用程序可以通过重新打开设备并请求 VBI 数据来查找与视频捕获设备关联的 VBI 设备(或反之亦然)。有关详细信息,请参阅打开和关闭设备

没有 VIDIOCKEY 和用于微代码编程的 V4L 函数的替代品。 MPEG 压缩和播放设备的新接口记录在扩展控制 API中。