Media (Intel® oneAPI Video Processing Library, Intel Media SDK)
Access community support with transcoding, decoding, and encoding in applications using media tools from Intel. This includes Intel® oneAPI Video Processing Library and Intel® Media SDK.

How do I get a NV12 data after decoding in H264


Hi, All

I have a few quesetions during testing a sample decode in MSDK 2012.

1. when I output NV12 format after decoding in H264, the output result is good as like figure(no-error.png).

but I rewrite the source as following:

[cpp]    BYTE* pDec = new BYTE [pmfxOutSurface->Info.CropW * pmfxOutSurface->Info.CropH * 3 / 2];    

    memcpy( pDec, pmfxOutSurface->Data.Y, pmfxOutSurface->Info.CropW * pmfxOutSurface->Info.CropH);

    memcpy( pDec + pmfxOutSurface->Info.CropW * pmfxOutSurface->Info.CropH, pmfxOutSurface->Data.UV, pmfxOutSurface->Info.CropW * pmfxOutSurface->Info.CropH / 2);[/cpp]

the parts of output image are a few errors as like figure(image-errors-after-decodingfig-1.png).

I thought that the arrays of UV are wrong. I rewrited the source as like your WriteNextFrame() in source. the rewrited source is next following:

[cpp]int h = pmfxOutSurface->Info.CropH / 2;

int w = pmfxOutSurface->Info.CropW;

for (int i = 0; i < h; i++) { 

    for (int j = 0; j < w; j += 2)  {   

     memcpy(pDec + (pmfxOutSurface->Info.CropW * pmfxOutSurface->Info.CropH) + pmfxOutSurface->Data.Pitch * i + j, pmfxOutSurface->Data.UV + (pmfxOutSurface->Info.CropY * pmfxOutSurface->Data.Pitch / 2 + pmfxOutSurface->Info.CropX) + i * pmfxOutSurface->Data.Pitch + j, 1);                                  



for (int i = 0; i < h; i++) { 

     for (int j = 1; j < w; j += 2)  { 

         memcpy(pDec + (pmfxOutSurface->Info.CropW * pmfxOutSurface->Info.CropH) + pmfxOutSurface->Data.Pitch * i + j, pmfxOutSurface->Data.UV + (pmfxOutSurface->Info.CropY * pmfxOutSurface->Data.Pitch / 2 + pmfxOutSurface->Info.CropX)+ i * pmfxOutSurface->Data.Pitch + j, 1); 



But the errors are same to first test.

2. I want to resize the image using ippiResizeYUV420_8u_P2R after decoding. but this is a few errors as like figure(resize-errorfig-2.png).

My resize source is as following:

[cpp]int ResizeToWidth = 320;

int ResizeToHeight = 240;

BYTE* pDestY = new BYTE[ ResizeToWidth * ResizeToHeight ];

BYTE* pDestUV = new BYTE[ ResizeToWidth * ResizeToHeight / 2 ];

Ipp64f xRatio = static_cast<Ipp64f> (pmfxOutSurface->Info.CropW)  / static_cast<Ipp64f> (ResizeToWidth);

Ipp64f yRatio = static_cast<Ipp64f> (pmfxOutSurface->Info.CropH) / static_cast<Ipp64f> (ResizeToHeight);

IppiSize srcRoiSize = { pmfxOutSurface->Info.CropW, pmfxOutSurface->Info.CropH};

IppiSize dstRoiSize = { ResizeToWidth, ResizeToHeight };

int nBufSIze = 0;

ippiResizeYUV420GetBufSize( srcRoiSize, dstRoiSize, IPPI_INTER_SUPER, &nBufSIze);

Ipp8u *pBuffer = new Ipp8u[ nBufSIze ];

IppStatus rErr = ippiResizeYUV420_8u_P2R( (Ipp8u*) pmfxOutSurface->Data.Y, int(pmfxOutSurface->Info.CropW),  (Ipp8u*) pmfxOutSurface->Data.VU, int(pmfxOutSurface->Info.CropW / 2), srcRoiSize,  (Ipp8u*) pDestY, ResizeToWidth,  (Ipp8u*) pDestUV, (ResizeToWidth / 2), dstRoiSize,   IPPI_INTER_SUPER, (Ipp8u*) pBuffer);[/cpp]

How do I solve the problems?

Thank in advances.


0 Kudos
1 Reply
Hi nrson, 1) I suspect that the issue your facing has to do with not taking into account surface pitch when copying the individual lines. Please refer back to the Media SDK sample source code again to compare behavior. 2) I'm not convinced that ippiResizeYUV420_8u_P2R function supports NV12. You may need to use another IPP function or write your own. Alternatively you can use Media SDK VPP component to perform resize, or if your surface is a D3D surface you can use DirectX resizing directly. In any case, if you want to pursue using IPP and still face issues I suggest you instead post you question on the Intel IPP forum for help. Regards, Petter