天天看点

【FFmpeg编程进阶】(五)ffplay.c 源码学习(2/3) 之 SDL线程函数 read_thread()代码流程 - 待更新

2.3 SDL线程函数 read_thread()

2.3.1 打开媒体文件 avformat_open_input()

2.3.2 获取媒体信息 avformat_find_stream_info()

2.3.3 输出媒体信息 av_dump_format()

2.3.4 查找音/视频/字幕stream_index信息 av_find_best_stream()

2.3.5 启动音视频解码线程 stream_component_open()

2.3.6 将音/视频/字幕packet放对队列 packet_queue_put()

2.3.7 获取一帧压缩编码packet 数据 av_read_frame()

由文章篇幅过长,分三篇文章来学习ffplay.c 的源码,

如下:

《【FFmpeg编程进阶】(五)ffplay.c 源码学习(1/3) 之 main 函数代码流程》

《【FFmpeg编程进阶】(五)ffplay.c 源码学习(2/3) 之 SDL线程函数 read_thread()代码流程》

《【FFmpeg编程进阶】(五)ffplay.c 源码学习(3/3) 之 event_loop()代码流程》

本文链接:《【FFmpeg编程进阶】(五)ffplay.c 源码学习(2/3) 之 SDL线程函数 read_thread()代码流程》

在该函数中,主要工作就是获取 音频/视频/字幕的Packet包,然后放入对应的 Packet Queue 中

主要流程如下:

分配 <code>AVFormatContext</code> 结构体内存

打开媒体文件,上下文信息保存在 ic 中

获得媒体文件信息

修改SDL <code>window_title</code> 为 <code>file_name</code>

输出媒体信息到控制台上

获取视频、音频、字幕对应的<code>stream_index</code>

基于流与视频帧的宽高比,猜测视频帧的屏幕宽高比, 重新设定SDL窗口的<code>size</code>

分别打开视频/音频/字幕解码线程

如果检测到网络流 暂停,调用 <code>av_read_pause()</code> 暂停,否则调用<code>av_read_play()</code>继续播放

如果是发现传输流 RTSP 或者是流媒体,则延时10ms再取下一个包

如果要跳转播放,则先跳转到位置,然后 清空播放<code>packet_queue</code>,再放新的packet 到队列中

如果已经播放完毕,即队列中没有未播放的<code>stream</code>,则重新播放 或 自动退出

获取一帧压缩编码数据(即一个<code>AVPacket</code>)

如果读取失败,或到文件末尾,放入“空包”。放入空包意味着流的结束,一般在视频读取完成的时候放入空包。

将读取到的压缩编码数据包放入 <code>packet_queue</code> 中

本函数源代码分析见:《【FFmpeg编程进阶】(六)avformat_open_input() 函数源代码分析》

本函数源代码分析见:《【FFmpeg编程进阶】(八)avformat_find_stream_info() 函数代码分析 - 获取媒体信息》

在通过<code>avformat_find_stream_info()</code>获得媒体信息后,可以通过<code>av_dump_format()</code> 将媒体信息打印出来。

示例如下: