转载:https://www.cnblogs.com/cumtchw/p/10224329.html
YUV数据的几种采样格式以及保存方式:
1.YUV数据的几种采样格式
4:4:4 这个不用解释了,这是每个像素占三个字节的内存.
4:2:2 Y0U0V0 Y1U1V1 Y2U2V2 Y3U3V3对于这四个像素,采样之后存放的码流为:Y0U0 Y1V1 Y2U2 Y3V3,占用的内存大小为4+4/2 +4/2=8
4:2:0并不意味着只有Y和U而没有V,他指的是对于每行扫描线来说,只有一种色度分量以2:1的抽样率存储,相邻的扫描行存储不同的色度分量,也就是说,如果一行是4:2:0的话,下一行就是4:0:2, 对于[Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3] [Y4 U4 V4] [Y5 U5 V5] [Y6 U6 V6] [Y7U7 V7] 。采样之后存放的码流为Y0 U0 Y1 Y2 U2 Y3 Y4 V4 Y5 Y6 V6 Y7. 占用的内存是widthheight3/2.
2.YUV数据的几种保存格式
通常有两大类,打包格式和平面格式,打包格式是指将YUV保存在一个数组里面,然后YUV交叉存放,平面格式是指将YUV分量分别保存在三个不同的数组中.
YUV422
对于YUV422来说,有三种保存方式分别是平面,半平面和交叉方式.
注意422交叉存放时的顺序是UYVY.
YUV420
420是应该是没有交叉模式的,只有平面模式和半平面模式.
HISI获取的YUV数据格式是YUV420的,保存格式一般是NV12或者NV21,就是UV交叉存放的那种。
对于YUV420SP的格式来说,从上图可以看到,对于第i行j列的像素来说(i的范围是0 ~ width-1,j的范围是0 ~ height-1),
他的y数据指针就是 i*width + j ; i j 都是从0开始。
他的u数据指针是:width*height + (i/2) *width + (j/2)*2
他的V数据是:width*height + (i/2) *width + (j/2)*2 + 1
注意,上面的widthheight是指一帧图像的大小,假设是8 X 4 的图像,就是8(width) 4(height)。
还有就是,上面图片是以矩阵的形式展示了的,为了方便分清楚。而时间以文件的形式存放的话,他是连续存储的,第一行的最后一个数据的地址,接第二行的第一个数据的地址,存储的时候都是连续的空间。所以我们存放的时候是考虑,存完第一行数据后,下一个地址就是存第二行的第一个数据,以此类推。
还有,上面的图片是定义8 x 4的图像存储空间,实际我们用到的是更大的,不管图片多大,都是按上面的方式分配的,相对加大长宽而已。
数据存储的方式就是这样,先存Y,然后寸UV,所以以矩阵的形式展现数据的时候,看起来数据的大小,就是比图像原来的大小,多了UV的行数。