YUV
YUV(亦称YCrCb)是三个分量,Y是亮度信息,U,V是色度信号。如果只有Y,那么电视播放出来的是黑白,Y加上U,V后就是彩色电视。
这样解决黑白电视也能播放彩色电视的信号的问题。
-
ffmpeg中是如何管理这个yuv的数据的呢?
核心就是AVFrame这个结构体,成员data是个指针数组,每个成员所指向的就是yuv三个分量的实体数据了,成员linesize是指对应于每一行的大小,为什么需要这个变量,是因为在YUV格式和RGB格式时,每行的大小不一定等于图像的宽度.
===============================================================================
YUV格式
1. YUV 4:4:4采样,每一个Y对应一组UV分量8+8+8 = 24bits,3个字节。
2. YUV 4:2:2采样,每两个Y共用一组UV分量,一个YUV占8+4+4 = 16bits 2个字节。
3. YUV 4:2:0采样,每四个Y共用一组UV分量一个YUV占8+2+2 = 12bits 1.5个字节。
-
我就先说说YUV420格式吧。
YUV 4:2:0采样,即每4个Y公用一组UV分量。如下图:
因为一个Y分量对应一个像素点,所以若该图片的宽为width, 高为height,那么Y就等于(width * height),同理U就等于(Y / 4), V也等于(Y / 4)。那么这个YUV图片在内存中的长度就为:Y + Y/4 + Y/4 = (Y * 3) / 2 = (width * height*3) / 2
-
FFmpeg视频解码后,一般存储为AV_PIX_FMT_YUV420P 的format,而解码后的数据存储在结构体 AVFrame 中。YUV420P在内存中的排布如下:
YYYYYYYYYY UUUU VVVV
-
yuv420p在AVFrame中的存储格式:
planar YUV 4:2:0, (1 Cr & Cb sample per 2x2 Y samples)
即存储在结构体 AVFrame 的data[ ]数组中 ,
data[0]——-Y分量
data[1]——-U分量
data[2]——-V分量linesize[]数组中保存的是对应通道的数据宽度
linesize[0]——-Y分量的宽度
linesize[1]——-U分量的宽度
linesize[2]——-V分量的宽度 -
YUV格式有两大类:planar和packed。
对于packed的YUV格式,每个像素点的Y,U,V是连续交叉存储的。
对于planar的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V。
特别注意,linesize[0]的值并不一定等于图片的宽度,有时候为了对齐各解码器的CPU,实际尺寸会大于图片的宽度,这点在我们编程时(比如OpengGL硬件转换/渲染)要特别注意,否则解码出来的图像会异常。