FFmpeg 框架总览
FFmpeg的核心设计思想是模块化和分层,其架构可以分为三个层次:
- 底层核心库 (Core Libraries): 提供音视频处理的原子能力,如编解码、格式封装/解封装、滤镜、像素/采样格式转换等。这是FFmpeg的基石。
- 上层应用层 (Application Layer): 基于核心库开发出的可执行程序,供终端用户使用,如 ffmpeg,ffprobe,ffplay。
- 外部API (External API): 核心库导出的API,供第三方开发者(比如你我)在自己的C/C++项目中调用,以构建定制化的多媒体应用。
2. 核心数据处理流程 (以转码为例)
理解FFmpeg架构最好的方式,就是理解其内部的数据处理“流水线”。下面是一个典型的转码(transcoding)流程,清晰地展示了各大模块如何协同工作。
ASCII图表:FFmpeg核心数据流
代码段
 Input File (e.g., MP4)
       |
+------v------+
| libavformat | (解封装 Demuxer)
+------+------+
       |
       | 1. 压缩数据包 (Compressed Packet) -> AVPacket
       |
+------v------+
| libavcodec  | (解码器 Decoder)
+------+------+
       |
       | 2. 原始数据帧 (Raw Frame) -> AVFrame (Video: YUV, Audio: PCM)
       |
+------v------+
| libavfilter | (滤镜 Filter Graph, Optional) e.g., scale, watermark
+------+------+
       |
       | 3. 处理后的原始帧 (Processed Frame) -> AVFrame
       |
+------v------+
| libavcodec  | (编码器 Encoder)
+------+------+
       |
       | 4. 新的压缩数据包 (New Packet) -> AVPacket
       |
+------v------+
| libavformat | (封装 Muxer)
+------+------+
       |
 Output File (e.g., MKV)
流水线解读:
- 解封装 (Demuxing): libavformat读取输入文件(如input.mp4),解析其容器格式,从中分离出音频、视频等压缩数据流。每一“份”压缩数据被打包成一个AVPacket对象。
- 解码 (Decoding): libavcodec接收AVPacket,根据其编码格式(如H.264)选择对应的解码器,将其解码为原始的、未压缩的视频帧或音频采样。这些原始数据被存放在AVFrame对象中。
- 滤镜处理 (Filtering): (可选步骤)解码后的 AVFrame进入libavfilter的滤镜图(Filter Graph)。在这里可以进行各种处理,如缩放、裁剪、加水印、调速、音频混合等,处理完后输出新的AVFrame。
- 编码 (Encoding): 处理后的 AVFrame被送入libavcodec的编码器(如libx265),将其压缩成新的AVPacket。
- 封装 (Muxing): libavformat接收来自不同编码器(音频、视频)的AVPacket,按照目标容器格式(如output.mkv)的规范,将它们交织写入到输出文件中。
现在,我们来详细解读流水线中涉及的每一个核心模块库。
3. FFmpeg核心模块库详解
3.1. libavutil - 核心工具库
- 定位: 基础中的基础。它是FFmpeg所有其他库的依赖,提供了公共的、底层的工具函数和数据结构。
- 核心功能:
    - 数据结构: 提供了AVDictionary(键值对),AVRational(分数),AVFrame,AVPacket(这两个核心结构体的定义也在这里)等。
- 内存管理: av_malloc(),av_free()等安全的内存分配函数。
- 日志系统: av_log()提供了分级的日志输出。
- 数学运算: 提供了针对多媒体的优化数学函数,如CRC、FFT等。
- 字符串处理: av_str*系列函数。
 
- 数据结构: 提供了
- 开发者视角: 把它想象成FFmpeg世界的 libc或者STL,是编写任何FFmpeg程序都离不开的工具箱。
3.2. libavformat - 格式与协议库
- 定位: 文件I/O和网络流的管理者。它负责处理各种多媒体容器格式和流媒体协议。
- 核心功能:
    - 解封装 (Demuxing): 读取文件或网络流,解析容器(如MP4, MKV, FLV),分离出音视频压缩数据包(AVPacket)。
- 封装 (Muxing): 将编码后的AVPacket合并,按照特定容器格式(如MP4, MKV)写入文件。
- 协议支持 (Protocols): 实现了 file,http,rtmp,rtsp,hls等多种协议的I/O操作。
 
