其他分享
首页 > 其他分享> > ffmpeg buffer管理

ffmpeg buffer管理

作者:互联网


除了内存管理之外,数据的前后级流转也涉及到buffer管理. 个人觉得ffmpeg里面的buffer管理实现极为巧妙,也很值得借鉴.

概述

image

重要数据结构

AVBufferPool

在libavutil/buffer_internal.h中定义,为内部数据结构,不能在应用程序中直接引用.

image

image

BufferPoolEntry

在libavutil/buffer_internal.h中定义,为内部数据结构,不能在应用程序中直接引用.

从数据结构中开看到BufferPoolEntry就是一个链表,AVBufferPool中存储了BufferPoolEntry根节点.

image

AVBufferRef

在libavutil/buffer.h中定义,是对外的,可以在应用程序中直接引用.

image

       有两种方式创建AVBufferRef,一种是通过av_buffer_alloc,只要指定大小即可;另一种是

通过av_buffer_create,这种主要是用于已经有了数据的情况,同时它也支持自定义释放此

数据内存的方法

AVBuffer

在libavutil/buffer_internal.h中定义,为内部数据结构,不能在应用程序中直接引用.

AVBuffer对外不公开,必须要通过AVBufferRef来间接使用AVBuffer.

image

       AVBuffer在创建的时候引用计数为1,当调用av_buffer_ref()对其进行操作时,引用计数+1,当

av_buffer_unref对其操作时则引用计数-1(当-1后引用计数为0时,av_buffer_unref将自动释放分配的数据缓存

定义在libavutil/buffer.c中操作接口

Buffer管理

             以上的BufferPoolEntry的opaque、data、free都是指向了AVBuffer最开始的opaque、data、free,

然后AVBuffer自己的opaque和free则指向了BufferPoolEntry和pool_release_buffer为何这样设计呢,

因为AVBuffer最终要进行释放的话,那还是得调用它自己最本来的free函数,但是此时由于要放到

缓存池管理,因此在free时不能真正把AVBuffer释放了,因此用BufferPoolEntry来保存AVBuffer真正

的释放内存的函数,然后再用缓存池释放函数pool_release_buffer来代替free函数,这样,当用户

释放的时候,AVBuffer的free函数已经指向了pool_release_buffer函数,因此可以在pool_release_buffer

里把AVBuffer返回给缓存池,等到缓存池自己想要被释放的时候,这个时候缓存池就从BufferPoolEntry

把之前保存的真正释放AVBuffer的函数取出来,进行调用;不得不说,这个设计虽然非常绕,其实很巧妙.

image

如图:


有一个写的很好的播客,不过对应的ffmpeg版本要旧一点, 在ffmpeg 5.0版本中有些结构体和实现方式有变化.

https://blog.csdn.net/huweijian5/article/details/105549692/

2022-05-16

标签:ffmpeg,管理,buffer,opaque,free,BufferPoolEntry,pool,AVBuffer
来源: https://www.cnblogs.com/545235abc/p/16285869.html