FFmpeg filter的使用介绍

目录

  1. 参考
  2. FFmpeg filter简介
  3. filter的使用方法

1. 参考

2. FFmpeg filter简介

FFmpeg filter提供了很多音视频特效处理的功能,比如视频缩放、截取、翻转、叠加等。

其中定义了很多的filter,例如以下常用的一些filter。

  • scale:视频/图像的缩放
  • overlay:视频/图像的叠加
  • crop:视频/图像的裁剪
  • trim:截取视频的片段
  • rotate:以任意角度旋转视频

支持的filter的列表可以通过以下命令获得。

ffmpeg -filters

也可以查看文档[2],具体某个版本的支持情况以命令行获取到的结果为准。

以下是filter的一个简单的应用示例,对视频的宽和高减半。

ffmpeg -i input -vf scale=iw/2:ih/2 output

3. filter的使用方法

学习filter的使用,先需要了解一下filter的语法。
FFmpeg中filter包含三个层次,filter->filterchain->filtergraph。
具体参考下图:


filter_syntax.png

说明:

  • 第一层是 filter 的语法。
  • 第二层是 filterchain的语法。
  • 第三层是 filtergraph的语法。

filtergraph可以用文本形式表示,可以作为ffmpeg中的-filter/-vf/-af和-filter_complex选项以及ffplay中的-vf/-af和libavfilter/avfilter.h中定义的avfilter_graph_parse_ptr()函数的参数。

为了说明可能的情况,我们考虑下面的例子“把视频的上部分镜像到下半部分”。
处理流程如下:

  1. 使用split filter将输入流分割为两个流[main]和[temp]。
  2. 其中一个流[temp]通过crop filter把下半部分裁剪掉。
  3. 步骤2中的输出再经过vflip filter对视频进行和垂直翻转,输出[flip]。
  4. 把步骤3中输出[flip]叠加到[main]的下半部分。

以下整个处理过程的一个图示,也就是对filtergraph的一个描述[2]。

[main]
input --> split ---------------------> overlay --> output
            |                             ^
            |[tmp]                  [flip]|
            +-----> crop --> vflip -------+

可以用以下的命令来实现这个流程。

ffmpeg -i INPUT -vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2" OUTPUT

处理结果如下图所示。


vertical_mirror.PNG

下面具体了解每一层的语法,从而理解上面这个命令的含义。

3.1 filter的语法

用一个字符串描述filter的组成,形式如下

[in_link_1]…[in_link_N]filter_name=parameters[out_link_1]…[out_link_M]

参数说明:

  1. [in_link_N]、[out_link_N]:用来标识输入和输出的标签。in_link_N是标签名,标签名可以任意命名,需使用方括号括起来。在filter_name的前面的标签用于标识输入,在filter_name后面的用于标识输出。一个filter可以有多个输入和多个输出,没有输入的filter称为source filter,没有输出的filter称为sink filter。对输入或输出打标签是可选的,打上标签是为了连接其他filter时使用。
  2. filter_name:filter的名称。
  3. “=parameters”:包含初始化filter的参数,是可选的。

“=parameters”有以下几种形式

  1. 使用':'字符分隔的一个“键=值”对列表。如下所示。
ffmpeg -i input -vf scale=w=iw/2:h=ih/2 output
  1. 使用':'字符分割的“值”的列表。在这种情况下,键按照声明的顺序被假定为选项名。例如,scale filter的前两个选项分别是w和h,当参数列表为“iw/2:ih/2”时,iw/2的值赋给w,ih/2的值赋给h。如下所示。
ffmpeg -i input -vf scale=iw/2:ih/2 output
  1. 使用':' 字符分隔混合“值”和“键=值”对的列表。“值”必须位于“键=值”对之前,并遵循与前一点相同的约束顺序。之后的“键=值”对的顺序不受约束。如下所示。
ffmpeg -i input -vf scale=iw/2:h=ih/2 output

filter类定义了filter的特性以及输入和输出的数量,某个filter的使用方式可以通过以下命令获知。

ffmpeg -h filter=filter_name

也可以查看文档[2],但具体某个版本的参数形式以命令行获取到的结果为准。

以下是rotate filter的使用方式


filter_rotate.PNG
  • 可以看出它支持slice threading。
  • Inputs下面定义的是输入。可以看出rotate filter有一个输入,格式为Video。
  • Outputs下面定义的是输出。可以看出rotate filter有有一个输出,格式为video。
  • AVOptions下面定义了支持的参数,后面有默认值描述。为了简化输入参数,对长的参数名提供一个简化的名称。比如rotate filter中,“angle”的简化名称是“a”。

以下是使用到fiter的标签名的一个示例:抽取视频Y、U、V分量到不同的文件

ffmpeg -i jack.mp4 -filter_complex "extractplanes=y+u+v[y][u][v]" -map "[y]" jack_y.mp4 -map "[u]" jack_u.mp4 -map "[v]" jack_v.mp4    

extractplanes filter指定了三个输出,分别是 [y][u][v],抽取后,将不同的输出保存到不同的文件中。

3.2 filterchain的语法

用一个字符串描述filterchain的组成,形式如下

"filter1, filter2, ... filterN-1, filterN"

说明:

  1. 由一个或多个filter的连接而成,filter之间以逗号“,”分隔。
  2. 每个filter都连接到序列中的前一个filter,即前一个filter的输出是后一个filter的输入。

比如示例

ffmpeg -i INPUT -vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2" OUTPUT

示例说明:

  1. crop、vflip在同一个filterchain中,

3.3 filtergraph的语法

用一个字符串描述filtergraph的组成,形式如下
"filterchain1;filterchain2;...filterchainN-1;fiterchainN"
说明:

  1. 由一个或多个filter的组合而成,filterchain之间用分号";"分隔。
  2. filtergraph是连接filter的有向图。它可以包含循环,一对filter之间可以有多个连接。
  3. 当在filtergraph中找到两个相同名称的标签时,将创建相应输入和输出之间的连接。
  4. 如果输出没有被打标签,则默认将其连接到filterchain中下一个filter的第一个未打标签的输入。例如以下filterchain中。
nullsrc, split[L1], [L2]overlay, nullsink

说明:split filter有两个输出,overlay filter有两个输入。split的第一个输出标记为“L1”,overlay的第一个输入pad标记为“L2”。split的第二个输出将连接到overlay的第二个输入。

  1. 在一个filter描述中,如果没有指定第一个filter的输入标签,则假定为“In”。如果没有指定最后一个filter的输出标签,则假定为“out”。
  2. 在一个完整的filterchain中,所有没有打标签的filter输入和输出必须是连接的。如果所有filterchain的所有filter输入和输出pad都是连接的,则认为filtergraph是有效的[2]。

比如示例

ffmpeg -i INPUT -vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2" OUTPUT

其中有三个filterchain, 分别是:

  1. "split [main][tmp]"。它只有一个filter,即 split,它有一个默认的输入,即INPUT解码后的frame。有两个输出, 以 [main], [tmp] 标识。
  2. "[tmp] crop=iw:ih/2:0:0, vflip [flip]"。它由两个filter组成,crop和vflip,crop的输入 为[tmp],vflip的输出标识为[flip]。
  3. "[main][flip] overlay=0:H/2"。它由一个filter组成,即overlay。有两个输入,[main]和[flip]。有一个默认的输出。

推荐阅读更多精彩内容