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 格式生成交互式流程图
相关推荐
!chen4 小时前
Oracle Deep Data Security (Deep Sec) 初体验
数据库·oracle·ffmpeg
wyw00001 天前
FFmpeg实现带颜色MXF转mp4
python·ffmpeg
aqi001 天前
FFmpeg开发笔记(一百零二)国产的音视频移动开源工具FFmpegAndroid
android·ffmpeg·kotlin·音视频·直播·流媒体
ltlovezh2 天前
FFmpeg 是怎么“猜”出文件格式的?源码级拆解 Demuxer 自动识别机制
ffmpeg
Mike_6662 天前
摩尔线程AB100安装torch环境
人工智能·深度学习·ffmpeg·aarch64·摩尔线程·musa
aqi002 天前
FFmpeg开发笔记(一百零一)跨平台的开源音视频移动框架MobileFFmpeg
android·ffmpeg·音视频·直播·流媒体
starvapour3 天前
ffmpeg基于glob匹配将文件夹中图像按文件名连接成mp4
ffmpeg
blevoice4 天前
JL杰理AC696N开发板上调试蓝牙音质优化:开启AAC高清音频支持
单片机·ffmpeg·音视频·aac·ac6966b蓝牙音响方案·杰理智能音箱开发·杰理ac6965e蓝牙音频开发
誰能久伴不乏4 天前
从底层看透音视频架构:FFmpeg 实时视频推流深度解析
linux·c++·tcp/ip·ffmpeg