zoukankan      html  css  js  c++  java
  • YUV数据YUY2到I420

    /*

    主要的采样格式有YCbCr 4:2:0、YCbCr 4:2:2、YCbCr 4:1:1和 YCbCr 4:4:4。
    其中YCbCr 4:1:1 比较常用,其含义为:每个点保存一个 8bit 的亮度值(也就是Y值),
    每 2x2 个点保存一个 Cr 和Cb 值, 图像在肉眼中的感觉不会起太大的变化。
    所以, 原来用 RGB(R,G,B 都是 8bit unsigned) 模型, 1个点需要 8x3=24 bits(如下图第一个图),
    (全采样后,YUV仍各占8bit)。按4:1:1采样后,而现在平均仅需要 8+(8/4)+(8/4)=12bits(4个点,8*4(Y)+8(U)+8(V)=48bits),
    平均每个点占12bits(如下图第二个图)。这样就把图像的数据压缩了一半。

      上边仅给出了理论上的示例,在实际数据存储中是有可能是不同的,下面给出几种具体的存储形式:

      (1) YUV 4:4:4

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

      下面的四个像素为: [Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]

      存放的码流为: Y0 U0 V0 Y1 U1 V1 Y2 U2 V2 Y3 U3 V3

      (2) YUV 4:2:2

      每个色差信道的抽样率是亮度信道的一半,所以水平方向的色度抽样率只是4:4:4的一半。
    对非压缩的8比特量化的图像来说,每个由两个水平方向相邻的像素组成的宏像素需要占用4字节内存。

      下面的四个像素为:[Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]

      存放的码流为:Y0 U0 Y1 V1 Y2 U2 Y3 V3

      映射出像素点为:[Y0 U0 V1] [Y1 U0 V1] [Y2 U2 V3] [Y3 U2 V3]

      (3) YUV 4:1:1

      4:1:1的色度抽样,是在水平方向上对色度进行4:1抽样。对于低端用户和消费类产品这仍然是可以接受的。
    对非压缩的8比特量化的视频来说,每个由4个水平方向相邻的像素组成的宏像素需要占用6字节内存。

      下面的四个像素为: [Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]

      存放的码流为: Y0 U0 Y1 Y2 V2 Y3

      映射出像素点为:[Y0 U0 V2] [Y1 U0 V2] [Y2 U0 V2] [Y3 U0 V2]

      (4)YUV4:2:0

      4:2:0并不意味着只有Y,Cb而没有Cr分量。它指得是对每行扫描线来说,只有一种色度分量以2:1的抽样率存储。
    相邻的扫描行存储不同的色度分量,也就是说,如果一行是4:2:0的话,下一行就是4:0:2,再下一行是4:2:0...
    以此类推。对每个色度分量来说,水平方向和竖直方向的抽样率都是2:1,所以可以说色度的抽样率是4:1。
    对非压缩的8比特量化的视频来说,每个由2x2个2行2列相邻的像素组成的宏像素需要占用6字节内存。

      下面八个像素为:[Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]

      [Y5 U5 V5] [Y6 U6 V6] [Y7U7 V7] [Y8 U8 V8]

      存放的码流为:Y0 U0 Y1 Y2 U2 Y3

      Y5 V5 Y6 Y7 V7 Y8

      映射出的像素点为:[Y0 U0 V5] [Y1 U0 V5] [Y2 U2 V7] [Y3 U2 V7]

      [Y5 U0 V5] [Y6 U0 V5] [Y7U2 V7] [Y8 U2 V7]

    转自:http://blog.csdn.net/yiheng_l/article/details/3789586
    */

    /*
    简单的说,YUV的格式在存储上有两类布局: Packed和Plannar。
    Packed的方式就是把相邻几个象素打包起来。比如把水平方向2个象素打包到一个DWORD里。
    Planner方式则相反。Y分量和UV分量完全分开来保存。
    YUY2和YV12是最常用的两个代表。
    YUY2是packed方式的。水平方向两个像素打包到一个DWORD,并且UV采样率只有Y的一半,
    这符合人的视觉特征能有效的压缩数据,具体布局为[Y0, U0,Y1,V0]。 这种格式常见于MPEG1的解码器。
    YV12则常见于H.264的解码器,它属于plannar方式。
    对于一个MxN大小的视频来说,数据布局为[Y:M x N] [U:M/2 x N/2] [V:M/2 x N/2].
    也就是说UV的采样率在水平和垂直方向上都只有Y的一半。


    */

    /*
    YUYV和YUY2格式的保存格式
    +--------+--------+--------+--------+--------
    | Y1 | U | Y2 | V | ....
    +--------+--------+--------+--------+--------
    1 Byte 2Byte 3Byte 4Byte
    这种格式,每4个字节为一组。每组保存2个像素的数据,也就是连续的两个像素使用同一个UV。

    */

    转自:http://www.cnblogs.com/cplusplus/archive/2012/04/17/2453315.html

     1 #define uint8_t BYTE
     2     void YUY2toI420(int inWidth, int inHeight, uint8_t *pSrc, uint8_t *pDest)
     3     {
     4         int i, j;
     5         //首先对I420的数据整体布局指定
     6         uint8_t *u = pDest + (inWidth * inHeight);
     7         uint8_t *v = u + (inWidth * inHeight) / 4;
     8 
     9         for (i = 0; i < inHeight/2; i++)
    10         {
    11             /*采取的策略是:在外层循环里面,取两个相邻的行*/    
    12             uint8_t *src_l1 = pSrc + inWidth*2*2*i;//因为4:2:2的原因,所以占用内存,相当一个像素占2个字节,2个像素合成4个字节
    13             uint8_t *src_l2 = src_l1 + inWidth*2;//YUY2的偶数行下一行
    14             uint8_t *y_l1 = pDest + inWidth*2*i;//偶数行
    15             uint8_t *y_l2 = y_l1 + inWidth;//偶数行的下一行
    16             for (j = 0; j < inWidth/2; j++)//内层循环
    17             {
    18                 // two pels in one go//一次合成两个像素
    19                 //偶数行,取完整像素;Y,U,V;偶数行的下一行,只取Y
    20                 *y_l1++ = src_l1[0];//Y
    21                 *u++ = src_l1[1];//U
    22                 *y_l1++ = src_l1[2];//Y
    23                 *v++ = src_l1[3];//V
    24                 //这里只有取Y
    25                 *y_l2++ = src_l2[0];
    26                 *y_l2++ = src_l2[2];
    27                 //YUY2,4个像素为一组
    28                 src_l1 += 4;
    29                 src_l2 += 4;
    30             }
    31         }
    32     }
  • 相关阅读:
    构建之法阅读笔记05
    构建之法阅读笔记04
    构建之法阅读笔记03
    第九周学习进度条
    个人冲刺
    第八周进度条
    Git疑难解决
    Git常用命令
    git配置SSH公钥
    Laravel框架中如何使用 Presenter 模式?
  • 原文地址:https://www.cnblogs.com/lihaiping/p/4147650.html
Copyright © 2011-2022 走看看