简体   繁体   English

av_frame_get_buffer 后清理

[英]Cleaning up after av_frame_get_buffer

There are two aspects of my question.我的问题有两个方面。 I'm using libav, ffmpeg, 3.1.我正在使用 libav,ffmpeg,3.1。


First, how do you appropriately dispose of a frame whose buffer has been allocated with av_frame_get_buffer ?首先,您如何适当地处理已使用av_frame_get_buffer分配缓冲区的帧? Eg:例如:

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

Do any buffers have to be freed manually, beyond the call to av_frame_free(frame) ?除了调用av_frame_free(frame)之外,是否必须手动释放任何缓冲区? The documentation doesn't mention anything special, but in my experience the ffmpeg documentation often leaves out important details, or at least hides them in places far away from the obvious spots.文档没有提及任何特别之处,但根据我的经验,ffmpeg 文档通常会遗漏重要的细节,或者至少将它们隐藏在远离明显位置的地方。 I took a look at the code for av_frame_free and av_frame_unref but it branched out quite a bit and I couldn't quite determine if it covered everything.我查看了av_frame_freeav_frame_unref的代码,但它扩展了很多,我无法确定它是否涵盖了所有内容。


Second, if something beyond av_frame_free needs to be done, then is there any catch-all way to clean up a frame if you don't know how its data has been allocated?其次,如果需要完成av_frame_free之外的操作,那么如果您不知道框架的数据是如何分配的,那么有什么方法可以清理框架吗? For example, assuming someBuffer is already allocated with the appropriate size:例如,假设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);

Is there a way to free both frame and frame2 in the above examples using the exact same code?有没有办法在上面的例子中使用完全相同的代码来释放frameframe2 That is frame and its data should be freed, and frame2 should be freed, but not someBuffer , since libav did not allocate it.那就是frame和它的数据应该被释放,而frame2应该被释放,但不是someBuffer ,因为 libav 没有分配它。

To answer your first question - you don't need to do anything special to free buffers unless you are doing something funky (which you shouldn't). 要回答您的第一个问题-您不需要对空闲缓冲区做任何特殊的事情,除非您正在做一些时髦的事情(不应该这样做)。 Image data is owned by AVBuffer which includes a reference counter; 图像数据归AVBuffer所有,其中包括一个参考计数器; there are some references to that AVBuffer in a form of AVBufferRef . 有一些以AVBuffer形式对那个AVBufferAVBufferRef You can deal with AVBufferRef instances using relevant API - see libavutil/buffer.h for a description. 您可以使用相关的API处理AVBufferRef实例-有关说明,请参见libavutil/buffer.h AVFrame can hold references for the data it is pointing to, and generally you don't need to touch them as API will take care of that. AVFrame可以保存指向其指向的数据的引用,通常您无需触摸它们,因为API会解决这些问题。 You can use av_frame_get_buffer to allocate new buffers for the frame; 您可以使用av_frame_get_buffer为该帧分配新的缓冲区。 you can use av_frame_unref or av_frame_free to "clean up" the frame or clean up and release it (which might not free image data because it is used by some other AVFrame or by an encoder); 您可以使用av_frame_unrefav_frame_free来“清理”帧或清理并释放它(由于某些其他AVFrame或编码器使用了图像数据,它们可能不会释放图像数据); most if not all of other frame-related API is buffer-aware as well. 大多数(如果不是全部)其他与框架相关的API也都支持缓冲区。 Just make sure not to copy AVBufferRef pointers directly as that will circumvent reference counting - use av_buffer_ref instead. 只需确保不直接复制AVBufferRef指针即可,因为这会避免引用计数-使用av_buffer_ref代替。

To answer your second question - av_frame_free will do exactly that. 要回答您的第二个问题av_frame_free将完全做到这一点。 It will release any AVBufferRef s attached to AVFrame and then it will free AVFrame itself. 它会释放任何AVBufferRef小号连接到AVFrame ,然后它会释放AVFrame本身。 It will not touch anything that wasn't referenced by a buffer. 它不会碰到缓冲区未引用的任何内容。

if (frame->data != NULL) av_freep(&frame->data)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM