【问题标题】:Failing to properly initialize AVFrame for sws_scale conversion未能为 sws_scale 转换正确初始化 AVFrame
【发布时间】:2019-03-31 12:46:21
【问题描述】:

我正在使用 FFMpeg 解码视频,并想使用 OpenGL 编辑解码的帧,但为了做到这一点,我需要将 AVFrame 中的数据从 YUV 转换为 RGB。

为此,我创建了一个新的 AVFrame:

AVFrame *inputFrame = av_frame_alloc();
AVFrame *outputFrame = av_frame_alloc();
av_image_alloc(outputFrame->data, outputFrame->linesize, width, height, AV_PIX_FMT_RGB24, 1);
av_image_fill_arrays(outputFrame->data, outputFrame->linesize, NULL, AV_PIX_FMT_RGB24, width, height, 1);

创建转换上下文:

struct SwsContext *img_convert_ctx = sws_getContext(width, height, AV_PIX_FMT_YUV420P,
                                                  width, height, AV_PIX_FMT_RGB24,
                                                  0, NULL, NULL, NULL);

然后尝试转成RGB:

sws_scale(img_convert_ctx, (const uint8_t *const *)&inputFrame->data, inputFrame->linesize, 0, inputFrame->height, outputFrame->data, outputFrame->linesize);

但这会在运行时导致“[swscaler @ 0x123f15000] bad dst image pointers”错误。翻了一下FFMpeg的源码,发现原因是outputFrame的数据没有初始化,但是不明白应该怎么做。

我发现的所有现有答案或教程 (see example) 似乎都使用了已弃用的 API,并且不清楚如何使用新的 API。如有任何帮助,我将不胜感激。

【问题讨论】:

    标签: opengl ffmpeg


    【解决方案1】:

    我是这样称呼sws_scale的:

    image buf2((buf.w + 15)/16*16, buf.h, 3);
    sws_scale(sws_ctx, (const uint8_t * const *)frame->data, frame->linesize, 0, c->height, (uint8_t * const *)buf2.c, &buf2.ys);
    

    这里有两个区别:

    1. 你传递了&inputFrame->data,但它应该是inputFrame->data,没有地址运算符。

    2. 您不必分配第二个框架结构。 sws_scale 不在乎。它只需要一块大小合适(可能还有对齐)的内存。

    【讨论】:

    • 什么是“图像”结构?
    • @nihohit:我自己的图像类——它只是用malloc 分配内存。关键是它不必是AvFrame。但你的问题是第一个。
    【解决方案2】:

    在我的例子中,av_image_alloc / av_image_fill_arrays 没有创建帧->数据指针。

    这是我的做法,不确定是否一切正确,但它有效:

                d->m_FrameCopy = av_frame_alloc();
    
                uint8_t* buffer = NULL;
                int numBytes;
                // Determine required buffer size and allocate buffer
                numBytes = avpicture_get_size(
                    AV_PIX_FMT_RGB24, d->m_Frame->width, d->m_Frame->height);
                buffer = (uint8_t*)av_malloc(numBytes * sizeof(uint8_t));
    
                avpicture_fill(
                    (AVPicture*)d->m_FrameCopy,
                    buffer,
                    AV_PIX_FMT_RGB24,
                    d->m_Frame->width,
                    d->m_Frame->height);
    
                d->m_FrameCopy->format = AV_PIX_FMT_RGB24;
                d->m_FrameCopy->width = d->m_Frame->width;
                d->m_FrameCopy->height = d->m_Frame->height;
                d->m_FrameCopy->channels = d->m_Frame->channels;
                d->m_FrameCopy->channel_layout = d->m_Frame->channel_layout;
                d->m_FrameCopy->nb_samples = d->m_Frame->nb_samples;
    

    【讨论】:

      猜你喜欢
      • 2020-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-21
      • 2012-06-17
      • 2022-01-22
      • 2014-10-24
      相关资源
      最近更新 更多