ffmpeg YUV420 to RGB24 converts only one row

1.3k Views Asked by At

I'm trying to convert my YUV420p image to RGB24 in c++ and create bitmap from byte array in c#.

My image size is 1920 w * 1020 h and ffmpeg decoder give me 3 planars for data with linesizes = {1920, 960, 960}. But after sws_scale I'm getting RGB picture with only one plane with linesize = 5760. It does not looks correct: I should get (5760 * h), not just only one row of data. What I'm doing wrong?

 //c++ part
    if (avcodec_receive_frame(m_decoderContext, pFrame) == 0)
    {
        //RGB
        sws_ctx = sws_getContext(m_decoderContext->width,
            m_decoderContext->height,
            m_decoderContext->pix_fmt,
            m_decoderContext->width,
            m_decoderContext->height,
            AV_PIX_FMT_RGB24,
            SWS_BILINEAR,
            NULL,
            NULL,
            NULL
        );

        sws_scale(sws_ctx, (uint8_t const * const *)pFrame->data, pFrame->linesize,
            0, pFrame->height,
            pFrameRGB->data, pFrameRGB->linesize);


//c# part (im reading data from pipe and its equal to c++ part)------------------------------------------------------------------
        byte[] rgbch = new byte[frameLen];
        for (int i=0; i<frameLen; i++)
        {
            rgbch[i] = Convert.ToByte(pipe.ReadByte());
        }

        if (rgbch.Length > 0)
        {
            var arrayHandle = System.Runtime.InteropServices.GCHandle.Alloc(rgbch,
    System.Runtime.InteropServices.GCHandleType.Pinned);

            var bmp = new Bitmap(1920, 1080,
                3,
                System.Drawing.Imaging.PixelFormat.Format24bppRgb,
                arrayHandle.AddrOfPinnedObject()
            );

            pictureBox1.Image = bmp;
        }
1

There are 1 best solutions below

0
On BEST ANSWER

Your assumption that the linesize field of AVFrame is the total amount of data is not correct. As the name of the variable states it is the length of a single row, while the return value of sws_scale gives you the number of rows. Thus the total memory range size for the output bitmap is linesize multiplied by the return value.