FFplay源码分析-pause

2024-06-24 01:58
文章标签 分析 源码 pause ffplay

本文主要是介绍FFplay源码分析-pause,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《FFmpeg原理》的社群来了,想加入社群的朋友请购买 VIP 版,VIP 版有更高级的内容与答疑服务。


本系列 以 ffmpeg4.2 源码为准,下载地址:链接:百度网盘 提取码:g3k8

FFplay 源码分析系列以一条简单的命令开始,ffplay -i a.mp4。a.mp4下载链接:百度网盘,提取码:nl0s 。


ffplay 的大部分主要逻辑已经讲完了,本文主要讲解 ffpaly 暂停跟开始播放是如何实现的,还有在暂停状态下,各个线程在干什么。

首先分析 read_thread() 线程。

知道,read_thread() 线程 主要做的事情是读文件,读出packet,然后插入 PacketQueue 队列,直到插满。

那 如果 视频播放暂停了,is->paused 置为 1了,对read_thread() 会有哪些影响呢?

因为我们的命令是播放本地mp4 ,这种情况下 is->paused 置为 1,对read_thread() 的流程没有影响,read_thread 线程还是插满 队列,然后sleep 10ms,再尝试插队列。

再看看 audio_thread() 解码线程 有没影响,

is->paused 置为 1 对 audio_thread() 解码线程 也是没有影响的,audio_thread 插满 FrameQueue之后,就会阻塞在 frame_queue_peek_writable() 里面等待可写。

video_thread 视频解码线程也是一样,插满 FrameQueue之后,就会阻塞在 frame_queue_peek_writable() 里面等待可写。

再看看音频播放线程 sdl_audio_callback 有没影响。

sdl_audio_callback 在暂停状态下的处理要仔细研究。先看代码。

在 audio_decode_frame() 里的逻辑是 如果暂停了,立即返回 -1,audio_decode_frame 返回 -1 就会导致 sdl_audio_callback() 开始插入静音输入到 stream 指针。虽然他播放的静音数据,但是 音频时钟还在不断更新。set_clock_at() 函数的第二个参数 pts 虽然没变化,但是最后一个参数系统时间一直在递增。也就说即使暂停了,音频时钟也是一直在跑的。剧透一下,但是视频时钟不一样,视频时钟在暂停状态下不跑。

 if (!isnan(is->audio_clock)) {set_clock_at(&is->audclk,is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / is->audio_tgt.bytes_per_sec,is->audio_clock_serial, audio_callback_time / 1000000.0);sync_clock_to_slave(&is->extclk, &is->audclk);
}

再看看视频播放线程 event_loop() 有没影响。

event_loop 线程是这样的,即使在暂停状态下,refresh_loop_wait_event 里面也是每隔0.01s循环一次。

video_reflesh() 在暂停状态下是这样的,直接 goto display了,没有执行后面的 update_video_pts() ,所以我说,在暂停状态下,视频时钟没有跑。如图:

在这里插入图片描述

在暂停状态下,音频时钟一直在跑,视频时钟却停了,如果开始播放,音频时钟跟视频时钟肯定有很大的不同步,来看看ffplay是如何处理这个问题。

在这里插入图片描述

从上图可以看到,在重新启动的时候,ffplay是单独对视频时钟做了处理。把 is->frame_timer 跟 is->vidclk 都重新设置了一下。

这就是为什么 ffplay 重新启动播放的时候,需要对视频时钟单独搞这么一出。


简单总结一下,暂停状态下的情况:

  1. read_thread(),数据读取线程 还是不断读 packet,插满队列,然后sleep 10ms,再尝试插队列。不断等待队列可以插入数据。
  2. audio_thread(), 音频解码线程,不断解码数据,插FrameQueue,插满就停在 frame_queue_peek_writable() 里面等待队列有空位可以插入。
  3. video_thread(), 视频解码线程,不断解码数据,插FrameQueue,插满就停在 frame_queue_peek_writable() 里面等待队列有空位可以插入。
  4. sdl_audio_callback(), 音频播放线程,暂停状态会写入静音数据,但是每次回调都会修改音频时钟的系统时间,导致音频时钟一直在递增。
  5. video_reflesh(),视频播放线程,基本什么都没做,在refresh_loop_wait_event 里面每隔 0.01s 循环一次,如果窗口改变,需要重新渲染SDL,也只是重新渲染,不会执行 update_video_pts() 更新视频时钟。

