1.3 FFmpeg的基本组成

图1-1 FFmpeg基本组成模块

FFmpeg框架的基本组成包含AVFormat、AVCodec、AVFilter、AVDevice、AVUtil等模块库,结构如图1-1所示。

下面针对这些模块做一个大概的介绍。

(1)FFmpeg的封装模块AVFormat

AVFormat中实现了目前多媒体领域中的绝大多数媒体封装格式,包括封装和解封装,如MP4、FLV、KV、TS等文件封装格式,RTMP、RTSP、MMS、HLS等网络协议封装格式。FFmpeg是否支持某种媒体封装格式,取决于编译时是否包含了该格式的封装库。根据实际需求,可进行媒体封装格式的扩展,增加自己定制的封装格式,即在AVFormat中增加自己的封装处理模块。

(2)FFmpeg的编解码模块AVCodec

AVCodec中实现了目前多媒体领域绝大多数常用的编解码格式,既支持编码,也支持解码。AVCodec除了支持MPEG4、AAC、MJPEG等自带的媒体编解码格式之外,还支持第三方的编解码器,如H.264(AVC)编码,需要使用x264编码器;H.265(HEVC)编码,需要使用x265编码器;MP3(mp3lame)编码,需要使用libmp3lame编码器。如果希望增加自己的编码格式,或者硬件编解码,则需要在AVCodec中增加相应的编解码模块,关于AVCode的更多相关信息以及使用信息将会在后面的章节中进行详细的介绍。

(3)FFmpeg的滤镜模块AVFilter

AVFilter库提供了一个通用的音频、视频、字幕等滤镜处理框架。在AVFilter中,滤镜框架可以有多个输入和多个输出。我们参考下面这个滤镜处理的例子,如图1-2所示。

图1-2 AVFilter使用样例

图1-2所示样例中的滤镜处理将输入的视频切割成了两部分流,一部分流抛给crop滤镜与vflip滤镜处理模块进行操作,另一部分保持原样,当crop滤镜与vflip滤镜处理操作完成之后,将流合并到原有的overlay图层中,并显示在最上面一层,输出新的视频。对应的命令行如下:

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

下面看一下具体的执行情况,以验证该命令的可行性:

    ffmpeg version n3.3.2 Copyright (c) 2000-2017 the FFmpeg developers
        built with Apple LLVM version 8.1.0 (clang-802.0.42)
        configuration: --disable-yasm
        libavutil       55. 58.100 / 55. 58.100
        libavcodec      57. 89.100 / 57. 89.100
        libavformat     57. 71.100 / 57. 71.100
        libavdevice     57.  6.100 / 57.  6.100
        libavfilter       6. 82.100 /  6. 82.100
        libswscale       4.  6.100 /  4.  6.100
        libswresample    2.  7.100 /  2.  7.100
    Input #0, mov, mp4, m4a,3gp,3g2, mj2, from 'input.mp4':
        Metadata:
            major_brand      : isom
            minor_version    : 1
            compatible_brands: isomavc1
            creation_time    : 2015-02-02T18:19:19.000000Z
        Duration: 00:45:02.06, start: 0.000000, bitrate: 2708 kb/s
            Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x714
[SAR 1:1 DAR 640:357], 2576 kb/s, 25 fps, 25 tbr, 25k tbn, 50 tbc (default)
            Metadata:
                creation_time    : 2015-02-02T18:19:19.000000Z
                handler_name     : GPAC ISO Video Handler
            Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo,
fltp, 127 kb/s (default)
            Metadata:
                creation_time    : 2015-02-02T18:19:23.000000Z
                handler_name     : GPAC ISO Audio Handler
    Stream mapping:
        Stream #0:0 -> #0:0 (h264 (native) -> mpeg4 (native))
        Stream #0:1 -> #0:1 (aac (native) -> aac (native))
    Press [q] to stop, [? ] for help
    Output #0, mp4, to 'output.mp4':
        Metadata:
            major_brand       : isom
            minor_version     : 1
            compatible_brands: isomavc1
            encoder           : Lavf57.71.100
            Stream #0:0(und): Video: mpeg4 ( [0][0][0] / 0x0020), yuv420p
(progressive), 1280x714 [SAR 1:1 DAR 640:357], q=2-31, 200 kb/s, 25 fps, 12800 tbn,
25 tbc (default)
            Metadata:
                 creation_time      : 2015-02-02T18:19:19.000000Z
                 handler_name       : GPAC ISO Video Handler
                 encoder            : Lavc57.89.100 mpeg4
            Side data:
                 cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
                Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 48000 Hz,
stereo, fltp, 128 kb/s (default)
            Metadata:
                 creation_time      : 2015-02-02T18:19:23.000000Z
                 handler_name       : GPAC ISO Audio Handler
                 encoder            : Lavc57.89.100 aac
    frame=  729  fps=   85  q=31.0  size=  4332kB  time=00:00:29.31  bitrate=1210.7kbits/s
dup=2 drop=0 speed=3.41x

以上内容输出完成,该命令将自动退出,生成的视频结果是保留视频的上半部分,同时上半部分会镜像到视频的下半部分,二者合成之后作为输出视频,如图1-3所示。

图1-3 Filter运行前后对比

下面详细说明一下规则,具体如下。

● 相同的Filter线性链之间用逗号分隔

● 不同的Filter线性链之间用分号分隔

在以上示例中,crop与vflip使用的是同一个滤镜处理的线性链,split滤镜和overlay滤镜使用的是另外一个线性链,一个线性链与另一个线性链汇合时是通过方括号“[]”括起来的标签进行标示的。在这个例子中,两个流处理后是通过[main]与[f lip]进行关联汇合的。

split滤镜将分割后的视频流的第二部分打上标签[tmp],通过crop滤镜对该部分流进行处理,然后进行纵坐标调换操作,打上标签[flip],然后将[main]标签与[flip]标签进行合并,[flip]标签的视频流从视频的左边最中间的位置开始显示,这样就出现了镜像效果,如图1-3所示。

(4)FFmpeg的视频图像转换计算模块swscale

swscale模块提供了高级别的图像转换API,例如它允许进行图像缩放和像素格式转换,常见于将图像从1080p转换成720p或者480p等的缩放,或者将图像数据从YUV420P转换成YUYV,或者YUV转RGB等图像格式转换。

(5)FFmpeg的音频转换计算模块swresample

swresample模块提供了高级别的音频重采样API。例如它允许操作音频采样、音频通道布局转换与布局调整。