- 解封装 (Demuxing): 读取文件或网络流,解析容器(如MP4, MKV, FLV),分离出音视频压缩数据包(
- 关键数据结构: AVFormatContext(整个媒体文件的上下文),AVInputFormat(解封装器),AVOutputFormat(封装器),AVStream(文件中的单个流),AVIOContext(抽象的I/O接口)。
- 开发者视角: 当你需要读取或写入任何媒体文件/流时,libavformat是你的入口和出口。
3.3. libavcodec - 编解码库
- 定位: FFmpeg的心脏。它包含了几乎所有常见音视频编码格式的编码器(Encoder)和解码器(Decoder)。
- 核心功能:
    - 解码 (Decoding): 将 AVPacket(压缩数据) 转换为AVFrame(原始数据)。
- 编码 (Encoding): 将 AVFrame(原始数据) 压缩为AVPacket(压缩数据)。
 
- 解码 (Decoding): 将 
- 关键数据结构: AVCodec(编解码器实现),AVCodecContext(编解码器实例的上下文,包含QP、GOP、比特率等配置),AVPacket,AVFrame。
- 开发者视角: 这是实现编解码逻辑的核心。你需要配置AVCodecContext,然后调用avcodec_send_packet/avcodec_receive_frame(解码)或avcodec_send_frame/avcodec_receive_packet(编码)来完成工作。
3.4. libavfilter - 音视频滤镜库
- 定位: 强大的“音视频处理中枢”。它提供了一个通用的音视频处理框架。
- 核心功能: 允许你创建任意复杂的滤镜图(Filter Graph)来处理原始的AVFrame数据。- 视频滤镜: 缩放(scale), 裁剪(crop), 旋转(rotate), 叠加(overlay, 如加水印), 格式转换(format), 拼接(concat), 调速(setpts)等。
- 音频滤镜: 音量调节(volume), 混合(amix), 声道分离/合并(asplit/amerge), 重采样(aresample)等。
 
- 关键概念: AVFilter(单个滤镜),AVFilterGraph(滤镜图),AVFilterContext(滤镜实例),buffersrc(滤镜图的输入端),buffersink(滤镜图的输出端)。
- 开发者视角: 当你需要对解码后的原始数据进行任何形式的加工处理时,libavfilter是你的首选。
3.5. libswscale - 图像缩放与格式转换库
- 定位: 专业的视频像素处理工具。
- 核心功能:
    - 图像缩放: 提供了多种高质量、高性能的图像缩放算法。
- 色彩空间/像素格式转换: 例如,将解码器输出的YUV420P格式转换为显示器需要的RGB24格式。
 
- 开发者视角: 虽然libavfilter中的scale和format滤镜内部就使用了libswscale,但如果你需要更精细的、独立的图像处理控制,可以直接调用这个库。
3.6. libswresample - 音频重采样与格式转换库
- 定位: 专业的音频采样处理工具,是libswscale在音频领域的对应物。
- 核心功能:
    - 音频重采样: 改变音频的采样率,如从44.1kHz转到48kHz。
- 采样格式转换: 如从16位整型(s16)转到32位浮点型(flt)。
- 声道布局转换: 如从立体声(stereo)转到5.1环绕声。
 
- 开发者视角: 与libswscale类似,libavfilter的音频滤镜底层也依赖它,但你也可以为了更精细的控制而直接调用它。
3.7. libavdevice - 输入输出设备库
- 定位: 与硬件设备交互的桥梁。
- 核心功能: 提供了访问和捕获操作系统底层多媒体设备的接口。
- 应用举例:
    - 视频: 从摄像头捕获视频 (Linux下的V4L2, Windows下的dshow)。
- 音频: 从麦克风录音或播放到扬声器 (Linux下的ALSA, Windows下的DirectSound)。
- 屏幕: 屏幕录制 (Linux下的x11grab, Windows下的gdigrab)。
 
- 开发者视角: 当你需要让程序与摄像头、麦克风、屏幕等物理设备交互时,需要用到这个库。
4. 命令行工具
这些是构建在上述库之上的、用户可以直接使用的程序。
- ffmpeg: 核心转码工具,是所有库功能的集大成者。你给它的几乎所有参数,内部都会被翻译成对上述库API的调用。
- ffprobe: 媒体文件分析工具,用于查看文件的容器信息、流信息、帧信息等,主要基于- libavformat和- libavcodec。
- ffplay: 一个基于SDL和FFmpeg库的简单播放器,是学习FFmpeg API如何协同工作的绝佳范例。