我的问题有两个方面。我正在使用 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_free
和 av_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);
有没有办法使用完全相同的代码来释放上面示例中的 frame
和 frame2
? 那就是 frame
及其数据应该被释放,frame2
应该被释放,但 someBuffer
不会,因为 libav 没有分配它。
最佳答案
要回答您的第一个问题 - 您不需要做任何特别的事情来释放缓冲区,除非您正在做一些时髦的事情(您不应该这样做)。图像数据由 AVBuffer
拥有,其中包括一个引用计数器;有一些以 AVBufferRef
形式引用该 AVBuffer
。您可以使用相关 API 处理 AVBufferRef
实例 - 有关说明,请参阅 libavutil/buffer.h
。 AVFrame
可以保存它指向的数据的引用,通常您不需要接触它们,因为 API 会处理这些。您可以使用 av_frame_get_buffer
为帧分配新的缓冲区;您可以使用 av_frame_unref
或 av_frame_free
来“清理”框架或清理并释放它(这可能不会释放图像数据,因为它被其他一些 使用AVFrame
或编码器);大多数(如果不是全部)其他与帧相关的 API 也是缓冲区感知的。只需确保不要直接复制 AVBufferRef
指针,因为这会绕过引用计数 - 请改用 av_buffer_ref
。
要回答您的第二个问题 - av_frame_free
将完全做到这一点。它将释放所有附加到 AVFrame
的 AVBufferRef
,然后释放 AVFrame
本身。它不会触及缓冲区未引用的任何内容。
关于c++ - 在 av_frame_get_buffer 之后清理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40411996/