我尝试使用opengl逐帧处理视频。 我使用ffmpeg从视频文件中读取帧。
在开始处理帧之前,我想先读取一些帧并将它们存储在内存中。 所以我尝试在while循环中使用av_read_frame,并将帧数据复制到数组中,
但是,当我尝试显示这些帧时,我发现我只能获得最后几帧。 例如,如果我想缓存50帧,但我只能得到最后几帧(第45帧到第50帧)。
这是我用来缓存帧的代码:
void cacheFrames()
{
AVPacket tempPacket;
av_init_packet(&tempPacket);
int i = 0;
avcodec_flush_buffers(formatContext->streams[streamIndex] ->codec);
codecContext = formatContext->streams[streamIndex] ->codec;
while (av_read_frame(formatContext, &tempPacket) >= 0 && i <NUM_FRAMES)
{
int finished = 0;
if (tempPacket.stream_index == streamIndex)
{
avcodec_decode_video2(
codecContext,
frame,
&finished,
&tempPacket);
if (finished)
{
memcpy(datas[i].datas, frame->data, sizeof(frame->data)); // copy the frame data into an array
i++;
}
}
}
av_free_packet(&tempPacket);
}
那么,我做错了什么?
答案 0 :(得分:1)
data
定义为
uint8_t* AVFrame::data[AV_NUM_DATA_POINTERS]
操作
memcpy(datas[i].datas, frame->data, sizeof(frame->data)); // copy the frame data into an array
将AV_NUM_DATA_POINTERS
指针复制到datas [i] .datas中。这是不正确的,因为您只复制对自己未分配的帧缓冲区的引用。此外,只有最后一帧缓冲区保证在avcodec_decode_video2
之后可用。
只要您需要clone框架,就可以保留数据。
AVFrame* framearray[NUM_FRAMES];
...
if (finished)
{
framearray[i] = av_frame_clone(frame);
i++;
}