在转码过程ffmpeg每个输出可以由以下图描述:
_______ ______________ | | | | | input | demuxer | encoded data | decoder | file | ---------> | packets | -----+ |_______| |______________| | v _________ | | | decoded | | frames | |_________| ________ ______________ | | | | | | | output | <-------- | encoded data | <----+ | file | muxer | packets | encoder |________| |______________|
ffmpeg调用libavformat库(含分流器)来读取输入文件并获得含有他们编码信息的数据包。当有多个输入文件, ffmpeg将通过跟踪最小的时间戳来试图在所有活跃的输入流间同步。编码的数据包然后被传递到解码器(除非复制音频流被选择用于流,见进一步的说明)。解码器产生的未压缩的帧(原始视频/ PCM音频/ …),它可以进一步通过过滤器进行处理(见下一节)。通过过滤器后,这些帧被传递到编码器,编码器将其编码并输出编码后的数据包。最后,这些将被传输给混合器以将编码数据写入到输出文件。
3.1 过滤器
在编码之前, ffmpeg可以使用libavfilter库中的过滤处理原始的音频和视频帧。几个连接的过滤器可以形成一个过滤器组(filtergraphs)。 ffmpeg有两种filtergraphs:简单和复杂。
3.1.1 简单filtergraphs
简单filtergraphs是那些具有相同的类型且正好一个输入和输出的过滤器组。另外,在上图中,他们可以由简单地在解码和编码之间插入附加步骤来表示:
_________ ______________ | | | | | decoded | | encoded data | | frames |\ _ | packets | |_________| \ /||______________| \ __________ / simple _\|| | / encoder filtergraph | filtered |/ | frames | |__________|
简单filtergraphs配置了每个流的筛选器选项(与视频和音频分别-vf和-af别名)。一个简单的FilterGraph动态视频可以看一下这样的例子:
_______ _____________ _______ ________ | | | | | | | | | input | ---> | deinterlace | ---> | scale | ---> | output | |_______| |_____________| |_______| |________|
需要注意的是一些过滤改变帧属性而不是画面的内容。例如,在上例中,fps改变帧的数量,但不触及帧的内容。又如setpts过滤,其仅设置时间戳而保持帧不变。
3.1.2 复杂filtergraphs
复杂filtergraphs是那些不能被描述为简单的线性处理链的过滤器组。例如,当过滤器组具有多个输入和/或输出,或当输出流的类型是不同于输入。它们可以被表示为以下图:
_________ | | | input 0 |\ __________ |_________| \ | | \ _________ /| output 0 | \ | | / |__________| _________ \| complex | / | | | |/ | input 1 |---->| filter |\ |_________| | | \ __________ /| graph | \ | | / | | \| output 1 | _________ / |_________| |__________| | | / | input 2 |/ |_________|
复杂filtergraphs可使用-filter_complex选项配置。注意,此选项是全局性的,因为复杂FilterGraph,就其本质,不能明确地与单个流或文件相关联。
-lavfi选项相当于-filter_complex。
一个复杂FilterGraph动态的简单的例子是在overlay过滤器,它具有两个视频输入和一个视频输出,含有一个视频重叠在另一个的上面。其对应的音频过滤器是amix。
3.2 流复制
流复制是通过添加copy选项到-codec选项完成的。它使ffmpeg对指定的流忽略解码和编码步骤,所以它只能混合和拆包。它用于改变所述容器的格式或修改容器级别的元数据是有用的。在这种情况下,可以简化为这样:
_______ ______________ ________ | | | | | | | input | demuxer | encoded data | muxer | output | | file | ---------> | packets | -------> | file | |_______| |______________| |________|
由于不存在解码或编码,它是非常快,没有质量损失。然而因为许多因素的工作,它可能无法在某些情况下使用。应用过滤器显然也是不可能的,因为过滤器仅能作用在未压缩的数据上。