FFMPEG-Filter学习笔记-1

文档来源:http://www.ffmpeg.org/ffmpeg-filters.html#Description

1 Description

This document describes filters, sources, and sinks provided by the libavfilter library.
这个文档用来描述libavfilter库提供的 filters, sourcessinks.

2 Filtering Introduction

Filtering in FFmpeg is enabled through the libavfilter library.
我们可以通过ffmpeg的libavfilter库来使能 Filtering (滤镜)功能。

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可以有多个输入和多个输出。我们用下面的 filtergraph(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:
这张filtergraph中,[input]流被 split filter一分为二,分别命名为 [main] [tmp],
[tmp]流被 crop filter 裁剪,之后被 vflip filter竖直翻转,变为 [flip]流,
最后 [main] [flip]通过 overlay fitler 叠加输出,为 [output]流。可以使用如下命令来获取此效果。

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

为了可以看到更直观的效果,我使用了ffplay来直接使用filter并播放

ffplay -i EX_h.265_AAC_1080_2.mp4 -x 640 -y 480 -vf "split[main][tmp];[tmp]crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2"

与原图效果对比如下:
原图
处理后的图

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,使用 逗号 来分隔,不同链中的filter,使用 分号 来分隔。
在这个例子中, crop, vflip 处于同一个链中, split 和 overlay 处在不同的链。
我们使用加方括号的名字来标记滤镜链中的 points。
这个例子中, split filters 有两路输出,分别命名为 [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.

split filter的第二路输入--[tmp]流--会被crop filter 处理,裁掉了视频的下半部,并被竖直翻转。
overlay filter 不处理第一路输入(即 [main] 流), 只是把第二路流(即经过裁剪翻转后的流)覆盖到第一路流上。

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.

我们需要传一些参数给filters:参数和filter之间用等号隔开,参数之间使用冒号分隔。

(如: filter1=key1=value1:key2=value2

There exist so-called source filters that do not have an audio/video input, and sink filters that will not have audio/video output.

没有音视频输入流的filter 叫做 source filter, 没有音视频输出流的filter 叫做 sink filter。

3 graph2dot

The graph2dot program included in the FFmpeg tools directory can be used to parse a filtergraph description and issue a corresponding textual representation in the dot language.

ffmpeg源码中tools路径下的 graph2dot  程序,可以解析 filtergraph,并用dot 语言的形式来表示输出的文本文档。

Invoke the command:

graph2dot -h

to see how to use graph2dot.

请使用 graph2dot -h 命令来查看详细使用说明

You can then pass the dot description to the dot program (from the graphviz suite of programs) and obtain a graphical representation of the filtergraph.

你通过传dot描述(即你的filter参数)给dot program(来自graphviz 的套装程序)
来可以获得 filtergraph的图片。

For example the sequence of commands:

如下命令:
echo GRAPH_DESCRIPTION | \
tools/graph2dot -o graph.tmp && \
dot -Tpng graph.tmp -o graph.png && \
display graph.png

can be used to create and display an image representing the graph described by the GRAPH_DESCRIPTION string. Note that this string must be a complete self-contained graph, with its inputs and outputs explicitly defined. For example if your command line is of the form:

可以根据你的 GRAPH_DESCRIPTION字符串,来创建并显示一张filtergraph图片。
注意:这条字符串必须是一个完成闭环图,即输入输出都需要显示定义。
例如,你(使用filter)的命令可以是如下形式:
ffmpeg -i infile -vf scale=640:360 outfile

your GRAPH_DESCRIPTION string will need to be of the form:

那么你的 GRAPH_DESCRIPTION 字符串应该是如下形式:
nullsrc,scale=640:360,nullsink

you may also need to set the nullsrc parameters and add a format filter in order to simulate a specific input file.

你也可以给 nullsrc 之后增加 format filter, 以便以特定的格式去显示输入文件。

译注:

1、编译 graph2dot
直接在ffmpeg目录下, make tools/graph2dot 即可
2、使用
如:敲入如下命令
echo "nullsrc,split[main][tmp];[tmp]crop=iw:ih/2:0:0,vflip[flip];[main][flip]overlay=0:H/2,nullsink"| graph2dot -o graph.tmp && dot -Tpng graph.tmp -o graph.png && display graph.png
生成的graph.png如下:

在这里插入图片描述

4 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图包含了许多相关联的filter.
它可以包含若干cycle,因为一对filter之间可以有多个link (如第二节中的split 和overlay filter之间有两条link ,这就是一个cycle)。
每个link有一个输入,供头部的filter去处理,有一个输出,由尾部的filter生成。
(如第二节中的filtergraph中, split到overlay filter这条link上, 头部的split filter去接收输入 input,尾部的 overlay filter去生成 输出 output)

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,就是注册到app总的一个filter类的实例,
这个实例规定了filter的特性,以及输入输出流的数量。

A filter with no input pads is called a “source”, and a filter with no output pads is called a “sink”.

没有输入流的filter 叫做 source filter, 没有输出流的filter 叫做 sink filter。

4.1 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.

ffmpeg命令中 -filter/-vf/-af和 -filter_complex 之后的参数,
和 ffplay 命令中 -vf/-af 之后的参数,
还有 libavfilter/avfilter.h文件中avfilter_graph_parse_ptr函数涉及的参数,
都可以被 filtergraph识别。

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包含了一系列相关的filter,每一个filter的输出就是下一个filter的输入。
filter之间使用 逗号 分隔。(第二节中的crop 和vflip filter就是使用逗号分隔的)

A filtergraph consists of a sequence of filterchains. A sequence of filterchains is represented by a list of “;”-separated filterchain descriptions.

filtergraph包含了一系列 filterchain.
filterchain之间使用 分号分隔.
(第二节中的 spilt, overlay以及二者之间的那条filterchain,三者就是被分号分隔的)。

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]

一个filter表现形式如下:
[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实例的名字,而且必须是程序中注册过的filter类,
名字中的 “@id” 可以不写(是这个意思?暂时还没有搞明白这个@id的用法?)
之后是可选参数,可选参数的形式是 “=arguments”

arguments is a string which contains the parameters used to initialize the filter instance. It may have one of two forms:
arguments 就是用于初始化filter实例的字符串参数,必须是两种形式中的其中一种:

  • A ’:’-separated list of key=value pairs.

     冒号可以分隔 key=value 这种有名参数
    
  • 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.

      冒号可以分隔 value这种匿名参数。
      这种情况下,根据具体filter声明的参数key的顺序,依次匹配value值。
      例如: fade filter依次声明了三个选项-- type, start_frame和 nb_frame. 
      则参数列表 in:0:30,意味着 type为in, start_frame=0, nb_frame=30.
    
  • 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.

	一个冒号也可以同时分隔匿名参数和有名参数(同时分隔以上两种情况)。
	匿名参数列表必须置于有名参数列表之前,
	匿名参数列表的顺序必须按照filter中参数选项的声明顺序,
	之后的有名参数列表的顺序随意。

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 ‘|’.

如果选项值的成员有多个(例如,format filter可以接受多个pixel format参数),
则每个成员之间使用 '|' 来分隔。

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.

我们可以用单引号‘'’来引用参数列表,指示参数列表的前后范围,
引文中的特殊字符可以用反斜杠‘\’来转义;
否则遇到的这些特殊字符(特殊字符共有五个,分别为 [ ] = ; ,)
被当做终结字符来处理。

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.

link label可以放置于filter的名字和参数之前,也可以放置于其后 .
一个link label可以被命名,之后会被关联到filter的输入或者输出。
filter之前的 label会被当做输入流,之后的label被当做输出流。

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中两个 link label的名字相同时,二者的输入输出关系会被建立。

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

如果filter的一个输出流没有被标记,则它会被关联到当前filterchain中下一个filter的未被标记的输入流。
例如,如下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应该有两路输出流,overlay filter应该有两路输入流。
split filter的第一路输出流被标记为 “L1”
overlay filter的第一路输入流被标记为“L2”
split filter的第二路输入流会和overlay filter的第二路输入流会建立关联,尽管它们都没有被标记。

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的描述中,第一个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中,所有未被标记的输入输出流必须建立关联。
如果所有的输入输出流均建立了关联,则这个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遇到格式转换的场景时,会自动插入scale filter。
所以最好在filtergraph描述之前增加参数 sws_flags=flags,
用于指定这些scale filter的flags。

Here is a BNF description of the filtergraph syntax:

以下是 filtergraph 语法的 巴科斯范式(BNF)描述:
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]

4.2 Notes on filtergraph escaping

Filtergraph description composition entails several levels of escaping. See (ffmpeg-utils)the “Quoting and escaping” section in the ffmpeg-utils(1) manual for more information about the employed escaping procedure.
filtergraph有若干级别的转义.可以通过此文来学习了解转义过程。

A first level escaping affects the content of each filter option value, which may contain the special character : used to separate values, or one of the escaping characters '.

第一层转义只是filter层级的,只会影响每个filter选项值的内容,
这些内容可能包含一些特殊字符:用于分隔内容的字符,或者单引号。

A second level escaping affects the whole filter description, which may contain the escaping characters ’ or the special characters [],; used by the filtergraph description.

第二层转义是filtergraph description, 会影响整个filtergraph description,可能包含,单引号,一些特殊字符,如 [ ] ,等;

Finally, when you specify a filtergraph on a shell commandline, you need to perform a third level escaping for the shell special characters contained within it.

最后,如果是在shell命令行下使用 filtergraph时,还需要对命令行中的特殊字符进行转义,这是第三层级的转义。

For example, consider the following string to be embedded in the drawtext filter description text value:

例如,我们考虑下 drawtext filter description文本值中的字符串
this is a 'string': may contain one, or more, special characters

This string contains the ’ special escaping character, and the : special character, so it needs to be escaped in this way:

字符串中包含了单引号这个转义字符,还有冒号转义字符,
故我们转义后的内容如下:
text=this is a \'string\'\: may contain one, or more, special characters

A second level of escaping is required when embedding the filter description in a filtergraph description, in order to escape all the filtergraph special characters. Thus the example above becomes:

当我们将此句放置于filtergraph中时,我们需要考虑第二层级的转义,
我们可以用如下方式转义这些特殊字符:
drawtext=text=this is a \\\'string\\\'\\: may contain one\, or more\, special characters

(note that in addition to the ’ escaping special characters, also , needs to be escaped).

(注意先前的转义字符 \', 这次都需要转义)

Finally an additional level of escaping is needed when writing the filtergraph description in a shell command, which depends on the escaping rules of the adopted shell. For example, assuming that \ is special and needs to be escaped with another , the previous string will finally result in:

最后,如果在shell命令行中敲入这些 filtergraph 的选项时,仍需要考虑shell的转义规则。
例如,假定反斜杠\也是特殊字符,需要被转义,先前的字符串最终的形式如下:
-vf "drawtext=text=this is a \\\\\\'string\\\\\\'\\\\: may contain one\\, or more\\, special characters"

5 Timeline editing

Some filters support a generic enable option. For the filters supporting timeline editing, this option can be set to an expression which is evaluated before sending a frame to the filter. If the evaluation is non-zero, the filter will be enabled, otherwise the frame will be sent unchanged to the next filter in the filtergraph.

一些filter可以支持通用的enable选项。
针对支持时间轴编辑的filter,
这些选项可以使用表达式来表示,
filter在接收frame之前可以计算出表达式的结果。
如果计算结果不为零,则filter会被使能,
否则这些帧数据会原封不动地送给filtergraph中的下一个filter

The expression accepts the following values:

表达式可以接收如下值:

‘t’
timestamp expressed in seconds, NAN if the input timestamp is unknown

以秒为单位的时间戳,如果输入时间戳未知,则用NAN表示

‘n’
sequential number of the input frame, starting from 0

输入帧的数量,从0开始

‘pos’
the position in the file of the input frame, NAN if unknown

输入帧在文件中的位置,位置则用NAN表示

‘w’
‘h’
width and height of the input frame if video

输入视频的宽高信息

Additionally, these filters support an enable command that can be used to re-define the expression.

此外,一些filter可以支持 enable 命令,可以用于重新定义表达式。

Like any other filtering option, the enable option follows the same rules.

如同其他的filter选项,enable 选项也遵循相同的规则。

For example, to enable a blur filter (smartblur) from 10 seconds to 3 minutes, and a curves filter starting at 3 seconds:

例如,从10s到3min使能blur filter,从第三秒使能curves filter。
smartblur = enable='between(t,10,3*60)',
curves    = enable='gte(t,3)' : preset=cross_process

See ffmpeg -filters to view which filters have timeline support.

通过命令
ffmpeg -filters
来查看哪些filter支持时间轴编辑功能。

(译注:其实我觉得用这个命令会更好, ffmpeg -filters | grep " T")

6 Options for filters with several inputs (framesync)

Some filters with several inputs support a common set of options. These options can only be set by name, not with the short notation.

一些filter可以支持多个输入流共用一套选项,这些选项只能通过名字来设置,而不是短符号。

eof_action
The action to take when EOF is encountered on the secondary input; it accepts one of the following values:

这个选项规定了第二路输入流结束时的行为; 参数如下:

	repeat
	Repeat the last frame (the default).
	重复最后一帧(默认选项)

	endall
	End both streams.
	结束所有流

	pass
	Pass the main input through.
	原封不动地传递输入流

shortest
If set to 1, force the output to terminate when the shortest input terminates. Default value is 0.

如果设置为1,当多路流中有一路流结束,所有的流都结束。默认值为0

repeatlast
If set to 1, force the filter to extend the last frame of secondary streams until the end of the primary stream. A value of 0 disables this behavior. Default value is 1.

如果设置为1, 在主流结束退出之前,第二路流会一直重复最后一帧数据。
如果设置为0,会禁止这个行为。
默认值为1

猜你喜欢

转载自blog.csdn.net/u012188065/article/details/87888951