FFmpeg解码并转换RGB sws_scale错误

时间:2019-01-10 01:14:48

标签: c++ ffmpeg yuv libavcodec

我的代码有问题。

我想将YUV转换为RGB,但是sws_scale始终返回0,并且数据已填充00000000..NULL

我尝试使用谷歌搜索,但找不到任何问题。

我需要AVPicture或QImage吗?谁能指出我的问题?

 pVFrame = av_frame_alloc();
 while (av_read_frame(pFormatCtx, &packet) == 0) {
        if (packet.stream_index == VSI) {
            if (bool res = avcodec_send_packet(pVideoCodecCtx, &packet)) {
                printf("avcodec_send_packet failed %d %d %d\n", res, AVERROR(EINVAL), AVERROR(ENOMEM));
            }
            avcodec_receive_frame(pVideoCodecCtx, pVFrame);

            AVFrame* YUV_frame = Con_yuv_YUV420P(pVFrame);
            QFrame->push(Con_yuv_RGB(YUV_frame));
        }
    }
}


AVFrame* Con_yuv_RGB(AVFrame* YUV_frame)
{
AVFrame* RGBFrame = av_frame_alloc();

SwsContext* sws_Context = NULL;
sws_Context = sws_getCachedContext(sws_Context, YUV_frame->width, YUV_frame->height, pVideoCodecCtx->pix_fmt,
    YUV_frame->width, YUV_frame->height, AV_PIX_FMT_RGB32, SWS_BICUBIC, NULL, NULL, NULL);

if (sws_Context == NULL) {
    return false;
}
result = sws_scale(sws_Context, YUV_frame->data, YUV_frame->linesize, 0, (int)YUV_frame->height, RGBFrame->data, RGBFrame->linesize);
if (result < 0)
{
    return false;
}
av_frame_unref(YUV_frame);
if (RGBFrame == NULL) {
    av_frame_unref(RGBFrame);
    return false;
}

sws_freeContext(sws_Context);

return RGBFrame;

出什么问题了?

enter image description here

参考链接-https://gist.github.com/nakaly/11eb992ebd134ee08b75e4c67afb5703

http://codefromabove.com/2014/10/ffmpeg-convert-rgba-to-yuv/

sws_scale YUV --> RGB distorted image

https://www.gamedev.net/forums/topic/464977-sws_scale-problems/

https://ffmpeg.org/doxygen/2.7/group__libsws.html#gae531c9754c9205d90ad6800015046d74

添加: enter image description here

在转换之前。它必须填充缓冲区。

RGBFrame->width = YUV_frame->width;     RGBFrame->format = AV_PIX_FMT_RGB32;
RGBFrame->height = YUV_frame->height;
int result = av_frame_get_buffer(RGBFrame, 32);
if (result != 0)    return false;

1 个答案:

答案 0 :(得分:0)

ffmpeg文档涵盖了它:

https://www.ffmpeg.org/doxygen/2.3/group__lavu__frame.html#gac700017c5270c79c1e1befdeeb008b2f

  

AVFrame * av_frame_alloc(void)

     

分配一个AVFrame并将其字段设置为默认值。

     

必须使用av_frame_free()释放生成的结构。

     

返回一个填充有默认值或失败时为NULL的AVFrame。注意   这只会分配AVFrame本身,而不分配数据缓冲区。那些   必须通过其他方式分配,例如与av_frame_get_buffer()   或手动。

https://www.ffmpeg.org/doxygen/2.3/group__lavu__frame.html#ga6b1acbfa82c79bf7fd78d868572f0ceb

  

int av_frame_get_buffer(AVFrame * frame,int align)分配   新的音频或视频数据缓冲区。

     

在调用此字段之前,必须在框架上设置以下字段   功能:

     

格式(视频的像素格式,音频的样本格式)宽度和   视频的高度nb_samples和channel_layout的音频此功能   将填充AVFrame.data和AVFrame.buf数组,并在必要时填充   分配并填充AVFrame.extended_data和AVFrame.extended_buf。对于   平面格式,将为每个平面分配一个缓冲区。