简单总结一下,如有疏漏劳烦指正或补充。
一.YUV420P YUV420P YUV420SP YUV420SP packed planar 等格式区别
444,422和420
444:每个Y有一个U,一个V。
422: 每两个Y有一个U,一个V。 水平方向2:1,UV缩减一半。
420: 每4个Y才有一个U和V。在422基础上,垂直方向也缩减一半。
planar、semi-Planar、packed\Interleaved格式
P:
Planar,按平面分开放,先把U存放完后,再存放V。U是连续的,V也是连续的。YYYYYUUUUUVVVVSP:
semi-Planar 半平面,只有Y数据一个平面,UV数据合用一个平面。YYYYYUVUVUV…Packed:
打包,YUV不各自成平面,而是形成YUV YUV这样的一个个包。Interleaved:
YUV全部由分开交错存放,YUV YUV YUV
个人理解Packed和Interleaved是一回事。
常用格式
- YUV422p:
-
YV16: YYYYYYYY VVVV UUUU
-
I422/YU16: YYYYYYYY UUUU VVVV
- YUV422sp:
-
NV61:YYYYYYYY VUVUVUVU
-
NV16:YYYYYYYY UVUVUVUV
- YUV420p:
-
YV12:YYYYYYYY VV UU
-
I420:YYYYYYYY UU VV
- YUV420sp:
-
NV12:YYYYYYYY UVUV
-
NV21:YYYYYYYY VUVU
二. 空间占用的示例代码
以上了解之后,大小计算就没有悬念了。
RGBA8888:长x宽x4 每点有ARGB四个量: (长x宽)x4
YUV444:长x宽x3 每点有YUV三个量: (长x宽)x3
YUV422:长x宽x2 每点有Y三个量:UV要除2,长x宽+(长x宽+长x宽)/2=长x宽x2
YUV420:长x宽x3/2 每点有Y三个量:UV要除4,长x宽+(长x宽+长x宽)/2/2=长x宽+(长x宽)/2=长x宽x3/2
typedef enum PixelFmt
{
PIXEL_YUV420SP,
PIXEL_YVU420SP,
PIXEL_YUV420P,
PIXEL_YVU420P,
PIXEL_YUV422SP,
PIXEL_YVU422SP,
PIXEL_YUV422P,
PIXEL_YVU422P,
PIXEL_YUYV422,
PIXEL_UYVY422,
PIXEL_YVYU422,
PIXEL_VYUY422,
PIXEL_ARGB,
PIXEL_RGBA,
PIXEL_ABGR,
PIXEL_BGRA,
} PixelFmt;
int getFrameBitSize(int w,int h,PixelFmt fmt)
{
int pixelNum = w*h;
int frameBitSize = 0;
switch(fmt)
{
case PIXEL_YUV420SP...PIXEL_YVU420P:
frameBitSize = pixelNum*3/2;
break;
case PIXEL_YUV422SP...PIXEL_VYUY422:
frameBitSize = pixelNum*2;
break;
case PIXEL_ARGB...PIXEL_BGRA:
frameBitSize = pixelNum*4;
break;
}
return frameBitSize;
}