【流媒体】FFmpeg技术介绍与构建方法

目录

一、FFmpeg技术背景

[1.1 起源与发展](#1.1 起源与发展)

[1.2 设计原则](#1.2 设计原则)

二、整体架构

[2.1 应用层(命令行工具)](#2.1 应用层(命令行工具))

[2.2 中间层(功能模块)](#2.2 中间层(功能模块))

[2.3 基础层(核心处理)](#2.3 基础层(核心处理))

[2.4 硬件加速层](#2.4 硬件加速层)

[2.5 模块交互示例](#2.5 模块交互示例)

三、核心模块详解(含职责、流程、结构体)

[3.1 libavutil ------ 基础工具库(所有模块的基石)](#3.1 libavutil —— 基础工具库(所有模块的基石))

[3.1.1 职责](#3.1.1 职责)

[3.1.2 关键结构体](#3.1.2 关键结构体)

[3.1.3 技术实现要点](#3.1.3 技术实现要点)

[3.2 libavformat ------ 容器处理(Demuxer/Muxer)](#3.2 libavformat —— 容器处理(Demuxer/Muxer))

[3.2.1 职责](#3.2.1 职责)

[3.2.2 核心结构体](#3.2.2 核心结构体)

3.2.3工作流程(Demuxing)

3.2.4模块交互

[3.3 libavcodec ------ 编解码核心](#3.3 libavcodec —— 编解码核心)

[3.3.1 职责](#3.3.1 职责)

[3.3.2 核心结构体](#3.3.2 核心结构体)

[3.3.3 解码流程(典型)](#3.3.3 解码流程(典型))

[3.3.4 模块交互](#3.3.4 模块交互)

[3.4 libavfilter ------ 音视频滤镜框架](#3.4 libavfilter —— 音视频滤镜框架)

[3.4.1 职责](#3.4.1 职责)

[3.4.2 核心概念:](#3.4.2 核心概念:)

[3.4.3 关键结构体](#3.4.3 关键结构体)

[3.4.4 工作流程](#3.4.4 工作流程)

[3.4.5 模块交互:](#3.4.5 模块交互:)

[3.5 libswscale 与 libswresample ------ 格式转换专用库](#3.5 libswscale 与 libswresample —— 格式转换专用库)

[3.5.1 libswscale(视频)](#3.5.1 libswscale(视频))

[3.5.2 libswresample(音频)](#3.5.2 libswresample(音频))

[3.6 libavdevice ------ 设备输入/输出](#3.6 libavdevice —— 设备输入/输出)

[3.6.1 职责](#3.6.1 职责)

[3.6.2 使用方式:](#3.6.2 使用方式:)

[四、FFmpeg 构建](#四、FFmpeg 构建)

[4.1 获取源代码](#4.1 获取源代码)

[4.2 安装依赖](#4.2 安装依赖)

[4.3 配置构建选项](#4.3 配置构建选项)

[4.4 编译与安装](#4.4 编译与安装)

[五、FFmpeg 使用方式](#五、FFmpeg 使用方式)

[方式 1:命令行工具(快速处理音视频)](#方式 1:命令行工具(快速处理音视频))

[方式 2:C/C++ 程序中集成 FFmpeg 库(开发级使用)](#方式 2:C/C++ 程序中集成 FFmpeg 库(开发级使用))


一、FFmpeg技术背景

1.1 起源与发展

FFmpeg项目诞生于2000年,由法国程序员Fabrice Bellard主导开发。其最初目标是创建一个开源的MPEG-4视频编码器,以解决当时商业编码器价格昂贵的问题。项目名称"FFmpeg"中的"FF"不仅代表"Fast Forward"(快速前进),还隐含了对MPEG标准组织的调侃 - 将"MPEG"的首字母"M"替换为"FF"。

经过20多年的发展,FFmpeg已从一个简单的编码器成长为完整的音视频处理解决方案。目前由全球开发者社区共同维护,采用LGPL/GPL开源协议。其核心组件包括:

  • libavcodec:编解码库(支持350+编码格式)
  • libavformat:多媒体容器处理
  • libavfilter:滤镜处理框架
  • libswscale:图像缩放/色彩空间转换

典型应用场景:

  • YouTube使用FFmpeg处理用户上传视频
  • VLC媒体播放器依赖其解码能力
  • HandBrake视频转换工具基于FFmpeg核心
  • OBS直播软件利用其实时编码功能

1.2 设计原则

  • 模块化架构:

    • 将音视频处理流程分解为独立的功能模块
    • 例如可单独使用libswresample进行音频重采样
    • 支持最小化编译(仅包含所需组件)
  • 零拷贝优先:

    • 采用AVBufferRef引用计数机制
    • 示例:多个滤镜处理同一帧时共享内存
    • 通过av_frame_ref()实现帧数据共享
  • 统一API设计:

    • 硬件加速(Vulkan/VAAPI)与软件处理使用相同接口
    • 文件输入(avformat_open_input)与网络流(RTMP)调用方式一致
    • 编码(avcodec_send_frame)与解码(avcodec_receive_packet)对称API
  • 可扩展性:

    • 运行时注册机制(av_register_all)
    • 支持动态加载第三方编解码器
    • 滤镜系统允许自定义处理链(如添加水印滤镜)
    • 协议层可扩展(支持新增流媒体协议)

二、整体架构

FFmpeg 由 8 个核心库 + 3 个命令行工具组成,采用分层架构设计:

2.1 应用层(命令行工具)

  • ffmpeg:多媒体处理工具(转码/剪辑/流处理)
  • ffplay:基于 SDL 的简易播放器
  • ffprobe:媒体文件分析工具 示例:ffmpeg -i input.mp4 -c:v libx264 output.mp4

2.2 中间层(功能模块)

  • libavfilter:滤镜处理框架(支持 200+ 滤镜) ▶ 示例:添加水印、画面旋转、音频混音
  • libavformat:封装/解封装(支持 100+ 格式)
  • libavdevice:设备采集/输出(摄像头/屏幕捕获)

2.3 基础层(核心处理)

  • libavcodec:编解码器(含 1000+ 编解码器) ▶ 硬件加速接口:支持 CUDA/QSV/VAAPI 等
  • libswscale:图像缩放/色彩空间转换
  • libswresample:音频重采样/格式转换
  • libavutil:基础工具(数学运算/内存管理/日志)

2.4 硬件加速层

  • 通过 libavcodec 对接各平台加速接口
  • 典型应用:4K视频转码时启用 NVIDIA NVENC

2.5 模块交互示例

视频转码流程:avformat(解封装) → avcodec(解码) → avfilter(处理) → swscale(分辨率调整) → avcodec(编码) → avformat(封装)

三、核心模块详解(含职责、流程、结构体)

3.1 libavutil ------ 基础工具库(所有模块的基石)

3.1.1 职责
  • 提供通用数据结构、内存管理、日志、数学运算、时间戳处理等。
3.1.2 关键结构体
结构体 说明 字段重点
AVFrame 存储原始音视频帧(解码后或编码前) data[8], linesize[8], width/height, sample_rate, nb_samples, format, pts
AVPacket 存储压缩数据包(编码后或解码前) data, size, pts, dts, stream_index, flags
AVBufferRef 引用计数内存管理(用于 AVFrame.dataAVPacket.data buffer(指向实际内存), size, refcount
AVRational 有理数,用于表示时间基(time base) num(分子), den(分母),如 {1, 1000} 表示毫秒
3.1.3 技术实现要点
  • 内存安全av_frame_alloc() / av_frame_unref() / av_frame_free() 成对使用。
  • 时间戳转换av_rescale_q() 用于在不同 time base 间转换 PTS/DTS。
  • 日志系统av_log() 支持多级别(ERROR/WARNING/INFO/DEBUG)。

3.2 libavformat ------ 容器处理(Demuxer/Muxer)

3.2.1 职责
  • Demuxing :从文件/网络流中分离出音视频流(如 MP4 → H.264 + AAC)。
  • Muxing :将多个流封装成目标容器(如 H.264 + AAC → MP4)。
  • 支持 200+ 容器格式(MP4、MKV、FLV、TS、RTMP、HLS 等)。
3.2.2 核心结构体
结构体 说明
AVFormatContext 整个媒体文件/流的上下文,包含所有流、元数据、IO 上下文
AVStream 单个流(音频/视频/字幕),包含 codecpar(编解码参数)、time_baseindex
AVInputFormat / AVOutputFormat Demuxer/Muxer 描述符(如 ff_mov_demuxer
AVIOContext I/O 抽象层(文件/HTTP/RTMP 统一接口)
3.2.3工作流程(Demuxing)
cpp 复制代码
AVFormatContext *fmt_ctx = NULL;
avformat_open_input(&fmt_ctx, "input.mp4", NULL, NULL); // 1. 打开输入
avformat_find_stream_info(fmt_ctx, NULL);               // 2. 探测流信息

for (int i = 0; i < fmt_ctx->nb_streams; i++) {
    AVStream *st = fmt_ctx->streams[i];
    // st->codecpar->codec_id == AV_CODEC_ID_H264 ?
}

AVPacket pkt;
while (av_read_frame(fmt_ctx, &pkt) >= 0) { // 3. 循环读取 packet
    // pkt.stream_index 指明属于哪个流
    // 处理解码...
    av_packet_unref(&pkt);
}
avformat_close_input(&fmt_ctx);
3.2.4模块交互
  • 输出 AVPacket → 交给 libavcodec 解码。
  • libavcodec 接收 AVPacket → 封装写入文件(muxing)。

3.3 libavcodec ------ 编解码核心

3.3.1 职责
  • 提供数百种音视频编解码器的实现(软解/软编)。
  • 支持硬件加速(通过 AVHWDeviceContext)。
3.3.2 核心结构体
结构体 说明
AVCodec 编解码器描述符(如 ff_h264_decoder
AVCodecContext 编解码器运行时上下文(宽高、比特率、profile、线程数等)
AVCodecParameters 只读 的编解码参数(用于 AVStream.codecpar,避免修改原始信息)
3.3.3 解码流程(典型)
cpp 复制代码
// 1. 查找解码器
AVCodec *dec = avcodec_find_decoder(AV_CODEC_ID_H264);
AVCodecContext *dec_ctx = avcodec_alloc_context3(dec);

// 2. 从 AVStream 复制参数
avcodec_parameters_to_context(dec_ctx, stream->codecpar);

// 3. 打开解码器
avcodec_open2(dec_ctx, dec, NULL);

// 4. 解码循环
AVPacket *pkt = ...; // 来自 av_read_frame
AVFrame *frame = av_frame_alloc();

avcodec_send_packet(dec_ctx, pkt);          // 输入压缩包
while (avcodec_receive_frame(dec_ctx, frame) == 0) { // 输出原始帧
    // 处理 frame(送滤镜 or 显示)
    av_frame_unref(frame);
}
3.3.4 模块交互
  • 输入:AVPacket(来自 libavformat 或用户)
  • 输出:AVFrame(送给 libavfilter 或显示)
  • 反之亦然(编码时)

3.4 libavfilter ------ 音视频滤镜框架

3.4.1 职责
  • AVFrame 进行实时处理:缩放、裁剪、水印、降噪、变速、色彩校正等。
3.4.2 核心概念:
  • Filter Graph:由多个 filter 节点组成的有向图。
  • Buffer Source/Sink:图的输入/输出端口。
3.4.3 关键结构体
结构体 说明
AVFilterGraph 滤镜图上下文
AVFilterContext 单个滤镜实例(如 scale, overlay
AVBuffersrcParameters 输入源参数(宽高、格式、time_base)
3.4.4 工作流程
cpp 复制代码
// 1. 创建图
AVFilterGraph *graph = avfilter_graph_alloc();

// 2. 创建输入/输出
AVFilterContext *buffersrc, *buffersink;
avfilter_graph_create_filter(&buffersrc, avfilter_get_by_name("buffer"), "in", args, NULL, graph);
avfilter_graph_create_filter(&buffersink, avfilter_get_by_name("buffersink"), "out", NULL, NULL, graph);

// 3. 连接滤镜(例如:缩放)
AVFilterContext *scale = ...
avfilter_link(buffersrc, 0, scale, 0);
avfilter_link(scale, 0, buffersink, 0);

// 4. 配置图
avfilter_graph_config(graph, NULL);

// 5. 处理帧
av_buffersrc_add_frame(buffersrc, input_frame);
AVFrame *output_frame = av_frame_alloc();
av_buffersink_get_frame(buffersink, output_frame);
3.4.5 模块交互:
  • 输入:AVFrame(来自 libavcodec 解码)
  • 输出:AVFrame(送给 libavcodec 编码或显示)

3.5 libswscalelibswresample ------ 格式转换专用库

3.5.1 libswscale(视频)
  • 功能:图像缩放、颜色空间转换(YUV ↔ RGB)、像素格式转换。
  • 核心函数:sws_getContext(), sws_scale()
  • 结构体:SwsContext
3.5.2 libswresample(音频)
  • 功能:重采样(44.1kHz → 48kHz)、声道布局转换(立体声 → 5.1)、格式转换(float → s16)。
  • 核心函数:swr_init(), swr_convert()
  • 结构体:SwrContext

3.6 libavdevice ------ 设备输入/输出

3.6.1 职责
  • 抽象摄像头、麦克风、屏幕捕获、采集卡等硬件设备。
  • 在 Linux 上基于 V4L2,在 Windows 上基于 dshow,在 macOS 上基于 AVFoundation。
3.6.2 使用方式:
cpp 复制代码
// 打开摄像头(Linux)
AVFormatContext *dev;
avformat_open_input(&dev, "/dev/video0", av_find_input_format("v4l2"), NULL);

四、FFmpeg 构建

4.1 获取源代码

4.1.1 官方下载方式:

  • 生产环境推荐使用稳定版(标记为 release 的版本)
  • 开发测试可使用 git master 分支获取最新功能

4.1.2 版本选择建议:

  • 通过 git 克隆最新版本:git clone https://git.ffmpeg.org/ffmpeg.git
  • 或下载稳定版压缩包:wget https://ffmpeg.org/releases/ffmpeg-x.x.x.tar.gz
  • 解压命令:tar -xzvf ffmpeg-x.x.x.tar.gz

4.2 安装依赖

4.2.1 基础编译工具:

  • GCC/G++ 编译器
  • make 工具
  • pkg-config
  • 安装命令(Ubuntu示例):sudo apt install build-essential pkg-config

4.2.2 常用编解码器依赖:

  • libx264(H.264编码)

  • libx265(HEVC编码)

  • libvpx(VP8/VP9编码)

  • libfdk-aac(AAC音频编码)

  • 安装示例:sudo apt install libx264-dev libx265-dev libvpx-dev libfdk-aac-dev

    bash 复制代码
    # 基础编译工具
    sudo apt update
    sudo apt install build-essential pkg-config
    
    # 可选但推荐的第三方库(按需安装)
    sudo apt install \
        yasm nasm \                          # 汇编优化
        libx264-dev libx265-dev \            # H.264/H.265 编码
        libvpx-dev \                         # VP8/VP9
        libfdk-aac-dev \                     # 高质量 AAC
        libmp3lame-dev \                     # MP3 编码
        libopus-dev \                        # Opus 音频
        libvorbis-dev \                      # Vorbis
        libass-dev \                         # 字幕渲染
        libfreetype6-dev \                   # 文字水印
        libva-dev libdrm-dev \               # Intel VA-API 硬件加速
        libnvcodec-dev \                     # NVIDIA NVENC/NVDEC(需额外添加仓库)
        libsdl2-dev                          # ffplay 依赖

4.3 配置构建选项

4.3.1 基本配置命令:

复制代码
./configure \
  --prefix=/usr/local/ffmpeg \
  --enable-gpl \
  --enable-nonfree \
  --enable-libx264 \
  --enable-libx265 \
  --enable-libvpx \
  --enable-libfdk-aac

4.3.2 常用配置参数说明:

  • --prefix:指定安装目录
  • --enable-shared:构建动态链接库
  • --disable-static:禁用静态库构建
  • --extra-cflags/--extra-ldflags:自定义编译/链接选项
  • --enable-gpl: 启用 GPL 许可代码(如 x264)
  • --enable-nonfree:启用非自由许可证代码(如 fdk-aac)
  • --enable-debug=3:保留调试符号,便于 GDB 调试
  • --disable-programs:若只用于开发,可不编译 ffmpeg/ffplay

4.3.3 平台特定配置:

  • Windows:需要安装 MSYS2 或 Cygwin 环境
  • macOS:建议使用 Homebrew 安装依赖
  • 交叉编译:需指定 --cross-prefix--arch 参数

4.4 编译与安装

4.1 编译过程:

  • 执行 make -j$(nproc) 进行并行编译
  • 可使用 make -j4 指定并行任务数
  • 完整编译通常需要10-30分钟(取决于硬件配置)

4.2 安装步骤:

  • 执行 sudo make install 安装到指定目录

  • 设置环境变量:

    复制代码
    export PATH="/usr/local/ffmpeg/bin:$PATH"
    export LD_LIBRARY_PATH="/usr/local/ffmpeg/lib:$LD_LIBRARY_PATH"

4.3 验证安装:

  • 执行 ffmpeg -version 查看版本信息
  • 检查编解码器支持:ffmpeg -codecs
  • 测试转码功能:ffmpeg -i input.mp4 -c:v libx264 output.mp4

五、FFmpeg 使用方式

方式 1:命令行工具(快速处理音视频)

这是FFmpeg最常见的使用方式,适合快速完成音视频处理任务。用户可以直接在终端/命令行中执行FFmpeg命令,无需编程即可实现:

  • 格式转换(如MP4转AVI)

  • 视频裁剪(指定开始和结束时间)

  • 调整分辨率(如1080p转720p)

  • 提取音频(从视频中分离音轨)

  • 添加水印(图片或文字)

  • 示例命令:

    bash 复制代码
    # 将input.mp4转换为output.avi
    ffmpeg -i input.mp4 output.avi
    
    # 裁剪视频从00:01:30到00:02:45
    ffmpeg -i input.mp4 -ss 00:01:30 -to 00:02:45 -c copy output.mp4
     

方式 2:C/C++ 程序中集成 FFmpeg 库(开发级使用)

适用于需要深度定制音视频处理功能的开发者:

  • 通过链接FFmpeg静态/动态库(libavcodec, libavformat等)
  • 使用FFmpeg API进行编程控制
  • 可实现:
    • 自定义编解码流程
    • 实时流媒体处理
    • 复杂滤镜效果
    • 硬件加速编解码

典型开发流程:

c 复制代码
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>

int main() {
    av_register_all(); // 初始化FFmpeg
    // 更多处理代码...
    return 0;
}
 

编译时需要正确链接FFmpeg库

bash 复制代码
gcc -o program program.c -lavcodec -lavformat -lavutil
 
相关推荐
大大祥2 小时前
Android FFmpeg集成
android·ffmpeg·kotlin·音视频·jni·ndk·音视频编解码
没有羊的王K2 小时前
下载安装FFmpeg教程
ffmpeg
kkoral3 小时前
【FFmpeg 智慧园区场景应用】1.实战命令清单
ffmpeg
天虎3 小时前
使用VS2019编译ShiftMediaProject版本FFmpeg
ffmpeg
kkoral4 小时前
【FFmpeg 智慧园区场景应用】2.自动化处理 Shell 脚本
运维·ffmpeg·自动化
代码煮茶君15 小时前
FFmpeg 音视频转码全攻略:参数详解与实战指南
ffmpeg·音视频
深念Y1 天前
录屏意外中断的视频修复软件 untrunc
ffmpeg·文件·视频·录屏·软件·修复工具·untrunc
Black蜡笔小新1 天前
国标设备如何在EasyCVR视频汇聚平台获取RTSP/RTMP流?
网络·ffmpeg·音视频
lcyw2 天前
GB28181: 使用ffmpeg编码h264为ps流
ffmpeg