无法正确初始化AVFrame进行sws_scale转换

时间:2019-03-31 12:46:22

标签: opengl ffmpeg

我正在使用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]错误的dst图像指针”错误。当我查看FFMpeg的源代码时,我发现原因是未初始化outputFrame的数据,但我不知道应该如何初始化。

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

2 个答案:

答案 0 :(得分: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不在乎。它只需要一块适当大小(也许对齐)的内存。

答案 1 :(得分:0)

就我而言,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;