6.1. V4L 和 V4L2 之间的差异¶
Video For Linux API 最早于 Linux 2.1 中引入,旨在统一和取代驱动开发者在前几年独立开发的各种电视和无线电设备相关接口。从 Linux 2.5 开始,大幅改进的 V4L2 API 取代了 V4L API。对旧 V4L 调用的支持已从内核中移除,但库 Libv4l 用户空间库 支持将 V4L API 系统调用转换为 V4L2 调用。
6.1.1. 打开和关闭设备¶
出于兼容性考虑,推荐用于 V4L2 视频捕获、覆盖、无线电和原始 VBI 捕获设备的字符设备文件名与 V4L 使用的文件名保持不变。它们列在 接口 中,并在下文的 V4L 设备类型、名称和编号 中。
图文电视设备(次设备号范围 192-223)已在 V4L2 中移除,不再存在。目前没有可用的硬件来处理纯图文电视。取而代之的是使用原始或切片 VBI。
V4L videodev
模块根据注册的设备类型,自动按加载顺序为驱动程序分配次设备号。我们建议 V4L2 驱动程序默认注册具有相同编号的设备,但系统管理员可以使用驱动程序模块选项分配任意次设备号。主设备号保持为 81。
设备类型 |
文件名 |
次设备号 |
---|---|---|
视频捕获和覆盖 |
|
0-63 |
无线电接收器 |
|
64-127 |
原始 VBI 捕获 |
|
224-255 |
V4L 禁止(或曾经禁止)多次打开设备文件。V4L2 驱动程序可能支持多次打开,详情和后果请参阅 打开和关闭设备。
V4L 驱动程序对 V4L2 ioctl 的响应是返回 EINVAL
错误代码。
6.1.2. 查询功能¶
V4L 的 VIDIOCGCAP
ioctl 等同于 V4L2 的 ioctl VIDIOC_QUERYCAP。
struct video_capability
中的 name
字段在 struct v4l2_capability
中变成了 card
,type
被 capabilities
取代。请注意,V4L2 不再像这样区分设备类型,最好将其视为支持视频捕获、视频覆盖和 VBI 捕获等相关功能集的基本视频输入、视频输出和无线电设备。有关介绍,请参阅 打开和关闭设备。
|
struct |
目的 |
---|---|---|
|
|
支持 视频捕获 接口。 |
|
|
该设备具有 调谐器或调制器。 |
|
|
支持 原始 VBI 捕获 接口。 |
|
|
支持 视频覆盖 接口。 |
|
struct |
是否支持色键覆盖。有关覆盖的更多信息,请参阅 视频覆盖接口。 |
|
struct |
是否支持裁剪覆盖图像,请参阅 视频覆盖接口。 |
|
struct |
覆盖是否会覆盖帧缓冲区内存,请参阅 视频覆盖接口。 |
|
|
此标志指示硬件是否可以缩放图像。V4L2 API 通过使用 VIDIOC_S_CROP 和 VIDIOC_S_FMT ioctl 分别设置裁剪尺寸和图像大小来表示缩放因子。驱动程序返回最接近的可能尺寸。有关裁剪和缩放的更多信息,请参阅 图像裁剪、插入和缩放 -- CROP API。 |
|
|
应用程序可以使用 ioctl VIDIOC_ENUM_FMT ioctl 枚举支持的图像格式,以确定设备是否仅支持灰度捕获。有关图像格式的更多信息,请参阅 图像格式。 |
|
|
应用程序可以调用 VIDIOC_G_CROP ioctl 来确定设备是否支持捕获完整图片的一部分(V4L2 中的“裁剪”)。如果不支持,ioctl 将返回 |
|
|
应用程序可以使用 ioctl VIDIOC_ENUM_FMT ioctl 枚举支持的图像格式,以确定设备是否支持 MPEG 流。 |
|
|
参见上文。 |
|
|
参见上文。 |
|
|
参见上文。 |
audios
字段被 capabilities
标志 V4L2_CAP_AUDIO
取代,表示设备是否有任何音频输入或输出。要确定它们的数量,应用程序可以使用 VIDIOC_G_AUDIO ioctl 枚举音频输入。音频 ioctl 在 音频输入和输出 中描述。
maxwidth
、maxheight
、minwidth
和 minheight
字段已被移除。调用 VIDIOC_S_FMT 或 VIDIOC_TRY_FMT ioctl 并指定所需尺寸将返回最接近的可能尺寸,同时考虑到当前视频标准、裁剪和缩放限制。
6.1.3. 视频源¶
V4L 提供 VIDIOCGCHAN
和 VIDIOCSCHAN
ioctl,使用 struct video_channel
枚举 V4L 设备的视频输入。等效的 V4L2 ioctl 是 ioctl VIDIOC_ENUMINPUT、VIDIOC_G_INPUT 和 VIDIOC_S_INPUT,它们使用 struct v4l2_input
,如 视频输入和输出 中所讨论。
计数输入的 channel
字段被重命名为 index
,视频输入类型重命名如下:
struct |
struct |
---|---|
|
|
|
|
与表示此输入调谐器数量的 tuners
字段不同,V4L2 假定每个视频输入最多连接到一个调谐器。但是,一个调谐器可以有多个输入,即射频连接器,并且一个设备可以有多个调谐器。与输入关联的调谐器(如果有)的索引号存储在 struct v4l2_input
的 tuner
字段中。调谐器的枚举在 调谐器和调制器 中讨论。
冗余的 VIDEO_VC_TUNER
标志已被删除。与调谐器关联的视频输入类型为 V4L2_INPUT_TYPE_TUNER
。VIDEO_VC_AUDIO
标志被 audioset
字段取代。V4L2 考虑具有多达 32 个音频输入的设备。audioset
字段中的每个设置位表示此视频输入组合的一个音频输入。有关音频输入以及如何在其间切换的信息,请参阅 音频输入和输出。
描述支持的视频标准的 norm
字段被 std
取代。V4L 规范提到了一个标志 VIDEO_VC_NORM
,指示标准是否可以更改。此标志是与 norm
字段一起的后期添加,但在此期间已被移除。V4L2 对视频标准有类似但更全面的方法,有关更多信息,请参阅 视频标准。
6.1.4. 调谐¶
V4L VIDIOCGTUNER
和 VIDIOCSTUNER
ioctl 以及 struct video_tuner
可用于枚举 V4L 电视或无线电设备的调谐器。等效的 V4L2 ioctl 是 VIDIOC_G_TUNER 和 VIDIOC_S_TUNER,它们使用 struct v4l2_tuner
。调谐器在 调谐器和调制器 中介绍。
计数调谐器的 tuner
字段被重命名为 index
。name
、rangelow
和 rangehigh
字段保持不变。
指示支持的视频标准的 VIDEO_TUNER_PAL
、VIDEO_TUNER_NTSC
和 VIDEO_TUNER_SECAM
标志已删除。此信息现在包含在关联的 struct v4l2_input
中。目前没有替代 VIDEO_TUNER_NORM
标志来指示视频标准是否可以切换。用于选择不同视频标准的 mode
字段已被 视频标准 中描述的一整套新 ioctl 和结构取代。由于其普遍性,应提及 BTTV 驱动程序除了常规的 VIDEO_MODE_PAL
(0)、VIDEO_MODE_NTSC
、VIDEO_MODE_SECAM
和 VIDEO_MODE_AUTO
(3) 之外,还支持多种标准,即 N/PAL Argentina、M/PAL、N/PAL 和 NTSC Japan,编号为 3-6(原文如此)。
指示立体声接收的 VIDEO_TUNER_STEREO_ON
标志在 rxsubchans
字段中变为 V4L2_TUNER_SUB_STEREO
。此字段还允许检测单声道和双语音频,详情请参阅 struct v4l2_tuner
的定义。目前没有替代 VIDEO_TUNER_RDS_ON
和 VIDEO_TUNER_MBS_ON
标志。
VIDEO_TUNER_LOW
标志在 struct v4l2_tuner
的 capability
字段中被重命名为 V4L2_TUNER_CAP_LOW
。
用于更改调谐器频率的 VIDIOCGFREQ
和 VIDIOCSFREQ
ioctl 被重命名为 VIDIOC_G_FREQUENCY 和 VIDIOC_S_FREQUENCY。它们接受指向 struct v4l2_frequency
的指针,而不是无符号长整型。
6.1.5. 图像属性¶
V4L2 没有 VIDIOCGPICT
和 VIDIOCSPICT
ioctl 以及 struct video_picture
的等效项。以下字段已被 V4L2 控件取代,可通过 ioctls VIDIOC_QUERYCTRL, VIDIOC_QUERY_EXT_CTRL 和 VIDIOC_QUERYMENU、VIDIOC_G_CTRL 和 VIDIOC_S_CTRL ioctl 访问:
struct |
V4L2 控制 ID |
---|---|
|
|
|
|
|
|
|
|
|
|
V4L 图像控件的范围假定为 0 到 65535,没有特定的重置值。V4L2 API 允许任意限制和默认值,这些值可以通过 ioctls VIDIOC_QUERYCTRL, VIDIOC_QUERY_EXT_CTRL 和 VIDIOC_QUERYMENU ioctl 进行查询。有关控件的一般信息,请参阅 用户控件。
视频图像的 depth
(每像素平均位数)由所选图像格式决定。V4L2 不会明确提供此类信息,因为它假定识别该格式的应用程序会知道图像深度,而其他应用程序则无需了解。 palette
字段已移至 struct v4l2_pix_format
struct |
struct |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
无 |
|
|
|
无 [7] |
|
|
|
|
|
|
|
V4L2 图像格式在 图像格式 中定义。图像格式可以使用 VIDIOC_S_FMT ioctl 选择。
6.1.6. 音频¶
VIDIOCGAUDIO
和 VIDIOCSAUDIO
ioctl 以及 struct video_audio
用于枚举 V4L 设备的音频输入。等效的 V4L2 ioctl 是 VIDIOC_G_AUDIO 和 VIDIOC_S_AUDIO,它们使用 struct v4l2_audio
,如 音频输入和输出 中所讨论。
计数音频输入的 audio
“通道号”字段被重命名为 index
。
在 VIDIOCSAUDIO
上,mode
字段选择 VIDEO_SOUND_MONO
、VIDEO_SOUND_STEREO
、VIDEO_SOUND_LANG1
或 VIDEO_SOUND_LANG2
音频解调模式中的一种。当当前音频标准是 BTSC 时,VIDEO_SOUND_LANG2
指的是 SAP,而 VIDEO_SOUND_LANG1
则毫无意义。V4L 规范中也未记录,无法查询所选模式。在 VIDIOCGAUDIO
上,驱动程序在此字段中返回实际接收到的音频节目。在 V4L2 API 中,此信息分别存储在 struct v4l2_tuner
的 rxsubchans
和 audmode
字段中。有关调谐器的更多信息,请参阅 调谐器和调制器。与音频模式相关,struct v4l2_audio
还报告这是否是单声道或立体声输入,无论来源是否是调谐器。
以下字段已被 V4L2 控件取代,可通过 ioctls VIDIOC_QUERYCTRL, VIDIOC_QUERY_EXT_CTRL 和 VIDIOC_QUERYMENU、VIDIOC_G_CTRL 和 VIDIOC_S_CTRL ioctl 访问:
struct |
V4L2 控制 ID |
---|---|
|
|
|
|
|
|
|
|
为了确定驱动程序支持哪些控件,V4L 提供了 flags
VIDEO_AUDIO_VOLUME
、VIDEO_AUDIO_BASS
、VIDEO_AUDIO_TREBLE
和 VIDEO_AUDIO_BALANCE
。在 V4L2 API 中,ioctls VIDIOC_QUERYCTRL, VIDIOC_QUERY_EXT_CTRL 和 VIDIOC_QUERYMENU ioctl 报告是否支持相应的控件。因此,VIDEO_AUDIO_MUTABLE
和 VIDEO_AUDIO_MUTE
标志被布尔型 V4L2_CID_AUDIO_MUTE
控件取代。
所有 V4L2 控件都有一个 step
属性,取代了 struct video_audio
的 step
字段。V4L 音频控件的范围假定为 0 到 65535,没有特定的重置值。V4L2 API 允许任意限制和默认值,这些值可以通过 ioctls VIDIOC_QUERYCTRL, VIDIOC_QUERY_EXT_CTRL 和 VIDIOC_QUERYMENU ioctl 进行查询。有关控件的一般信息,请参阅 用户控件。
6.1.7. 帧缓冲区覆盖¶
与 VIDIOCGFBUF
和 VIDIOCSFBUF
等效的 V4L2 ioctl 是 VIDIOC_G_FBUF 和 VIDIOC_S_FBUF。struct video_buffer
的 base
字段保持不变,只是 V4L2 定义了一个标志来指示非破坏性覆盖,而不是 NULL
指针。所有其他字段都移至 struct v4l2_framebuffer
的 struct v4l2_pix_format
fmt
子结构中。depth
字段被 pixelformat
取代。有关 RGB 格式及其各自颜色深度的列表,请参阅 RGB 格式。
V4L2 不使用特殊的 ioctl VIDIOCGWIN
和 VIDIOCSWIN
,而是使用通用数据格式协商 ioctl VIDIOC_G_FMT 和 VIDIOC_S_FMT。它们接受指向 struct v4l2_format
的指针作为参数。此处使用的是 fmt
联合体的 win
成员,即 struct v4l2_window
。
struct video_window
的 x
、y
、width
和 height
字段已移至 struct v4l2_window
的 struct v4l2_rect
子结构 w
中。chromakey
、clips
和 clipcount
字段保持不变。struct video_clip
被重命名为 struct v4l2_clip
,它也包含一个 struct v4l2_rect
,但其语义仍然相同。
VIDEO_WINDOW_INTERLACE
标志已删除。取而代之的是,应用程序必须将 field
字段设置为 V4L2_FIELD_ANY
或 V4L2_FIELD_INTERLACED
。VIDEO_WINDOW_CHROMAKEY
标志已移至 struct v4l2_framebuffer
中,并以新名称 V4L2_FBUF_FLAG_CHROMAKEY
存在。
在 V4L 中,将位图指针存储在 clips
中并将 clipcount
设置为 VIDEO_CLIP_BITMAP
(-1) 会请求位图裁剪,使用固定大小为 1024 × 625 位的位图。Struct v4l2_window
为此目的有一个单独的 bitmap
指针字段,位图大小由 w.width
和 w.height
决定。
启用或禁用覆盖的 VIDIOCCAPTURE
ioctl 已重命名为 ioctl VIDIOC_OVERLAY。
6.1.8. 裁剪¶
为了仅捕获完整图片的一部分,V4L 定义了使用 struct video_capture
的 VIDIOCGCAPTURE
和 VIDIOCSCAPTURE
ioctl。等效的 V4L2 ioctl 是 VIDIOC_G_CROP 和 VIDIOC_S_CROP,它们使用 struct v4l2_crop
,以及相关的 ioctl VIDIOC_CROPCAP ioctl。这是一个相当复杂的问题,详情请参阅 图像裁剪、插入和缩放 -- CROP API。
struct v4l2_crop
的 x
、y
、width
和 height
字段已移至 struct v4l2_rect
子结构 c
中。decimation
字段已删除。在 V4L2 API 中,缩放因子由裁剪矩形的大小以及捕获或覆盖图像的大小隐式决定。
用于分别仅捕获奇数或偶数场的 VIDEO_CAPTURE_ODD
和 VIDEO_CAPTURE_EVEN
标志已替换为 struct v4l2_pix_format
和 struct v4l2_window
中名为 field
的字段中的 V4L2_FIELD_TOP
和 V4L2_FIELD_BOTTOM
。这些结构用于使用 VIDIOC_S_FMT ioctl 选择捕获或覆盖格式。
6.1.9. 读取图像,内存映射¶
6.1.9.1. 使用读方法捕获¶
使用 read()
函数从 V4L 或 V4L2 设备读取图像之间没有本质区别,但 V4L2 驱动程序不要求支持此 I/O 方法。应用程序可以通过 ioctl VIDIOC_QUERYCAP ioctl 确定该函数是否可用。所有与应用程序交换数据的 V4L2 设备都必须支持 select()
和 poll()
函数。
为了选择图像格式和大小,V4L 提供了 VIDIOCSPICT
和 VIDIOCSWIN
ioctl。V4L2 使用通用数据格式协商 ioctl VIDIOC_G_FMT 和 VIDIOC_S_FMT。它们接受指向 struct v4l2_format
的指针作为参数,此处使用的是其 fmt
联合体中名为 pix
的 struct v4l2_pix_format
。
有关 V4L2 读接口的更多信息,请参阅 读/写。
6.1.9.2. 使用内存映射捕获¶
应用程序可以通过将设备内存中的缓冲区(或更常见的是仅将分配在支持 DMA 的系统内存中的缓冲区)映射到其地址空间来从 V4L 设备读取数据。这避免了读方法的数据复制开销。V4L2 也支持内存映射,但有一些不同。
V4L |
V4L2 |
---|---|
必须在分配缓冲区之前选择图像格式,使用 VIDIOC_S_FMT ioctl。如果没有选择格式,驱动程序可能会使用上一个(可能由另一个应用程序请求的)格式。 |
|
应用程序无法更改缓冲区数量。它内置在驱动程序中,除非它有一个模块选项可以在驱动程序模块加载时更改数量。 |
ioctl VIDIOC_REQBUFS ioctl 分配所需数量的缓冲区,这是初始化序列中的一个必需步骤。 |
驱动程序将所有缓冲区映射为一块连续的内存区域。 |
缓冲区是单独映射的。每个缓冲区的偏移量和大小可以使用 ioctl VIDIOC_QUERYBUF ioctl 确定。 |
|
驱动程序维护一个输入队列和一个输出队列。ioctl VIDIOC_QBUF, VIDIOC_DQBUF 将任何空缓冲区入队到输入队列。已填充的缓冲区使用 VIDIOC_DQBUF ioctl 从输出队列中出队。要等待填充的缓冲区可用,可以使用此函数、 |
有关内存映射和示例的更深入讨论,请参阅 流 I/O (内存映射)。
6.1.10. 读取原始 VBI 数据¶
最初 V4L API 没有指定原始 VBI 捕获接口,仅将设备文件 /dev/vbi
保留用于此目的。唯一支持此接口的驱动程序是 BTTV 驱动程序,实际上它定义了 V4L VBI 接口。从设备读取会得到一个具有以下参数的原始 VBI 图像:
struct |
V4L, BTTV 驱动程序 |
---|---|
采样率 |
28636363 Hz NTSC(或任何其他 525 行标准);35468950 Hz PAL 和 SECAM(625 行标准) |
偏移量 |
? |
每行样本数 |
2048 |
样本格式 |
V4L2_PIX_FMT_GREY。最后四个字节(一个机器字节序整数)包含一个帧计数器。 |
起始[] |
10, 273 NTSC; 22, 335 PAL 和 SECAM |
计数[] |
16, 16 [9] |
标志 |
0 |
V4L 规范中未记录,在 Linux 2.3 中,增加了使用 struct vbi_format
的 VIDIOCGVBIFMT
和 VIDIOCSVBIFMT
ioctl 来确定 VBI 图像参数。这些 ioctl 仅与 原始 VBI 数据接口 中指定的 V4L2 VBI 接口部分兼容。
不存在 offset
字段,sample_format
应该是 VIDEO_PALETTE_RAW
,等同于 V4L2_PIX_FMT_GREY
。其余字段可能与 struct v4l2_vbi_format
等效。
显然,只有 Zoran (ZR 36120) 驱动程序实现了这些 ioctl。其语义与 V4L2 中指定的语义有两种不同之处。参数在 open()
时重置,并且如果参数无效,VIDIOCSVBIFMT
总是返回 EINVAL
错误代码。
6.1.11. 杂项¶
V4L2 没有 VIDIOCGUNIT
ioctl 的等效项。应用程序可以通过重新打开设备并请求 VBI 数据来查找与视频捕获设备关联的 VBI 设备(反之亦然)。详情请参阅 打开和关闭设备。
目前没有替代 VIDIOCKEY
和用于微码编程的 V4L 函数的方案。MPEG 压缩和播放设备的新接口已在 扩展控件 API 中记录。