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.601 (SDTV) よりも BT.709 (HDTV) 規格の方が関連性が高いでしょう。
IPP には BT.709 規格の RGB から NV12 への直接変換機能がありません。BGRをNV12
に変換する機能があります。
このソリューションには、次の 2 つの段階が含まれます。
- RGBからBGR (スワップ チャネル)に変換します。RGBからBGRへの変換 に使用する
コード サンプル。ippiSwapChannels_8u_C3R
- BGRからNV12に変換します。BGRからNV12への変換に使用する
コード サンプル。 ippiBGRToYCbCr420_709CSC_8u_C3P2R
サンプル関数は、中間 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...
}