简体   繁体   English

如何使用IPP将RGB转换为NV12色彩空间

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

Video encoders like Intel® Media SDK require NV12 video input format. 像Intel®MediaSDK这样的视频编码器需要NV12视频输入格式。

NV12 format is YUV 4:2:0 format ordered in memory with a Y plane first, followed by packed chroma samples in interleaved UV plane. NV12格式是YUV 4:2:0格式,在存储器中排序,首先是Y平面,然后是交错UV平面中的打包色度样本。

Example: 例:
YYYYYY
YYYYYY
UVUVUV

在此输入图像描述

RGB color format, refers to Pixel-Order RGB (byte per pixel, lower byte is Red): RGB颜色格式,指像素级RGB(每像素字节,低字节为红色):
RGBRGBRGBRGBRGB
RGBRGBRGBRGBRGB

在此输入图像描述

I did some Web research, and found out that regarding NV12, YUV is defined as YCbCr color space. 我做了一些网络研究,发现对于NV12, YUV被定义为YCbCr色彩空间。 There are currently at least 2 possible YCbCr formats apply NV12: 目前至少有两种可能的YCbCr格式适用于NV12:

My question is: Is there as IPP function that converts RGB color space to NV12? 我的问题是: 是否有将IP色彩空间转换为NV12的IPP功能?

I found out that IPP function exists: 我发现IPP功能存在:

ippiRGBToYCbCr420_8u_C3P2R ippiRGBToYCbCr420_8u_C3P2R

It was hard to find, because the function name or description does not mention NV12. 很难找到,因为功能名称或描述没有提到NV12。
The function uses BT.601 standard. 该功能使用BT.601标准。

Here is a code sample for converting RGB to NV12 in BT.601 standard: 以下是在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...          
}



Converting RGB to NV12 with BT.709 standard: 使用BT.709标准将RGB转换为NV12:

As for 2019, BT.709 (HDTV) standard is probably more relevant than BT.601 (SDTV). 至于2019年,BT.709(HDTV)标准可能比BT.601(SDTV)更具相关性。

IPP lacks a function for direct conversion from RGB to NV12 in BT.709 standard. IPP缺乏在BT.709标准中从RGB直接转换为NV12的功能。
There is a function that converts BGR to NV12 . 有一个功能可以将BGR转换为NV12
The solution includes two stages: 该解决方案包括两个阶段:

  1. Convert from RGB to BGR (swap channels). RGB转换为BGR (交换通道)。
    Code sample uses ippiSwapChannels_8u_C3R for RGB to BGR conversion. 代码示例使用ippiSwapChannels_8u_C3R进行RGBBGR转换。
  2. Convert from BGR to NV12 . BGR转换为NV12
    Code sample uses ippiBGRToYCbCr420_709CSC_8u_C3P2R for BGR to NV12 conversion. 代码示例使用ippiBGRToYCbCr420_709CSC_8u_C3P2R进行BGRNV12的转换。

The sample function requires some extra memory space for storing the intermediate BGR image. 样本函数需要一些额外的存储空间来存储中间BGR图像。
A pointer to the sketch memory is passed to the function (the memory should be allocated outside the function). 指向草图存储器的指针被传递给函数(存储器应该在函数外部分配)。

Here is a code sample for converting RGB to NV12 in BT.709 standard: 以下是在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