【FFMPEG】AVFrame中buffer分配的两种方式

AVFrame在使用ffmpeg进行编解码过程中,是最基本的数据结构。

在某些场景下,需要对AVFrame的数据区域进行提前分配,有两种方法,需要根据自己的需求来使用。

(1)

 * This function will fill AVFrame.data and AVFrame.buf arrays and, if
 * necessary, allocate and fill AVFrame.extended_data and AVFrame.extended_buf.

 * For planar formats, one buffer will be allocated for each plane.

int av_frame_get_buffer(AVFrame *frame, int align);

使用该接口分配到的数据空间,是可复用的,即内部有引用计数(reference),本次对frame data使用完成,可以解除引用,av_frame_unref(AVFrame *frame),调用后,引用计数减1,如果引用计数变为0,则释放data空间。

当然,也可以添加引用,接口:av_frame_ref(AVFrame *dst, const AVFrame *src)。

(2)

 * Allocate an image with size w and h and pixel format pix_fmt, and
 * fill pointers and linesizes accordingly.
 * The allocated image buffer has to be freed by using
 * av_freep(&pointers[0]).

int av_image_alloc(uint8_t *pointers[4], int linesizes[4], int w, int h, enum AVPixelFormat pix_fmt, int align);

如上接口,和(1)不同在于,(1)只要输入frame指针即可,而本接口看不到frame的数据结构,相比(1),分配的级别更低,看注释中“The allocated image buffer has to be freed by using  av_freep(&pointers[0])”,即,这种分配方式,不能用(2)中的解除引用来进行隐形释放了,需要自行调用释放才行。

注意使用过程中的坑:使用(1)进行分配后,调用ffmpeg某底层接口,结果,该接口对输入的frame做了一次解除引用,而外部调用并不知晓本次操作,从而导致可能的内存误释放,进而引起程序崩溃。

两个接口使用的代码示例:

  1. AVFrame *AllocFrame(enum AVPixelFormat format, int width, int height)
  2. {
  3. AVFrame *frame = av_frame_alloc();
  4. if (!frame) return NULL;
  5. frame->format = format;
  6. frame->width = width;
  7. frame->height = height;
  8. frame->pts = 0;
  9. int ret = av_image_alloc(frame->data, frame->linesize, frame->width, frame->height, (enum AVPixelFormat)frame->format, 1);
  10. if (ret < 0)
  11. {
  12. av_frame_free(&frame);
  13. return NULL;
  14. }
  15. return frame;
  16. }
  1. AVFrame *AllocFrame(enum AVPixelFormat pix_fmt, int width, int height) {
  2.   AVFrame *frame;
  3.   int ret;
  4.   frame = av_frame_alloc();
  5.   if (!frame) return NULL;
  6.   frame->format = pix_fmt;
  7.   frame->width = width;
  8.   frame->height = height;
  9.   ret = av_frame_get_buffer(frame, 32);
  10.   if (ret < 0) {    
  11.   av_frame_free(&frame);   
  12.   return NULL;
  13.   }
  14.   return frame;
  15. }
https://blog.csdn.net/Blaze_bxh/article/details/80010857
上一篇:FFmpeg音频解码


下一篇:FFmpeg av_image_fill_arrays填充AVFrame数据缓冲