本系列 以 ffmpeg4.2 源码为准,下载地址:链接:百度网盘 提取码:g3k8
FFplay 源码分析系列以一条简单的命令开始,ffplay -i a.mp4。a.mp4下载链接:百度网盘,提取码:nl0s 。
FFplay 最后一篇文章了,本文章主要讲解,文件播放结束之后的情况,各线程处于一种什么样的状态。
read_thread 数据读取线程:
数据读取线程 里面 av_read_frame() 返回 ret 等于 -1,设置 is->eof 为 1,休眠10ms,然后继续尝试av_read_frame()读文件。代码如下:
audio_thread 音频解码线程:
因为文件播放完毕了,PacketQueue队列空了,audio_thread 会阻塞在 packet_queue_get() 里面,等待 PacketQueue 有数据可读。函数调用流程如下:
audio_thread() -> decoder_decode_frame() -> packet_queue_get()
video_thread 音频解码线程:
因为文件播放完毕了,PacketQueue队列空了,video_thread 也会阻塞在 packet_queue_get() 里面,等待 PacketQueue 有数据可读。函数调用流程如下:
video_thread() -> get_video_frame() -> decoder_decode_frame() -> packet_queue_get()
sdl_audio_callback 音频播放线程:
因为文件播放完毕了,frameQueue队列空了,sdl_audio_callback 会阻塞在 frame_queue_peek_readable() 函数里面。函数调用流程如下:
sdl_audio_callback() -> audio_decode_frame() -> frame_queue_peek_readable()
event_loop 视频播放线程:
因为 event_loop是主线程,他不能阻塞,它还要处理seek事件,所以 video_reflesh() 里面先用 frame_queue_nb_remaining() 判断队列是否是空,如果是空直接返回,过 0.01s 再执行一次 video_reflesh()。如图:
总结:
ffplay 在播放完文件之后,默认不会立即退出,大多数线程都在阻塞等待,如果此刻你拖动进度条,就会产生一个seek操作,让这些休眠的线程重新跑起来,继续播放。
ffplay 源码分析,文件播放结束分析完毕。
©版权所属:知识星球:弦外之音,QQ:2338195090。
由于笔者的水平有限, 加之编写的同时还要参与开发工作,文中难免会出现一些错误或者不准确的地方,恳请读者批评指正。如果读者有任何宝贵意见,可以加我微信 Loken1。
推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习