1.8. 数字视频(DV)时序¶
到目前为止讨论的视频标准都是关于模拟电视及相应的视频时序。现在有更多不同的硬件接口,如高清电视接口(HDMI)、VGA、DVI 连接器等,它们传输视频信号,因此需要扩展 API 以选择这些接口的视频时序。由于 v4l2_std_id 可用的位数有限,无法扩展,因此添加了一组新的 ioctl 来设置/获取输入和输出的视频时序。
这些 ioctl 处理定义每个视频格式的详细数字视频时序。这包括诸如有效视频宽度和高度、信号极性、前沿(frontporches)、后沿(backporches)、同步宽度等参数。linux/v4l2-dv-timings.h
头文件可用于获取 CEA-861-E 和 VESA DMT 标准中的格式时序。
要枚举和查询设备支持的 DV 时序的属性,应用程序使用 ioctl VIDIOC_ENUM_DV_TIMINGS, VIDIOC_SUBDEV_ENUM_DV_TIMINGS 和 ioctl VIDIOC_DV_TIMINGS_CAP, VIDIOC_SUBDEV_DV_TIMINGS_CAP ioctl。要为设备设置 DV 时序,应用程序使用 VIDIOC_S_DV_TIMINGS ioctl;要获取当前 DV 时序,它们使用 VIDIOC_G_DV_TIMINGS ioctl。要检测视频接收器检测到的 DV 时序,应用程序使用 ioctl VIDIOC_QUERY_DV_TIMINGS ioctl。
当硬件检测到视频源变化(例如,视频信号出现或消失,或视频分辨率改变)时,它会发出一个 V4L2_EVENT_SOURCE_CHANGE 事件。使用 ioctl VIDIOC_SUBSCRIBE_EVENT 和 ioctl VIDIOC_DQEVENT 来检查此事件是否已报告。
如果视频信号发生变化,应用程序必须停止流传输,释放所有缓冲区,并调用 ioctl VIDIOC_QUERY_DV_TIMINGS 获取新的视频时序,如果有效,则可以通过调用 ioctl VIDIOC_S_DV_TIMINGS 来设置这些时序。这将同时更新格式,因此使用 ioctl VIDIOC_G_FMT 来获取新格式。现在应用程序可以分配新的缓冲区并重新开始流传输。
ioctl VIDIOC_QUERY_DV_TIMINGS 只会报告硬件检测到的内容,它永远不会改变配置。如果当前设置的时序与实际检测到的时序不同,则通常意味着您将无法捕获任何视频。正确的方法是依赖 V4L2_EVENT_SOURCE_CHANGE 事件,这样您就知道何时发生了变化。