c++ - 在 av_frame_get_buffer 之后清理

标签 c++ ffmpeg libav

我的问题有两个方面。我正在使用 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);

有没有办法使用完全相同的代码来释放上面示例中的 frameframe2 那就是 frame 及其数据应该被释放,frame2 应该被释放,但 someBuffer 不会,因为 libav 没有分配它。

最佳答案

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

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

关于c++ - 在 av_frame_get_buffer 之后清理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40411996/

相关文章:

c++ - 通过 WinSocks 或任何其他 API 的应用程序的特殊路由?

c++ - 动态内存分配故障恢复

c++ - 给定噪声分布,用噪声破坏图像?

compilation - 你如何编译Winff?

ffmpeg - 将 AVPackets 复用到 mp4 文件中 - 重新审视

c++ - 以编程方式将原始数据发送到打印机

bash - 使用 bash 脚本以自然顺序列出文件夹中的文件

使用ffmpeg android在视频上叠加图像

FFMPEG:是否有可能在新 API 中获得 coded_width?

codec - FFMPEG中帧和包的区别