v4l2文档之——color and format【转】

转自:https://blog.csdn.net/zoe6553/article/details/17715407

v4l2文档第五A--颜色与格式 
  颜色与格式这是不定期发布的关于写视频驱动程序的LWN系统文章的第五篇.没有看过介绍篇的,也许想从这里 开始。
  应用在可以使视频设备工作之前,它必须与驱动达成了解,知道视频数据是何种格式的。这种协商将是一个非常复杂的过程,其原因有二:1、视频硬件所支持的视 频格互不相同。2、在内核的格式转换是令人难以接受的。所以应用在找出一种硬件支持的格式,并做出一种大家都可以接受的配置。这篇文章将会讲述格式的基本 描述方式;下期文章则会讲述V4L2驱动与应用协商格式时所实现的API。

1、色域 
  色域在广义上来讲,就是系统在描述色彩时所使用的坐标。V4L2规范中定义了好几个,但只有两个使用最为广泛。它们是:
   •V4L2_COLORSPACE_SRGB.多数开发者所熟悉的[red,green,blue]数组包含在这个色域之中。它为每一种颜色提供了一个简 单的强度值,把它们混合在一起,从而产生了一种广泛的颜色的效果。表示RGB值的方法有很多,我们在下面将会有所介绍。 
这个色域也包含YUV和YCbCr的表示方法,这个表示方法最早是为了早期的彩色电视信号可以在黑白电视中的播放,所以Y(或说亮度)值只是一个简单的亮 度值,单独播放时可以产生灰度图像。U和V(或Cb和Cr)色度值描述的是色彩中蓝色和红色的分量。绿色可以通过从亮度中减去这些分量而得到。YUV和 RGB之间的转换并不简单,但是我们有一些成形的公式 可选。
注意:YUV和YCbCr并非完成一样,虽然有时他们的名字会替代使用。
   •V4L2_COLORSPACE_SMPTE170M 这个是NTSC或PAL等电视信号的模拟色彩表示方法,电视调谐器通常产生的色域都属于这个色域。 
还存在很多其他的色域,他们多数都是电视相关标准的变种。点击查看V4L2规范 中的详细列表。
2、密集存储和平面存储
  如汝所见,像素值是以数组的方式表示的,通常由RGB或YUV值组成。要把这数组组织成图像,通常有两种常用的方法。
  •Packed 格式把一个像素的所有值存领教在一起.
  •Planar 格式把每一个分量单独存储成一个阵列,这样在YUV格式中,所有Y值都连续地一起存储在一个阵列中,U值存储在另一个中,V值存在第三个中.这些平面常常都存储在一个缓冲区中,但并不一定非要这样. 
紧密型存储方式可能使用更为广泛,特别是RGB格式,但这两种存储方式都可以由硬件产生并由应用程序请求。如果设备可以产生紧密型和平面型两种,那么驱动就要让两种都在用户空间可见。

3、四字符码(four Charactor Code:FourCC)
V4L2 API中表示色彩格式采用的是广受好评的四字符码(fourcc)机制。这些编码都是32位的值,由四个ASCII码产生。如此一来,它就有一个优点就是,易于传递,对人可读。当一个色彩格式读作,例如,”RGB4″就没有必要去查表了。
  注意:四字符码在很多不同的设定中都会使用,有些还是早于linux的.Mplayer中内部使用它们,然而,fourcc只是说明一种编码机制,并不说 明使用何种编码。Mplayer有一个转换函数,用于在它自己的fourcc码和v4l2用的fourcc码之间做出转换。
4、RGB格式
在下面的格式描述中,字节是按存储顺序列出的。在小端模式下,LSByte在前面。每字节的LSbit在右侧。每种色域中,轻阴影位是最高有效的。


当使用有空位(上图中灰色部分)的格式 , 应用可以使用空位作alpha(透明度)值.
上面的最后一个格式是”Bayer”格式,此格式与多数摄像机感光器所得到的真实数据非常接近。每个像素都有绿色分量,但蓝和红只是隔一个 像素才有分量。本质上讲,绿色带有更重的强度信息,而蓝红色则在丢失时以相隔像素的内插值替换。这种模式我们交在YUV格式中再次见到。
5、YUV格式
YUV的紧密型模式在下面首先展示,看表的关键处如下:


  
也有几中平面型的YUV格式在用,但把它们全画出来并没有什么大的帮助,所以我们只是在下面举一下例子,常用”YUV 4:2:2″(V4L2_PIX_FMT_YUV422, fourcc422P)格式使用三组阵列,一幅4X4的图片将如下表示:


 
对于Bayer格式, YUV 4:2:2 每隔一个Y值有一个U和一个V值,展示图像需要以内插值替换的丢失的值。
其他的平面YUV格式有:
•V4L2_PIX_FMT_YUV420: YUV 4:2:0格式,每四个Y值才有一个U值一个V值.U和V都要在水平和垂直两个方向上都以内插值替换.平面是以Y-U-V的顺序存储的,与上面的例子一致. 
•V4L2_PIX_FMT_YVU420: 与YUV 4:2:0格式类似,只是U,V值调换了位置. 
•V4L2_PIX_FMT_YUV410: 每16个Y值才有一个U值和V值.阵列的顺序是 Y-U-V. 
•V4L2_PIX_FMT_YVU410: 每16个Y 值才有一个U值和V值.阵列的顺序是Y-V-U.
 
6、其他格式
还有一些可能对驱动有用的格式如下:
•V4L2_PIX_FMT_JPEG: 一种定义模糊的JPEG流;更多信息请看这里 . 
•V4L2_PIX_FMT_MPEG: MPEG流.还有一些MPEG流格式的变种;未来的文章中将讨论流的控制。
还有一些其他的混杂的格式,其中一些还是有传利保护的;这里 有一张列表.

7、格式的描述
现在我们己经了解了颜色的格式,下面将要看看下V4L2 API中是如何描述图像格式的了。这里的主要的结构体是struct v4l2_pix_format (定义于<linux/videodev2.h>),它包含如下字段:

•__u32 图片宽度,以像素为单位. 
•__u32 height:图片高度,以像素为单位. 
•__u32 pixelformat: 描述图片格式的四字符码. 
•enum v4l2_field field:很多图片的源会使数据交错 -先传输奇数行,然后是偶到行.真正的摄像头设备是不会做数据的交错的。 V4L2 API 允许应用使用很多种方式交错字段.常用的值为V4L2_FIELD_NONE (字段不交错),V4l2_FIELD_TOP (只交错顶部字面),或V4L2_FIELD_ANY (无所谓)。 
•__u32 bytesperline: 相临扫描行之间的字节数.这包括各种设备可能会加入的填充字节.对于平面格式,这个值描述的是最大的 (Y) 平面. 
•__u32 sizeimage: 存储图片所需的缓冲区的大小. 
•enum v4l2_colorspace colorspace: 使用的色域. 
加到一起,这些参数以合理而完整的方式描述了视频数据缓冲区。应用可以填充 v4l2_pix_format 请求用户空间开发者所能想到的几乎任何格式. 然而,在驱动层面上,驱动开发者则要限制在硬件所能支持的格式上. 所以每一个 V4L2 应用都必须经历一个与驱动协定的过程,以便于使用一个硬件支持并且能滿足应用需要的图像格式。下一期文章,我们将从驱动角度,描述这种协定是什么进行的。

原文地址:https://www.cnblogs.com/sky-heaven/p/9548494.html