FFmpeg源码学习---ffmpeg
1、ffmpeg源码主函数
┌────────────────────┐
│ main() │
└─────────┬───────────┘
↓
┌────────────────────┐
│ 初始化 (日志/网络等) │
│ init_dynload() │
│ avformat_network_init() │
└─────────┬───────────┘
↓
┌────────────────────────┐
│ 解析命令行参数 options │
│ ffmpeg_parse_options() │
└─────────┬──────────────┘
↓
┌────────────────────────┐
│ 检查输入输出文件 │
└─────────┬──────────────┘
↓
┌────────────────────────┐
│ 记录基准测试起点 │
│ get_benchmark_time_stamps() │
└─────────┬──────────────┘
↓
┌────────────────────────┐
│ 核心转码处理 │
│ transcode() │
└─────────┬──────────────┘
↓
┌────────────────────────┐
│ 记录基准测试终点 │
│ 并打印用时信息 │
└─────────┬──────────────┘
↓
┌────────────────────────┐
│ 清理资源释放内存 │
│ ffmpeg_cleanup(), sch_free() │
└─────────┬──────────────┘
↓
┌────────────────────┐
│ return 退出程序 │
└────────────────────┘
1.1初始化网络设备及日志
1.2解析命令行参数
步骤 | 作用 | 解释 |
---|---|---|
GlobalOptionsContext go = { .sch = sch }; | 初始化全局选项 | go 是一个保存全局选项的结构体,把 Scheduler *sch 传进去,后面需要用。 |
OptionParseContext octx; | 初始化参数解析上下文 | octx 负责临时保存解析中间状态,比如分组后的参数。 |
memset(&octx, 0, sizeof(octx)); | 清零初始化 | 确保 octx 是干净的。 |
split_commandline() | 切分命令行参数成内部结构 | 把 argc/argv 这些参数,按输入、输出、滤镜、解码器分类,放到 octx 里。如果失败就跳 goto fail 。 |
parse_optgroup() | 解析全局参数 | 把命令行里的一些全局设置(比如 -y , -loglevel , -filter_complex )应用到程序状态里。 |
term_init() | 初始化终端 | 配置终端行为,比如是否处理 Ctrl+C 这种信号。 |
for (i = 0; i < go.nb_filtergraphs; i++) | 创建复杂滤镜链 | 如果命令行有 -filter_complex ,需要提前建好滤镜图(filtergraph)。 |
open_files(...GROUP_INFILE...) | 打开所有输入文件 | 找到所有输入文件,比如 -i input.mp4 ,调用 ifile_open() 打开。 |
open_files(...GROUP_OUTFILE...) | 打开所有输出文件 | 找到所有输出文件,比如 output.avi ,调用 of_open() 打开。 |
open_files(...GROUP_DECODER...) | 创建 loopback 解码器 | 少见功能,一般是给特殊 case 用的(比如自定义解码器)。 |
fg_finalise_bindings() | 绑定滤镜链输入输出 | 让滤镜链知道自己接收哪个流,输出到哪里。 |
correct_input_start_times() | 校正输入流时间戳 | 修正各种输入流的起始时间,比如音频、视频同步问题。 |
apply_sync_offsets() | 应用同步偏移 | 如果设置了 -itsoffset 这类参数,需要调整同步。 |
1.3转码
- 初始化:
- 打印流映射信息。
- 设置转码初始化完成的标志。
- 启动调度器:
- 调用
sch_start(sch)
启动调度器,开始转码任务。 - 如果启动失败,直接返回错误码。
- 调用
- 用户交互:
- 如果启用了标准输入交互(
stdin_interaction
),提示用户可以通过键盘输入控制转码过程(例如按q
停止转码)。
- 如果启用了标准输入交互(
- 转码主循环:
- 进入主循环,等待调度器完成转码任务。
- 在循环中,检查用户输入(例如按
q
停止转码)。 - 定期打印转码状态报告。
- 停止调度器:
- 调用
sch_stop(sch, &transcode_ts)
停止调度器。 - 写入输出文件的尾部信息(trailer)。
- 调用
- 清理资源:
- 调用
term_exit()
进行资源清理。 - 打印最终的转码状态报告。
- 调用
- 返回结果:
- 返回转码过程的最终状态码。