zl程序教程

您现在的位置是:首页 >  其他

当前栏目

YUV格式与RGB的转换

转换 格式 rgb YUV
2023-09-27 14:27:15 时间

前言

YUV与RGB是两种不同的颜色空间,视频一般都用YUV来进行存储,因为相同分辨率的视频RGB占用空间为YUV420的1.5倍

YUV的采样方式

YUV根据采样方式的不同,其占用大小也不一样,主流有如下三种

  • YUV444
    每一个Y对应一组UV分量,即:一个YUV占8+8+8 = 24bits,3个字节。
  • YUV422
    每两个Y共用一组UV分量,即:一个YUV占8+4+4 = 16bits 2个字节。
  • YUV420
    每四个Y共用一组UV分量,即:一个YUV占8+2+2 = 12bits 1.5个字节。

YUV420的分类

因为YUV420占用空间最小,所以目前主流都是使用的YUV420方式,它根据存储方式的不同又分为YUV420P和YUV420SP两种
1、YUV420P
称为planer平面模式,Y ,U,V分别位于三个不同平面。一般在内存中按照如下方式存储:YYYY.....U......V.......或者YYYY.....V......U.......;

  • I420:又叫YU12,是按照YUV顺序存储的,安卓摄像头视频录制的视频就支持这种存储方式
    存储方式为:亮度(行×列) + U(行×列/4) + V(行×列/4)
  • YV12:是按照YVU的顺序存储的
    存储方式为:亮度(行×列) + V(行×列/4) + U(行×列/4)

planner格式的YUV420拿到每一个YUV像素的伪代码为(C语言):

 


2、YUV420SP
称为双-planner平面模式,用两个平面存储YUV,其中Y存储于一个平面,UV存储于另一个平面。一般在内存中按照如下方式存储:YYYY........U......V.......或者YYYY........UVUV.......

  • NV12:存储顺序是先存Y,再UV交替存储。YYYYUVUVUV;iOS系统采用此种方式
    存储方式为:亮度(行×列) + UV(行×列/2)
  • NV21:存储顺序是先存Y,再存U,再VU交替存储。YYYYVUVUVU;按照系统采用此种方式
    存储方式为:亮度(行×列) + VU(行×列/2)
    双-planner平面模式分离出YUV的伪代码为(C语言,以NV12为例):

 

// 这里代表 y和uv的数据内存块
uint_8 *ybuf,uvbuf;
// 代表视频的宽高
int width,height;
for(int y = 0; y < height; y++) {
    uint8_t *yBufferLine = ybuf+y * width;
    // y/2能保证每四个YYYY对应一组uv
    uint8_t *cbCrBufferLine = uvbuf + (y >> 1) * width;
    for(int x = 0; x < width; x++) {
        uint_8 y = yBufferLine[x];
        uint_8 cb = cbCrBufferLine[x & ~1] ;
        uint_8 cr = cbCrBufferLine[x | 1];
    }
}