1.25. 数据格式

1.25.1. 数据格式协商

不同的设备与应用程序交换不同类型的数据,例如视频图像、原始或切片 VBI 数据、RDS 数据报。即使在同一类型中,也有许多不同的格式,特别是图像格式非常丰富。尽管驱动程序必须提供一个默认值,并且选择在设备关闭和重新打开后仍然存在,但应用程序在进行数据交换之前应始终协商数据格式。协商意味着应用程序请求特定格式,驱动程序选择并报告硬件为满足请求所能提供的最佳方案。当然,应用程序也可以只查询当前选择。

存在一种单一机制,通过使用聚合结构体 v4l2_formatVIDIOC_G_FMTVIDIOC_S_FMT ioctl 来协商所有数据格式。此外,VIDIOC_TRY_FMT ioctl 可用于检查硬件可以做什么,而无需实际选择新的数据格式。V4L2 API 支持的数据格式涵盖在 接口 中的相应设备部分。要更详细地了解图像格式,请参阅 图像格式

VIDIOC_S_FMT ioctl 是初始化序列中的一个重要转折点。在此之前,多个面板应用程序可以并发访问同一设备以选择当前输入、更改控件或修改其他属性。第一个 VIDIOC_S_FMT 将逻辑流(视频数据、VBI 数据等)独占分配给一个文件描述符。

独占意味着没有其他应用程序,更准确地说,没有其他文件描述符可以抓取此流或更改与协商参数不一致的设备属性。例如,当新标准使用不同数量的扫描行时,视频标准更改可能会使所选图像格式无效。因此,只有拥有该流的文件描述符才能进行无效更改。相应地,抓取不同逻辑流的多个文件描述符会相互阻止干扰其设置。例如,当视频叠加即将开始或已经在进行中时,同时视频捕获可能会被限制为相同的裁剪和图像大小。

当应用程序省略 VIDIOC_S_FMT ioctl 时,其锁定副作用由下一步(使用 ioctl VIDIOC_REQBUFS ioctl 选择 I/O 方法)或第一次 read()write() 调用隐式地发生。

通常,一个文件描述符只能分配一个逻辑流,例外情况是驱动程序允许同时进行视频捕获和叠加,并使用相同的文件描述符以兼容 V4L 和 V4L2 的早期版本。通过关闭并重新打开设备可以切换逻辑流或返回“面板模式”。驱动程序可能支持使用 VIDIOC_S_FMT 进行切换。

所有与应用程序交换数据的驱动程序都必须支持 VIDIOC_G_FMTVIDIOC_S_FMT ioctl。强烈建议但可选地实现 VIDIOC_TRY_FMT

1.25.2. 图像格式枚举

除了通用格式协商函数外,还有一个特殊的 ioctl 可用于枚举视频捕获、叠加或输出设备支持的所有图像格式。[1]

ioctl VIDIOC_ENUM_FMT ioctl 必须由所有与应用程序交换图像数据的驱动程序支持。

重要提示

驱动程序不应在内核空间中转换图像格式。它们必须只枚举硬件直接支持的格式。如有必要,驱动程序编写者应发布示例转换例程或库以集成到应用程序中。