4.6. 原始 VBI 数据接口¶
VBI 是垂直消隐间隔 (Vertical Blanking Interval) 的缩写,是模拟视频信号中一系列行之间的间隙。在 VBI 期间,不会传输图像信息,从而允许阴极射线管电视的电子束返回到屏幕顶部时有一些时间。使用示波器,您会发现这里的垂直同步脉冲和短数据包 ASK 调制[1] 到视频信号上。这些是诸如图文电视或隐藏字幕等服务的传输。
此接口类型的主题是原始 VBI 数据,它从视频信号中采样,或添加到信号中以进行输出。数据格式类似于未压缩的视频图像,即若干行乘以每行若干个样本,我们称之为 VBI 图像。
按照惯例,V4L2 VBI 设备通过名为 /dev/vbi
和 /dev/vbi0
到 /dev/vbi31
的字符设备特殊文件访问,主设备号为 81,次设备号为 224 到 255。/dev/vbi
通常是指向首选 VBI 设备的符号链接。此惯例适用于输入和输出设备。
为了解决查找相关视频和 VBI 设备的问题,VBI 捕获和输出也可作为 /dev/video
下的设备功能使用。要使用这些设备捕获或输出原始 VBI 数据,应用程序必须调用 VIDIOC_S_FMT ioctl。以 /dev/vbi
的方式访问时,原始 VBI 捕获或输出是默认设备功能。
4.6.1. 查询功能¶
支持原始 VBI 捕获或输出 API 的设备在由 ioctl VIDIOC_QUERYCAP ioctl 返回的结构体 v4l2_capability
的 capabilities
字段中分别设置 V4L2_CAP_VBI_CAPTURE
或 V4L2_CAP_VBI_OUTPUT
标志。必须至少支持一种读取/写入或流式 I/O 方法。VBI 设备可能具有或不具有调谐器或调制器。
4.6.2. 补充功能¶
VBI 设备应根据需要支持 视频输入或输出、调谐器或调制器 和 控件 ioctl。视频标准 ioctl 提供对 VBI 设备进行编程至关重要的信息,因此必须支持。
4.6.3. 原始 VBI 格式协商¶
原始 VBI 采样能力可能会有所不同,特别是采样频率。为了正确解释数据,V4L2 指定了一个 ioctl 来查询采样参数。此外,为了允许一定的灵活性,应用程序还可以建议不同的参数。
通常,这些参数在 open()
时不会重置,以允许 Unix 工具链,即对设备进行编程,然后像读取普通文件一样从中读取。编写良好的 V4L2 应用程序应始终确保它们真正获得所需的内容,请求合理的参数,然后检查实际参数是否合适。
要查询当前的原始 VBI 捕获参数,应用程序将结构体 v4l2_format
的 type
字段设置为 V4L2_BUF_TYPE_VBI_CAPTURE
或 V4L2_BUF_TYPE_VBI_OUTPUT
,并使用指向此结构的指针调用 VIDIOC_G_FMT ioctl。驱动程序填充 fmt
联合的结构体 v4l2_vbi_format
的 vbi
成员。
要请求不同的参数,应用程序将结构体 v4l2_format
的 type
字段设置为如上所述,并初始化结构体 v4l2_vbi_format
vbi
成员的 fmt
联合的所有字段,或者最好只是修改 VIDIOC_G_FMT 的结果,并使用指向此结构的指针调用 VIDIOC_S_FMT ioctl。仅当给定参数不明确时,驱动程序才会返回 EINVAL
错误代码,否则,它们将根据硬件功能修改参数并返回实际参数。当驱动程序在此处分配资源时,它可能会返回 EBUSY
错误代码,以指示返回的参数有效,但当前无法使用所需的资源。例如,当要捕获的视频和 VBI 区域重叠时,或者当驱动程序支持多次打开而另一个进程已经请求 VBI 捕获或输出时,可能会发生这种情况。无论如何,应用程序必须预期其他可能返回 EBUSY
的资源分配点,即在 ioctl VIDIOC_STREAMON、VIDIOC_STREAMOFF ioctl 以及第一个 read()
、write()
和 select()
调用时。
VBI 设备必须实现 VIDIOC_G_FMT 和 VIDIOC_S_FMT ioctl,即使 VIDIOC_S_FMT 忽略所有请求并且始终返回与 VIDIOC_G_FMT 相同的默认参数。VIDIOC_TRY_FMT 是可选的。
-
type v4l2_vbi_format¶
__u32 |
|
每秒采样数,即单位为 1 Hz。 |
__u32 |
|
VBI 图像的水平偏移量,相对于行同步脉冲的前沿,以样本计数:VBI 图像中的第一个样本将位于前沿之后的 |
__u32 |
|
|
__u32 |
|
定义样本格式,如 图像格式 中所示,这是一个四字符代码。[2]通常这是 |
__u32 |
|
这是与VBI图像的第一行关联的扫描系统行号,分别对应第一场和第二场。有关有效值,请参阅图 4.2. ITU-R 525 行号 (M/NTSC 和 M/PAL) 和 图 4.3. ITU-R 625 行号。 |
__u32 |
|
分别是第一场和第二场图像中的行数。 |
驱动程序应尽可能灵活。 例如,可以将 VBI 捕获窗口向下扩展或移动到图像区域,从而实现“全场模式”以捕获嵌入在图像中的数据服务传输。 如果不需要来自相应场的数据,应用程序可以将第一个或第二个 两个 要初始化 |
||
__u32 |
|
请参阅下方的原始 VBI 格式标志。目前只有驱动程序设置标志,应用程序必须将此字段设置为零。 |
__u32 |
|
此数组保留供将来扩展使用。驱动程序和应用程序必须将其设置为零。 |
|
0x0001 |
此标志指示无法正确区分场的硬件。 通常,VBI 图像首先在内存中存储第一场(较低的扫描线号)。 这可能是顶场或底场,具体取决于视频标准。 设置此标志后,可以首先存储第一场或第二场,但这些场仍然按正确的时间顺序排列,较旧的场先存储在内存中。[3] |
|
0x0002 |
默认情况下,两个场图像将按顺序传递;第一场的所有行之后是第二场的所有行(比较场序 |
请记住,VBI 图像格式取决于所选的视频标准,因此应用程序必须先选择新的标准或查询当前标准。 在格式协商之前或在切换视频标准后(可能会使协商的 VBI 参数失效)尝试读取或写入数据,应被驱动程序拒绝。 活动 I/O 期间不允许进行格式更改。
4.6.4. 读取和写入 VBI 图像¶
为了确保与场号同步并更易于实现,一次传递的最小数据单元是一个帧,它由两个 VBI 图像场组成,它们在内存中紧随其后。
一个帧的总大小计算如下:
(count[0] + count[1]) * samples_per_line * sample size in bytes
样本大小很可能始终为一个字节,但应用程序必须检查 sample_format
字段,以便与其他驱动程序正常工作。
VBI 设备可以支持 读/写 和/或流式传输(内存映射 或 用户指针)I/O。后者可以通过使用缓冲区时间戳来实现视频和 VBI 数据的同步。
请记住,VIDIOC_STREAMON ioctl 和第一个 read()
、write()
和 select()
调用可能是资源分配点,如果所需的硬件资源暂时不可用,则返回 EBUSY
错误代码,例如设备已被另一个进程使用。