FFmpeg In Android - Yuv格式

YUV(也称YCrCb)也是一种颜色编码方法,主要用于电视系统以及模拟视频领域,它将亮度信息(Y)与色彩信息(UV)分离,没有UV信息一样 可以显示完整的图像,只不过是黑白的,这样的设计很好地解决了彩色电视机与黑白电视的兼容问题。并且,YUV不像RGB那样要求三个独立的视频信号同时传 输,所以用YUV方式传送占用极少的频宽。
“Y”代表亮度(Luma channel), 也就是灰阶值;“U”和“V”表示的则是色度(Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色.
业界采用A:B:C的方式来表示U,V相对于Y采样值,例如 YUV 4:4:4 ,YUV 4:2:2, YUV 4:2:0

(下面图片中,交叉X代表一个Y采样, 圆圈O代表一个UV采样)

YUV 4:4:4
YUV三个信道的抽样率相同,因此在生成的图像里,每个象素的三个分量Y,U,V信息完整(每个分量通常8比特),经过8比特量化之后,未经压缩的每个像素占用3个字节。

假设图片宽高为w * h, 每个像素点3个字节,则图片大小size = w * h * 3 ,

YUV 4:2:2
每个色差信道的抽样率是亮度信道的一半,即每2个Y,对应一个U,一个V,则未经压缩2个像素占用Y*2+U+V=4个字节

假设图片宽高为w * h, 则图片大小size = w * h / 2 * 4 = w * h * 2,

YUV4:2:0
4:2:0并不意味着只有Y,Cb而没有Cr分量。它指得是对每行扫描线来说,只有一种色度分量以2:1的抽样率存储。进行隔行扫描,相邻的扫描行存储不同的色度分量,也就是说,如果一行是4:2:0的话,下一行就是4:0:2,再下一行是4:2:0…以此类推。即每4个Y,对应一个U,一个V,则未经压缩4个像素占用Y*4+U+V=6个字节

假设图片宽高为w * h, 则图片大小size = w * h / 4 * 6 = w * h * 3 / 2 = w * h * 1.5

上面只是逻辑布局,但作为码农更想知道他们的物理布局(存储方式),因为要读取数据。这要先了解两个概念:packed(打包模式)和planar(平行模式). 对于packed打包模式,Y,U,V都存储在一个单独数组,其布局取决于格式。对于planar平行模式,Y, U, V分开存储.

FFmpeg YUV420中,AVFrame->data[0]专门存Y,data[1]专门存U,data[2]专门存V。而packed则是打包,所有数据都存在data[0]中,而data[1]和data[2]都为NULL。
具体哪个格式是planar,哪个格式是packed,可以查看pixfmt.h文件。注:有些格式名称后面是LE或BE,分别对应little-endian或big-endian。另外名字后面有P的是planar格式。

在前面的例子(链接)中,运行avpicture_fill后,data[0]将指向buff的开始位置,即data[0]等于buff。data[1]指向buff数组的某一个位置(该位置为U分量的开始处),data[2]也指向buff数组某一个位置(该位置为V分量的开始处)。
有些网友说到,对于planar模式,需要分开读取和写的。其实,无论是planar还是packed模式,在用acpicture_fill函数处理后,都可以用下面的方法把一张图像的数据读取到AVFrame中,而不需要分别读data[0]、data[1]、data[2]。因为对于图像文件来说,如果是plannar模式的图像格式,其存储必然是先存完一张图像所有的所有Y、紧接着再存一张图像的所有U、紧接着存一张图像的所有V。这刚好和data数组的三个指针的对应的。
fread(frame->data[0], 1, bytes_num, fin);
同样对于写图像也是如此。无需分data[0]、data[1]、data[2]。

这里主要说明linesize这个成员的含义。
YUV格式中有一个很重要的等量关系,那就是有多少个像素就有多少个y。
linesize正如其名,一条线(即一行)的大小。对于yuv420p。data[0]存放的是y,对应地linesize[0]就
指明一行有多少个y。对于352*288的图像,一行有352个像素。根据刚才的等量关系。那么linesize[0]就
应该为352.即一行有352个y。对于linesize[1],因为data[1]存放的是u。而一行352个像素在yuv420p格式中,
其只需352/2,即176个。所以linesize[1]的大小为176。同理linesize[2]也为176。

转:RGB、YUV和HSV颜色空间模型
转:YUV(一)-数据格式分析
转:Video Rendering with 8-Bit YUV Formats
转:FFMPEG 实现 YUV,RGB各种图像原始数据之间的转换(swscale
转:YUV格式详细解释与FFMPEG的关系
转:图像视频编码和FFmpeg(2)-----YUV格式介绍和应用

猜你喜欢

转载自blog.csdn.net/kingdam578/article/details/83384751