5

Intel® Media SDK などのビデオ エンコーダーには、NV12 ビデオ入力形式が必要です。

NV12 フォーマットは YUV 4:2:0 フォーマットで、最初に Y プレーン、次にインターリーブされた UV プレーンにパックされたクロマ サンプルがメモリ内で順序付けられます。

例:
YYYYYY
YYYYYY
UVUVUV

ここに画像の説明を入力

RGB カラー形式は、Pixel-Order RGB (ピクセルごとのバイト、下位バイトは赤) を指します。
RGBRGBRGBRGBRGB
RGBRGBRGBRGBRGB

ここに画像の説明を入力

Web で調べたところ、NV12 に関して、YUVは YCbCr 色空間として定義されていることがわかりました。現在、NV12 を適用できる YCbCr 形式が少なくとも 2 つあります。

私の質問は: RGB 色空間を NV12 に変換するIPP機能はありますか?

4

1 に答える 1

12

IPP関数が存在することがわかりました:

ippiRGBToYCbCr420_8u_C3P2R

関数名または説明に NV12 についての言及がないため、見つけるのが困難でした。
この機能は BT.601 規格を使用しています。

以下は、 BT.601標準 でRGBNV12に変換するためのコード サンプルです。

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.601 (SDTV) よりも BT.709 (HDTV) 規格の方が関連性が高いでしょう。

IPP には BT.709 規格の RGB から NV12 への直接変換機能がありません。BGRNV12
に変換する機能があります。 このソリューションには、次の 2 つの段階が含まれます。

  1. RGBからBGR (スワップ チャネル)に変換します。RGBからBGRへの変換 に使用する
    コード サンプル。ippiSwapChannels_8u_C3R
  2. BGRからNV12に変換します。BGRからNV12への変換に使用する
    コード サンプル。 ippiBGRToYCbCr420_709CSC_8u_C3P2R

サンプル関数は、中間 BGR イメージを格納するために追加のメモリ領域を必要とします。
スケッチ メモリへのポインタが関数に渡されます (メモリは関数の外に割り当てる必要があります)。

以下は、 BT.709標準 でRGBNV12に変換するためのコード サンプルです。

//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...
}
于 2016-06-11T21:41:15.877 に答える