av_frame_get_buffer 后清理

Jas*_*n C 5 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, ...);
Run Code Online (Sandbox Code Playgroud)

除了调用av_frame_free(frame)?之外,是否必须手动释放任何缓冲区?文档没有提到任何特别之处,但根据我的经验,ffmpeg 文档通常会遗漏重要的细节,或者至少将它们隐藏在远离明显位置的地方。我查看了av_frame_freeand的代码,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);
Run Code Online (Sandbox Code Playgroud)

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

And*_*kin 4

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

回答你的第二个问题 -av_frame_free就会这样做。它将释放任何AVBufferRef附加的 s AVFrame,然后它会释放AVFrame自己。它不会触及缓冲区未引用的任何内容。