Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.

Intel IPP RGBToYUV420 function is getting IppStsSizeErr result code

Yeşilçimen__Ahmet
474 Views

Hi,

I am using IPP 2017.0.3(r55431) and Delphi 10.2, i am trying convert RGB to YUV420P but i am getting IppStsSizeErr result code.

I have m_dst_picture, m_src_picture: AVPicture structure created by FFMPEG.

 { allocate the encoded raw picture }

  ret := avpicture_alloc(@m_dst_picture, AV_PIX_FMT_YUV420P, c^.width, c^.height);

  if (ret < 0) then

    Exit(False);

  { allocate BGR frame that we can pass to the YUV frame }
  ret := avpicture_alloc(@m_src_picture, AV_PIX_FMT_BGR24, c^.width, c^.height);
  if (ret < 0) then
    Exit(False);

  { convert BGR frame (m_src_picture) to and YUV frame (m_dst_picture) }
  sws_scale(sws_ctx, @m_src_picture.data[0], @m_src_picture.linesize, 0, c^.height, @m_dst_picture.data[0], @m_dst_picture.linesize);//It works fine.

I want to convert the RGB buffer directly to YUV420P.The original code first loads RGB into the AVPicture then convert RGB to YUV420P with sws_scale and it causes slowness.

Here I copy the BGR buffer to m_src_picture of FFMPEG. But this leads to performance loss, so I want to convert it directly to YUV420P using Intel IPP.

procedure WriteFrameBGR24(frame: PByte);
var
  y: Integer;
begin
  for y := 0 to m_c^.height - 1 do
    Move(PByte(frame - (y * dstStep))^, PByte(m_src_picture.data[0] + (y * m_src_picture.linesize[0]))^, dstStep);
end;

In the code below I am trying to convert using Intel IPP.

 { Converting RGB to YUV420P. }

**roiSize is 1920 and 1080

**The values created by FFMPEG for YUV420P in m_dst_picture.linesize are [0]=1920,[1]=960,[2]=960 respectively.

Do I need to convert the values of the linesize to another value?

**The reason why the srcStep parameter is a minus sign is the Bottom-Up Bitmap and the frame pointer indicates the Bmp.ScanLine[0] address, which indicates the highest pointer address.

srcStep := (((width * (3 * 8)) + 31) and not 31) div 8; //for 24 bitmap

 { Swap of BGR channels to RGB. }

  st := ippiSwapChannels_8u_C3IR(frame, -srcStep, roiSize, @BGRToRGBArray[0]); //It works fine

 { Convert RGB to YUV420P. }

  st := ippiRGBToYUV420_8u_C3P3R(frame, -srcStep, @m_dst_picture.data[0], @m_dst_picture.linesize[0], roiSize); //IppStsSizeErr 

How do I solve this problem ?

Thank you.

0 Kudos
1 Reply
Yeşilçimen__Ahmet
474 Views

I solved the problem, I forgot to set DLL calling convention as stdcall, but I would like to use ippiBGRToYUV420_8u_AC4P3R instead of ippiRGBToYUV420_8u_C3P3R Because my real bitmap format is BGR. I do not want to use the ippiSwapChannels_8u_C3IR function for performance reasons. All parameters of two functions have the same kind of type and name, but I'm getting the error message below.

Access violation at address 0454FCCF in module 'ippccs8.dll'. Read of address 0B3EF008.

There is no error when I am using ippiRGBToYUV420_8u_C3P3R function, but if I use the ippiBGRToYUV420 function, an error occurs.

function ippiRGBToYUV420_8u_C3P3R(const pSrc: PIpp8u; srcStep: Integer; pDst: PPIpp8u; dstStep: PInteger; roiSize: IppiSize): TIppStatus; stdcall;

function ippiBGRToYUV420_8u_AC4P3R(const pSrc: PIpp8u; srcStep: Integer; pDst: PPIpp8u; dstStep: PInteger; roiSize: IppiSize): TIppStatus; stdcall;

I think this is a bug?

Thank you.

0 Kudos
Reply