可以在ffmpeg一些数据结构(oopc的类表示)中见到“void *priv_data”这种形式的成员,它有啥作用?设计的目的是啥?
这种私有数据存放是比较常见的设计方式了,一般保存对象this指针、结构体指针等等,用作模块的私有数据。ffmpeg也是这样。
《ffmpeg面向对象——rtsp拉流探索(1)》中rtsp拉流的对象图拿来分析下。
输入格式AVInputFormat类因为是根据url匹配出来的,所以定义了很多AVInputFormat类对象,但是其私有数据放到了AVFormatContext类的void *priv_data;成员中。如下图:
rtsp的输入格式AVInputFormat的实例对象是ff_rtsp_demuxer,为啥不把rtsp的私有数据RTSPState放到AVInputFormat类的成员中?其实都可以,只是不同的源代码实现。目前的方式原因在于:
(1)输入格式中的定义的接口read_header等形参是把AVInputFormat类的管理者AVFormatContext类对象作为形参的。
(2)节省内存。ffmpeg各个模块的私有数据放到表格里,延迟分配内存,而不是直接预先分配内存放到表格里。比如rtsp的输入格式AVInputFormat的实例对象ff_rtsp_demuxer定义:
它不是预先分配内存,而匹配到了再分配内存。
这个内存分配绑定机制参见《ffmpeg面向对象——参数配置机制及其设计模式探索》第6节。
还有协议类的私有数据也是如此,如下截图
URLProtocol协议类也是运行时匹配才能确定,比如tcp协议,它的私有数据就放到上一层的管理类——URLContext协议管理类——的void *priv_data;成员中。
如出一辙,这是ffmpeg的设计思路,形成了固定的模式,这种不用猜,肯定很多,这就形参了ffmpeg的代码规则。