C++ 在循环中使用av_read_frame缓存AVFrames仅获取最后几帧

C++ 在循环中使用av_read_frame缓存AVFrames仅获取最后几帧,c++,ffmpeg,C++,Ffmpeg,我正在尝试使用opengl逐帧处理视频。 我使用ffmpeg从视频文件中读取帧 在开始处理帧之前,我想先读取一些帧并将它们存储在内存中。 所以我尝试在while循环中使用av_read_frame,并将帧数据复制到数组中 但是,当我试图显示这些帧时,我发现我只得到最后几帧。 例如,如果我想缓存50帧,但只能获取最后几帧(第45帧到第50帧) 下面是我用来缓存帧的代码: void cacheFrames() { AVPacket tempPacket; av_init_packet

我正在尝试使用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);
}
void cacheFrames()
{
AVPacket-temp-packet;
av_初始_数据包(和临时数据包);
int i=0;
avcodec_flush_缓冲区(formatContext->streams[streamIndex]->编解码器);
codecContext=formatContext->streams[streamIndex]->codec;
while(av_read_frame(formatContext,&tempacket)>=0&&i data,sizeof(frame->data));//将帧数据复制到数组中
i++;
}
}
}
av_免费_数据包(和临时数据包);
}

那么,我做错了什么呢?

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_指针
指针复制到数据[i].datas中。这是不正确的,因为您只将引用复制到未分配给自己的帧缓冲区。另外,在
avcodec\u decode\u video2
之后,仅保证最后一帧缓冲区可用

将数据保留到帧中所需的时间

AVFrame* framearray[NUM_FRAMES];
...
if (finished)
{
     framearray[i] = av_frame_clone(frame);
     i++;
}

谢谢,哥们,你说得对,我以前试过用av帧拷贝,但没用。av_frame_clone很有魅力。不客气。有些ffmpeg函数很棘手,几乎需要您阅读源代码才能理解它们实际上在做什么