簡體   English   中英

如何使用IPP將RGB轉換為NV12色彩空間

[英]How to convert RGB to NV12 color space using IPP

像Intel®MediaSDK這樣的視頻編碼器需要NV12視頻輸入格式。

NV12格式是YUV 4:2:0格式,在存儲器中排序,首先是Y平面,然后是交錯UV平面中的打包色度樣本。

例:
YYYYYY
YYYYYY
UVUVUV

在此輸入圖像描述

RGB顏色格式,指像素級RGB(每像素字節,低字節為紅色):
RGBRGBRGBRGBRGB
RGBRGBRGBRGBRGB

在此輸入圖像描述

我做了一些網絡研究,發現對於NV12, YUV被定義為YCbCr色彩空間。 目前至少有兩種可能的YCbCr格式適用於NV12:

我的問題是: 是否有將IP色彩空間轉換為NV12的IPP功能?

我發現IPP功能存在:

ippiRGBToYCbCr420_8u_C3P2R

很難找到,因為功能名稱或描述沒有提到NV12。
該功能使用BT.601標准。

以下是在BT.601標准中將RGB轉換為NV12的代碼示例:

void Rgb2NV12(const unsigned char I[], int image_width, int image_height, unsigned char J[])
{
    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), Handle errors...          
}



使用BT.709標准將RGB轉換為NV12:

至於2019年,BT.709(HDTV)標准可能比BT.601(SDTV)更具相關性。

IPP缺乏在BT.709標准中從RGB直接轉換為NV12的功能。
有一個功能可以將BGR轉換為NV12
該解決方案包括兩個階段:

  1. RGB轉換為BGR (交換通道)。
    代碼示例使用ippiSwapChannels_8u_C3R進行RGBBGR轉換。
  2. BGR轉換為NV12
    代碼示例使用ippiBGRToYCbCr420_709CSC_8u_C3P2R進行BGRNV12的轉換。

樣本函數需要一些額外的存儲空間來存儲中間BGR圖像。
指向草圖存儲器的指針被傳遞給函數(存儲器應該在函數外部分配)。

以下是在BT.709標准中將RGB轉換為NV12的代碼示例:

//sketch_buff - Temporary buffer for storing image in BGR format.
//              Size of sketch_buff must be at least image_width*image_height*3 bytes.
void Rgb2NV12_709(const unsigned char I[],
                  const int image_width, 
                  const int image_height,
                  unsigned char sketch_buff[],
                  unsigned char J[])
{
    IppStatus ipp_status;    
    int srcStep = image_width*3;
    int dstBgrStep = image_width*3;
    int dstYStep = image_width;
    int dstCbCrStep = image_width;
    IppiSize roiSize = {image_width, image_height};

    const Ipp8u* pRGB = (Ipp8u*)I;
    Ipp8u* pBGR = (Ipp8u*)sketch_buff; //BGR image is stored in sketch_buff
    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.

    const int bgrOrder[3] = {2, 1, 0};

    //Swap Red and Blue color channels - convert from RGB to BGR
    //Store the result into sketch_buff (sketch buffer is allocated outside the function)
    ipp_status = ippiSwapChannels_8u_C3R(pRGB, srcStep, pBGR, dstBgrStep, roiSize, bgrOrder);

    //if (ipp_status != ippStsNoErr), Handle errors...

    //Convert BGR to NV12 in BT.709 standard
    ipp_status = ippiBGRToYCbCr420_709CSC_8u_C3P2R(pBGR, srcStep, pDstY, dstYStep, pDstCbCr, dstCbCrStep, roiSize);

    //if (ipp_status != ippStsNoErr), Handle errors...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM