ffmpeg 使用 ffplay 进行 hls 拉流 分析 1
从使用ffplay 调用 http://192.168.1.100:8080/live/livestream.m3u8 开始,进入到ffmpeg 的分析使用的协议选择相应的解复用器的步骤。
其他协议或者文件方式的使用ffplay也是这个步骤流程的。

目录:

  • 一、流程图:
  • 二、代码分析:
    • 1、ffplay.c调用avformat_open_input()进行打开文件
    • 2、进入utils.c的avformat_open_input()前面这些是一些初始化操作 分配AVFormatContext、保存参数到AVDictionary、设置参数
    • 3、utils.c的avformat_open_input()中调用init_input()进行打开文件和探测协议格式
    • 4、utils.c的init_input()中调用av_probe_input_format2()会根据后缀名探测格式
    • 5、format.c中av_probe_input_format2()调用av_probe_input_format3()
    • 6、format.c中av_probe_input_format3()
    • 7、遍历时查找到hls时调用hls_probe()返回0。这次探测格式就失败了
    • 8、utils.c中init_input()中调用io_open()默认打开操作
    • 9、io_open是在option.c中的avformat_get_context_defaults()绑定io_open_default()
    • 10、option.c中的io_open_default()中调用ffio_open_whitelist()
    • 11、aviobuf.c中ffio_open_whitelist()中调用ffurl_open_whitelist()
    • 12、avio.c中ffurl_open_whitelist()调用ffurl_alloc()创建url上下文
    • 13、avio.c中ffurl_alloc()调用url_find_protocol()查找协议
    • 14、avio.c中url_find_protocol根据url(文件名)查找协议
    • 15、avio.c中ffurl_alloc()调用url_alloc_for_protocol()根据协议创建上下文
    • 16、avio.c中url_alloc_for_protocol()创建协议上下文,进行一系列初始化操作
    • 17、avio.c中的ffurl_open_whitelist()创建url上下文后,调用ffurl_connect()进行连接
    • 18、avio.c中的ffurl_connect()根据不同的协议进行打开url操作
    • 19、 得到连接上的URLContext,返回到ffio_open_whitelist() 再调用ffio_fdopen()创建ffio_fdopen(),创建AVIOContext
    • 20、 ffio_fdopen()调用avio_alloc_context()创建AVIOContext,和一些初始化操作
    • 21、 avio_alloc_context()再调用ffio_init_context()初始化
    • 22、ffio_init_context()初始化,io_read_packet(),io_write_packet这些函数就是封装了调用URLProtocol的url_read(),url_write()。
    • 23、经过获取HTTP 协议上下文再创建AVIOContext后,返回到utils.c的init_input() 调用av_probe_input_buffer2()来读取数据
    • 24、 init_input()中调用avio_read()读取数据。 avio_read()中又封装了几层
    • 25、 avio_read()返回后就得到m3u8文件数据再调用av_probe_input_format2()就可以得到是使用ff_hls_demuxer解复用器
    • 26、 从init_input()返回到avformat_open_input()调用解复用器的read_header()
    • 27、 hls_read_header()中第一次调用parse_playlist()解析m3u8中的播放列表
    • 28、 parse_playlist()判断两次不同的调用时处理
    • 29、parse_playlist()接着读取一行判断m3u8标志和保存之前分片
    • 30、 parse_playlist()接着循环一行行读取处理
    • 31、 parse_playlist() 中判断是否嵌套m3u8做不同处理
    • 32、 parse_playlist()最后处理之前的分片
    • 33、返回hls_read_header()判断是否执行第二次parse_playlist()
    • 34、 hls_read_header()中选择开始的分片
    • 35、 hls_read_header()最后开启每个播放列表的解复用器
  • 三、关于使用参数指定输入格式时的分析:
    • 1、ffplay.c中
    • opt_format()处理指定格式参数
    • 2、format.c 中av_find_input_format()根据指定格式查找解复用器
    • 3、allformat.c中av_demuxe_iterate遍历所有解复用器

一、流程图:

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

二、代码分析:

1、ffplay.c调用avformat_open_input()进行打开文件

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

2、进入utils.c的avformat_open_input()前面这些是一些初始化操作 分配AVFormatContext、保存参数到AVDictionary、设置参数

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

3、utils.c的avformat_open_input()中调用init_input()进行打开文件和探测协议格式

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

4、utils.c的init_input()中调用av_probe_input_format2()会根据后缀名探测格式

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

5、format.c中av_probe_input_format2()调用av_probe_input_format3()

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

6、format.c中av_probe_input_format3()

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网
ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

7、遍历时查找到hls时调用hls_probe()返回0。这次探测格式就失败了

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网
ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

8、utils.c中init_input()中调用io_open()默认打开操作

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

9、io_open是在option.c中的avformat_get_context_defaults()绑定io_open_default()

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

10、option.c中的io_open_default()中调用ffio_open_whitelist()

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

11、aviobuf.c中ffio_open_whitelist()中调用ffurl_open_whitelist()

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

12、avio.c中ffurl_open_whitelist()调用ffurl_alloc()创建url上下文

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

13、avio.c中ffurl_alloc()调用url_find_protocol()查找协议

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

14、avio.c中url_find_protocol根据url(文件名)查找协议

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网
得到的是ff_http_protocol
ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

15、avio.c中ffurl_alloc()调用url_alloc_for_protocol()根据协议创建上下文

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

16、avio.c中url_alloc_for_protocol()创建协议上下文,进行一系列初始化操作

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

17、avio.c中的ffurl_open_whitelist()创建url上下文后,调用ffurl_connect()进行连接

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

18、avio.c中的ffurl_connect()根据不同的协议进行打开url操作

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

19、 得到连接上的URLContext,返回到ffio_open_whitelist() 再调用ffio_fdopen()创建ffio_fdopen(),创建AVIOContext

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

20、 ffio_fdopen()调用avio_alloc_context()创建AVIOContext,和一些初始化操作

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

21、 avio_alloc_context()再调用ffio_init_context()初始化

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

22、ffio_init_context()初始化,io_read_packet(),io_write_packet这些函数就是封装了调用URLProtocol的url_read(),url_write()。

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

23、经过获取HTTP 协议上下文再创建AVIOContext后,返回到utils.c的init_input() 调用av_probe_input_buffer2()来读取数据

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

24、 init_input()中调用avio_read()读取数据。 avio_read()中又封装了几层

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

25、 avio_read()返回后就得到m3u8文件数据再调用av_probe_input_format2()就可以得到是使用ff_hls_demuxer解复用器

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

26、 从init_input()返回到avformat_open_input()调用解复用器的read_header()

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

27、 hls_read_header()中第一次调用parse_playlist()解析m3u8中的播放列表

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

28、 parse_playlist()判断两次不同的调用时处理

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

29、parse_playlist()接着读取一行判断m3u8标志和保存之前分片

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

30、 parse_playlist()接着循环一行行读取处理

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网
ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网
ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

31、 parse_playlist() 中判断是否嵌套m3u8做不同处理

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网
ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

32、 parse_playlist()最后处理之前的分片

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

33、返回hls_read_header()判断是否执行第二次parse_playlist()

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

34、 hls_read_header()中选择开始的分片

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

35、 hls_read_header()最后开启每个播放列表的解复用器

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网
ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网
ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

三、关于使用参数指定输入格式时的分析:

1、ffplay.c中

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

opt_format()处理指定格式参数

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

2、format.c 中av_find_input_format()根据指定格式查找解复用器

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网

3、allformat.c中av_demuxe_iterate遍历所有解复用器

ffmpeg 使用ffplay 进行 hls 拉流 分析 1-编程知识网