FFplay源码分析-EOF

本系列 以 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()读文件。代码如下:

FFplay源码分析-EOF_第1张图片

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源码分析-EOF_第2张图片

总结:

ffplay 在播放完文件之后,默认不会立即退出,大多数线程都在阻塞等待,如果此刻你拖动进度条,就会产生一个seek操作,让这些休眠的线程重新跑起来,继续播放。


ffplay 源码分析,文件播放结束分析完毕。

©版权所属:知识星球:弦外之音,QQ:2338195090。

由于笔者的水平有限, 加之编写的同时还要参与开发工作,文中难免会出现一些错误或者不准确的地方,恳请读者批评指正。如果读者有任何宝贵意见,可以加我微信 Loken1。

推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习

你可能感兴趣的:(FFplay源码分析,音视频)