IOS 视频格式之YUV

YUV简介

yuv格式是一种图片储存格式,跟RGB格式类似。yuv中,y表示亮度(Luminance或Luma),单独只有y数据就可以形成一张图片,只不过这张图片是灰色的。u和v表示色度(Chrominance或Chroma)(u和v也被称为:Cb-蓝色差,Cr-红色差),作用是描述影像色彩及饱和度,用于指定像素的颜色。最早的电视信号,为了兼容黑白电视,采用的就是yuv格式。一张yuv的图像,去掉uv,只保留y,这张图片就是黑白的。yuv可以通过抛弃色差来进行带宽优化。比如yuv420格式图像相比RGB来说,要节省一半的字节大小,抛弃相邻的色差对于人眼来说,差别不大。

YU(Cb)V(Cr)存储格式

YUV码流的存储格式与其采样方式密切相关,像素采集主要有以下三种方式:
  • YUV4:4:4:每一个Y对应一组UV分量8+8+8 = 24bits,3个字节。
  • YUV4:2:2:每两个Y共用一组UV分量,一个YUV占8+4+4 = 16bits, 2个字节。
  • YUV4:2:0:每四个Y共用一组UV分量一个YUV占8+2+2 = 12bits , 1.5个字节。
但是如何如何根据其采样格式从码流中还原每个像素点的YUV值呢,因为只有正确的还原了每个像素点的YUV值,才能将YUV与RGB的转换公式提取出每个像素点的RGB值进而显示出来。如果我们用黑点表示采样该像素点的Y分量,以空心圆圈表示采用该像素点的UV分量,则三种采样方式可由下图来表示:


存储格式.png

IOS系统定义视频格式规则

kCVPixelFormatType_{长度|序列}{颜色空间}{Plannar|BiPlanar}{VideoRange|FullRange}
说明:
  • 长度:表示bit长度;其中
yuv格式图像占用字节数为 :size = width * height + (width * height) / 4 + (width * height) / 4 = width * height * 1.5;
RGB24格式图像占用字节数为:size = width * height * 3;
RGB32 和 RGBA格式的图像占用字节数为:size = width * height * 4;
  • 颜色空间:即内存中的顺序。这里注意区分是大端模式(BE)还是小端模式(LE);比如
BGRA:kCVPixelFormatType_32BGRA,内存中的顺序是 B G R A B G R A...。

YUV420p:又叫planer平面模式,Y、U、V分别在不同的平面,也就是三个平面;

YUV420p数据格式.png

分为以下两种:
I420格式(又叫YU12,安卓的模式):y,u,v 3个部分分别存储:Y0,Y1…Yn,U0,U1…Un/2,V0,V1…Vn/2。
YV12:存储顺序是先存储完所有的Y,后面紧跟着存V,V的步长(也就是宽)是Y的步长的一半,V的行高是Y的一半。V存储完后面紧跟着存U,所有的U,步长河行高和V相同,也就是都是Y的一半。即:YYYVVVUUU。
YV12.png

YUV420sp, 又叫bi-planer或two-planer双平面,Y一个平面,UV在同一个平面交叉存储。


yuv420sp数据格式.png

有以下两种格式,区别是UV的顺序不一样:
NV12格式:IOS只有这一种模式,y和uv 2个部分分别存储:Y0,Y1…Yn,U0,V0,U1,V1…Un/2,Vn/2


NV12.png

NV21格式:安卓的模式,同NV12,只是U和V的顺序相反:Y0,Y1…Yn,V1…Un/2,Vn/2,U0,V0,U1。
  • Plannar :表示平面存储,uv分开存储;BiPlanar表示双平面,uv占用相同的空间;这两种格式主要应用在yuv图片上;
kCVPixelFormatType_420YpCbCr8PlanarFullRange是420p,kCVPixelFormatType_420YpCbCr8BiPlanarFullRange是nv12.
  • 颜色范围:VideoRange 和 FullRange 的区别在于数值的范围。FullRange比VideoRange的范围要大一些,颜色也会更更富一些。如果没有指定颜色范围,默认都是FullRange。比如:
kCVPixelFormatType_32BGRA = 'BGRA', 输出的是BGRA的格式。
kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange= '420v' 是 nv12,只是范围是范围: (luma=[16,235] chroma=[16,240]);上面我们说的kCVPixelFormatType_420YpCbCr8BiPlanarFullRange = '420f',表示输出的视频格式为NV12;范围: (luma=[0,255] chroma=[1,255])。但有一个除外:kCVPixelFormatType_420YpCbCr8Planar。因为有一个kCVPixelFormatType_420YpCbCr8PlanarFullRange定义,所以kCVPixelFormatType_420YpCbCr8Planar理论上应该是VideoRange。
特别提示:
我们可以通过 CVPixelBufferGetPlaneCount(pixel)来获取平面数量,发现kCVPixelFormatType_420YpCbCr8Planar(y420)和kCVPixelFormatType_420YpCbCr8PlanarFullRange(f420)是三个两面,属于420p,iOS不支持。IOS硬解码器只支持NV12也就是YUV420中的一种。

推荐阅读更多精彩内容