【流媒体】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
 
相关推荐
xmRao8 小时前
Qt+FFmpeg 实现 PCM 音频转 AAC 编码
qt·ffmpeg·pcm
xmRao8 小时前
Qt+FFmpeg 实现录音程序(pcm转wav)
qt·ffmpeg
阿里巴啦1 天前
python+yt-dlp开源项目,支持 YouTube, Bilibili, TikTok/抖音,快手 等多个平台的视频/音频/字幕下载/ai摘要等功能
python·ffmpeg·whisper·音视频·视频处理·ai摘要·音视频转录
来鸟 鸣间2 天前
linux下ffmpeg源码编译
linux·运维·ffmpeg
Echo_NGC22372 天前
【FFmpeg使用指南】Part 2:滤镜图架构与信号处理
架构·ffmpeg·音视频·信号处理
Echo_NGC22372 天前
【FFmpeg使用指南】Part 1:核心架构与媒体流处理
ffmpeg·音视频·媒体·视频
ssxueyi2 天前
用 Claude Code 从零开发自己的Direct3D 硬件加速播放器
ffmpeg·ai编程·directx·视频播放器·从零开始·claude code·csdn征文活动
Yan_uuu2 天前
ubuntu18.04 安装 x264、ffmpeg、nv-codec-hearers 支持GPU硬件加速
c++·图像处理·ubuntu·ffmpeg
runner365.git3 天前
做一个基于ffmpeg的AI Agent智能体
人工智能·ffmpeg·大模型
彷徨而立3 天前
【FFmpeg】理解 av_packet_from_data 和 av_packet_unref 接口
ffmpeg