本系列 以 ffmpeg4.2 源码为准,下载地址:链接:百度网盘 提取码:g3k8
ffmpeg 源码分析系列以一条简单的命令开始,ffmpeg -i a.mp4 b.flv
,分析其内部逻辑。
a.mp4下载链接:百度网盘,提取码:nl0s 。
本文主要分析 transcode_init()
的内部逻辑,流程图如下:
transcode_init()
里面 全都是 for
循环,一共有 8 个 for 循环。因为贴代码会把文章拉长,所以下面会用第几个for循环来表达。
transcode_init()
虽然有那么多 for,但实际上有些 for 根本跑不进去,在 ffmpeg -i a.mp4 b.flv
下跑不进去。如果被无关的 for 绕进去,不利于初学者入门。
- 第一,第一个 for 循环不用看,不会跑进去。第一个 for 貌似是修复
source_index
错误的。第二个 for 也可以跳过。 - 第三个 for 循环是重要的,因为里面调用了
init_input_stream()
,初始化输入流。init_input_stream()
下面会仔细分析 - 第四个 for 循环是初始化输出流的,调用了
init_output_stream()
,但很遗憾,这个for循环也是没跑进去的。因为output_streams[i]->filter
是有值的,所以会 执行continue
。输出流肯定是要初始化的,不过不在这里初始化,而是后面的reap_filters()
才会初始化。 - 第五个 for 循环是处理
program
的,可以跳过,不重要。 - 第六个 for 循环是处理
no stream
的,不会跑进去。 - 后面的 for 循环都是 dump 调试信息。
下面画一个 transcode_init()
的流程图。
可以看到transcode_init()
的逻辑实际上极其简单,就是遍历输入流,调 init_input_stream()
。所以只需要仔细分析 init_input_stream()
这个函数即可。
init_input_stream()
的代码量比较少,我直接截图一部分重点代码出来讲解。
主要有3个红框 框出来的重点。
- 对解码器
get_foramt
,get_buffer
赋值,主要是硬件加速那块,如果命令行没使用硬件加速,这几行代码是多余。硬件加速,我现在也不太清楚,欢迎看后续的硬件加速分析系列。 - 设置 解码器的
pkt_timebase
,比较重要,自己调api记得照抄。 - 调用
avcodec_open2
打开解码器。
其他的代码都是一些赋值,赋值给decoder_opts
,赋值给解码器context,已经很容易看懂。
转码初始化 transcode_init()
分析完毕。一句话总结, transcode_init()
干的活,就是给解码器context参数赋值,然后打开解码器。
©版权所属:知识星球:弦外之音,QQ:2338195090。
由于笔者的水平有限, 加之编写的同时还要参与开发工作,文中难免会出现一些错误或者不准确的地方,恳请读者批评指正。如果读者有任何宝贵意见,可以加我微信 Loken1。