1. 程式人生 > >關於yuv 格式-Semi Planar和Planar

關於yuv 格式-Semi Planar和Planar

關於yuv 格式

YUV 格式通常有兩大類:打包(packed)格式和平面(planar)格式。前者將 YUV 分量存放在同一個陣列中,
通常是幾個相鄰的畫素組成一個巨集畫素(macro-pixel);而後者使用三個陣列分開存放 YUV 三個分量,就像
是一個三維平面一樣。

 

幾種常見的yuv格式

1.YUV422 Planar

這裡,Y\U\V資料是分開存放的,每兩個水平Y取樣點,有一個Cb和一個Cr取樣點,如下圖

ffmpeg 中的定義  PIX_FMT_YUV422P,   ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)  

android  OMX  中的定義  OMX_COLOR_FormatYUV422Planar     //*  YUV422Planar           : Three arrays Y,U,V.

 

2. YUV420 Planar

這個格式跟YUV422 Planar 類似,但對於Cb和Cr的取樣在水平和垂直方向都減少為2:1,如下圖

 

ffmpeg 中定義  PIX_FMT_YUV420P    //< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)

android OMX 中定義  OMX_COLOR_FormatYUV420Planar     //  *  YUV420Planar           : Three arrays Y,U,V   

 

3.YUV422 Semi-Planar                                         Semi 是’半‘的意思 我的理解這個半平面模式

   這個格式的資料量跟YUV422 Planar的一樣,但是U、V是交叉存放的,如下圖。

 

ffmpeg 中 未找到定義

android  OMX  中 OMX_COLOR_FormatYUV422SemiPlanar    ////YUV422SemiPlanar       : Two arrays, one is all Y, the other is U and V

 

4.YUV420 Semi-Planar

 這個格式的資料量跟YUV420 Planar的一樣,但是U、V是交叉存放的,如下圖。

 ffmpeg 中定義  

PIX_FMT_NV12,      ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V)

android   OMX  中定義 OMX_COLOR_FormatYUV420SemiPlanar    //YUV420SemiPlanar       : Two arrays, one is all Y, the other is U and V 

 

5.YUV422 Interleaved        Interleaved -- 交錯   

這個格式的資料量跟YUV422 Planar的一樣,但是Y、U、V是交叉存放的,如下圖。 這個是打包(packed)模式的

ffmpeg  中  PIX_FMT_UYVY422   ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1

android  OMX 中  OMX_COLOR_FormatCbYCrY    //CbYCrY                 : Organized as 16bit UYVY (i.e. CbYCrY)

 

 

 24bit RGB888 -> 16bit RGB565 的轉換

 

 24ibt RGB888 R7 R6 R5 R4 R3 R2 R1 R0 G7 G6 G5 G4 G3 G2 G1 G0 B7 B6 B5 B4 B3 B2 B1 B0

 

 16bit RGB656 R7 R6 R5 R4 R3 G7 G6 G5 G4 G3 G2 B7 B6 B5 B4 B3

HI_S32 SAMPLE_COMM_VENC_PlanToSemi(HI_U8 *pY, HI_S32 yStride, 
                       HI_U8 *pU, HI_S32 uStride,
					   HI_U8 *pV, HI_S32 vStride, 
					   HI_S32 picWidth, HI_S32 picHeight)
{
    HI_S32 i;
    HI_U8* pTmpU, *ptu;
    HI_U8* pTmpV, *ptv;
    
    HI_S32 s32HafW = uStride >>1 ;
    HI_S32 s32HafH = picHeight >>1 ;
    HI_S32 s32Size = s32HafW*s32HafH;
        
    pTmpU = malloc( s32Size ); ptu = pTmpU;
    pTmpV = malloc( s32Size ); ptv = pTmpV;
    
    memcpy(pTmpU,pU,s32Size);
    memcpy(pTmpV,pV,s32Size);
    
    for(i = 0;i<s32Size>>1;i++)
    {
        *pU++ = *pTmpV++;
        *pU++ = *pTmpU++;
        
    }
    for(i = 0;i<s32Size>>1;i++)
    {
        *pV++ = *pTmpV++;
        *pV++ = *pTmpU++;        
    }

    free( ptu );
    free( ptv );

    return HI_SUCCESS;
}