首页 > 代码库 > 解构ffmpeg(二)
解构ffmpeg(二)
通过比较DirectShow和ffmpeg两者的FilterGraph,分析ffmpeg的FilterGraph运作。
首先FilterGraph是一个图,图由点和边构成。在FilterGraph中的点就是Filter。在DirectShow中,没有边对象,Filter的连接依赖Pin组件以及IPin接口,一对InputPin和OutputPin构成一条边。每个Filter可以有至少一个Pin,即每个点有至少一条边,(排除只有一个点的图,和没有邻接边的点的情况)。构成连接的InputPin和OutputPin互相持有对方的引用。FilterGraph的运作依赖IPin接口的三个方法read,async_read以及receive。上流数据通过出边(OutputPin)调用对端的入边(InputPin)的receive推送到下游。逆过来,下游通过入边(InputPin)调用对端的出边(OutputPin)的read或async_read向上流拉数据。上游源数据得以经过图中某条路径到达下游目的地。
在ffmpeg里,AVFilterContext则是点,AVFilterLink则是边。AVFilterLink是AVFilterContext的出入边,AVFilterContext则是AVFilterLink的邻点。AVFilterPad是相当于Pin的部件,使FilterGraph可以运行起来。AVFilterPad主要功能是三个接口函数,poll_frame,request_frame以及filter_frame。
通过递归向下游“先序”遍历,推送帧数据
filter_frame (link, frame) { filter (frame); input_pad->filter_frame (link, frame); }
通过递归向上游“后序”遍历,拉帧数据
request_frame (link, frame) { output_pad->request_frame (link, frame); filter (frame); }
对象图请参看上一篇《解构ffmpeg(一)》。
解构ffmpeg(二)