OpenCores学习(5) -- A/V同步机制

PVPlayer 在渲染 (render) 所有多媒体数据是都需要保持一个暂时的同步,也就是通常所说的 A/V 同步。为了达到同步,需要如下一些信息:媒体回放的时钟,媒体数据的时间戳,从 Sink 中获取的时间信息(比如从音频设备设定的特定的采样率来获取的播放速率)。图 1 描述了与同步相关的 PVPlayer 模块之间的关系。

OpenCore <wbr><wbr>中文文档 <wbr><wbr>- <wbr><wbr>A/V同步机制

图 1 与同步相关的模块及关系

一、媒体时钟

 

PVMFMediaClock ,媒体时钟主要负责维持一个时间的引用,从而保持媒体回放的节奏,获取和实现媒体播放的同步。

 

 

 

1 、媒体时钟的特点

 

1.1时间源

 

媒体时钟可以作为一个时间源提供给多媒体,它本身可能来自于系统时钟或其他时间源(比如音频设备时钟)。它可以给多媒体提供一个时间基准,同时来维护该时间基准。

 

 

 

1.2时钟观察者

 

媒体时钟可以把自己作为一个观察者,来通知对象时钟状态的改变。以下接口实现了其作为观察者的角色:

 

PVMFMediaClockObserver :用来通知时钟基值,时钟计数的更新,时钟的调整;

 

PVMFMediaClockStateObserver :用来通知时钟状态的改变;

 

PVMFMediaClockNotificationsObs :用来获取回调通知。

 

 

 

1.3NPT 映射

 

媒体时钟是一个单调递增的时钟,而媒体在播放时却可能需要 Seek 到任意位置,为了控制媒体的播放,使其正确 Render ,媒体时钟需要在媒体时钟时间和 NPT 之间维护一个 NPT ( normal play time )映射,任意对媒体播放位置的改变将会通知进行一次映射。图 2 描述了媒体时钟和 NPT 之间的映射。

 

图中的箭头和带颜色的区段描述了 Seek 的次序以及每次播放的时间段, Media clock 和 NPT 之间相同的颜色区间即对应了相应的映射。由此可以看出其映射公式为(以第二段为例): NPT = ( media_time - 5550 + 380) 。

 

1.4 时钟的回调

 

在媒体时钟上设置回调是组件采取动作的基础,这些回调可以减少在时钟发生 改变时,组件自己需要设置他们的时钟。媒体时钟采用输入特定时间窗口来取 代绝对时间,这样可以使得处于竞争状态的任务或线程可以尽可能早的得到响 应。

 

 

 

 

1.5 延迟处理

 

当集成了多个不同媒体流的 Sinks 来输出一个多媒体时,每个 Sink 都可能会有 不同程度的延迟,为了弥补不同媒体流之间的延迟从而同步播放,就需要进行 延迟处理。每个 Sink 都向媒体时钟注册自己的延迟,最后由媒体时钟来调整最 终的调度的延迟。

 

 

 

 

1.6 NPT 时钟转换

 

当一个新的 NPT 开始时,用户可以给媒体时间设置一个绝对时间。用户还可以 任意调整 NPT 的方向(比如向前,向后)。

 

 

 

二、时间戳

 

为了及时准确地输出媒体数据,就不得不考虑媒体数据中包含的时间戳信息以及媒体回放时钟。如果时间戳值等于当前回放时间,则媒体数据是同步的,需要进行 Render ;如果时间戳小于当前回放时间,则说明媒体数据到达时间晚了;反之,如果时间戳大于当前回放时间,则说明媒体数据到达时间早了。如何处理这些来早的或来晚的媒体数据则取决于 PVPlayer 引擎的配置,通常情况下,来早的数据需要等待,直到播放时间到达;来晚的数据则会被丢弃而不被 Render 。但有时候来晚的数据也会被 Render 。

 

 

 

三、同步音频

 

音频数据的 Render 通常不需要外部时钟来进行同步,因为音频设备通常会被配置一定的采样率来消化音频数据。因此,音频设备被配置的这个采样率通常也作为媒体回放时钟的速率。

 

 

 

1 、 Render 开始时的同步

 

一旦媒体时钟开始后,就必须要求媒体数据尽可能快地被 Render ,然而硬件在 Render 时很可能需要额外的时间,或者硬件需要等到更多的媒体数据被缓存。因此会导致媒体时钟的开始时间与媒体数据真正被输出的时间不一致,从而导致 PVPlayer 报告给应用程序的播放进度与真实播放进度产生误差。为了解决这一问题,采用了在硬件没有开始输出媒体数据时,媒体时钟就处于暂停状态,当硬件开始输出媒体数据时给媒体时钟发一个消息来通知媒体时钟也开始运行。这样就可以保证在媒体时钟开始的时候,媒体数据也开始进行输出。

 

OpenCore <wbr><wbr>中文文档 <wbr><wbr>- <wbr><wbr>A/V同步机制



图 3 开始输出的同步示例

图 3 描述了在有一定初始延迟时开始输出的同步例子。

 

作为一个主动态的 MIO 组件,无论时钟状态为暂停还是运行, PVPlayer 都向 MIO 组件传送数据,而 MIO 组件也应该继续接受和缓存数据,并决定何时把数据发送到硬件。

 

而作为一个被动态的 MIO 组件,只有当时钟状态为运行时, PVPlayer 才向 MIO 组件发送数据,而接收到数据的 MIO 组件也需要将收到的数据立即发送给硬件。

2 、重新定位后的同步

 

当应用程序请求重新定位媒体播放位置时, MIO 组件和硬件缓存的数据需要被立即释放,并且在新的位置开始播放。

 

图 4 描述了重新定位后如何实现媒体的同步的示例。

OpenCore <wbr><wbr>中文文档 <wbr><wbr>- <wbr><wbr>A/V同步机制

3 、播放中的同步

尽管硬件消费数据的速率应该与媒体时钟的速率是一致的,但毕竟他们是单独运行的,因此不可避免的会有一些不同。通常情况下,这中差距是很小的,然而随着播放的进行,差距将会被积累,最终导致不同步。



因此,为了控制在短时间内播放时钟与音频输出进程差距在很小的范围内,需要不时地调整两者之间的差,使之小于一个特定的阈值。

 

 

 

四、同步视频

 

与音频输出相比,视频的输出需要参考一个时钟来决定何时输出一个特定的视频帧,视频帧的输出要尽可能的与该帧的时间戳相一致。 PVPlayer 维护了一个与音频播放同步的播放时钟,因此,一旦视频输出与播放时钟同步,那么也就意味着视频输出与音频输出同步。

 

 

 

五、音视频同步

 

音视频同步是音频同步和视频同步的终极目标。在 PVPlayer 架构中,媒体时钟需要调整以便与音频输出过程相一致,而对于视频输出来说,在输出一个视频帧时要使得该帧的时间戳与媒体时钟同步。因此音频输出设备、视频帧的时间戳与媒体时钟的结合便造就了 A/V 同步。

 

图 6 描述了参与音视频同步模块之间的交互过程。

 

OpenCore <wbr><wbr>中文文档 <wbr><wbr>- <wbr><wbr>A/V同步机制

图 6 A/V 同步交互过程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值