Hi3516DV300实现音视频同步播放

1. 音视频同步

1.1 音视频帧PTS计算

有些人会疑惑,为什么用ffmpeg读出来的音视频帧的pts会是无效时间戳,时间戳都无效了,我还怎么同步?其实很简单,音视频的时间戳都是相对第0帧而言的,如果知道当前帧是第几帧,不就知道帧的时间戳了吗。因此时间戳可以如下计算:

音频帧PTS: 帧长 / 采样率 * 帧编号, 帧编号从0开始,即0,1,2......

视频帧PTS: 1 / 帧率 * 帧编号,帧编号从0开始,即0,1,2......

上述公式很好理解,即每帧持续时间 * 帧编号就得到当前帧的时间戳了。注意,上述的帧编号是显示帧编号,不是解码帧编号,当无B帧时,上述公式可以直接套用

 

1.2 音视频同步机制

同步方法使用音频作为主时钟源,视频根据音频时钟进行同步。在该方式下,音频帧的持续时间永远不需要控制,只需要控制视频帧的持续时间即可。

 

整个音视频同步的结构共有4个时钟:

1. 视频时钟,即播放第一帧视频开始经过的时间

2. 音频时钟,即播放第一帧音频开始经过的时间

3. 系统时钟,即当前系统时间(CLOCK_MONOTONIC, 系统的滴答值)

4. 视频帧定时时钟,标记当前显示的视频帧开始显示的时间(绝对值,数值上基于系统时间)

 

同步时,四个时钟有两组比较:

1. 视频时钟和音频时钟比较,计算出音视频时钟的差值(视频时钟 - 音频时钟, 若>0, 则视频播放快了, 若<0,则视频播放慢了)。若视频播放快了,则增加当前视频帧显示的时间;若视频播放慢了,则跳过当前视频帧,直接显示下一视频帧

2. 系统时钟和视频帧定时时钟比较,计算出差值(系统时钟 - 视频帧定时时钟)。将差值和音视频时钟的差值进行比较,判断是否该显示下一帧(差值 - 音视频时钟的差值, 若>0, 则当前视频帧还没显示完,继续显示,反之显示下一帧)。

 

上述同步机制参考ffplay.c,这是一种通用的音视频同步方法。简而言之,就是根据音视频时钟的差值来动态调整视频帧的显示时长,以达到同步的效果。

 

2. Hi3516DV300同步机制实现

2.1 数据流通路

视频:VDEC绑定VPSS, VPSS绑定VO。VDEC是硬解码,解码耗时可以忽略不计,同时VPSS绑定VO,VPSS可以自适应VO窗口大小,方便使用。

音频:ADEC绑定AO。音频解码是CPU软解码,由于音频是主同步源,因此解码耗时不影响同步,只需保证音频流播放的连续即可。

 

2.2 关键时钟

从上述时钟可以看出最重要的时钟是音频时钟。其作为主同步源时钟,务必要保证其时钟值的正确性,否则视频帧的矫正时间是不正确的。

音频时钟的获取和更新通过API HI_MPI_AO_QueryChnStat进行。通过查询AO缓存的音频帧数来更新音频时钟。但需要注意的是,通过 HI_MPI_AO_QueryChnStat 不能准确地更新音频时钟,经过测试,HI_MPI_AO_QueryChnStat 无法每atb(audio time base, 帧长 / 采样率),缓存帧数就减少1。因此,还需要额外的控制机制,才能准确地更新音频时钟。

 

3. 总结

在海思平台建立上述数据通路以及关键时钟,再套用上述通用的同步机制,即可基于海思平台实现音视频同步。

 

 

 

 

 

 

  

 

 

 

 

你可能感兴趣的:(Hi3516DV300实现音视频同步播放)