初始化AVFrame失败导致sws_scale转换出错。

3
我正在使用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的源代码时,发现输出帧的数据没有初始化,但我不知道应该如何初始化。
所有现有的答案或教程(参见示例)似乎都使用已弃用的API,并且不清楚如何使用新的API。我将感激任何帮助。
2个回答

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 不关心它。它只需要一个适当大小(和可能的对齐方式)的内存块。


"image" 结构体是什么? - nihohit
@nihohit: 我自己的图像类 -- 它只是使用 malloc 分配内存。关键在于它不一定要是一个 AvFrame。但你的问题是第一个问题。 - Yakov Galka

0
在我的案例中,av_image_alloc / av_image_fill_arrays 没有创建 frame->data 指针。
以下是我是如何实现的,不确定是否全部正确,但它能够正常工作:
            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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接