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> 将媒体信息打印出来。
示例如下: