视频直播YUV颜色格式完全解析
--解决MediaCodec与Camera颜色空间不匹配导致的花屏、叠影等问题
作者: |
蒋东国 |
时间: |
2017年4月5日 星期三 |
应用来源: |
zbj 测试:华为nova |
博客地址: |
http://blog.csdn.net/andrexpert/article/details/69267043 |
在AndroidAPI <= 20(Android5.0之前的版本)中Google支持的CameraPreview Callback的YUV常用格式有两种:一个是NV21,一个是YV12。如果我们需要对Camera采集的图像进行编码等,必须要对其进一步处理,比如格式转换、旋转等操作,否则会出现一些花屏、叠影等问题。
1. YUV简介
YUV是一种亮度信号Y和色度信号U、V是分离的色彩空间,它主要用于优化彩色视频信号的传输,使其向后相容老式黑白电视。与RGB视频信号传输相比,它最大的优点在于只需占用极少的频宽(RGB要求三个独立的视频信号同时传输)。其中“Y”表示明亮度(Luminance或Luma),也就是灰阶值;而“U”和“V”表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。使用YUV的优点有两个:
(1) 彩色YUV图像转黑白YUV图像转换非常简单,这一特性用在于电视信号上;
(2) YUV是数据总尺寸小于RGB格式;
2. YUV与RGB区别
YUV的存储中与RGB格式最大不同在于,RGB格式每个点的数据是连继保存在一起的。即R,G,B是前后不间隔的保存在2-4byte空间中。而YUV的数据中为了节约空间,U,V分量空间会减小。每一个点的Y分量独立保存,但连续几个点的U,V分量是保存在一起的,通常人的肉眼察觉不出。
3. YUV格式分析
YUV格式分为两种类型:Packed类型和Planar类型。其中,Packed类型是将YUV分量存在在同一个数组中,每个像素点的Y、U、V是连续交错存储的;Planar类型是将YUV分量分别存放到三个独立的数组中,且先连续存储所有像素点的Y,紧接着存储所有像素点的U,最后是所有像素点的V。
(1) YUV采样格式
YUV码流的存储格式与采样方式密切相关,目前主流的采样方式有如下三种:YUV444、YUV422、YUV420,其中,YUV444采样是每一个Y对应一组UV分量,每个像素(YUV)占32Bits;YUV422采样是每两个Y共用一组UV分量,每个像素占16bits(Y占8bits、UV分量占8bits);YUV420采样是每四个Y共用一组UV分量,每个像素(YUV)占16bits或者12bits。通常,YUV A:B:C的意思一般是指基于4个象素来讲,其中Y采样了A次,U采样了B次,V采样了C次。假设以黑点表示采样该像素点的Y分量,以空心圆圈表示采用该像素点的UV分量,三种采样格式表示如下图:
a) YUV444:YUV444即表示Y、U、V所占比为4:4:4,这种采样方式的色度值UV不会较少采样,Y、U、V分量各占一个字节,连同Alpha通道一个字节,YUV444每个像素占4字节,也就是说这个格式实质就是24bpp的RGB格式。采样示例:
如果原始数据四个像素是:A0Y0 U0 V0 ,A1 Y1 U1 V1,A2 Y2 U2 V2,A3 Y3 U3 V3
经过4:4:4采样后,数据仍为:A0Y0 U0 V0 ,A1 Y1 U1 V1,A2 Y2 U2 V2,A3 Y3 U3 V3
b) YUV422:YUV422即表示Y、U、V所占比为4:2:2,这种采样方式的色度值UV分量采样减半,比如第一个像素采样为Y、U,第二个像素采样Y、V,依此类推…YUV422每个像素占2个字节。采样示例:
如果原始数据四个像素是:Y0U0 V0 ,Y1 U1 V1,Y2 U2 V2,Y3 U3 V3
经过4:2:2采样后,数据变成