我正在使用 FFMPEG 解码视频流,并且我已经实现了用于
AVFrame
内存分配和取消分配的自定义函数(通过为 codec_ctx->get_buffer2
设置自定义函数)。因此,当 AVFrame
需要新内存时,我会进行内存分配并使用 AvBufferRef
将 av_buffer_create
包裹在其周围。我还定义了自定义的解除分配函数,因此当不再需要引用计数AvBufferRef
时,我会进行内存清理。
这样我就可以准确记录内存何时分配以及缓冲区何时空闲。
在视频解码期间,我想要进行搜索,为此我需要清除我的
AVCodecContext
中的所有缓冲区。我正在关注官方文档:
NULL
到解码器AVCodecContext
这是代码:
avcodec_send_packet(codec_ctx, NULL);
auto result = 0;
while (result != AVERROR_EOF)
{
auto frame = av_frame_alloc();
result = avcodec_receive_frame(codec_ctx, frame);
av_frame_free(&frame);
}
avcodec_flush_buffers(codec_ctx);
但是,我可以看到(由于我的自定义内存管理)并非所有帧都被释放。 仅当我通过调用
avcodec_free_context
关闭编解码器上下文时,我才能看到所有帧都被释放。
有什么提示我可以完全释放
AVCodecContext
中的所有资源(而不关闭它)吗?
我终于可以自己回答这个问题了:
函数
avcodec_flush_buffers
将调用解码器实现中的刷新函数。就我而言(VP9 解码器),刷新函数无法正确清理所有资源。
然而,效果很好的是以下方法。
avcodec_send_packet
返回 AVERROR(EAGAIN)
这样,解码器上所有剩余的帧引用都将被释放。