4.7. 切片 VBI 数据接口¶
VBI 代表垂直消隐间隔,是模拟视频信号线序列中的一个间隙。在 VBI 期间,不传输图像信息,从而留出一些时间让阴极射线管电视的电子束返回到屏幕顶部。
切片 VBI 设备使用硬件来解调 VBI 中传输的数据。 V4L2 驱动程序不应通过软件执行此操作,另请参见原始 VBI 接口。数据作为固定大小的短数据包传递,每个数据包覆盖一条扫描线。每个视频帧的数据包数量是可变的。
切片 VBI 捕获和输出设备通过与原始 VBI 设备相同的字符特殊文件访问。当驱动程序同时支持这两个接口时,/dev/vbi
设备的默认功能是原始 VBI 捕获或输出,并且只有在调用如下定义的VIDIOC_S_FMT ioctl 后,切片 VBI 功能才可用。同样,/dev/video
设备可能支持切片 VBI API,但此处的默认功能是视频捕获或输出。如果要通过驱动程序同时支持传递原始和切片 VBI 数据,则必须使用不同的文件描述符。
4.7.1. 查询功能¶
支持切片 VBI 捕获或输出 API 的设备分别在v4l2_capability
结构体的capabilities
字段中设置V4L2_CAP_SLICED_VBI_CAPTURE
或V4L2_CAP_SLICED_VBI_OUTPUT
标志,该结构体由ioctl VIDIOC_QUERYCAP ioctl 返回。必须支持至少一种读取/写入或流式I/O 方法。切片 VBI 设备可能具有调谐器或调制器。
4.7.2. 补充功能¶
如果切片 VBI 设备具有这些功能,则应支持视频输入或输出和调谐器或调制器 ioctl,并且可能支持用户控件 ioctl。视频标准 ioctl 提供对编程切片 VBI 设备至关重要的信息,因此必须支持。
4.7.3. 切片 VBI 格式协商¶
为了找出硬件支持哪些数据服务,应用程序可以调用VIDIOC_G_SLICED_VBI_CAP ioctl。所有实现切片 VBI 接口的驱动程序都必须支持此 ioctl。当硬件每个帧可以捕获或输出的 VBI 行数,或者硬件可以在给定行上识别的服务数量受到限制时,结果可能与VIDIOC_S_FMT ioctl 的结果不同。例如,在 PAL 第 16 行上,硬件可能能够查找 VPS 或 Teletext 信号,但不能同时查找两者。
为了确定当前选择的服务,应用程序将v4l2_format
结构体的type
字段设置为V4L2_BUF_TYPE_SLICED_VBI_CAPTURE
或V4L2_BUF_TYPE_SLICED_VBI_OUTPUT
,并且VIDIOC_G_FMT ioctl 填充fmt.sliced
成员,即v4l2_sliced_vbi_format
结构体。
应用程序可以通过初始化或修改fmt.sliced
成员并使用指向v4l2_format
结构的指针调用VIDIOC_S_FMT ioctl 来请求不同的参数。
切片 VBI API 比原始 VBI API 更复杂,因为必须告诉硬件期望在每条扫描线上使用哪种 VBI 服务。并非所有服务都可能受到硬件在所有行上的支持(对于 VBI 输出尤其如此,其中 Teletext 通常不受支持,而其他服务只能插入到一条特定行中)。但是,在许多情况下,只需将service_set
字段设置为所需的服务,并让驱动程序根据硬件功能填充service_lines
数组就足够了。只有在需要更精确的控制时,程序员才应显式设置service_lines
数组。
VIDIOC_S_FMT ioctl 根据硬件功能修改参数。当驱动程序在此点分配资源时,如果所需的资源暂时不可用,则可能会返回EBUSY
错误代码。可能返回EBUSY
的其他资源分配点可以是ioctl VIDIOC_STREAMON, VIDIOC_STREAMOFF ioctl 和第一个read()
,write()
和select()
调用。
-
type v4l2_sliced_vbi_format¶
4.7.3.1. 结构体 v4l2_sliced_vbi_format¶
__u16 |
|
如果在通过VIDIOC_S_FMT或VIDIOC_TRY_FMT时 在返回时,驱动程序将此字段设置为返回的 |
||
__u16 |
|
应用程序使用驱动程序应在相应扫描线上查找或插入的数据服务集初始化此数组。根据硬件功能,驱动程序返回请求的集合、子集(可能只是一个服务)或空集。当硬件无法处理同一行上的多个服务时,驱动程序应选择一个。不能对驱动程序选择哪个服务做出假设。 |
||
元素 |
525 行系统 |
625 行系统 |
||
|
1 |
1 |
||
|
23 |
23 |
||
|
264 |
314 |
||
|
286 |
336 |
||
驱动程序必须将 |
||||
__u32 |
|
一次 |
||
__u32 |
|
此数组保留供将来扩展使用。 应用程序和驱动程序必须将其设置为零。 |
4.7.3.2. 切片 VBI 服务¶
符号 |
值 |
参考 |
通常的行 |
有效负载 |
---|---|---|---|---|
|
0x0001 |
PAL/SECAM 行 7-22, 320-335(第二个字段 7-22) |
45 字节 Teletext 数据包的最后 42 个字节,即没有时钟预热和成帧代码,先传输 lsb。 |
|
|
0x0400 |
PAL 第 16 行 |
ETS 300 231 图 9 中的字节编号 3 到 15,先传输 lsb。 |
|
|
0x1000 |
NTSC 第 21, 284 行(第二个字段 21) |
按传输顺序的两个字节,包括奇偶校验位,先传输 lsb。 |
|
|
0x4000 |
PAL/SECAM 第 23 行 |
参见下面的V4L2_SLICED_WSS_625 有效负载。 |
|
|
0x1000 |
适用于 525 行系统的服务集。 |
||
|
0x4401 |
适用于 625 行系统的服务集。 |
当应用程序尝试在没有事先进行格式协商的情况下,在切换视频标准(可能会使协商的 VBI 参数失效)之后,以及在切换视频输入(可能会作为副作用更改视频标准)之后读取或写入数据时,驱动程序可能会返回EINVAL
错误代码。当应用程序尝试在 i/o 正在进行时(在ioctl VIDIOC_STREAMON, VIDIOC_STREAMOFF和VIDIOC_STREAMOFF调用之间,以及在第一次read()
或write()
调用之后)更改格式时,VIDIOC_S_FMT ioctl 可能会返回EBUSY
错误代码。
4.7.3.2.1. V4L2_SLICED_WSS_625 有效负载¶
V4L2_SLICED_WSS_625
的有效负载为
字节
0
1
位
msb
lsb
msb
lsb
7
6
5
4
3
2
1
0
x
x
13
12
11
10
9
8
4.7.4. 读取和写入切片 VBI 数据¶
单个read()
或write()
调用必须传递属于一个视频帧的所有数据。即一个或多个元素的v4l2_sliced_vbi_data
结构体数组,总大小不超过io_size
字节。同样,在流式 I/O 模式下,io_size
字节的一个缓冲区必须包含一个视频帧的数据。未使用v4l2_sliced_vbi_data
元素的id
必须为零。
-
type v4l2_sliced_vbi_data¶
4.7.4.1. 结构体 v4l2_sliced_vbi_data¶
__u32 |
|
来自切片 VBI 服务的标志,用于标识此数据包中的数据类型。只能设置一个位。当捕获的数据包的 |
__u32 |
|
此数据是从哪个视频字段捕获的,或者应插入到哪个视频字段。 |
__u32 |
|
此数据是从哪个字段(相对于帧)行号捕获的,或者应插入到哪个字段(相对于帧)行号。有关有效值,请参见图 4.2. ITU-R 525 行编号 (M/NTSC 和 M/PAL)和图 4.3. ITU-R 625 行编号。如果硬件无法可靠地识别扫描线,则切片 VBI 捕获设备可以将所有数据包的行号设置为 |
__u32 |
|
此字段保留供将来扩展使用。应用程序和驱动程序必须将其设置为零。 |
__u8 |
|
数据包有效负载。有关每种数据类型传递的内容和字节数,请参见切片 VBI 服务。此数组末尾的填充字节的内容未定义,驱动程序和应用程序应忽略它们。 |
数据包始终按升序行号顺序传递,没有重复的行号。当应用程序违反此规则时,write()
函数和ioctl VIDIOC_QBUF, VIDIOC_DQBUF ioctl 必须返回EINVAL
错误代码。当应用程序传递不正确的字段或行号,或者尚未与VIDIOC_G_FMT或VIDIOC_S_FMT ioctl 协商的field
、line
和id
组合时,它们也必须返回 EINVAL 错误代码。当行号未知时,驱动程序必须按传输顺序传递数据包。驱动程序可以在数据包数组中的任何位置插入id
设置为零的空数据包。
为了确保同步并与丢帧区分开来,当捕获的帧不携带任何请求的数据服务时,驱动程序必须传递一个或多个空数据包。当应用程序未能及时传递 VBI 数据以进行输出时,驱动程序必须再次输出上一个 VPS 和 WSS 数据包,并禁用 Closed Caption 和 Teletext 数据的输出,或者输出 Closed Caption 和 Teletext 解码器忽略的数据。
切片 VBI 设备可能支持读/写和/或流式(内存映射和/或用户指针)I/O。后者具有通过使用缓冲区时间戳同步视频和 VBI 数据的可能性。
4.7.5. MPEG 流中的切片 VBI 数据¶
如果设备可以生成 MPEG 输出流,则它可能能够提供协商的切片 VBI 服务作为嵌入在 MPEG 流中的数据。用户或应用程序使用V4L2_CID_MPEG_STREAM_VBI_FMT控件控制此切片 VBI 数据插入。
如果驱动程序未提供V4L2_CID_MPEG_STREAM_VBI_FMT控件,或者仅允许将该控件设置为V4L2_MPEG_STREAM_VBI_FMT_NONE,则该设备无法将切片 VBI 数据嵌入 MPEG 流中。
V4L2_CID_MPEG_STREAM_VBI_FMT控件不会隐式地设置设备驱动程序以捕获或停止捕获切片 VBI 数据。该控件仅指示将切片 VBI 数据嵌入 MPEG 流中,前提是应用程序已协商捕获切片 VBI 服务。
也可能存在设备只能将切片 VBI 数据嵌入某些类型的 MPEG 流中的情况:例如 MPEG-2 PS,但不能嵌入 MPEG-2 TS。在这种情况下,如果请求插入切片 VBI 数据,则切片 VBI 数据将嵌入支持的 MPEG 流类型中,并从设备不支持插入切片 VBI 数据的 MPEG 流类型中静默省略。
以下小节指定嵌入式切片 VBI 数据的格式。
4.7.5.1. MPEG 流嵌入式,切片 VBI 数据格式:NONE¶
驱动程序应将V4L2_MPEG_STREAM_VBI_FMT_NONE嵌入式切片 VBI 格式解释为停止将切片 VBI 数据嵌入 MPEG 流的控制。设置此格式后,设备和驱动程序都不会在 MPEG 流中插入“空”嵌入式切片 VBI 数据包。未为此格式指定任何 MPEG 流数据结构。
4.7.5.2. MPEG 流嵌入式,切片 VBI 数据格式:IVTV¶
当支持V4L2_MPEG_STREAM_VBI_FMT_IVTV嵌入式切片 VBI 格式时,它指示驱动程序在 MPEG 流的 MPEG-2 Program Pack 中封装的 MPEG-2 Private Stream 1 PES 数据包中嵌入每个帧最多 36 行切片 VBI 数据。
历史背景:此格式规范源自ivtv
驱动程序使用的自定义嵌入式切片 VBI 数据格式。此格式已在内核源文件Documentation/userspace-api/media/drivers/cx2341x-uapi.rst
中进行了非正式指定。此格式的有效负载的最大大小和其他方面由 CX23415 MPEG 解码器在提取、解码和显示 MPEG 流中嵌入的切片 VBI 数据方面的功能和限制所驱动。
此格式的使用不专用于ivtv
驱动程序也不专用于 CX2341x 设备,因为将切片 VBI 数据包插入 MPEG 流是在驱动程序软件中实现的。至少cx18
驱动程序也以这种格式将切片 VBI 数据插入到 MPEG-2 PS 中。
以下定义指定了设置V4L2_MPEG_STREAM_VBI_FMT_IVTV时包含切片 VBI 数据的 MPEG-2 Private Stream 1 PES 数据包的有效负载。(此处未详细说明 MPEG-2 Private Stream 1 PES 数据包头和封装的 MPEG-2 Program Pack 头。有关这些数据包头的详细信息,请参阅 MPEG-2 规范。)
包含切片 VBI 数据的 MPEG-2 Private Stream 1 PES 数据包的有效负载由结构体v4l2_mpeg_vbi_fmt_ivtv
指定。有效负载的长度可变,具体取决于视频帧中存在的切片 VBI 数据的实际行数。有效负载可以在末尾用未指定的填充字节填充,以将有效负载的末尾对齐到 4 字节边界。有效负载永远不应超过 1552 字节(2 个字段,每个字段 18 行,每行 43 字节数据和一个 4 字节幻数)。
-
type v4l2_mpeg_vbi_fmt_ivtv¶
4.7.5.3. 结构体 v4l2_mpeg_vbi_fmt_ivtv¶
__u8 |
|
来自结构体 v4l2_mpeg_vbi_fmt_ivtv magic 字段的幻数的“幻数”常量,指示这是一个有效的切片 VBI 数据有效负载,并且还指示要用于有效负载数据的匿名联合的哪个成员, |
union { |
(anonymous) |
|
|
切片 VBI 数据有效负载的主要形式,包含 1 到 35 行切片 VBI 数据。有效负载的这种形式提供了行掩码,指示提供了哪些 VBI 行。 |
|
|
当存在 36 行切片 VBI 数据时使用的切片 VBI 数据有效负载的另一种形式。有效负载的这种形式不提供行掩码;隐式设置所有有效的行掩码位。 |
|
} |
4.7.5.4. 结构体 v4l2_mpeg_vbi_fmt_ivtv magic 字段的幻数¶
已定义符号 |
值 |
描述 |
---|---|---|
|
“itv0” |
指示结构体 |
|
“ITV0” |
指示结构体 |
-
类型 v4l2_mpeg_vbi_itv0¶
-
类型 v4l2_mpeg_vbi_ITV0¶
4.7.5.5. 结构体 v4l2_mpeg_vbi_itv0 和 v4l2_mpeg_vbi_ITV0¶
__le32 |
|
位掩码,指示存在的 VBI 服务行。 这些 linemask[0] b0: line 6 first field
linemask[0] b17: line 23 first field
linemask[0] b18: line 6 second field
linemask[0] b31: line 19 second field
linemask[1] b0: line 20 second field
linemask[1] b3: line 23 second field
linemask[1] b4-b31: unused and set to 0
|
|
这是一个可变长度数组,保存 1 到 35 行的切片 VBI 数据。 存在的切片 VBI 数据行对应于 |
4.7.5.6. 结构体 v4l2_mpeg_vbi_ITV0¶
|
一个 36 行切片 VBI 数据的固定长度数组。 |
-
类型 v4l2_mpeg_vbi_itv0_line¶
4.7.5.7. 结构体 v4l2_mpeg_vbi_itv0_line¶
__u8 |
|
来自 结构体 v4l2_mpeg_vbi_itv0_line id 字段的行标识符常量 的行标识符值,指示存储在此行上的切片 VBI 数据的类型。 |
__u8 |
|
该行的切片 VBI 数据。 |
4.7.5.8. 结构体 v4l2_mpeg_vbi_itv0_line id 字段的行标识符¶
已定义符号 |
值 |
描述 |
---|---|---|
|
1 |
有关行有效负载的描述,请参阅 切片 VBI 服务。 |
|
4 |
有关行有效负载的描述,请参阅 切片 VBI 服务。 |
|
5 |
有关行有效负载的描述,请参阅 切片 VBI 服务。 |
|
7 |
有关行有效负载的描述,请参阅 切片 VBI 服务。 |