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。
设备类型 |
文件名 |
次要编号 |
---|---|---|
视频捕获和叠加 |
|
0-63 |
无线电接收器 |
|
64-127 |
原始 VBI 捕获 |
|
224-255 |
V4L 禁止(或曾经禁止)多次打开设备文件。V4L2 驱动程序可以支持多次打开,有关详细信息和后果,请参阅 打开和关闭设备。
V4L 驱动程序使用 EINVAL
错误代码响应 V4L2 ioctl。
6.1.2. 查询功能¶
V4L 的 VIDIOCGCAP
ioctl 等效于 V4L2 的 ioctl VIDIOC_QUERYCAP。
结构 video_capability
中的 name
字段在结构 v4l2_capability
中变为 card
,type
被 capabilities
替换。请注意,V4L2 不会像这样区分设备类型,最好将基本视频输入、视频输出和无线电设备视为支持一组相关功能(如视频捕获、视频叠加和 VBI 捕获)的设备。有关介绍,请参阅 打开和关闭设备。
|
结构 |
目的 |
---|---|---|
|
|
支持视频捕获接口。 |
|
|
该设备具有调谐器或调制器。 |
|
|
支持原始 VBI 捕获接口。 |
|
|
支持视频叠加接口。 |
|
结构 |
是否支持色键叠加。有关叠加的更多信息,请参阅视频叠加接口。 |
|
结构 |
是否支持裁剪叠加图像,请参阅视频叠加接口。 |
|
结构 |
叠加是否会覆盖帧缓冲区内存,请参阅视频叠加接口。 |
|
|
此标志指示硬件是否可以缩放图像。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 使用结构体 video_channel
,通过 VIDIOCGCHAN
和 VIDIOCSCHAN
ioctl 来枚举 V4L 设备的视频输入。等效的 V4L2 ioctl 是 ioctl VIDIOC_ENUMINPUT、 VIDIOC_G_INPUT 和 VIDIOC_S_INPUT,它们使用结构体 v4l2_input
,如 视频输入和输出 中所述。
用于计数输入的 channel
字段被重命名为 index
,视频输入类型被重命名如下:
结构体 |
结构体 |
---|---|
|
|
|
|
与表示此输入调谐器数量的 tuners
字段不同,V4L2 假定每个视频输入最多连接到一个调谐器。但是,一个调谐器可以有多个输入,即射频连接器,并且一个设备可以有多个调谐器。与输入关联的调谐器的索引号(如果有)存储在结构体 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 和结构体 video_tuner
来枚举 V4L 电视或无线电设备的调谐器。等效的 V4L2 ioctl 是 VIDIOC_G_TUNER 和 VIDIOC_S_TUNER,它们使用结构体 v4l2_tuner
。调谐器在 调谐器和调制器 中介绍。
用于计数调谐器的 tuner
字段被重命名为 index
。 name
、 rangelow
和 rangehigh
字段保持不变。
指示支持的视频标准的 VIDEO_TUNER_PAL
、 VIDEO_TUNER_NTSC
和 VIDEO_TUNER_SECAM
标志被删除。此信息现在包含在关联的结构体 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
。此字段还允许检测单声道和双语音频,有关详细信息,请参阅结构体 v4l2_tuner
的定义。目前,对于 VIDEO_TUNER_RDS_ON
和 VIDEO_TUNER_MBS_ON
标志,没有替代项。
VIDEO_TUNER_LOW
标志在结构体 v4l2_tuner
的 capability
字段中被重命名为 V4L2_TUNER_CAP_LOW
。
用于更改调谐器频率的 VIDIOCGFREQ
和 VIDIOCSFREQ
ioctl 被重命名为 VIDIOC_G_FREQUENCY 和 VIDIOC_S_FREQUENCY。它们接受指向结构体 v4l2_frequency
的指针,而不是 unsigned long integer。
6.1.5. 图像属性¶
V4L2 没有与 VIDIOCGPICT
和 VIDIOCSPICT
ioctl 和结构体 video_picture
等效的项。以下字段被 V4L2 控件替换,这些控件可以通过 ioctl VIDIOC_QUERYCTRL、VIDIOC_QUERY_EXT_CTRL 和 VIDIOC_QUERYMENU、 VIDIOC_G_CTRL 和 VIDIOC_S_CTRL ioctl 访问。
结构体 |
V4L2 控制 ID |
---|---|
|
|
|
|
|
|
|
|
|
|
V4L 图片控件的范围被假定为 0 到 65535,没有特定的重置值。 V4L2 API 允许任意限制和默认值,可以使用 ioctl VIDIOC_QUERYCTRL、VIDIOC_QUERY_EXT_CTRL 和 VIDIOC_QUERYMENU ioctl 查询。有关控件的常规信息,请参阅 用户控件。
视频图像的 depth
(每个像素的平均位数)由选定的图像格式暗示。 V4L2 没有明确提供此类信息,假定识别格式的应用程序知道图像深度,而其他应用程序不需要知道。palette
字段移动到了结构体 v4l2_pix_format
。
结构体 |
结构体 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
无 |
|
|
|
无 [7] |
|
|
|
|
|
|
|
V4L2 图像格式在 图像格式 中定义。可以使用 VIDIOC_S_FMT ioctl 来选择图像格式。
6.1.6. 音频¶
VIDIOCGAUDIO
和 VIDIOCSAUDIO
ioctl 以及结构体 video_audio
用于枚举 V4L 设备的音频输入。等效的 V4L2 ioctl 是 VIDIOC_G_AUDIO 和 VIDIOC_S_AUDIO,它们使用结构体 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 中,此信息分别存储在结构体 v4l2_tuner
的 rxsubchans
和 audmode
字段中。有关调谐器的更多信息,请参阅 调谐器和调制器。与音频模式相关,结构体 v4l2_audio
还会报告这是单声道还是立体声输入,无论源是否为调谐器。
以下字段被可以使用 ioctls VIDIOC_QUERYCTRL、VIDIOC_QUERY_EXT_CTRL 和 VIDIOC_QUERYMENU、VIDIOC_G_CTRL 和 VIDIOC_S_CTRL ioctl 访问的 V4L2 控件所替换
结构体 |
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
属性,用于替换结构体 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。结构体 video_buffer
的 base
字段保持不变,除了 V4L2 定义了一个标志来指示非破坏性覆盖而不是 NULL
指针。所有其他字段都移动到结构体 v4l2_pix_format
的 fmt
子结构体中,该结构体位于结构体 v4l2_framebuffer
中。depth
字段被 pixelformat
替换。有关 RGB 格式及其各自的颜色深度的列表,请参阅 RGB 格式。
V4L2 使用通用的数据格式协商 ioctl VIDIOC_G_FMT 和 VIDIOC_S_FMT 来代替特殊的 ioctl VIDIOCGWIN
和 VIDIOCSWIN
。它们采用指向结构体 v4l2_format
的指针作为参数。这里使用 fmt
联合的 win
成员,一个结构体 v4l2_window
。
结构体 video_window
的 x
、y
、width
和 height
字段移动到结构体 v4l2_rect
子结构体 w
中,该子结构体位于结构体 v4l2_window
中。chromakey
、clips
和 clipcount
字段保持不变。结构体 video_clip
被重命名为结构体 v4l2_clip
,该结构体还包含一个结构体 v4l2_rect
,但语义仍然相同。
VIDEO_WINDOW_INTERLACE
标志被删除。相反,应用程序必须将 field
字段设置为 V4L2_FIELD_ANY
或 V4L2_FIELD_INTERLACED
。VIDEO_WINDOW_CHROMAKEY
标志移动到结构体 v4l2_framebuffer
中,其新名称为 V4L2_FBUF_FLAG_CHROMAKEY
。
在 V4L 中,将位图指针存储在 clips
中,并将 clipcount
设置为 VIDEO_CLIP_BITMAP
(-1) 会请求位图剪切,使用 1024 × 625 位的固定大小位图。结构体 v4l2_window
有一个单独的 bitmap
指针字段用于此目的,并且位图大小由 w.width
和 w.height
确定。
用于启用或禁用覆盖的 VIDIOCCAPTURE
ioctl 重命名为 ioctl VIDIOC_OVERLAY。
6.1.8. 裁剪¶
为了仅捕获完整图片的一部分,V4L 定义了使用结构体 video_capture
的 VIDIOCGCAPTURE
和 VIDIOCSCAPTURE
ioctl。等效的 V4L2 ioctl 是 VIDIOC_G_CROP 和 VIDIOC_S_CROP,它们使用结构体 v4l2_crop
,以及相关的 ioctl VIDIOC_CROPCAP ioctl。这是一个相当复杂的问题,有关详细信息,请参阅 图像裁剪、插入和缩放 -- CROP API。
字段 x
、y
、width
和 height
已移至结构体 v4l2_rect
的子结构体 c
中,该结构体为 v4l2_crop
。字段 decimation
已被删除。在 V4L2 API 中,缩放因子由裁剪矩形的大小以及捕获或叠加图像的大小隐含表示。
捕获奇数场或偶数场的标志 VIDEO_CAPTURE_ODD
和 VIDEO_CAPTURE_EVEN
已被结构体 v4l2_pix_format
和结构体 v4l2_window
的名为 field
的字段中的 V4L2_FIELD_TOP
和 V4L2_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 提供 VIDIOCSPICT
和 VIDIOCSWIN
ioctl。V4L2 使用通用的数据格式协商 ioctl VIDIOC_G_FMT 和 VIDIOC_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 分配所需数量的缓冲区,这是初始化序列中的必需步骤。 |
驱动程序将所有缓冲区映射为一段连续的内存范围。 |
缓冲区是单独映射的。可以使用 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 图像
结构体 |
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_format
的 VIDIOCGVBIFMT
和 VIDIOCSVBIFMT
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中。