ffplay 源码分析,pause 暂停播放分析完毕。

©版权所属:弦外之音。

由于笔者的水平有限, 加之编写的同时还要参与开发工作,文中难免会出现一些错误或者不准确的地方,恳请读者批评指正。

这篇关于FFplay源码分析-pause的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1088874

相关文章

Nginx分布式部署流程分析

《Nginx分布式部署流程分析》文章介绍Nginx在分布式部署中的反向代理和负载均衡作用,用于分发请求、减轻服务器压力及解决session共享问题,涵盖配置方法、策略及Java项目应用,并提及分布式事... 目录分布式部署NginxJava中的代理代理分为正向代理和反向代理正向代理反向代理Nginx应用场景

Redis中的有序集合zset从使用到原理分析

《Redis中的有序集合zset从使用到原理分析》Redis有序集合(zset)是字符串与分值的有序映射,通过跳跃表和哈希表结合实现高效有序性管理,适用于排行榜、延迟队列等场景,其时间复杂度低,内存占... 目录开篇:排行榜背后的秘密一、zset的基本使用1.1 常用命令1.2 Java客户端示例二、zse

Redis中的AOF原理及分析

《Redis中的AOF原理及分析》Redis的AOF通过记录所有写操作命令实现持久化,支持always/everysec/no三种同步策略,重写机制优化文件体积,与RDB结合可平衡数据安全与恢复效率... 目录开篇:从日记本到AOF一、AOF的基本执行流程1. 命令执行与记录2. AOF重写机制二、AOF的

MyBatis Plus大数据量查询慢原因分析及解决

《MyBatisPlus大数据量查询慢原因分析及解决》大数据量查询慢常因全表扫描、分页不当、索引缺失、内存占用高及ORM开销,优化措施包括分页查询、流式读取、SQL优化、批处理、多数据源、结果集二次... 目录大数据量查询慢的常见原因优化方案高级方案配置调优监控与诊断总结大数据量查询慢的常见原因MyBAT

分析 Java Stream 的 peek使用实践与副作用处理方案

《分析JavaStream的peek使用实践与副作用处理方案》StreamAPI的peek操作是中间操作,用于观察元素但不终止流,其副作用风险包括线程安全、顺序混乱及性能问题,合理使用场景有限... 目录一、peek 操作的本质:有状态的中间操作二、副作用的定义与风险场景1. 并行流下的线程安全问题2. 顺

MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决

《MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决》MyBatis默认开启一级缓存,同一事务中循环调用查询方法时会重复使用缓存数据,导致获取的序列主键值均为1,... 目录问题原因解决办法如果是存储过程总结问题myBATis有如下代码获取序列作为主键IdMappe

Java中最全最基础的IO流概述和简介案例分析

《Java中最全最基础的IO流概述和简介案例分析》JavaIO流用于程序与外部设备的数据交互,分为字节流(InputStream/OutputStream)和字符流(Reader/Writer),处理... 目录IO流简介IO是什么应用场景IO流的分类流的超类类型字节文件流应用简介核心API文件输出流应用文

java 恺撒加密/解密实现原理(附带源码)

《java恺撒加密/解密实现原理(附带源码)》本文介绍Java实现恺撒加密与解密,通过固定位移量对字母进行循环替换,保留大小写及非字母字符,由于其实现简单、易于理解,恺撒加密常被用作学习加密算法的入... 目录Java 恺撒加密/解密实现1. 项目背景与介绍2. 相关知识2.1 恺撒加密算法原理2.2 Ja

Nginx屏蔽服务器名称与版本信息方式(源码级修改)

《Nginx屏蔽服务器名称与版本信息方式(源码级修改)》本文详解如何通过源码修改Nginx1.25.4,移除Server响应头中的服务类型和版本信息,以增强安全性,需重新配置、编译、安装,升级时需重复... 目录一、背景与目的二、适用版本三、操作步骤修改源码文件四、后续操作提示五、注意事项六、总结一、背景与

Android实现图片浏览功能的示例详解(附带源码)

《Android实现图片浏览功能的示例详解(附带源码)》在许多应用中,都需要展示图片并支持用户进行浏览,本文主要为大家介绍了如何通过Android实现图片浏览功能,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码