FFmpeg滤镜API用法与实例解析

FFmpeg中,滤镜(filter)处理的是未压缩的原始音视频数据(RGB/YUV视频帧,PCM音频帧等)。一个滤镜的输出可以连接到另一个滤镜的输入,多个滤镜可以连接起来,构成滤镜链/滤镜图,各种滤镜的组合为FFmpeg提供了丰富的音视频处理功能。

比较常用的滤镜有:scale、trim、overlay、rotate、movie、yadif。scale滤镜用于缩放,trim滤镜用于帧级剪切,overlay滤镜用于视频叠加,rotate滤镜实现旋转,movie滤镜可以加载第三方的视频,yadif滤镜可以去隔行。

1. 滤镜的构成及命令行用法

本节内容节选自“FFmpeg使用基础”,翻译整理自《FFmpeg Basics》及官网文档“Documentation-ffmpeg”。

在多媒体处理中,术语滤镜(filter)指的是修改未编码的原始音视频数据帧的一种软件工具。滤镜分为音频滤镜和视频滤镜。FFmpeg提供了很多内置滤镜,可以用很多方式将这些滤镜组合使用。通过一些复杂指令,可以将解码后的帧从一个滤镜引向另一个滤镜。这简化了媒体处理,因为有损编解码器对媒体流进行多次解码和编码操作会降低总体质量,而引入滤镜后,不需要多次解码编码操作,相关处理可以使用多个滤镜完成,而滤镜处理的是原始数据,不会造成数据损伤。

1.1 滤镜的使用

FFmpeg的libavfilter库提供了滤镜API,支持多路输入和多路输出。

滤镜(filter)的语法为:
[input_link_lable1][input_link_lable2]... filter_name=parameters [output_link_lable1][output_link_lable12]...
上述语法中,输入输出都有连接标号(link lable),连接符号是可选项,输入连接标号表示滤镜的输入,输出连接标号表示滤镜的输出。连接标号通常用在滤镜图中,通常前一个滤镜的输出标号会作为后一个滤镜的输入标号,通过同名的标号将滤镜及滤镜链连接起来。连接标号的用法参考1.3.2节示例。

示例1:
ffplay -f lavfi -i testsrc -vf transpose=1
“-vf”(同“-filter:v”)选项表示使用视频滤镜,“transpose=1”是滤镜,此行命令表示使用transpose视频滤镜产生一个顺时针旋转90度的测试图案

示例2:
ffmpeg -i input.mp3 -af atempo=0.8 output.mp3
“-af”(同“-filter:a”)选项表示使用音频滤镜,“atempo=0.8”是滤镜,此行命令表示使用atempo音频滤镜将输入音频速率降低到80%后写入输出文件

注意:有些滤镜只会修改帧属性而不会修改帧内容。例如,fps滤镜,setpts滤镜等。

1.2 滤镜链的使用

滤镜链(filterchain)是以逗号分隔的滤镜(filter)序列,语法如下:
filter1,fiter2,filter3,...,filterN-2,filterN-1,filterN
滤镜链中如果有空格,需要将滤镜链用双引号括起来,因为命令行中空格是分隔参数用的。

示例1:
ffmpeg -i input.mpg -vf hqdn3d,pad=2*iw output.mp4
“hqdn3d,pad=2iw”是filterchain,第一个filter是“hqdn3d”(降噪);第二个filter是“pad=2iw”(将图像宽度填充到输入宽度的2倍)。此行命令表示,将输入视频经降噪处理后,再填充视频宽度为输入宽度的2倍。

1.3 滤镜图的使用

滤镜图(filtergraph)通常是以分号分隔的滤镜链(filterchain)序列。滤镜图分为简单滤镜图和复杂滤镜图。
滤镜图(filtergraph)的语法如下:
filter1;fiter2;filter3;...;filterN-2;filterN-1;filterN

1.3.1 简单滤镜图

简单滤镜图(filtergraph)只能处理单路输入流和单路输出流,而且要求输入和输出具有相同的流类型。
简单滤镜图由-filter选项指定。简单滤镜图示意图如下:

_______ _____________________ ________ | | | | | | | input | ---> | simple filter graph | ---> | output | |_______| |_____________________| |________| 1.3.2 复杂滤镜图

复杂滤镜图(filtergraph)用于简单滤镜图处理不了的场合。比如,多路输入流和(或)多路输出流,或者输出流与输入流类型不同。
有些特殊的滤镜(filter)本身就属于复杂滤镜图,用-filter_complex选项或-lavfi选项指定,如overlay滤镜和amix滤镜就是复杂滤镜图。overlay滤镜有两个视频输入和一个视频输出,将两个输入视频混合在一起。而amix滤镜则是将两个输入音频混合在一起。
复杂滤镜图(filtergraph)示意图如下:

_________ | | | input 0 |\ __________ |_________| \ | | \ _________ /| output 0 | \ | | / |__________| _________ \| complex | / | | | |/ | input 1 |---->| filter |\ |_________| | | \ __________ /| graph | \ | | / | | \| output 1 | _________ / |_________| |__________| | | / | input 2 |/ |_________|

示例1:
ffmpeg -i INPUT -vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2" OUTPUT
上例中"split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2"是复杂滤镜图,由三个滤镜链构成(分号分隔),第二个滤镜链“[tmp] crop=iw:ih/2:0:0, vflip [flip]”由两个滤镜构成(逗号分隔)。第一个滤镜链中:滤镜split产生两个输出[main]和[tmp];第二个滤镜链中:[tmp]作为crop滤镜的输入,[flip]作为vflip滤镜的输出,crop滤镜输出连接到vflip滤镜的输入;第三个滤镜链中:[main]和[flip]作为overlay滤镜的输入。整行命令实现的功能是:将输入分隔为两路,其中一路经过裁剪和垂直翻转后,再与另一路混合,生成输出文件。示意图如下所示:

[main] input --> split ---------------------> overlay --> output | ^ |[tmp] [flip]| +-----> crop --> vflip -------+ 1.3.3 滤镜图中的连接标号

在滤镜图中可以使用连接标号(link lable),连接标号表示特定滤镜/滤镜链的输入或输出,参1.1节。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpzpdg.html