ffmpeg入门--YUV格式

YUV


YUV(亦称YCrCb)是三个分量,Y是亮度信息,U,V是色度信号。如果只有Y,那么电视播放出来的是黑白,Y加上U,V后就是彩色电视。
这样解决黑白电视也能播放彩色电视的信号的问题。

  • ffmpeg中是如何管理这个yuv的数据的呢?

    核心就是AVFrame这个结构体,成员data是个指针数组,每个成员所指向的就是yuv三个分量的实体数据了,成员linesize是指对应于每一行的大小,为什么需要这个变量,是因为在YUV格式和RGB格式时,每行的大小不一定等于图像的宽度.

===============================================================================

YUV格式


1. YUV 4:4:4采样,每一个Y对应一组UV分量8+8+8 = 24bits,3个字节。
2. YUV 4:2:2采样,每两个Y共用一组UV分量,一个YUV占8+4+4 = 16bits 2个字节。
3. YUV 4:2:0采样,每四个Y共用一组UV分量一个YUV占8+2+2 = 12bits 1.5个字节。

  • 我就先说说YUV420格式吧。
    YUV 4:2:0采样,即每4个Y公用一组UV分量。如下图:
    在这里插入图片描述
    因为一个Y分量对应一个像素点,所以若该图片的宽为width, 高为height,那么Y就等于(width * height),同理U就等于(Y / 4), V也等于(Y / 4)。

    那么这个YUV图片在内存中的长度就为:Y + Y/4 + Y/4 = (Y * 3) / 2 = (width * height*3) / 2

  • FFmpeg视频解码后,一般存储为AV_PIX_FMT_YUV420P 的format,而解码后的数据存储在结构体 AVFrame 中。YUV420P在内存中的排布如下:

    YYYYYYYYYY UUUU VVVV

  • yuv420p在AVFrame中的存储格式:

    planar YUV 4:2:0, (1 Cr & Cb sample per 2x2 Y samples)

    即存储在结构体 AVFrame 的data[ ]数组中 ,

    data[0]——-Y分量
    data[1]——-U分量
    data[2]——-V分量

    linesize[]数组中保存的是对应通道的数据宽度

    linesize[0]——-Y分量的宽度
    linesize[1]——-U分量的宽度
    linesize[2]——-V分量的宽度

  • YUV格式有两大类:planar和packed。
    对于packed的YUV格式,每个像素点的Y,U,V是连续交叉存储的。
    对于planar的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V。

特别注意,linesize[0]的值并不一定等于图片的宽度,有时候为了对齐各解码器的CPU,实际尺寸会大于图片的宽度,这点在我们编程时(比如OpengGL硬件转换/渲染)要特别注意,否则解码出来的图像会异常。

视频存储格式YUV420 NV12 NV21 i420

猜你喜欢

转载自blog.csdn.net/qq_41498261/article/details/84330493