fftools/graph-FFmpeg Filtergraph 打印系统文档

FFmpeg Filtergraph 打印系统文档

概述

FFmpeg 的 filtergraph 打印系统(graphprint)是一个调试和诊断工具,用于将 ffmpeg 运行时的 filtergraph 拓扑结构输出为结构化文本或可视化图表。它能够展示从输入文件经过解码器、过滤器链、编码器到输出文件的完整数据流路径。

该系统由以下文件组成:

文件 说明
fftools/graph/graphprint.h 头文件,声明公共 API
fftools/graph/graphprint.c 实现文件,包含所有打印逻辑
fftools/resources/graph.css Mermaid HTML 输出的 CSS 样式
fftools/resources/graph.html Mermaid HTML 输出的 HTML 模板

公共 API

c 复制代码
int print_filtergraph(FilterGraph *fg, AVFilterGraph *graph);

功能 :打印单个 filtergraph 的详细信息到内部缓冲区 fg->graph_print_buf

参数

  • fg --- 指向 FilterGraph 结构体的指针,包含 filtergraph 的配置信息
  • graph --- 指向 AVFilterGraph 结构体的指针,包含 libavfilter 层面的 filter 图信息

返回值:成功返回 0,失败返回负的 AVERROR 错误码

调用时机 :在每个 filtergraph 配置完成后调用(见 ffmpeg_filter.c:3417

输出内容

  • graph 索引、名称、描述
  • graph 的输入端信息(输入索引、链接标签、关联 filter、媒体类型)
  • graph 的输出端信息(输出索引、名称、链接标签、关联 filter、媒体类型)
  • 每个 filter 的详细信息(名称、类型、参数、输入/输出 pad 的媒体参数)

线程模型:由于 FFmpeg 的多线程架构,每个 filtergraph 在各自的线程中将自身序列化到缓冲区,后续由主线程统一组装。


c 复制代码
int print_filtergraphs(FilterGraph **graphs, int nb_graphs,
                       InputFile **ifiles, int nb_ifiles,
                       OutputFile **ofiles, int nb_ofiles);

功能:汇总所有 filtergraph 的缓冲数据,补充输入/输出文件流信息,统一输出到目标位置。

参数

  • graphs --- FilterGraph 指针数组
  • nb_graphs --- filtergraph 数量
  • ifiles --- InputFile 指针数组
  • nb_ifiles --- 输入文件数量
  • ofiles --- OutputFile 指针数组
  • nb_ofiles --- 输出文件数量

返回值:成功返回 0,失败返回负的 AVERROR 错误码

调用时机 :在 ffmpeg 退出前的清理阶段调用(见 ffmpeg.c:316

输出内容(除各 filtergraph 的信息外,还包括):

  • 输入文件及其流信息
  • 输出文件及其流信息
  • 解码器信息
  • 编码器信息
  • 流链接关系(stream links)

命令行选项

这三个选项定义在 ffmpeg_opt.c:1847-1854

-print_graphs

将 filtergraph 数据打印到 stderr(通过 av_log 输出)。

复制代码
ffmpeg -i input.mp4 -vf "scale=640:360" -c:v libx264 -y output.mp4 -print_graphs

-print_graphs_file <filename>

将 filtergraph 数据写入指定文件。使用 - 表示输出到 stdout。

复制代码
ffmpeg -i input.mp4 -vf "scale=640:360" -c:v libx264 -y output.mp4 \
       -print_graphs_file /tmp/graph.json

-print_graphs_format <format>

设置输出格式。默认为 json。可选格式包括:

格式 说明
json JSON 格式(默认)
compact 紧凑文本格式
csv CSV 格式
flat 扁平键值对格式
ini INI 风格格式
xml XML 格式
default 默认文本格式
mermaid Mermaid 流程图文本格式
mermaidhtml Mermaid 流程图嵌入 HTML(可用浏览器查看可视化结果)
复制代码
ffmpeg -i input.mp4 -vf "scale=640:360" -c:v libx264 -y output.mp4 \
       -print_graphs_file /tmp/graph.html -print_graphs_format mermaidhtml

输出数据结构

输出数据按以下层级组织(对应 graphprint.c:78-121 中定义的 section):

复制代码
root
├── graphs                    # 所有 filtergraph
│   └── graph                 # 单个 filtergraph
│       ├── graph_index       # graph 索引
│       ├── name              # 名称(如 "Graph 0.0")
│       ├── id                # 唯一标识符(如 "Graph_0_0")
│       ├── description       # filtergraph 描述字符串
│       ├── graph_inputs      # graph 输入端
│       │   └── graph_input   # 单个输入
│       ├── graph_outputs     # graph 输出端
│       │   └── graph_output  # 单个输出
│       └── filters           # 所有 filter 节点
│           └── filter        # 单个 filter
│               ├── filter_inputs   # filter 输入 pad
│               │   └── filter_input
│               │       └── hw_frames_context  # 硬件帧上下文
│               └── filter_outputs  # filter 输出 pad
│                   └── filter_output
│                       └── hw_frames_context
├── inputfiles                # 输入文件
│   └── inputfile
│       └── inputstreams
│           └── inputstream
├── outputfiles               # 输出文件
│   └── outputfile
│       └── outputstreams
│           └── outputstream
├── decoders                  # 解码器
│   └── decoder
├── encoders                  # 编码器
│   └── encoder
└── streamlinks               # 流链接关系
    └── streamlink

使用示例

示例 1:简单视频缩放 --- JSON 输出

bash 复制代码
ffmpeg -i input.mp4 \
       -vf "scale=1280:720" \
       -c:v libx264 -y output.mp4 \
       -print_graphs_file /tmp/graph.json \
       -print_graphs_format json

输出 JSON 文件包含完整的 filtergraph 拓扑,包括每个 filter 的名称、类型、输入/输出 pad 上的媒体参数(分辨率、像素格式、帧率等)。

示例 2:复杂 filtergraph --- Mermaid HTML 可视化

bash 复制代码
ffmpeg -i video.mp4 -i audio.mp4 \
       -filter_complex "[0:v]split=2[v1][v2]; \
                        [v1]scale=1280:720,format=yuv420p[vout1]; \
                        [v2]scale=640:360,format=yuv420p[vout2]" \
       -map "[vout1]" -c:v libx264 -y out1.mp4 \
       -map "[vout2]" -c:v libx264 -y out2.mp4 \
       -print_graphs_file /tmp/graph.html \
       -print_graphs_format mermaidhtml

用浏览器打开 /tmp/graph.html,可以看到完整的 filtergraph 流程图,直观展示数据从输入文件分流、分别缩放、最终输出的完整路径。

示例 3:直接打印到 stderr

bash 复制代码
ffmpeg -i input.mp4 -vf "hqdn3d=4:3:6:4.5" -c:v libx264 -y output.mp4 -print_graphs

filtergraph 信息会随其他日志信息一起输出到 stderr。

示例 4:输出到 stdout

bash 复制代码
ffmpeg -i input.mp4 -vf "scale=320:240" -c:v libx264 -y output.mp4 \
       -print_graphs_file - -print_graphs_format json

使用 - 作为文件名表示输出到 stdout。

内部工作流程

复制代码
┌──────────────────────────────────────────────────────────────┐
│                     ffmpeg 启动                               │
└──────────────────────┬───────────────────────────────────────┘
                       │
                       ▼
┌──────────────────────────────────────────────────────────────┐
│  解析命令行选项,记录 print_graphs / print_graphs_file 等值    │
│  (ffmpeg_opt.c:80-82)                                       │
└──────────────────────┬───────────────────────────────────────┘
                       │
                       ▼
┌──────────────────────────────────────────────────────────────┐
│  配置阶段:每个 filtergraph 在各自线程中完成配置                │
│                                                              │
│  if (print_graphs || print_graphs_file)                      │
│      print_filtergraph(fg, fgt.graph);                       │
│      → 将单个 graph 信息序列化到 fg->graph_print_buf          │
│      (ffmpeg_filter.c:3417-3418)                            │
└──────────────────────┬───────────────────────────────────────┘
                       │
                       ▼
┌──────────────────────────────────────────────────────────────┐
│  退出清理阶段:主线程汇总所有数据                               │
│                                                              │
│  if (print_graphs || print_graphs_file)                      │
│      print_filtergraphs(graphs, ..., ifiles, ..., ofiles, ...)│
│      → 合并所有 fg->graph_print_buf                           │
│      → 补充输入/输出文件流、解码器、编码器、流链接信息           │
│      → 根据格式(json/mermaid/...)输出到文件或 stderr         │
│      → 释放资源管理器 (ff_resman_uninit)                      │
│      (ffmpeg.c:316-317)                                     │
└──────────────────────────────────────────────────────────────┘

实现细节

格式化系统

打印系统基于 FFmpeg 的 AVTextFormat 框架(位于 fftools/textformat/),这是一个通用的结构化文本输出框架,支持多种输出格式。

格式选择逻辑在 init_graphprint() 中:

c 复制代码
const char *w_name = print_graphs_format ? print_graphs_format : "json";
text_formatter = avtext_get_formatter_by_name(w_name);

Mermaid 图表支持

当选择 mermaidmermaidhtml 格式时:

  1. 从资源管理器加载 CSS 样式和 HTML 模板(graphprint.c:924-931
  2. 启用图表模式(is_diagram = 1),自动包含更多可选字段
  3. 跳过 buffer filter(如 abuffer/buffer),使图表更简洁
  4. 生成 Mermaid 语法描述的流程图

线程安全

由于每个 filtergraph 在独立线程中运行,print_filtergraph() 使用原子计数器 atomic_int prefix_numgraphprint.c:159)为每个 graph 分配唯一的前缀编号,确保 ID 不冲突。

适用场景

  • 调试复杂 filtergraph:查看 filter 链的实际配置和媒体参数
  • 验证 filter 连接:确认 filter 之间的连接关系是否正确
  • 分析性能瓶颈:查看每个 filter 的输入/输出参数,了解转换开销
  • 文档记录:将 filtergraph 拓扑保存为文件,用于记录或分享
  • 可视化展示:使用 Mermaid HTML 格式生成交互式流程图
相关推荐
luoyayun3616 小时前
Qt + FFmpeg 实战:获取音视频文件基础属性、流信息和元数据
qt·ffmpeg·音视频·元数据·获取音视频文件属性
Rudon滨海渔村6 小时前
ffmpeg裁剪视频黑屏、不准时等处理方式 - ffmpeg基本操作
ffmpeg·音视频
The Sheep 20231 天前
ffmpeg速成
ffmpeg
街灯L1 天前
【Ubuntu】使用ffmpeg解析m3u8网页视频
ubuntu·ffmpeg·音视频
烟雨江南7852 天前
特高压输电线路带电作业直升机吊篮与强电磁感应放电:基于“灵声智库”空间自适应滤波与声纹授权的离线语音控制指令方案
人工智能·ffmpeg·webrtc·语音识别·ai质检
AJi2 天前
H264码率控制
ffmpeg
换个昵称都难3 天前
webrtc voice engine 介绍(新版webrtc)
ffmpeg·音视频·webrtc
小鹿软件办公4 天前
巧用 Adobe Audition 中置声道提取,轻松分离人声与背景音乐
adobe·ffmpeg·简鹿人声分离
2023自学中6 天前
imx6ull开发板 移植 ffmpeg 4.2.11 + x264 视频编码库
linux·ffmpeg·音视频·嵌入式·开发板
feibaoqq6 天前
光电视频监控技术(GB28181/ONVIF/私有协议)
ffmpeg·音视频·低空安防