av_frame_get_buffer 后清理

Cleaning up after av_frame_get_buffer

我的问题有两个方面。我正在使用 libav、ffmpeg、3.1。


首先,如何正确处理已分配缓冲区的帧av_frame_get_buffer?例如:

AVFrame *frame = av_frame_alloc();
frame->width = ...;
frame->height = ...;
frame->format = ...;
av_frame_get_buffer(frame, ...);

除了调用 av_frame_free(frame) 之外,是否需要手动释放任何缓冲区? documentation 没有提到任何特别的东西,但在我的体验 ffmpeg 文档经常遗漏重要细节,或者至少将它们隐藏在远离明显点的地方。我查看了 av_frame_freeav_frame_unref 的代码,但它分支了很多,我无法确定它是否涵盖了所有内容。


其次,如果 需要完成 av_frame_free 以外的事情,那么如果 有没有什么万能的方法来清理框架不知道它的数据是怎么分配的?例如,假设 someBuffer 已经分配了适当的大小:

AVFrame *frame2 = av_frame_alloc();
frame2->width = ...;
frame2->height = ...;
frame2->format = ...;
av_image_fill_arrays(frame2->data, frame2->linesize, someBuffer, 
                     frame2->format, frame2->width, frame2->height, 1);

有没有办法使用完全相同的代码来释放上述示例中的 frameframe2frame它的数据应该被释放,并且 frame2 应该被释放,但不是 someBuffer,因为 libav 没有分配它。

回答你的第一个问题 - 你不需要做任何特别的事情来释放缓冲区,除非你正在做一些时髦的事情(你不应该这样做)。图像数据归 AVBuffer 所有,其中包括一个参考计数器;有一些以 AVBufferRef 的形式引用 AVBuffer。您可以使用相关的 API 处理 AVBufferRef 个实例 - 有关说明,请参阅 libavutil/buffer.hAVFrame 可以保存它指向的数据的引用,通常您不需要触摸它们,因为 API 会处理这些。您可以使用 av_frame_get_buffer 为帧分配新的缓冲区;您可以使用 av_frame_unrefav_frame_free 到 "clean up" 框架或清理并释放它(这可能不会释放图像数据,因为它被其他 AVFrame 或其他人使用编码器);大多数(如果不是全部)其他与帧相关的 API 也是缓冲区感知的。请确保不要直接复制 AVBufferRef 指针,因为那样会绕过引用计数 - 请改用 av_buffer_ref

要回答你的第二个问题 - av_frame_free 会做到这一点。它会释放任何附加到 AVFrameAVBufferRef,然后它会释放 AVFrame 本身。它不会触及缓冲区未引用的任何内容。