filter 即过滤器,可用来处理各种音视频特效,在代码中体现为一系列的算法。
熟悉 filter 首先要了解几个概念:
- filter chain 即有的特效需要多个 filter 组合,多个 filter 组合起来就是一个 filter chains
- filter graph, 完成目的特效所使用所有 filter 导向图,可以理解为 几个 filter chains 组合成一个 filter graph
- filter pad, 代表一个 filter 的输入输出引脚,本身 filter 就是一系列的算法代码,它需要处理数据,那么数据来源就是 输入,处理后的数据就是输出
- filter Link, 表示 filter 相连,只有一个 filter 的输出引脚和另一个 filter 的输入引脚名字相同,才表示这两个 filter 相连
一个 filter 的基本结构如下图所示,需要注意的是,输入输出引脚不一定是一个,或者有多个输入或输出
filter 相连:
一个简单的 graph:
如何实现一个 filter graph,最关键的就是如何将 graph 画出来,而借助 ffmpeg,我们只需要关心以下几个点:
- graph 的源数据缓存 buffer filter
- graph 的输出数据缓存 buffersink filter
- filter_desc 描述的 filter chains, 以及如何将 这个filter chains和源数据缓存和输出数据缓存相连即可
简单说明:
- buffer, 源数据缓存 filter
- 一个graph必须至少有一个 buffer
- buffer filter 只有一个输出引脚
- 通过 add_frame 接口给 buffer 送原始数据,而操作 buffer filter 需要 buffer_ctx 这个就和ffmpeg其他的 ctx 一样
- buffersink,输出数据缓存
- 一个graph必须至少有一个 buffersink
- buffersink filter 只有一个输入引脚
- 通过 add_frame 接口给 buffer 送原始数据,而操作 buffer filter 需要 buffer_ctx 这个就和ffmpeg其他的 ctx 一样
- filter_desc,即想完成目的特效所使用的命令
- 比如缩放 filter_desc=”[in]scale=w=640:h=480[out]”, 其中 [in] 表示其输入引脚名为 “in”, [out] 表示其输出引脚名为 “out”
- 而解析 filter_desc,由 ffmpeg 完成 filter chains 的组合, 使用 avfilter_graph_parse_ptr 即可
- 将 filter chains 和源数据缓存和输出数据缓存相连,就使用到了buffer 的输出引脚名和 buffer sink的输入引脚名。
- 将 buffer 的输出引脚名 和 filter_desc 的输入引脚名设置为相同名字时,这表示相连
- 将 buffersink 输入引脚名 和 filter_desc 的输出引脚名设置相同,则表示相连
- 连接的内部处理 使用的也是 avfilter_graph_parse_ptr 接口
完成以上的操作,即实现了 一个 filter graph,可对比 ffmpeg 给出的例子屡清楚以上的流程