Intel IPP 圖像空間轉換

1、 背景測試

  用QuickSync VPP模塊作RGBA到NV12的顏色空間轉換致使文字顯示蒙上一層顏色的問題, 暫時懷疑是VPP自身的問題,由於參數設置都是按官方demo設置的。因此嘗試使用IPP來作RGBA到NV12的轉化。ui

2、IPP 探索歷程google

  1. 下載IPP安裝包, google 「IPP」,便可找到下載連接。編碼

  2.安裝, 執行 install.sh。 若是有問題,看看文檔,安裝環境是否知足安裝需求。spa

  3.編寫測試程序(可在官網找到),須要關注頭文件和庫的目錄,在安裝目錄下均可以找到。code

3、RGBA到NV12的轉換orm

  1. 頭文件ippcc.h, 庫文件 libippcc.soblog

  2. 實例:接口

void Rgb2NV12(const unsigned char I[],
              const int image_width, 
              const int image_height,
              unsigned char J[])
{
    //memcpy(J, I, image_width*image_height*3);

    IppStatus ipp_status;

    int srcStep = image_width*3;
    int dstYStep = image_width;
    int dstCbCrStep = image_width;
    IppiSize roiSize = {image_width, image_height};

    const Ipp8u* pSrc = (Ipp8u*)I;

    Ipp8u *pDstY    = (Ipp8u*)J;                            //Y color plane is the first image_width*image_height pixels of J.
    Ipp8u *pDstCbCr    = (Ipp8u*)&J[image_width*image_height];    //In NV12 format, UV plane starts below Y.

    ipp_status = ippiRGBToYCbCr420_8u_C3P2R(pSrc, srcStep, pDstY, dstYStep, pDstCbCr, dstCbCrStep, roiSize);

    if (ipp_status != ippStsNoErr)
    {
        memset(J, 128, image_width*image_height*3/2);
    }
}

上面實例是轉RGB24到NV12的接口ip

IPPAPI(IppStatus, ippiRGBToYCbCr420_8u_C3P2R,( const Ipp8u* pRGB, int rgbStep,  Ipp8u* pY, int YStep,Ipp8u* pCbCr, int CbCrStep, IppiSize roiSize ))//  RGB24-->NV12
IPPAPI(IppStatus, ippiRGBToYCbCr420_8u_C4P2R,( const Ipp8u* pRGB, int rgbStep,  Ipp8u* pY, int YStep,Ipp8u* pCbCr, int CbCrStep, IppiSize roiSize ))//  ARGB-->NV12
IPPAPI(IppStatus, ippiBGRToYCbCr420_8u_C3P2R,( const Ipp8u* pRGB, int rgbStep,  Ipp8u* pY, int YStep,Ipp8u* pCbCr, int CbCrStep, IppiSize roiSize ))//  BGR24-->NV12
IPPAPI(IppStatus, ippiBGRToYCbCr420_8u_AC4P2R,( const Ipp8u* pRGB, int rgbStep,  Ipp8u* pY, int YStep,Ipp8u* pCbCr, int CbCrStep, IppiSize roiSize ))// ABGR-->NV12

實際結果以測試結果爲準。

有一些分辨率在把NV12編碼成h264時須要對齊行像素,此時能夠更改YStep,CbCrStep進行對齊。例如:

IppiSize roiSize;
roiSize.width = m_mfxEncParams.mfx.FrameInfo.CropW;
roiSize.height = m_mfxEncParams.mfx.FrameInfo.CropH;
mfxU16 pitch = m_pVPPSurfacesVPPOutEnc[nEncSurfIdx].Data.Pitch;
ippiBGRToYCbCr420_8u_AC4P2R( (Ipp8u*)pInputBuffer, roiSize.width*4,  (Ipp8u*)m_pVPPSurfacesVPPOutEnc[nEncSurfIdx].Data.Y, pitch, (Ipp8u*)m_pVPPSurfacesVPPOutEnc[nEncSurfIdx].Data.UV,pitch, roiSize);

上面的Data.Pitch就是編碼器對特定分辨率下的行對齊的字節寬度。

相關文章
相關標籤/搜索