FFplay外部时钟分析—ffplay.c源码分析

作者:罗上文,微信:Loken1,公众号:FFmpeg弦外之音

FFplay 播放器有 3 个时间:

1,视频流的播放时刻,(视频时钟)

2,音频流的播放时刻,(音频时钟)

3,预定的时间,预定的播放时刻,实际上就是物理世界的自然时间,(外部时钟)

1-1

上图中的 14:00:00:123 就是其中一个预定的时间,完全准确的情况下,会在 14:00:00:123 播放第 4 帧视频 ,播放第 7 帧音频。

但是,计算机系统是分时系统,大部分情况不会那么准确,有可能发生以下的情况。

14:00:00:133 的时候才播放第 4 帧视频。

14:00:00:143 的时候才播放第 7 帧音频。

因此:

14:00:00:133 的时候,视频时钟比外部时钟慢 0.01s。

14:00:00:143 ` 的时候,音频时钟比外部时钟慢 0.02s。


可以通过以下命令设置 外部时钟为主时钟:

ffplay -sync ext -i juren-30s.mp4

当外部时钟设置为主时钟的时候,在《FFplay视频同步分析》提到的3处视频同步代码,全部都会生效。在 《FFplay音频同步分析》提到的音频同步代码也会生效。

外部时钟只会赋值一次,会取音频时钟,或者视频时钟来赋值,主要看播放的第一帧是音频还是视频。

这是合理的,因为从上面第一张图可以看出来,第一帧的时候,音频时钟或者视频时钟 是跟外部时钟一样的。外部时钟的起始值就是第一帧的时间。

从第一帧开始,外部时钟才开始跑起来。

为什么外部时钟只会赋值一次?

因为只需要把第一帧的 pts + 物理世界里消逝的时间,就能知道当前的外部时钟播放到哪里了。


外部时钟 的赋值在 sdl_audio_callback()video_refresh() 里,这两个都是播放线程,就看谁先播放第一帧,谁就去赋值外部时钟。

1-2

可以看到,赋值 外部时钟的函数是 sync_clock_to_slave() 函数,我们来看一下这个函数的实现,如下:

1-3

可以看到,只有外部时钟不为空,才会跑进去 set_clock()当然如果超过 AV_NOSYNC_THRESHOLD 也会跑进去,不过一般这个条件不会成立。


总结,外部时钟,实际上就是记录现在已经到达了哪个预定的播放时刻。

当视频流离自己预定的播放时刻距离太远的时候,超过了同步阈值,就会调整视频的速度。

当音频流离自己预定的播放时刻距离太远的时候,超过了同步阈值,就会调整音频的速度。

1-1



感谢 NETINT(镕铭微电子) 赞助《FFmpeg原理》免费版一书的服务器费用,下面是 VPU 产品介绍

版权所属 xianwanzhiyin.net 罗上文 2024 all right reserved,powered by Gitbook该文件修订时间: 2023-05-17 11:39:55

results matching ""

    No results matching ""