博客访问量日渐减少,于是我决定丢一点技术东东上去,吸引爬虫光顾一下。
先谈谈 h.264 的编解码问题。
个人建议做视频、音频的孩子们,一定要抓住 RFC 和 standard ,然后多看开源编解码程序。
近来抽空看了两个 decoder ,一个是从 ffmpeg 里面抽取出来的 h.264 部分,还有从 JM 。
解码器生成最后结果是 yuv420 格式(后面会提到)。
关于 yuv ,看到论坛里不少人都急于找工具去看自己解得一帧图像是否正确,更有不少人提供 yuv420 2 rgb24 和 yuv422 2 rgb24 等代码。
这里建议使用 强大的 ps 的 .raw 文件的功能。
.raw 文件可用来查看 纯 rgb 图片 和 纯 yuv 图片,很适合做图像。
yuv 格式:
YUV是指亮度参量和色度参量分开表示的像素格式,而这样分开的好处就是不但可以避免相互干扰,还可以降低色度的采样率而不会对图像质量影响太大。YUV 是一个比较笼统地说法,针对它的具体排列方式,可以分为很多种具体的格式。
YUV格式通常有两大类:打包(packed)格式和平面(planar)格式。前者将YUV分量存放在同一个数组中,通常是几个相邻的像素组成一个宏像 素(macro-pixel);而后者使用三个数组分开存放YUV三个分量,就像是一个三维平面一样。
YUY2到Y211都是打包格式,而IF09到YVU9都是平面格式。
(注意:在介绍各种具体格式时,YUV各分量都会带有下标,如Y0、 U0、V0表示第一个像素的YUV分量,Y1、U1、V1表示第二个像素的YUV分量,以此类推。)
yuv采样:
• | 4:4:4 表示色度频道没有下采样。每像素 24 位 |
• | 4:2:2 表示 2:1 的水平下采样,没有垂直下采样。对于每两个 U 样例或 V 样例,每个扫描行都包含四个 Y 样例。每像素 16 位 |
• | 4:2:0 表示 2:1 的水平下采样,2:1 的垂直下采样。每像素 16 位 |
• | 4:1:1 表示 4:1 的水平下采样,没有垂直下采样。对于每个 U 样例或 V 样例,每个扫描行都包含四个 Y 样例。与其他格式相比,4:1:1 采样不太常用,本文不对其进行详细讨论。每像素 16 位 |
在我做的 h264 中,支 持4:2:0的连续或隔行视频的编码和解码。
其中“Y”表示明亮度(Luminance或Luma),也就是灰阶值;而“U”和“V”表示的则是色度(Chrominance或Chroma),作用 是描述影像色彩及饱和度,用于指定像素的颜色。“亮度”是通过RGB输入信号来创建的,方法是将RGB信号的特定部分叠加到一起。“色度”则定义了颜色的 两个方面—色调与饱和度,分别用Cr和CB来表示。其中,Cr反映了GB输入信号红色部分与RGB信号亮度值之间的差异。而CB反映的是RGB输入信号蓝 色部分与RGB信号亮度值之同的差异。
常见H264测试的YUV序列:
CIF图像大小的YUV序列(352*288),在文件 开始并没有文件头,直接就是YUV数据,先存第一帧的Y信息,长度为352*288个byte, 然后是第一帧U信息长度是352*288/4个byte, 最后是第一帧的V信息,长度是352*288/4个byte, 因此可以算出第一帧数据总长度是352*288*1.5,即152064个byte, 如果这个序列是300帧的话, 那么序列总长度即为152064*300=44550KB,这也就是为什么常见的300帧CIF序列总是44M的原因.
IYUV格式(planar)为每个像素都提取Y分量,而在UV分量的提取时,首先将 图像分成若干个2 x 2的宏块,然后每个宏块提取一个U分量和一个V分量。YV12格式与 IYUV类似,但仍然是平面模式。
YUV411、YUV420格式多见于DV数据中。
YUV411用于NTSC制。为每个像素都提取Y分量,而UV分量在水平方向上每4个像素采样一次。
YUV420用于 PAL制。并非V分量采样为0,而是跟YUV411相比, 在水平方向上提高一倍色差采样频率,在垂直方向上以U/V间隔的方式减小一半色差采样。
各种格式的具体使用位数的需求(使用4:2:0采样,对于每个元素用8个位大小表示):
格式: Sub-QCIF 亮度分辨率: 128*96 每帧使用的位: 147456
格式: QCIF 亮度分辨率: 176*144 每帧使用的位: 304128
格式: CIF 亮度分辨率: 352*288 每帧使用的位: 1216512
格 式: 4CIF 亮度分辨率: 704*576 每帧使用的位: 4866048