我正在使用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。我将不胜感激。
答案 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);
这里有两个区别:
您通过了&inputFrame->data
,但它应该是inputFrame->data
,没有地址操作符。
您不必分配第二个框架结构。 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;