Android音视频【六】视频数据存储方式YUV

人间观察

这个社会很浮躁,千万不要考验人性

在视频中的数据保存和传输都是YUV数据格式。主要是为了降低数据大小,如果用argb格式的数据,1px可能需要4个字节,而用YUV可能就需要1.5个字节。

YUV简介

与RGB类似,YUV也是一种颜色编码方法,主要用于视频领域,它将亮度信息(Y)与色彩信息(UV)分离,没有UV信息一样可以显示完整的图像,只不过是黑白的,比如这样的设计解决了彩色电视机与黑白电视的兼容问题。

YUV,分为三个分量,“Y”表示的是明亮度(Luminance或Luma),也就是灰度值;而“U”和“V” 表示的则是色度(Chrominance或Chroma),作用是用于指定像素的颜色。

UV 即CbCr(C代表颜色,b代表蓝色,r代表红色)

分类

YUV格式有两大类:平面(planar)和紧凑(packed)。

对于planar的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是存储所有像素点的V,或者是先v后u

对于packed的YUV格式,每个像素点的Y,U,V是连续交替存储的。比如YUV420P 其中的P表示“紧凑”,YUV420SP 其中的SP表示“半紧凑”。

采样

主流的采样方式有三种,YUV4:4:4,YUV4:2:2,YUV4:2:0

YUV 4:4:4采样,每一个Y对应一组UV分量,一个YUV占8+8+8 = 24bits 3个字节。

YUV 4:2:2采样,每两个Y共用一组UV分量,一个YUV占8+4+4 = 16bits 2个字节。

YUV 4:2:0采样,每四个Y共用一组UV分量,一个YUV占8+2+2 = 12bits 1.5个字节。

最常见的YUV420P和YUV420SP都是基于4:2:0采样的,所以如果图片的宽为width,高为heigth,在内存中占的空间为width * height * 3 / 2,其中前width * height的空间存放Y分量,接着width * height / 4存放U分量,最后width * height / 4存放V分量。

YUV格式

常见的YUV格式有YUY2、YUYV、YVYU、UYVY、AYUV、Y41P、Y411、Y211、IF09、IYUV、YV12、YVU9、YUV411、YUV420等,Android中比较常见是YUV420分为两种:YUV420PYUV420SP。所以就先了解下YUV420PYUV420SP.

YUV420P

YUV420P是平面模式,Y , U , V分别在不同平面,也就是有三个平面,它是YUV标准格式4:2:0

为了更方便的看如下表示:

YUV420P-YU12格式.png

为了说明存储方式,每一组用不同的颜色表示。每一种颜色是一组,每四个Y共用一组UV分量,比如Y1 Y2 Y7 Y8 U1V1 Y3 Y4 Y8 Y10 U2V2

那么真实的在字节流中就是按照行从左到右一行一行的拼起来的:


yuv-stream.png

YUV420P分为:YU12和YV12

YU12格式

在Android中也叫作I420格式,首先是所有Y值,然后是所有U值,最后是所有V值。比如6x6的图片,内存大小就是6x6x3/2=54个字节。为了更清晰的查看,我们换行看,真实的是一行byte[]数据流。

YYYYYY
YYYYYY
YYYYYY
YYYYYY
UUUUUU
VVVVVV

YV12格式

YV12格式与YU12基本相同,首先是所有Y值,然后是所有V值,最后是所有U值。比如6x6的图片,内存大小就是6x6x3/2=54个字节

YYYYYY
YYYYYY
YYYYYY
YYYYYY
VVVVVV
UUUUUU

YUV420SP

YUV420SP 也是是平面模式。分为NV21和NV12两种格式。Y是一个平面,UV是一个平面,UV/VU为交替存储,而不是分为三个平面。

在Android Camera中文档中强烈推荐使用NV21YV12,因为这两种格式支持所有的相机设备。Camera默认输出YUV的数据格式为NV21。但是在Camera2中,推荐使用的格式则是YUV_420_888

ImageFormat.NV21 注释

YCrCb format used for images, which uses the NV21 encoding format.
This is the default format for android.hardware.Camera preview images, when not otherwise set with android.hardware.Camera.Parameters.setPreviewFormat(int).
For the android.hardware.camera2 API, the YUV_420_888 format is recommended for YUV output instead.

Camera.Parameters预览参数设置setPreviewFormat 注释

Sets the image format for preview pictures.
If this is never called, the default format will be ImageFormat.NV21, which uses the NV21 encoding format.
Use getSupportedPreviewFormats to get a list of the available preview formats.
It is strongly recommended that either ImageFormat.NV21 or ImageFormat.YV12 is used, since they are supported by all camera devices.

为了更方便的看如下表示,真实的在字节流中就是按照行从左到右一行一行的拼起来的。


YUV420SP-NV21格式.png

NV21格式

在Android Camera中手机从摄像头采集的预览数据默认值是NV21。

NV21存储顺序是先存Y值,再VU交替存储:YYYYVUVUVU,比如6x6的图片,内存大小就是6x6x3/2=54个字节

YYYYYY
YYYYYY
YYYYYY
YYYYYY
VUVUVU
VUVUVU

NV12格式

NV12存储顺序是先存Y值,再UV交替存储:YYYYUVUVUV,比如6x6的图片,内存大小就是6x6x3/2=54个字节

YYYYYY
YYYYYY
YYYYYY
YYYYYY
UVUVUV
UVUVUV

这里先熟悉下Android中常见的YUV420PYUV420SP。一般我们在使用yuv数据的时候,会对yuv数据进行变换,比如:摄像头数据旋转,从一种格式转为另一种数据等。

你可能感兴趣的:(Android音视频【六】视频数据存储方式YUV)