FFmpeg 概述与完整文档
本文档整理自 FFmpeg/FFmpeg 官方文档与社区资料,便于本地查阅与二次整理。
目录
- 概述
- 快速开始
- 构建与安装指南
- 基本命令行用法
- 解复用与解码示例
- 最新更新与发布说明
- 问题与社区反馈
- 关于贡献者与项目历史
- 库结构与职责
- 数据流管道设计
- 滤镜图架构
- [编解码器 API 参考](#编解码器 API 参考)
- 解码器实现模式
- 编码器实现模式
- 数据包与帧管理
- [格式 API 参考](#格式 API 参考)
- 解复用器实现
- 复用器实现
- 网络协议支持
- [滤镜 API 参考](#滤镜 API 参考)
- 构建滤镜图
- 编写自定义滤镜
- 音频与视频滤镜示例
- 硬件上下文框架
- [CUDA 加速集成](#CUDA 加速集成)
- [VAAPI 与 QSV 实现](#VAAPI 与 QSV 实现)
- [VideoToolbox 与 MediaCodec](#VideoToolbox 与 MediaCodec)
- [图像缩放 API](#图像缩放 API)
- 色彩转换算法
- 音频重采样与混音
- 内存管理工具
- 数学函数
- 像素格式处理
- 延伸阅读与参考链接
概述
FFmpeg 是世界上最全面的多媒体处理框架,提供了一套完整的库和工具生态系统,用于处理音频、视频、字幕及相关元数据。该开源项目为桌面、移动和服务器环境中的无数应用提供支持,既为最终用户提供命令行工具,也为开发者提供用于将多媒体功能集成到应用中的 API。
FFmpeg 的架构基于模块化设计,每个组件在多媒体处理管道中都有明确用途。框架支持广泛的编解码器、容器格式、网络协议和硬件加速技术,是转码、流传输与多处理任务的事实标准。
架构概述
FFmpeg 生态系统采用分层架构:工具层建立在专用库之上。工具层 包括 ffmpeg(命令行转码与处理)、ffplay(媒体播放器)、ffprobe(分析工具)以及 aviocat、ismindex、qt-faststart 等。核心库 包括:libavcodec(编解码器)、libavformat(容器与 I/O)、libavutil(核心工具)、libavfilter(滤镜图)、libavdevice(设备抽象)、libswresample(音频处理)、libswscale(图像缩放与转换)。外部依赖包括硬件加速(CUDA、VAAPI、QSV)、外部编解码器(libx264、libvpx)及系统库(OpenGL、VDPAU)。
命令行工具通过串联库函数完成复杂操作:例如 ffmpeg 可用 libavcodec 解码、libavfilter 滤镜处理、libswresample 重采样、libavformat 封装,一条命令完成全流程。
核心库
| 库 | 用途 | 主要能力 |
|---|---|---|
| libavcodec | 编解码器 | 音视频字幕的编码器与解码器 |
| libavformat | 容器处理 | 流协议、解复用器、复用器与 I/O |
| libavutil | 核心工具 | 哈希、数学、内存管理 |
| libavfilter | 滤镜 | 音视频滤镜图与复杂转换 |
| libavdevice | 设备 | 采集与播放设备 |
| libswresample | 音频 | 混合、重采样、声道布局转换 |
| libswscale | 图像 | 色彩转换与缩放 |
libavformat 与 libavcodec 最常配合使用:前者处理容器级读写(数据包),后者处理编解码(帧)。理解"数据包 vs 帧"是使用 FFmpeg API 的基础。
命令行工具与项目结构
ffmpeg :多媒体处理工具箱,用于转码、格式转换、流传输、音频提取。ffplay :极简播放器,用于预览与解码测试。ffprobe:分析容器结构、流信息与元数据。这些工具基于与开发者相同的库构建,可作为 API 用法的参考。
项目结构:doc/ 含文档与示例;libav*/ 为各库实现;fftools/ 为命令行工具源码;ffbuild/ 为构建系统;tests/、compat/、doc/examples/ 分别为测试、兼容与示例。doc/examples/ 中的可运行示例(如 demux_decode.c)演示解复用、解码、编码、滤镜与硬件加速等模式。
许可与贡献
代码主要采用 LGPL 2.1+,部分组件为 GPL 2+。贡献通过 ffmpeg-devel 邮件列表以 git format-patch / git send-email 提交补丁;GitHub PR 不参与审查。提交前请阅读 doc/developer.texi 中的编码规则(C11/C99)、提交指南与架构原则。
入门路径
建议先按 INSTALL.md 完成配置-构建-安装,再通过命令行熟悉转码与术语,最后从 doc/examples/(尤其是 demux_decode.c)入手进行 API 集成。后续可阅读快速开始、构建与安装指南、基本命令行用法、解复用与解码示例,以及库结构与职责、数据流管道设计等深度章节。
快速开始
本指南提供 FFmpeg 入门步骤:核心概念、基本工作流与快速示例,便于在最少设置下上手。
理解架构与核心库
FFmpeg 由模块化库与命令行工具组成;库提供编程访问,工具提供命令行能力。七个主要库:libavcodec (编解码,如 H.264、AAC、VP9)、libavformat (解复用/复用、I/O、流协议)、libavutil (内存、数学、哈希、像素格式)、libavfilter (音视频滤镜图)、libavdevice (采集与播放设备)、libswresample (重采样、混音、声道布局)、libswscale (色彩与缩放)。命令行工具:ffmpeg (转码与流)、ffplay (播放与测试)、ffprobe(分析与元数据)。
从源码构建
前置:POSIX shell、GNU Make 3.81+、C 编译器、pkg-config;可选 autoconf/automake。三步:① ./configure(可用 --help、--list-decoders/encoders/filters、--enable-libx264 等);② make -j$(nproc);③ make install(可用 --prefix 指定路径)。构建示例:树内 make examples,或复制 doc/examples 后用 Makefile.example 与已安装库构建。
核心数据结构与解复用/解码
AVFormatContext (容器与流)、AVCodecContext (编解码状态)、AVStream (单路流)、AVPacket (压缩包)、AVFrame (原始帧)、AVFilterGraph(滤镜图)。基本流程:avformat_open_input → avformat_find_stream_info → avcodec_alloc_context3 / parameters_to_context / open2 → 循环 av_read_frame → avcodec_send_packet → avcodec_receive_frame 处理帧。decode_video.c 演示纯视频解码(avcodec_find_decoder、send_packet/receive_frame);发送/接收 API 替代旧同步 API,便于性能与硬件加速。
常见用例与后续
命令行示例:转码为 H.264/AAC MP4、提取音频、scale 调整分辨率;音频 loudnorm、-ar 采样率、amix 混音。编程示例:transcode.c 演示完整解复用→解码→滤镜→编码→复用;mux.c 演示程序化生成媒体。后续可阅读构建与安装指南、基本命令行用法、解复用与解码示例、库结构与职责;doc/examples/ 含 20+ 示例,可从 demux_decode.c、decode_video.c、transcode.c、mux.c 入手。
构建与安装指南
从源码构建与安装的完整说明:构建架构、配置选项与平台注意事项。
构建架构与先决条件
FFmpeg 使用 configure 生成 Makefile 的自定义构建系统;ffbuild/ 含通用规则与版本管理。需 ISO C11、POSIX shell;GNU Make 3.81+ 、C 编译器、可选 NASM(x86)。平台:类 Unix 需 GNU Make(BSD make 不可);Solaris 可用 bash ./configure;Darwin 需 Xcode,x86_64 需 NASM,PowerPC/ARM 需 gas-preprocessor;Windows 用 MSYS2 + MinGW-w64。
分步流程与配置选项
步骤:可选 tools/merge-all-source-plugins → ./configure(可外树构建)→ make / make -j$(nproc) → make install(可用 DESTDIR)。./configure --help 列出解码器/编码器/滤镜等。核心选项 :--prefix、--disable-avfilter 等组件、--enable-libx264/libvpx 外部编解码器、--enable-cuda/vaapi 硬件加速、--enable-gpl/version3/nonfree 许可。外部依赖默认禁用,需显式 --enable-*;GPL/nonfree 影响分发。Make:V=1、DBG=1、DESTDIR、GEN=1;目标 all、install、examples、checkheaders、fate。
示例构建与平台
构建示例 :树内 make examples 或安装后 doc/examples 下 make -f Makefile.example(需 PKG_CONFIG_PATH)。平台:BSD 用 gmake;Darwin 通用二进制可分别构建再 lipo;Windows MinGW 用 MSYS2 MinGW shell,可选 --toolchain=msvc;交叉编译用 --cross-prefix、--arch、--target-os。故障排除:shell 问题用 bash ./configure;缺库则安装对应 -dev 包。
基本命令行用法
介绍从命令行使用 FFmpeg 的基本概念与常见媒体处理任务。
命令行结构与转码流水线
基本语法:ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url} ...。选项顺序重要:选项作用于下一个指定文件;所有输入须在输出前指定。流水线:解复用器 (从容器提取流)→ 解码器 (包→原始帧)→ 滤镜 (可选)→ 编码器 (帧→包)→ 复用器(写入容器)。
流选择与指定符
未指定 -map 时自动选择:视频取最高分辨率、音频取最多声道、字幕取首个匹配类型;数据/附件流须显式 -map。-map 格式为 input_index:stream_index(如 0:0、1:2)。流指定符:-c:v/-c:a/-c:s(视频/音频/字幕)、-c:V 非图像视频、-d 数据流、-map 0:p:program_id、0:#stream_id;空指定符匹配所有流。
基本操作与常用选项
格式转换:ffmpeg -i input.avi output.mp4。流拷贝(-c copy):不编解码,直接复制包,适合换容器或提取流。常用参数:-c:v/-c:a 编解码器、-b:v/-b:a 码率、-r 帧率、-s 分辨率、-crf 质量。示例:转网络 MP4(libx264 2M + aac 128k)、-vn -c:a copy 提取音频、-map 合并多源、-vf scale=1280:-1 等比缩放。全局选项:-y/-n 覆盖、-hide_banner、-v quiet、-stats、-threads。帮助:ffmpeg -h / -h long / -h full、-codecs、-decoders、-encoders、-formats、-filters。
解复用与解码示例
使用 libavformat 与 libavcodec 进行解复用与解码的示例与实现模式:从容器提取包并解码为原始帧。
流水线与 demux_decode.c
流水线:格式上下文(解复用)→ 编解码器上下文(解码)→ 帧/包结构。demux_decode.c 展示完整流程:avformat_open_input → avformat_find_stream_info → open_codec_context(av_find_best_stream、avcodec_find_decoder)→ avcodec_parameters_to_context、avcodec_open2;视频可用 av_image_alloc 分配输出缓冲。处理循环:av_read_frame 取包 → 按流索引路由 → decode_packet(avcodec_send_packet → 循环 avcodec_receive_frame 直至 EAGAIN);一包可多帧、一帧可跨多包。帧输出后 av_frame_unref;读完后传 NULL 包刷新解码器取缓冲中剩余帧。清理时释放上下文、帧、包与文件句柄。
原始比特流与硬件加速
decode_video.c :从原始 MPEG-1 比特流解码,用 av_parser_init/av_parser_parse2 识别帧边界,解码后 pgm_save。decode_audio.c :原始音频需缓冲区重填(低于阈值时前移并重填,末尾加 AV_INPUT_BUFFER_PADDING_SIZE 并置零以防 SIMD 越界)。hw_decode.c:av_hwdevice_find_type_by_name、hw_decoder_init(av_hwdevice_ctx_create)、get_format 回调选硬件像素格式、解码后用 av_hwframe_transfer_data 传到系统内存再写出。
最佳实践与构建
错误处理:检查返回值,用 av_err2str;引用计数:av_packet_unref/av_frame_unref;需在循环外保留帧时用 av_frame_ref 或复制缓冲区。构建:树内 make examples 或复制 doc/examples 后 make -f Makefile.example(需 PKG_CONFIG_PATH)。
最新更新与发布说明
近期重点:安全加固、Windows 硬件加速与核心编解码器性能优化。
安全 :DASH 解复用器(avformat/dashdec)堆缓冲区溢出修复,MPD XML 中负数起始编号触发,已加边界检查。Windows 硬件 :avfilter 新增 mestimate_d3d12 滤镜,基于 DirectX 12 视频编码 API 做硬件运动估计;avutil/hwcontext_d3d11va 增加 D3D11VA 资源与堆标志。H264 解码 :x86 H264 去块滤镜系统性优化(移除自定义栈与 MMXEXT、避免 MMX 与重载),SSE2 相对 C 从 0.88x 提升至 0.97x。稳定性 :swscale 滤镜内存零初始化修复(解决 mpv #17317);ffmpeg_demux readrate 初始突发修复(#21510);motion_est 左移未定义行为修复(#21486)。架构:swscale/x86 CPU 标志与 VEX/AVX 修正;h264dsp 命名清理。处理 DASH 或下游损坏/缓冲问题时建议更新;Windows 视频压缩可评估 D3D12 运动估计。
问题与社区反馈
问题来源包括安全研究、下游集成(如 mpv)与性能需求;项目对关键问题响应迅速并与提交紧密关联。
安全 :DASH 解复用器堆溢出(负起始数触发)已修复并致谢发现者;FFmpeg 常为模糊测试与形式化验证目标。下游 :swscale 滤镜内存未清零导致损坏,经 mpv #17317 反馈后修复;readrate 初始突发 #21510、运动估计左移 UB #21486 等均有明确 ticket 引用。性能:H.264 去块等优化附基准数据;D3D12 运动估计等新功能随示例与文档发布。社区重视明确归属、基准透明、极简修复与旧代码清理;问题可经 GitHub issues、邮件列表或下游 tracker 反馈。
关于贡献者与项目历史
FFmpeg 已存在二十余年,是开源多媒体处理中最有影响力的项目之一。当前 GitHub 仓库为官方 git.ffmpeg.org/ffmpeg.git 的镜像。
团队与治理
FFmpeg 以精英治理、社区驱动 运作,无单一公司主导;贡献来自全球个人、公司与组织。开发基于邮件列表(ffmpeg-devel),非 GitHub PR;补丁经 git format-patch/send-email 提交并审查。
近期贡献者与活动
Andreas Rheinhardt :H.264 去块等优化,附基准对比(如 SSE2 从 0.92x 提升至 0.97x);移除 MMX、简化栈分配、修复 motion_est 左移 UB(#21486);变更经 Rémi Denis-Courmont、Sean McGovern 等审查。Steven Liu :修复 DASH 解复用器堆溢出(MPD 负起始数),致谢发现者 Zhenpeng (Leo) Lin。Gyan Doshi :命令行与解复用,如 readrate 初始突发 #21510。Kacper Michajłow :修复 swscale 缓冲区未清零导致的损坏(mpv #17317)。stevxiao / Dmitrii Ovchinnikov:D3D12 运动估计滤镜、D3D11VA 资源与堆标志等硬件加速扩展。
开发理念与参与
文化特点:性能优先(变更附基准)、持续代码清理(移除 dsputil 残余、MMX、恒假分支)、跨平台正确性、安全响应。参与方式:安全研究、性能优化、硬件加速、错误修复、代码现代化。技术债务与架构演进(如从 dsputil 到统一 DSP)在保持兼容的前提下持续进行。详见 git.ffmpeg.org 与邮件列表。
库结构与职责
FFmpeg 为模块化库套件,分层依赖:高层库依赖基础工具,libavutil 为底层。
libavutil :基础工具,无依赖。内存(AVBuffer、动态数组)、数据结构(AVDictionary、AVRational)、多媒体类型(AVPixelFormat、AVSampleFormat、声道布局)、错误与日志、硬件抽象(AVHWDeviceContext)、哈希/加密、数学与 DSP。多数功能需包含特定头文件。libavcodec :编解码引擎,依赖 libavutil。编解码实现(H.264/265、VP8/9、AV1、AAC 等)、外部库封装(x264、libvpx 等)、硬件加速桥接、比特流滤镜、AVPacket/AVFrame、解析。发送/接收 API:avcodec_send_packet/receive_frame(解码)、send_frame/receive_packet(编码);EAGAIN 表示需更多输入或缓冲。libavformat :容器与 I/O,依赖 libavcodec、libavutil。解复用/复用、容器格式(MP4、MKV、FLV 等)、协议(文件、HTTP、RTMP、RTP 等)、流发现与元数据、定位。AVFormatContext 含 AVStream 数组与 AVIOContext (pb)。libavfilter :滤镜图,依赖 libavutil、libswscale、libswresample。有向图、视频/音频滤镜、格式协商(AVFilterLink、AVFilterPad、AVFilterFormats)、硬件滤镜、图可由字符串解析(如 scale=1920:1080,fps=30)。libavdevice :设备采集与输出,依赖 libavformat。输入(x11grab、pulse、v4l2、dshow、avfoundation)、输出(sdl、opengl)、通过 avdevice_register_all 与 avformat_open_input 使用。libswresample:音频重采样、格式与声道转换、混音、抖动与延迟补偿,SwrContext + AVOptions。
数据流管道设计
数据流管道通过互连组件的有向无环图编排媒体处理;ffmpeg 工具基于调度器在多线程中协调各库。
核心结构 :AVPacket(压缩数据、引用计数、时间与流索引)在解复用与编码间传递;AVFrame(解码后原始数据、像素/采样格式)在解码与滤镜/编码间传递;AVFormatContext 维护容器状态与 I/O。发送/接收 API:解码 avcodec_send_packet → avcodec_receive_frame;编码 avcodec_send_frame → avcodec_receive_packet;EAGAIN 表示需先调用另一侧;送 NULL 包进入排空,直至 EOF 后 avcodec_flush_buffers。
流程:解复用(avformat_open_input、avformat_find_stream_info、av_read_frame)→ 解码(AVCodecContext、parameters_to_context、send_packet/receive_frame)→ 滤镜图(libavfilter 有向图、格式协商)→ 编码(send_frame/receive_packet)→ 复用(avformat_new_stream、write_header、av_interleaved_write_frame、write_trailer)。调度器(fftools/ffmpeg_sched)将解复用/解码/滤镜/编码/复用编排为 DAG,经线程安全队列与背压同步;流复制(-c copy)时包直通解复用→复用,可经 BSF。
滤镜图架构
libavfilter 提供基于有向无环图(DAG)的滤镜框架:滤镜为节点,通过链路连接,链路负责格式协商与数据流;支持线性链与带分支/合并的复杂图,调度为基于拉取(sink 请求帧并向上游传播)。
核心结构
AVFilterGraph :图容器,管理 AVFilterContext 数组及 thread_type、nb_threads、max_buffered_frames 等全局配置。AVFilterContext :单滤镜实例,含父 AVFilter、输入/输出 pad 数组与对应 AVFilterLink、priv 私有数据。AVFilterLink :连接输出 pad 与输入 pad,承载协商后的格式(媒体类型、尺寸、色彩空间、time_base)及 incfg/outcfg(AVFilterFormatsConfig)供协商。AVFilterPad:连接点,定义名称、媒体类型及 filter_frame、request_frame、config_props 等回调;可由 AVFilter 静态声明或动态(AVFILTER_FLAG_DYNAMIC_INPUTS/OUTPUTS)添加。
生命周期与格式协商
创建 :avfilter_graph_alloc() → avfilter_graph_alloc_filter() 或 avfilter_graph_create_filter(),avfilter_init_str()/avfilter_init_dict() 初始化。连接 :avfilter_link() 在源输出 pad 与目标输入 pad 间建链;avfilter_insert_filter() 可在已有链中插入滤镜。格式协商 (在 avfilter_graph_config() 中):各滤镜 query_formats 填充链路的 incfg/outcfg → 求交集并 reduce_formats 缩减 → 为每链路选定格式;视频含像素格式/色彩空间/范围,音频含采样格式/率/声道布局。配置:avfilter_graph_config() 调用 graph_check_validity、graph_check_links、graph_config_links、graph_config_pointers;可 avfilter_graph_set_auto_convert() 启用自动插入 scale/aresample。
图解析
文本格式示例:[in] filter1=params1, filter2=params2 [out]; [in2] filter3 [out2]。avfilter_graph_parse() 需预分配 inputs/outputs(AVFilterInOut);avfilter_graph_parse2() 通过指针返回未链接的 inputs/outputs;另有 parse_ptr 等变体。解析后需将返回的 pad 与图中已有滤镜连接并 config。
编解码器 API 参考
libavcodec 提供统一编解码 API,采用发送/接收模型;核心结构为 AVCodecContext、AVCodec、AVPacket、AVFrame。
发现与初始化
avcodec_find_decoder(id)/find_encoder(id)、find_decoder_by_name/find_encoder_by_name;av_codec_iterate() 遍历已注册编解码器。AVCodec 含 name、long_name、类型、capabilities、wrapper_name。avcodec_alloc_context3(codec) 分配上下文,avcodec_parameters_to_context() 从流参数填充,avcodec_open2(ctx, codec, options) 打开。
核心结构
AVCodecContext :codec_type/codec_id、视频 width/height/pix_fmt、色彩 color_primaries/colorspace、音频 sample_rate/sample_fmt/ch_layout/frame_size、time_base/framerate、flags/bit_rate、get_buffer2/get_encode_buffer、hw_device_ctx/get_format 等;建议用 AVOptions 访问。AVPacket :引用计数缓冲区、pts/dts/duration/time_base、AVPacketSideDataType 边数据、关键帧等标志;需 AV_INPUT_BUFFER_PADDING_SIZE。能力标志:AV_CODEC_CAP_DELAY(需 NULL 刷新)、AV_CODEC_CAP_DR1、AV_CODEC_CAP_FRAME_THREADS、AV_CODEC_CAP_HARDWARE 等。
编码与解码流程
编码:avcodec_send_frame(ctx, frame) 提交帧,AVERROR(EAGAIN) 时先 avcodec_receive_packet();送 NULL 进入排空;avcodec_receive_packet() 取包。解码:avcodec_send_packet() / avcodec_receive_frame(),同理 EAGAIN 与 NULL 刷新。音频编码需 sample_fmt、sample_rate、ch_layout、frame_size;可变帧长见 AV_CODEC_CAP_VARIABLE_FRAME_SIZE。
解码器实现模式
解码器围绕 AVCodec/AVCodecContext 与 FFCodec 扩展;生命周期分初始化、帧解码、排空、刷新、清理。现代 API 为 send_packet/receive_frame,输入包与输出帧非 1:1,需正确处理 AVERROR(EAGAIN) 与 AVERROR_EOF。
线程与缓冲
帧级线程 :多帧并发,update_thread_context() 协调参考帧;适合低帧间依赖(如 VP9)。片级线程 :单帧分片,片边界屏障同步(如 MPEG-2、H.264)。块级线程 :块划分与原子进度协调(VP9/AV1)。内存:get_buffer2() 分配帧缓冲,AV_CODEC_CAP_DR1 表示使用;FramePool 管理参考帧;in_pkt/buffer_pkt 缓冲输入包。
硬件与状态
硬件通过 AVCodecHWConfig 与 get_format() 协商;可多后端(DXVA2、D3D11VA、NVDEC、VAAPI、VideoToolbox、Vulkan 等)。init 中分配 priv_data;AV_CODEC_CAP_DELAY 时需送 NULL 包排空。旧版 decode() 仍支持,新实现推荐 receive_frame()。
编码器实现模式
编码器以 AVCodec、AVCodecContext 与 priv_data 分离元数据、上下文与私有状态;生命周期为初始化、帧提交、包接收、清理。现代 API 为 send_frame/receive_packet;EAGAIN 时须先 receive_packet 再送帧,结束时送 NULL 排空并 receive 至 EOF。即使未声明 AV_CODEC_CAP_DELAY 也建议实现排空。
缓冲与码率控制
输入帧 :使用 av_frame_get_buffer() 或复制数据,编码器可能持有关键帧引用。输出包 :get_encode_buffer() 分配包,需 AV_INPUT_BUFFER_PADDING_SIZE;AV_GET_ENCODE_BUFFER_FLAG_REF 表示编码器持引用。内部 :AVCodecInternal.byte_buffer 用于比特流组装。码率控制:bit_rate、rc_max_rate/rc_min_rate、qcompress/qblur、rc_buffer_size/initial_buffer_occupancy、global_quality、qmin/qmax、rc_override 等;HRD 缓冲模型与两遍/场景优先级支持。
硬件加速
编码器通过多种模式支持硬件加速,与 get_format、hw_frames_ctx 等配合。详见各编码器与硬件文档。
数据包与帧管理
FFmpeg 以 AVPacket(压缩数据)、AVFrame(非压缩数据)与 AVBuffer API 构成引用计数数据管理;仅当引用数为 1 时可写,保证零拷贝与线程安全。
AVBuffer 与包
AVBufferRef :buffer、data、size;av_buffer_alloc()/av_buffer_create() 创建,av_buffer_ref()/unref() 管理;av_buffer_is_writable()、av_buffer_make_writable() 保证可写。AVPacket:buf(AVBufferRef)、data/size、pts/dts/duration、stream_index、flags、side_data;av_packet_alloc()/free()、av_new_packet()/av_packet_from_data();av_packet_ref()/unref()/move_ref()/clone();av_packet_make_refcounted()/make_writable()。buf 为 NULL 时 ref 做深拷贝。
AVFrame
布局 :data[]、linesize[],视频为平面(Y/U/V),音频为平面或打包;extended_data 用于多于 8 通道;数据须在 buf 或 extended_buf 中。分配 :av_frame_alloc() 仅分配结构;av_frame_get_buffer() 前须设 format、width/height 或 nb_samples/ch_layout。引用:av_frame_ref()、av_frame_unref()、av_frame_move_ref();buf[0]!=NULL 表示引用计数。写入前检查可写性或 make_writable。
格式 API 参考
Format API 参考文档提供 libavformat 的全面说明。libavformat 是 FFmpeg 的封装格式处理库,负责解复用(将媒体文件拆分为组件流)和复用(将编码数据写入封装格式),为输入和输出提供统一接口。
核心架构概述
Libavformat 作为封装层,位于编解码器层(libavcodec)与 I/O 层之间,管理媒体容器、流元数据,并提供协议抽象(本地文件、网络流、自定义 I/O 回调)。支持解复用与复用两种工作流,共享通用数据结构,初始化和处理模式不同。
核心结构体
AVFormatContext:所有格式操作的核心,不能栈上分配或直接用 av_malloc(),须用 avformat_alloc_context() 或由 avformat_open_input() 隐式创建。关键字段:iformat/oformat、streams/nb_streams、pb、metadata、duration、start_time。
AVStream:表示单个基本流,含 codecpar、time_base、start_time、duration、disposition、avg_frame_rate、metadata。复用前必须填充 codecpar。
AVInputFormat / AVOutputFormat:描述封装格式;可用 av_demuxer_iterate()、av_muxer_iterate() 迭代;含 name、long_name、extensions、mime_type、priv_class。
解复用 API
打开输入:avformat_open_input() 分配上下文、打开 URL、探测格式并读头;对缺头格式需 avformat_find_stream_info() 读更多帧以填充流参数。读取:av_read_frame() 循环返回 AVPacket,stream_index 标识流,pts/dts/duration 以流 time_base 为单位;返回的包为引用计数,须 av_packet_unref()。选项可通过 AVDictionary 传入 avformat_open_input(),或通过 AVFormatContext.flags(如 AVFMT_FLAG_GENPTS)。
复用 API
初始化:avformat_alloc_context()、设置 oformat、avformat_new_stream()、填充每流 codecpar、设置 pb(除非 AVFMT_NOFILE)。写入三阶段:avformat_write_header() → av_write_frame()/av_interleaved_write_frame() 循环 → av_write_trailer()。需按 DTS 交织时用 av_interleaved_write_frame()。write_header 可能修改流的 time_base,计算包时间戳时使用更新后的 time_base。
元数据、流处置与流组
元数据为 AVDictionary,可从 AVFormatContext.metadata、AVStream.metadata、AVChapter.metadata、AVProgram.metadata 访问;键支持语言后缀(-eng 等)和 -sort。流处置标志:AV_DISPOSITION_DEFAULT、DUB、ORIGINAL、COMMENT、LYRICS、FORCED、HEARING_IMPAIRED、CAPTIONS、ATTACHED_PIC;可用 av_disposition_from_string()/to_string()。流组(avformat_stream_group_create/add_stream)用于平铺视频、LCEVC、IAMF 等。
格式与上下文标志、I/O、清理
格式标志示例:AVFMT_NOFILE、AVFMT_GLOBALHEADER、AVFMT_NOTIMESTAMPS、AVFMT_VARIABLE_FPS、AVFMT_TS_NEGATIVE。上下文标志:AVFMT_FLAG_GENPTS、IGNIDX、BITEXACT、FAST_SEEK。自定义 I/O:avio_alloc_context() 创建 AVIOContext,在 open_input 前设 pb。网络协议使用前须 avformat_network_init()。解复用清理用 avformat_close_input();复用用 avformat_free_context(),pb 须单独 avio_closep()。元数据更新通过 event_flags(AVSTREAM_EVENT_FLAG_METADATA_UPDATED、NEW_PACKETS)通知,调用方处理后清除标志。
解复用器实现
解复用器构成容器解析基础,从容器提取编码包并以独立流暴露;libavformat 中格式无关基础设施与各格式的 AVInputFormat 实现分离,便于扩展并保持 API 一致。
核心结构与探测
AVInputFormat :name、long_name、flags(AVFMT_NOFILE、AVFMT_SEEK_TO_PTS 等)、extensions、codec_tag、priv_class、mime_type;read_probe、read_header、read_packet、read_close 等。AVFormatContext :封装解复用状态,公共部分为 API,内部 FFFormatContext 含 packet_buffer、data_offset、parse_pkt、id3v2_meta 等。AVStream/FFStream:每路基本流;使用 codecpar(替代已弃用 codec)、time_base、duration、disposition。格式探测:AVProbeData(filename、buf、buf_size、mime_type),read_probe 返回 0--100 分;阈值 AVPROBE_SCORE_MAX/EXTENSION/RETRY 等,缓冲 PROBE_BUF_MIN~MAX,含 AVPROBE_PADDING_SIZE。
生命周期
注册(REGISTER_DEMUXER)→ 探测(av_probe_input_format2 迭代 read_probe)→ 上下文初始化(read_header:avformat_new_stream、填充 codecpar/时间信息、私有数据)→ 流信息发现(avformat_find_stream_info 必要时部分解码取尺寸、帧率、extradata、时长)→ 包读取循环(av_read_frame → read_packet:从 pb 读取、解析容器帧、填 AVPacket stream_index/pts/dts/duration/flags,结尾返回 AVERROR_EOF)。时间戳须校验,未知用 AV_NOPTS_VALUE。
流解析、定位与错误
流解析策略:AVSTREAM_PARSE_NONE(容器已成帧)、AVSTREAM_PARSE_FULL(MPEG-PS/TS)、PARSE_HEADERS、PARSE_TIMESTAMPS、PARSE_FULL_ONCE、PARSE_FULL_RAW。定位:AVIndexEntry(pos、timestamp、AVINDEX_KEYFRAME、size、min_distance);av_seek_frame 支持 AVSEEK_FLAG_BYTE 或基于时间戳;AVFMT_GENERIC_INDEX 时框架可构建通用索引。流处置标志:AV_DISPOSITION_DEFAULT、FORCED、ORIGINAL、HEARING_IMPAIRED、ATTACHED_PIC、CAPTIONS 等。错误:AVERROR_EOF、EAGAIN、INVALIDDATA、NOFMT、PATCHWELCOME;损坏数据应尝试重新同步。AVFormatContext 非线程安全;包重用与延迟求值可优化性能。
复用器实现
Muxer 将编码后的多媒体流写入容器格式,基于 AVOutputFormat 与 AVFormatContext,分层架构将通用容器操作与格式实现分离。
架构与核心结构
通用 muxing 层(mux.c)处理包验证、时间戳计算与交错,格式特定 muxer(如 movenc、mpegtsenc、matroskaenc)实现 write_header/write_packet/write_trailer。AVOutputFormat 定义 name、long_name、extensions、audio_codec/video_codec、flags、codec_tag、priv_class。格式标志:AVFMT_GLOBALHEADER(extradata 写全局头)、AVFMT_NOTIMESTAMPS、AVFMT_VARIABLE_FPS、AVFMT_TS_NEGATIVE、AVFMT_TS_NONSTRICT。
生命周期与包处理
三阶段:初始化(avformat_alloc_output_context2、avformat_new_stream、avformat_write_header → init_muxer → write_header)、包写入(av_write_frame 或 av_interleaved_write_frame,后者按 DTS 交错)、终止(av_write_trailer,写尾、更新索引,MP4 faststart 时可能重写 moov)。包验证:stream_index 有效、DTS 单调(除 NONSTRICT)、PTS≥DTS、大小为正。compute_muxer_pkt_fields 可补算 DTS/时长;ff_interleave_packet_per_dts 实现基于 DTS 的交错队列。
MOV/MP4 与 BSF
MOV muxer 实现 ISOBMFF atom(ftyp、moov、trak、stbl、stsd、stts、stsc、stsz、stco/co64 等),支持编解码器 FourCC 映射、分段(frag_keyframe、frag_duration、frag_size、movflags dash)、movflags faststart 与丰富 AVOptions。包在写入前可经 BSF(如 h264_mp4toannexb、hevc_mp4toannexb、dump_extra、aac_adtstoasc)。错误通过返回值与 pb->error 报告;自定义 muxer 需实现 write_header/write_packet/write_trailer 并遵循格式规范。
网络协议支持
FFmpeg 网络协议层基于 URLProtocol 插件架构,各协议(HTTP、RTSP、RTP、TCP、UDP、RTMP 等)实现统一接口,由 URLContext 维护连接状态;协议通过 libavformat/protocols.c 注册,可用 avio_enum_protocols() 枚举。核心操作:url_open/url_open2、url_read、url_write、url_seek、url_close、url_accept、url_handshake。
HTTP/HTTPS :HTTP/1.1、认证(Basic/Digest)、重定向缓存、分块、ICY 元数据、gzip/deflate;选项如 seekable、http_proxy、headers、user_agent、reconnect、listen、method。RTSP :控制协议,媒体经 RTP;rtsp_transport 可选 UDP、TCP、UDP_MULTICAST、HTTP(S);SDP 解析、状态机(Options→Describe→Setup→Play→Pause→Teardown),支持 RealNetworks、WMS、SATIP 等服务器。TCP :listen、local_port/addr、timeout、send/recv_buffer_size、tcp_nodelay、tcp_keepalive。UDP :buffer_size、bitrate、burst_bits、多播(sources/block、ttl)、pkt_size、fifo_size、overrun_nonfatal。RTP:与 RTCP 配对、动态负载类型与 SDP rtpmap/fmtp、RTCP 同步与 NTP 映射。选项与白名单通过 AVDictionary/AVOptions 与 protocol_whitelist/blacklist 配置;rw_timeout 与 interrupt_callback 支持超时与中止。服务器端应限制协议白名单并配置 TLS/资源限制。
滤镜 API 参考
Filter API 基于图架构:滤镜通过链接形成有向管道,每滤镜在输入 pad 收帧、在输出 pad 产帧;图负责格式协商、硬件上下文传播与线程协调。
核心结构
AVFilter :滤镜模板,含 name、description、inputs/outputs(AVFilterPad)、priv_class、flags(AVFILTER_FLAG_DYNAMIC_INPUTS/OUTPUTS、SLICE_THREADS、METADATA_ONLY、SUPPORT_TIMELINE)。AVFilterContext :实例,含 filter、name、input_pads/inputs/nb_inputs、output_pads/outputs/nb_outputs、priv、graph、thread_type、nb_threads、hw_device_ctx。AVFilterLink :连接 src/srcpad 与 dst/dstpad,含 type、format、视频 w/h/sample_aspect_ratio/colorspace/color_range、音频 sample_rate/ch_layout、time_base、incfg/outcfg。AVFilterGraph:图容器,filters/nb_filters、scale_sws_opts、aresample_swr_opts、thread_type、nb_threads、max_buffered_frames、execute。
发现与创建、链接与解析
avfilter_get_by_name()、av_filter_iterate()。创建:avfilter_graph_alloc();avfilter_graph_alloc_filter() + avfilter_init_dict() 或 avfilter_graph_create_filter() 一次创建并初始化。链接:avfilter_link(src_ctx, out_idx, dst_ctx, in_idx),然后 avfilter_graph_config()。图解析:avfilter_graph_parse2(graph, filter_descr, &inputs, &outputs) 或 AVFilterGraphSegment(avfilter_graph_segment_parse、avfilter_graph_segment_apply)做更细粒度控制。
Buffer Source/Sink 与格式
视频 buffer、音频 abuffer 为入口;AVBufferSrcParameters 设 format、time_base、width/height、sample_aspect_ratio、frame_rate、color_space/color_range 等,av_buffersrc_parameters_set() 设置;av_buffersrc_add_frame_flags()(AV_BUFFERSRC_FLAG_PUSH、KEEP_REF、NO_CHECK_FORMAT)推帧。出口 buffersink/abuffersink:av_buffersink_get_frame()/get_frame_flags()(AV_BUFFERSINK_FLAG_NO_REQUEST、PEEK),av_buffersink_get_w/h/format/time_base/frame_rate() 查询属性。格式协商通过 AVFilterFormatsConfig(formats、samplerates、channel_layouts、color_spaces、color_ranges、alpha_modes),可手动在 pad 上设置支持的格式列表。
构建滤镜图
滤镜图为有向无环图,节点为滤镜、边为连接;图通过从汇到源拉取或从源到汇推送帧进行处理。三要素:AVFilterGraph(容器)、AVFilterContext(实例)、AVFilterLink(连接,承载协商后的格式与时间基)。
构建方式
直接 API :avfilter_graph_alloc() → 创建 buffersrc/abuffer(参数匹配解码输出)→ 创建 buffersink/abuffersink(可选 av_opt_set 指定 pixel_formats/sample_formats/channel_layouts)→ 创建中间滤镜(avfilter_graph_create_filter 或 alloc_filter + avfilter_init_dict)→ avfilter_link() 连接 → avfilter_graph_config() 触发格式协商。字符串解析:avfilter_graph_parse()/parse_ptr()/parse2(),语法为 filter=param:value、链用逗号、连接用分号、标签用 [label]。parse_ptr 返回未连接端点,可接到 buffersrc/buffersink。
格式协商与段 API
avfilter_graph_config() 时各滤镜 query_formats() 提供支持格式列表,连接上取交集得到商定格式(视频含像素格式/色彩空间/范围,音频含采样格式/通道布局/采样率);可返回 AVERROR(EAGAIN) 推迟。图段 API:avfilter_graph_segment_parse() 解析为 AVFilterGraphSegment(含链与 AVFilterParams),再 create_filters、apply_opts、init、link 分步应用,便于运行时修改参数或插入自定义滤镜。
处理循环与集成
推帧:av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF);拉帧:av_buffersink_get_frame(),EAGAIN/EOF 需继续输入或结束。滤镜可用 filter_frame/request_frame 或 activate() 状态机。线程:thread_type=AVFILTER_THREAD_SLICE、nb_threads=0 自动;max_buffered_frames 限制缓冲;avfilter_graph_set_auto_convert() 控制自动 scale/aresample。调试:avfilter_graph_dump()、AV_LOG_DEBUG。与转码管道集成时,缓冲源用解码器 time_base,缓冲汇协商编码器可接受格式,config 后从 sink 连接取输出参数初始化编码器。
编写自定义滤镜
自定义滤镜扩展 libavfilter:区分滤镜定义 (AVFilter) 与实例 (AVFilterContext),定义提供 name、description、inputs/outputs、priv_class、flags,实例持有 priv(由 FFFilter.priv_size 指定)、链接与图引用。
生命周期与回调
初始化 :avfilter_graph_alloc_filter() + avfilter_init_str/init_dict。init 中分配资源、解析参数;query_formats 声明支持的格式/采样率/通道布局(ff_set_common_formats_from_list 等);config_props 在协商后验证参数、分配每链接资源。处理 :filter_frame 收帧,分配输出帧(ff_get_video_buffer 等)、复制属性、执行转换、av_frame_free(in)、ff_filter_frame(outlink, out);注意引用计数,不修改数据时可直接转发。清理:uninit 释放缓冲区、表达式、外部引用;框架释放 priv。
视频与音频实现
视频:私有上下文 + AVOption + AVFilterPad(filter_frame、config_props)+ FFFilter(FILTER_INPUTS/OUTPUTS、priv_size)。按像素格式分支(平面 YUV 逐平面、打包 RGB 逐分量),步长用 ptrdiff_t。切片线程:filter_slice(ctx, arg, jobnr, nb_jobs) 处理水平切片,filter_frame 内 ctx->internal->execute(ctx, filter_slice, &td, NULL, nb_jobs),并设置 AVFILTER_FLAG_SLICE_THREADS。音频:处理采样数组与通道布局;volume 等示例展示多采样格式与精度、eval_mode;循环内按位深处理采样。注册后滤镜可通过名称在图中使用。
音频与视频滤镜示例
libavfilter 示例涵盖合成音频、解码后音频/视频过滤及与转码管道集成。图由 AVFilterGraph/AVFilterContext/AVFilterLink 与 buffersrc-buffersink 构成;源无输入、汇无输出。
音频 :filter_audio.c 为纯合成链(abuffer→volume→aformat→abuffersink),展示三种选项设置------直接 av_opt_set、AVDictionary + avfilter_init_dict、参数字符串 + avfilter_init_str。decode_filter_audio.c 从文件解复用解码后过滤,重采样至 8kHz 单声道 S16;buffersrc 参数需与解码输出一致(time_base、sample_rate、sample_fmt、channel_layout),buffersink 用 av_opt_set 指定输出格式。视频 :decode_filter_video.c 使用 scale=78:24,transpose=cclock 等,buffersrc 需 video_size、pix_fmt、time_base、pixel_aspect,buffersink 可指定如 gray8。循环:av_buffersrc_add_frame_flags(..., KEEP_REF)、av_buffersink_get_frame(),EAGAIN 表示需更多输入。图构建可手动 avfilter_link 或 avfilter_graph_parse_ptr 解析字符串(支持 [main][tmp] 等标签)。清理按分配逆序:avfilter_graph_free、av_frame_free、av_packet_free、avcodec_free_context、avformat_close_input;错误路径用 goto 统一释放。与编码集成时用 av_buffersink_get_time_base() 保持时间基;多流时每流类型单独图。构建:make examples 或 doc/examples 下 Makefile.example;graph2dot 可导出图结构。
硬件上下文框架
硬件上下文框架提供设备管理、硬件帧池与 HW/系统内存传输的统一抽象,支持 CUDA、VAAPI、QSV、DXVA2、D3D11VA、D3D12VA、VideoToolbox、Vulkan、OpenCL、MediaCodec、VDPAU、DRM、AMF、OHCODEC 等类型。
架构与核心结构
三层:设备层(代表硬件能力)、帧池层(硬件缓冲区管理)、传输层(HW↔系统内存及上下文间映射)。AVHWDeviceContext :type、hwctx(类型特定,如 AVCUDADeviceContext、AVVAAPIDeviceContext)、free、user_opaque;通过 AVBufferRef 引用计数。AVHWFramesContext:device_ref/device_ctx、hwctx、pool、initial_pool_size、format(硬件像素格式)、sw_format、width/height;池内帧属性一致。
设备与帧池
设备创建:av_hwdevice_ctx_create(type, NULL, NULL, 0) 简单创建;av_hwdevice_ctx_alloc() + 填充 hwctx + av_hwdevice_ctx_init() 自定义;av_hwdevice_ctx_create_derived() 从现有设备派生(如 CUDA→Vulkan)。发现:av_hwdevice_find_type_by_name()、av_hwdevice_get_type_name()、av_hwdevice_iterate_types()。帧池:av_hwframe_ctx_alloc(device_ref) → 设置 format、sw_format、width、height、initial_pool_size → av_hwframe_ctx_init();av_hwframe_get_buffer(frames_ref, frame, 0) 从池取帧。各类型通过 hwctx 暴露特定配置(如 CUDA 的 cuda_ctx/stream,VAAPI 的 display、surface_ids)。能力查询:av_hwdevice_hwconfig_alloc()、av_hwdevice_get_hwframe_constraints()。传输:av_hwframe_transfer_data() 在硬件帧与系统内存间拷贝;支持上下文间映射的可用 frame mapping API。
CUDA 加速集成
FFmpeg 的 CUDA 集成遵循硬件上下文框架:设备上下文、帧上下文与传输层三层;AVHWDeviceContext 含 AVCUDADeviceContext,与 NVDEC/NVENC 等 hwaccel 集成。
设备初始化与像素格式
初始化:cuda_device_create 执行驱动初始化、设备枚举与上下文创建;支持新上下文、主上下文(AV_CUDA_USE_PRIMARY_CONTEXT,多库共享)或当前上下文(AV_CUDA_USE_CURRENT_CONTEXT)。cuda_context_init 处理三种路径;默认设备 0。支持的 sw_format:NV12、NV16、YUV420P、YUVA420P、YUV444P、YUV422P、P010/P016、P210/P216、YUV*P10、YUV444P12MSB、YUV444P16、RGB32/BGR32、0RGB32/0BGR32、VULKAN 互操作等;cuda_frames_init 校验格式并用 cuDeviceGetAttribute 取纹理对齐,YUV420P 时 U/V 对齐加倍。
内存与传输
动态帧池:cuda_pool_alloc 内 cuCtxPushCurrent → cuMemAlloc → av_buffer_create(ptr, cuda_buffer_free) → cuCtxPopCurrent;释放时 cuMemFree。缓冲区大小按纹理对齐经 av_image_get_buffer_size 计算。传输:cuda_transfer_data 经 CUDA 流异步执行;主机↔设备用 cuMemcpy2DAsync,设备→主机后需 cuStreamSynchronize;设备↔设备保持异步。传输前/后正确 push/pop 上下文。
错误处理与派生
ff_cuda_check 将 CUresult 映射为 AVERROR_EXTERNAL,用 cuGetErrorName/cuGetErrorString 记录;宏 FF_CUDA_CHECK、FF_CUDA_CHECK_DL、CHECK_CU。设备派生:cuda_device_derive 支持从 Vulkan 等派生,取 Vulkan 物理设备 UUID 与 CUDA 设备匹配后保留或创建上下文,便于与 Vulkan 渲染共享 GPU。使用示例:av_hwdevice_ctx_create(CUDA, NULL, NULL, 0) → av_hwframe_ctx_alloc → 设 format=AV_PIX_FMT_CUDA、sw_format=NV12、width/height → av_hwframe_ctx_init。性能:默认流 NULL、遵守纹理对齐、异步传输、多库时用主上下文、GPU 处理优先 NV12。
VAAPI 与 QSV 实现
FFmpeg 在统一硬件上下文框架下实现 VAAPI(Linux,Intel/AMD)与 QSV(Intel 跨平台),二者均通过 AVHWDeviceContext/AVHWFramesContext 与编解码器集成。
VAAPI(hwcontext_vaapi.c):设备经 DRM/X11/Win32 连接,含驱动怪癖与格式/表面属性查询。格式映射覆盖 YUV420/422/444(NV12、P010、P012、YUYV、Y210、YUV444P、XV30/XV36 等)与 RGB(BGRA、X2RGB10 等)。帧以 VASurfaceID 管理,池预分配表面;传输支持系统↔硬件拷贝与 VAImage 映射;DRM PRIME 支持导出/导入与 DRM_PRIME_2 格式修饰符,实现与 Vulkan/VDPAU 等零拷贝互操作。
QSV(hwcontext_qsv.c):基于 Intel Media SDK/oneVPL,可选用 VAAPI、D3D9、D3D11 作为子设备。两种池模式:固定池(QSV 自管表面)与派生子分配(表面由 VAAPI/D3D11 提供,零拷贝与滤镜图集成)。格式以 NV12、P010、YUYV、BGRA 等为主;会话创建含 oneVPL 加载器与设备过滤;传输经 VPP 或子设备能力,含边框填充处理。编解码器通过 hw_configs 声明设备类型、像素格式与方法;解码/编码流程与硬件上下文框架一致。
VideoToolbox 与 MediaCodec
二者均接入 FFmpeg 硬件上下文框架,编解码器通过统一 API 使用,平台细节由各实现封装。
VideoToolbox(Apple):解码经 VTDecompressionSession、帧存于 CVPixelBuffer,支持 H.264、HEVC、VP9、AV1、MPEG-2/4、ProRes 等;extradata 格式为 avcC/hvcC 等。生命周期:会话创建(格式描述、解码器规范)→ 帧解码 → 会话清理。像素格式按位深与色度自动映射(4:2:0/2:2/4:4:4、8/10/16 bit、NV12/P010、AYUV 等);错误映射为 FFmpeg 错误码,支持流参数变更时重配。设备创建:av_hwdevice_ctx_create(VIDEOTOOLBOX)。
MediaCodec(Android):使用 NDK API,异步缓冲区队列;输入入队、输出出队,可渲染到 Surface 或拷至系统内存。须显式释放:av_mediacodec_release_buffer() 或 av_mediacodec_render_buffer_at_time()。格式通过 MediaFormat 协商,输出格式需在配置后查询(设备差异大);表面经 av_mediacodec_default_init(avctx, mediacodec_ctx, android_surface) 附加,零拷贝渲染。帧到 CPU 用 av_hwframe_transfer_data() 等通用路径。初始化与 VideoToolbox 不同:av_mediacodec_alloc_context() + av_mediacodec_default_init。
图像缩放 API
libswscale 用于高性能图像缩放、色彩空间与像素格式转换,位于解码与编码之间;推荐使用基于帧的现代 API,同时保留基于缓冲区的传统 API。
架构与 Context
SwsContext 封装缩放算法、线程、抖动与色彩空间等配置;可运行于动态模式(随帧属性自动适应,无需重初始化)或传统模式(固定参数显式初始化)。现代用法:sws_alloc_context() 创建 → 设置 ctx->flags(如 SWS_BICUBIC)、ctx->threads(0 为自动)、ctx->dither(如 SWS_DITHER_AUTO)→ 直接 sws_scale_frame(ctx, dst_frame, src_frame) → sws_free_context(&ctx)。帧属性在每次调用时从 src/dst 帧读取。
验证、算法与主要操作
转换前可用 sws_test_format()、sws_test_colorspace()、sws_test_primaries()、sws_test_transfer() 或 sws_test_frame() 验证支持;返回正数表示支持。缩放算法:SWS_FAST_BILINEAR(实时)、SWS_BILINEAR、SWS_BICUBIC(默认缩小)、SWS_BICUBLIN、SWS_LANCZOS(放大质量高)、SWS_GAUSS、SWS_POINT、SWS_AREA、SWS_SPLINE 等。主接口 sws_scale_frame(ctx, dst, src) 完成格式/分辨率/色彩空间转换;dst->data[0] 可为 NULL 由库分配。sws_is_noop(dst, src) 可判断是否无需转换。
高级配置与性能
抖动:SWS_DITHER_NONE、SWS_DITHER_AUTO、SWS_DITHER_BAYER、SWS_DITHER_ED(误差扩散,质量高但单线程)等。色度:SWS_FULL_CHR_H_INT、SWS_FULL_CHR_H_INP。Alpha:ctx->alpha_blend(SWS_ALPHA_BLEND_UNIFORM/CHECKERBOARD/NONE)。位精确:SWS_ACCURATE_RND | SWS_BITEXACT。传统 API:sws_getContext(srcW, srcH, srcFormat, dstW, dstH, dstFormat, flags, ...)、sws_scale(ctx, srcSlice, srcStride, ...)、sws_freeContext(ctx)。与 libavutil/libavcodec/libavfilter/libavformat 集成;详见色彩转换算法与像素格式处理章节。
色彩转换算法
libswscale 实现综合色彩转换框架:像素格式、色彩空间与色彩范围间的高性能转换;以 SwsContext 为中心,多通道图可动态构建转换链(SwsOpList 可优化编译)。YUV→RGB 使用预定义系数矩阵(R=Y+crv*V 等),系数 2^16 缩放 32 位整数;支持 BT.709、BT.2020 NCL、BT.601、FCC、SMPTE 240M 等,sws_getCoefficients() 可查。解码含范围归一化与色彩空间矩阵;缺省色彩空间时用 BT.470BG 并告警。有限/全范围(Y 16--235 或 0--255)与 HDR 传递(PQ、HLG)影响抖动精度(SDR 12 位、HDR 14 位)。抖动:SWS_DITHER_NONE/AUTO/BAYER/ED 等;Bayer 矩阵递归生成。色度:SWS_FULL_CHR_H_INT、SWS_FULL_CHR_H_INP;色度位置 src/dst_h_chr_pos、v_chr_pos。支持 200+ 像素格式;sws_test_format/colorspace/primaries/transfer/frame() 做兼容性测试。与缩放算法集成;推荐 sws_scale_frame() 动态 API,传统用 sws_getContext()+sws_scale()。LUT3D、adapt_colors、格式链优化与 sws_is_noop()、sws_frame_setup() 验证。
音频重采样与混音
libswresample 提供采样率转换、通道重混音与采样格式转换;围绕 SwrContext,流水线可含重采样、通道矩阵、格式转换三阶段,引擎可选 SWR 或 SOXR。
重采样与通道混合
重采样:多相滤波器组;滤波器类型 Cubic(实时)、Blackman-Nuttall(高质量下采样)、Kaiser(可配置 beta)。配置:filter_size、phase_shift、linear_interp、exact_rational、cutoff。通道混合:矩阵乘法,matrix[i][j] 为输入 j 对输出 i 的贡献;center_mix_level、surround_mix_level、lfe_mix_level、rematrix_volume;swr_set_matrix() 可设自定义矩阵。采样格式与抖动:SWR_DITHER_NONE/Rectangular/Triangular/Noise Shaping 等;dither_method、dither_scale、output_sample_bits。
API 与高级
分配:swr_alloc() + av_opt_set_* 或 swr_alloc_set_opts2();swr_init() 初始化,参数变更后再次调用。转换:swr_convert(swr, out, out_count, in, in_count);用 swr_get_delay()、av_rescale_rnd 估算输出采样;NULL 输入刷新缓冲。基于帧:swr_config_frame()、swr_convert_frame()。时间戳补偿:swr_next_pts();min_compensation、min_hard_compensation、comp_duration、async。swr_get_out_samples() 估输出数;通道映射支持非标准布局。
内存管理工具
FFmpeg 内存管理分三层:堆操作、引用计数缓冲区、动态数组;面向 SIMD 对齐、溢出保护与零拷贝。
堆与快速分配
对齐分配:av_malloc/av_mallocz/av_calloc/av_malloc_array,平台对齐(64/32/16 字节)、溢出保护、最大分配可配。重分配:av_realloc/av_reallocp;av_realloc_f 失败时释放原指针;av_realloc_array/av_reallocp_array 数组+溢出保护。快速分配:av_fast_realloc(保留内容)、av_fast_malloc/av_fast_mallocz(失败时释放旧缓冲),几何增长 min_size+min_size/16+32。释放:av_free、av_freep(&ptr) 释放后置 NULL。复制:av_strdup/av_strndup、av_memdup、av_memcpy_backptr(重叠复制)。
动态数组与缓冲区
动态数组:av_dynarray_add(指针数组,失败时释放数组)、av_dynarray2_add(值数组,elem_data 可 NULL 零初始化)。缓冲区:AVBuffer/AVBufferRef,av_buffer_alloc、av_buffer_create、av_buffer_ref/unref、av_buffer_is_writable、av_buffer_make_writable、av_buffer_realloc;池 av_buffer_pool_init/get/uninit。引用结构:av_refstruct_alloc/ref/unref、av_refstruct_replace。安全:整数溢出检查、av_max_alloc 限制、调试时破坏已释放内存;重分配失败须手动 av_free 原指针。与各库共享 AVBufferRef 实现零拷贝管道。
数学函数
libavutil 数学工具涵盖基本算术、时间戳重缩放、整数/定点/浮点 DSP 与变换,为编解码与滤镜提供计算基础。
常数、舍入与时间戳
mathematics.h:M_E、M_LN2、M_PI、M_SQRT2 等;AVRounding:AV_ROUND_ZERO/INF/DOWN/UP/NEAR_INF、AV_ROUND_PASS_MINMAX(保持 INT64_MIN/MAX)。av_gcd()(Stein 二进制 GCD)。时间戳:av_rescale_rnd(a,b,c,rnd)、av_rescale()、av_rescale_q()/av_rescale_q_rnd(),防溢出、支持 AV_NOPTS_VALUE。
整数、定点与浮点 DSP
intmath.h:av_log2/av_log2_16bit、ff_ctz/ff_ctzll、ff_clz。integer.h:AVInteger 128 位算术(av_add_i、av_mul_i、av_shr_i、av_log2_i、av_int2i/av_i2int)。AVFloatDSPContext:vector_fmul、vector_fmac_scalar、vector_fmul_scalar、点积与加窗等,SIMD 优化。AVFixedDSPContext:定点乘加、vector_fmul_window_scaled 等,缩放一致。AVTXContext:FFT、MDCT、RDFT、DCT(AV_TX_FLOAT/DOUBLE/INT32 变体),步长与缩放可配。
高级与随机
LLSModel 线性最小二乘(update_lls、evaluate_lls);PCA(ff_pca_init/add/free)。表达式:av_expr_parse_and_eval()、av_expr_parse()+av_expr_eval(),支持变量与内置函数。AVLFG:av_lfg_get、av_mlfg_get、av_bmg_get(高斯),av_lfg_init/init_from_data。运行时按 CPU 能力选择实现。
像素格式处理
libavutil 提供像素格式枚举与描述:AVPixelFormat、av_get_pix_fmt()、av_get_pix_fmt_name()、av_pix_fmt_desc_get()(AVPixFmtDescriptor:name、nb_components、log2_chroma_w/h、flags、comp 等)、av_pix_fmt_count_planes()、av_pix_fmt_swap_endianness()。用于查询平面数、色度缩小、分量布局与字节序;与 libswscale(格式/色彩转换)、libavcodec(编解码器输入输出格式)配合。av_image_fill_arrays()、av_image_get_buffer_size()、av_image_copy_to_buffer() 等便于分配与拷贝。详见 pixel format 与 libavutil 文档。
延伸阅读与参考链接
- 官方文档:FFmpeg 官网、文档
- 源码与示例:仓库 FFmpeg/FFmpeg、doc/examples/