多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] ## FFmpeg的工作流程 ## 编解码流程 `ffmpeg`的每个转换过程像下图描述的程序 ``` _______ ______________ | | | | | input | demuxer | encoded data | decoder | file | ---------> | packets | -----+ |_______| |______________| | v _________ | | | decoded | | frames | |_________| ________ ______________ | | | | | | | output | <-------- | encoded data | <----+ | file | muxer | packets | encoder |________| |______________| ``` `ffmpeg`调用`libavformat`库(含分离器)读取输入文件,分离出各类编码的数据包(流),当有多个输入文件时,`ffmpeg`试图跟踪最低时间戳实现任意输入流同步。编码数据包(除非是指定为流式拷贝,相关内容请参考特性描述对[流式拷贝](https://www.bookstack.cn/read/other-doc-cn-ffmpeg/ffmpeg-doc-cn-03.md#%E6%B5%81%E6%8B%B7%E8%B4%9D)的说明)通过解码器解码出非压缩的数据帧(raw视频/PCM格式音频…),这些数据帧可以被滤镜进一步处理(下面会讲到)。经过滤镜处理的数据被重新编码为新的数据包(流),然后经过混合器混合(例如按一定顺序和比例把音频数据包和视频数据包交叉组合),写入到输出文件。 ## 滤镜处理/Filtering 在编码前,`ffmpeg`可以对raw(真实/原)音频和视频使用`libavfilter`库中的滤镜进行处理。多个滤镜可以组成滤镜链图(滤镜链图filtergraphs )。在`ffmpeg`看来只有2种滤镜:简单滤镜,复合滤镜。 ### 简单滤镜 简单滤镜就是只有1个输入和输出的滤镜,滤镜两边的数据都是同一类型的,可以理解为在非压缩数据帧到再次编码前简单附加了一步: ``` _________ ______________ | | | | | decoded | | encoded data | | frames |\ _ | packets | |_________| \ /||______________| \ __________ / simple _\|| | / encoder filtergraph | filtered |/ | frames | |__________| ``` 简单滤镜一般用于配置每个流 -filter 选项(-vf 和 -af 分别对应视频和音频)。一个最简单的视频滤镜如下: ``` _______ _____________ _______ ________ | | | | | | | | | input | ---> | deinterlace | ---> | scale | ---> | output | |_______| |_____________| |_______| |________| ``` ### 复合滤镜 复合滤镜是那些不能简单描述为一个线性处理过程应用到一个流的情况,例如当过程中有多个输入和/或输出,或者输出流类型不同于输入时,示意图如下: ``` _________ | | | input 0 |\ __________ |_________| \ | | \ _________ /| output 0 | \ | | / |__________| _________ \| complex | / | | | |/ | input 1 |---->| filter |\ |_________| | | \ __________ /| graph | \ | | / | | \| output 1 | _________ / |_________| |__________| | | / | input 2 |/ |_________| ``` 复合滤镜由`-filter_complex`选项进行设定。**注意**这是一个全局选项,因为一个复合滤镜必然是不能只关联到一个单一流或者文件的。`-lavfi`选项等效于`-filter_complex` 一个复合滤镜的简单例子就是`overlay`滤镜,它从两路输入中,把一个视频叠加到一个输出上。对应的类似音频滤镜是`amix`。 ### 流拷贝 流拷贝(Stream copy)是一种对指定流数据仅仅进行复制的`拷贝(copy)`模式。这种情况下`ffmpeg`不会对指定流进行解码和编码步骤,而仅仅是分离和混合数据包。这种模式常用于文件包装格式的转换或者修改部分元数据信息,这个过程简单图示如下: ``` _______ ______________ ________ | | | | | | | input | demuxer | encoded data | muxer | output | | file | ---------> | packets | -------> | file | |_______| |______________| |________| ``` 因为这种模式下不存在解码和编码过程,所以也特别快,而且不会造成新的质量损失。然而这也使得这样的模式不能适合很多工作需求,例如这个模式下不能使用大量的滤镜了,因为滤镜仅能对未压缩(编码)的数据进行处理。