V4L2文档翻译(五)

http://linuxtv.org/downloads/v4l-dvb-apis/format.html

数据格式


数据格式协商


不同设备通过应用交换不同种类的数据。比如视频图像,raw或分割的VBI数据,RDS数据电报。甚至是一个种类不同格式也是有可能的,特别是丰富的图像格式。尽管驱动在设备关闭和重打开时提供了一个默认值和一些预置选项,在做数据交换前应用程序也应该协商数据格式。协商意味着应用程序要请求一个特殊格式,驱动选择并上报硬件能完成的最好、也最能满足请求的答案。当然,应用可以只请求当前的选择。

使用结构体struct v4l2_format和VIDIOC_G_FMT和VIDIOC_S_FMT ioctl的组合是一个单独的用来协商所有数据格式的机制。另外VIDIOC_TRY_FMT ioctl可以用来检查不用选择新的数据格式,硬件可以干什么。V4L2 API所支持的数据格式涵盖了第四节:接口中的各种设备。图片格式请查看第二节:图片格式。

VIDIOC_S_FMT ioctl在初始化序列中是一个主要的转折点。在多个panel程序通过同一个设备同时选择当前输入之前,改变控制或者修改其他的属性。第一个VIDIOC_S_FMT会为分别为文件句柄分配一个逻辑流(视频数据、VBI数据等)。

特别是其他应用程序,精确的说是没有其他的文件句柄可以劫持这个流或者将设备属性改变为其他协商参数。一个视频的标准改变,比如使用一个新的标准扫描不同的行号,会导致所选择的图片格式无效。所以只有拥有流的文件句柄可以做无效修改。考虑到多个文件句柄持有不同的逻辑流,那么要阻止他们互相干涉各自的设置。比如,当视频overlay将要开始或已经开始后,同时视频捕捉同样的裁剪和图像尺寸就是被限制的。

当应用程序省去VIDIOC_S_FMT ioctl就暗示他的效果在下一步产生,通过VIDIOC_REQBUFS ioctl选择IO方法或通过第一次的read()或write()。

通常情况下一个逻辑流只能被分配给一个文件句柄,例外是当驱动通过兼容的V4L或早期版本的V4L2同时授权视频捕捉和overlay使用同样的文件句柄。

所有能够与应用程序交换数据的驱动必须支持VIDIOC_G_FMT和VIDIOC_S_FMT ioctl。VIDIOC_TRY_FMT是强烈推荐的,但是可选。


图像格式列举

作为通用格式协商功能,视频捕捉、overlay或输出设备支持一个特殊的ioctl来列举所有图片格式。

能够与应用程序交换图片数据的驱动必须支持VIDIOC_ENUM_FMT ioctl。


重点

驱动并不应该在内核空间完成图像格式的转换。他们必须列举出硬件能够直接支持的有哪些格式。如果有必要,驱动书写者应该发布一个转换例程或库。


单一与多平面API


一些设备为视频帧输入或输出申请的数据可能被放置在不连续的内存空间中。正因为这样,一个视频帧不得不被寻址在一个或多个内存地址中,比如一个平面一个指针。一个平面是当前帧的子缓冲。类似这样的格式请看第二节:图像格式。

首先,V4L2 API并不支持多平面缓冲以及一套延伸机制来处理他们。这些延伸组成的就是可以被认为是多平面的API。

一些V4L2 API调用和结构的解释不一,这主要取决于使用的是单平面还是多平面。应用程序可以根据ioctl调用选择不同的方法来匹配对应的缓冲格式。多平面版本的缓冲类型有“_MPLANE”这样的后缀。可以通过枚举v4l2_buf_type来查看有效的多平面缓冲类型。


多平面格式

多平面API介绍了一些新的多平面格式。这些格式使用了一套分离自FourCC的代码。区分多平面API和一个多平面格式是很重要的。多平面API调用可以很好的处理所有单一平面格式(自动他们被融入了多平面API结构体后),而单平面API就不能处理多平面格式。


区分单一和多平面API的调用

  • VIDIOC_QUERYCAP
    两个多平面添加到一起。他们会被放到一起作为非多平面格式,这样单一格式和多平面格式就都可以处理。
  • VIDIOC_G_FMT VIDIOC_S_FMT VIDIOC_TRY_FMT
    有两个新添加的用来描述多平面格式的结构体:struct v4l2_pix_format_mplane和v4l2_plane_pix_format。驱动可以定义新的多平面格式,这个格式可以和现存的来自FourCC代码的的单一平面那些截然不同。

  • VIDIOC_QBUF VIDIOC_DQBUF VIDIOC_QUERYBUF
    一个新的描述平面的结构体struct v4l2_plane。这个结构体的集合在struct v4l2_buffer的m.plane成员中。

  • VIDIOC_REQBUFS
    会申请多平面缓冲区。

你可能感兴趣的:(Linux学习,开发与驱动)