Filtering Introduction
Filtering in FFmpeg is enabled through the libavfilter library.
FFmpeg中的Filtering可以通过libavfilter library来使用。
In libavfilter, a filter can have multiple inputs and multiple outputs. To illustrate the sorts of things that are possible, we consider the following filtergraph.
在libavfilter中,一个filter可以有多个输入和多个输出。为了说明这些事情可实现的可能,我们看下下面这幅图
[main]
input --> split ---------------------> overlay --> output
| ^
|[tmp] [flip]|
+-----> crop --> vflip -------+
This filtergraph splits the input stream in two streams, then sends one stream through the crop filter and the vflip filter, before merging it back with the other stream by overlaying it on top. You can use the following command to achieve this:
这副图中input stream被切割为2个stream,然后将其中一路stream通过crop filter和vflip filter送出然后通过盖在另一路stream上方的方式与另一路stream融合。你可以通过下面的命令来实现此功能:
ffmpeg -i INPUT -vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2" OUTPUT
The result will be that the top half of the video is mirrored onto the bottom half of the output video.
上述命令的执行结果是视频的上半部分是输出视频的下半部分的镜像。
Filters in the same linear chain are separated by commas, and distinct linear chains of filters are separated by semicolons. In our example,crop,vflip are in one linear chain, split and overlay are separately in another. The points where the linear chains join are labelled by names enclosed in square brackets. In the example, the split filter generates two outputs that are associated to the labels [main] and [tmp].
同一线性链路中的Filters使用逗号隔开,不同链路中的filters使用分号隔离。在我们的例子中crop和vflip是一个线性链路,split 和 overlay在另一个线性链路。两条线性链路的交汇点使用使用方括号中的名称来标记。在例子中,split filter产生了两个输出分别标记为[main]和[tmp]
The stream sent to the second output of split, labelled as [tmp], is processed through the crop filter, which crops away the lower half part of the video, and then vertically flipped. The overlay filter takes in input the first unchanged output of the split filter (which was labelled as [main]), and overlay on its lower half the output generated by the crop,vflip filterchain.
spilt输出的第二路stream被标记为[tmp], 该stream被 crop filter处理:裁剪掉视频的下半部分,然后垂直翻转.overlay filter 将 split filter(标记为[main])的第一个未更改输出作为输入,并在其下半部分覆盖crop,vflip filterchain生成的输出。
Some filters take in input a list of parameters: they are specified after the filter name and an equal sign, and are separated from each other by a colon.
一些过滤器接受参数列表的输入:它们在filter名称和等号之后指定,并且彼此之间用冒号分隔。
There exist so-called source filters that do not have an audio/video input, and sink filters that will not have audio/video output.
没有audio/video输入的filters被称作source filters, 没有audio/video输出的filters被称作 sink filters。
Filtergraph description
A filtergraph is a directed graph of connected filters. It can contain cycles, and there can be multiple links between a pair of filters. Each link has one input pad on one side connecting it to one filter from which it takes its input, and one output pad on the other side connecting it to one filter accepting its output.
filtergraph是连接filters的有向图。它可以包含循环,一对filters中间可以存在多个链路。每个链接的一侧有一个 input pad ,将其连接到一个filter ,从中获取输入,另一侧有一个output pad,将其连接到一个接受其输出的filter。
Each filter in a filtergraph is an instance of a filter class registered in the application, which defines the features and the number of input and output pads of the filter.
filtergraph 中的每个filter 都是在应用程序中注册的filter class的实例,它定义了filter的特征和 input output pad的数量。
A filter with no input pads is called a “source”, and a filter with no output pads is called a “sink”.
没有输入pads 的filter 称为“source”,没有输出pads 的filter 称为“sink”。
Filtergraph syntax
A filtergraph has a textual representation, which is recognized by the -filter/-vf/-af and -filter_complex options in ffmpeg and -vf/-af in ffplay, and by the avfilter_graph_parse_ptr() function defined in libavfilter/avfilter.h.
filtergraph 有一个文本表示,它在ffmpeg中通过 -filter/-vf/-af和 -filter_complex 选项识别,ffplay中通过-vf/-af 识别。并通过 avfilter_graph_parse_ptr()在中定义的函数 libavfilter/avfilter.h函数解析。
A filterchain consists of a sequence of connected filters, each one connected to the previous one in the sequence. A filterchain is represented by a list of “,”-separated filter descriptions.
filterchain 由一系列连接的filters组成,每个filters都连接到序列中的前一个filters。filterchain 由“,”分隔的filter列表表示。
A filtergraph consists of a sequence of filterchains. A sequence of filterchains is represented by a list of “;”-separated filterchain descriptions.
filtergraph由一系列过filterchains组成。filterchains序列由“;”分隔的过filterchains描述列表表示。
A filter is represented by a string of the form: [in_link_1]…[in_link_N]filter_name@id=arguments[out_link_1]…[out_link_M]
过滤器由以下形式的字符串表示: [ in_link_1 ]…[ in_link_N ] filter_name@id = arguments [ out_link_1 ] … [ out_link_M ]
filter_name is the name of the filter class of which the described filter is an instance of, and has to be the name of one of the filter classes registered in the program optionally followed by “@id”. The name of the filter class is optionally followed by a string “=arguments”.
filter_name是filter class的名称,filter_name所描述的filter是它的一个实例,并且必须是在程序中注册的filter class之一的名称,可选地后跟“@id ”。filter class的名称后面可以选择跟一个字符串“= arguments ”。
arguments is a string which contains the parameters used to initialize the filter instance. It may have one of two forms:
A ’:’-separated list of key=value pairs.
A ’:’-separated list of value. In this case, the keys are assumed to be the option names in the order they are declared. E.g. the fade filter declares three options in this order – type, start_frame and nb_frames. Then the parameter list in:0:30 means that the value in is assigned to the option type, 0 to start_frame and 30 to nb_frames.
A ’:’-separated list of mixed direct value and long key=value pairs. The direct value must precede the key=value pairs, and follow the same constraints order of the previous point. The following key=value pairs can be set in any preferred order.
arguments是一个字符串,其中包含用于初始化filter实例的参数。它可能具有以下两种形式之一:
- 以“:”分隔的键=值对列表。
- 以“:”分隔的值列表。在这种情况下,假定键是按声明顺序排列的选项名称。例如,fade过滤器按此顺序声明三个选项 –type, start_frame and nb_frames. 那么参数列表in:0:30表示将in的值 赋值给option type, 0赋值给start_frame和30赋值给nb_frames.
- 以“:”分隔的混合直接值和长键=值对列表 。直接值必须在键=值对之前,并遵循与前一点相同的约束顺序。可以按任何首选顺序设置 以下
键=值对。
If the option value itself is a list of items (e.g. the format filter takes a list of pixel formats), the items in the list are usually separated by ‘|’.
如果option值本身是一个列表(例如,format filter采用像素格式列表),则列表中的项目通常由 ‘|’.
The list of arguments can be quoted using the character ‘'’ as initial and ending mark, and the character ‘\’ for escaping the characters within the quoted text; otherwise the argument string is considered terminated when the next special character (belonging to the set ‘[]=;,’) is encountered.
arguments list可以使用字符 ‘'’作为开始和结束标记被引用,字符 ‘’ 用于转义引用文本中的字符;否则 当下一个特殊字符( ‘[]=;,’)被遇到的时候,argument字符串将被认为中断了。
A special syntax implemented in the ffmpeg CLI tool allows loading option values from files. This is done be prepending a slash ’/’ to the option name, then the supplied value is interpreted as a path from which the actual value is loaded. E.g.
ffmpeg -i <INPUT> -vf drawtext=/text=/tmp/some_text <OUTPUT>
ffmpeg中实现的特殊语法,CLI 工具允许从文件加载选项值。这是通过在选项名称前添加一个斜杠“/”来完成的,然后将提供的值解释为加载实际值的路径。
will load the text to be drawn from /tmp/some_text. API users wishing to implement a similar feature should use the avfilter_graph_segment_*() functions together with custom IO code.
上述命令中将加载要从中绘制的文本/tmp/some_text. 希望实现类似功能的 API 用户应将这些avfilter_graph_segment_*() 功能与自定义 IO 代码一起使用。
The name and arguments of the filter are optionally preceded and followed by a list of link labels. A link label allows one to name a link and associate it to a filter output or input pad. The preceding labels in_link_1 … in_link_N, are associated to the filter input pads, the following labels out_link_1 … out_link_M, are associated to the output pads.
filter的名称和参数可选地前后跟有链接标签列表。链接标签允许人们命名链接并将其关联到filter 输出或输入pad。前面的标签in_link_1 … in_link_N与pad输入pad相关联,以下标签out_link_1 … out_link_M与输出pad相关联。
When two link labels with the same name are found in the filtergraph, a link between the corresponding input and output pad is created.
当在filtergraph中找到两个具有相同名称的链接标签时,将创建相应输入和输出pad 之间的链接。
If an output pad is not labelled, it is linked by default to the first unlabelled input pad of the next filter in the filterchain. For example in the filterchain
如果未标记输pad,则默认情况下将其链接到过滤器链中下一个filterchain的第一个未标记输入pad。例如在下面的filterchain中
nullsrc, split[L1], [L2]overlay, nullsink
the split filter instance has two output pads, and the overlay filter instance two input pads. The first output pad of split is labelled “L1”, the first input pad of overlay is labelled “L2”, and the second output pad of split is linked to the second input pad of overlay, which are both unlabelled.
split filter实例有两个输出pad,overlay filter实例有两个输入pad。split 的第一个输出pad标记为“L1”,overlay 的第一个输入pad标记为“L2”,split 的第二个输出pad链接到 overlay 的第二个输入pad,两者均未标记。
In a filter description, if the input label of the first filter is not specified, “in” is assumed; if the output label of the last filter is not specified, “out” is assumed.
在filter description中,如果没有指定第一个filter的输入标签,则假定为“in”;如果未指定最后一个filter的输出标签,则假定为“out”。
In a complete filterchain all the unlabelled filter input and output pads must be connected. A filtergraph is considered valid if all the filter input and output pads of all the filterchains are connected.
在完整的filterchain中,所有未标记的filter 输入和输出pads都必须连接。如果所有过filtergraph的所有过滤器输入和输出pad都已连接,则过filtergraph被认为是有效的。
Libavfilter will automatically insert scale filters where format conversion is required. It is possible to specify swscale flags for those automatically inserted scalers by prepending sws_flags=flags; to the filtergraph description.
Libavfilter 会自动在需要格式转换的地方插入缩放filters 。可以通过 在 filtergraph 描述之前为那些自动插入的缩放器指定 swscale 标志。 sws_flags=flags;
Here is a BNF description of the filtergraph syntax:
NAME ::= sequence of alphanumeric characters and '_'
FILTER_NAME ::= NAME["@"NAME]
LINKLABEL ::= "[" NAME "]"
LINKLABELS ::= LINKLABEL [LINKLABELS]
FILTER_ARGUMENTS ::= sequence of chars (possibly quoted)
FILTER ::= [LINKLABELS] FILTER_NAME ["=" FILTER_ARGUMENTS] [LINKLABELS]
FILTERCHAIN ::= FILTER [,FILTERCHAIN]
FILTERGRAPH ::= [sws_flags=flags;] FILTERCHAIN [;FILTERGRAPH]