ffmpeg YUV420 转 RGB24 只转换一行

Posted

技术标签:

【中文标题】ffmpeg YUV420 转 RGB24 只转换一行【英文标题】:ffmpeg YUV420 to RGB24 converts only one row 【发布时间】:2016-08-10 09:53:41 【问题描述】:

我正在尝试在 c++ 中将我的 YUV420p 图像转换为 RGB24,并在 c# 中从字节数组创建位图。

我的图像大小为 1920 w * 1020 h,ffmpeg 解码器为我提供了 3 个平面,用于数据线大小 = 1920、960、960。但是在 sws_scale 之后,我得到的 RGB 图片只有一个线大小 = 5760 的平面。 它看起来不正确:我应该得到 (5760 * h),而不仅仅是一行数据。我做错了什么?

 //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;
        

【问题讨论】:

为什么你认为它不正确?输入平面像素数据,取出交错的像素数据,其中每行的大小为 3 * 1920,内存区域总共为 3 * 1920 * 高度。 好吧,我不明白那个 3*1920*height 内存区域在哪里。我在pFrameRGB-&gt;data 中只有一行 3 * 1920... 对于完整图像我需要所有其他行吗?.. sws_scale 的返回值是多少?它应该是输出缓冲区中的行数 - pFrameRGB-&gt;data。如果它不是 1 那么你的假设是错误的。如果它真的是 1,那么就出了问题。 我错过了 sws_scale 的返回值。有了它,我的缓冲区中有适量的“列”……所以,基本上,据我所知,linesize 的大小不是data - 它只在data 中显示一个行大小? 是的,变量的名字告诉它:) 【参考方案1】:

您认为AVFrame 的linesize 字段是数据总量的假设不正确。正如变量的名称所述,它是单行的长度,而sws_scale 的返回值为您提供行数。因此,输出位图的总内存范围大小为linesize 乘以返回值。

【讨论】:

以上是关于ffmpeg YUV420 转 RGB24 只转换一行的主要内容,如果未能解决你的问题,请参考以下文章

从 YUV420P 到 RGB 的 FFMPEG Api 转换产生奇怪的输出

如何将yuv420p数据旋转90

如何把摄像头采集的rgb图像转成yuv格式,并进行H264硬编码?

yuv420p 转rgb计算

开源YUV420转RGB源码或directshow

YUV420转RGB