Nuplayer中音视频同步主要依靠MediaClock中记录的锚点时间,所以先看下MediaClock类
1, 1
MediaClock:: MediaClock () :mAnchorTimeMediaUs (1), mAnchorTimeRealUs (1), mMaxTimeMediaUs (INT64_MAX), mStartingTimeMediaUs (1), mPlaybackRate (1.0) { }
1.2锚点时间更新
空白MediaClock:: updateAnchor ( int64_t anchorTimeMediaUs, int64_t anchorTimeRealUs, int64_t maxTimeMediaUs) { 互斥:自动锁键盘锁(mLock); int64_t nowUs=ALooper: GetNowUs (); int64_t nowMediaUs=anchorTimeMediaUs + (nowUs - anchorTimeRealUs) *(双)mPlaybackRate;//mPlaybackRate是播放倍速//下面这段是超过阈值的保护 如果(mAnchorTimeRealUs !=1) { int64_t oldNowMediaUs=mAnchorTimeMediaUs + (nowUs - mAnchorTimeRealUs) *(双)mPlaybackRate; 如果(nowMediaUs & lt;oldNowMediaUs ,,nowMediaUs祝辞oldNowMediaUs - kAnchorFluctuationAllowedUs) { 返回; } }//mAnchorTimeRealUs当前系统时间,锚点真正的系统时间戳,可以理解为最后一帧播放的时间,对应到系统时钟后的时间。//mAnchorTimeMediaUs为锚点媒体时间戳,可以理解为从最开始播放时记录下来的第一个媒体时间戳,一直到当前正在播放这一帧的总时长,但是它主要将音频分与系统时钟做了统一,即将音频同步到系统时钟上。 在这函数里面只是考虑到函数调用的耗时,将这个耗时加到mAnchorTimeMediaUs而已,本质还是直接记录传入的2个入参时间 mAnchorTimeRealUs=nowUs; mAnchorTimeMediaUs=nowMediaUs; }
1.3从别人链接处摘录的解释
realTimeUs=PTS - nowMediaUs + nowUs
getRealTimeFor
=PTS - (mAnchorTimeMediaUs + (nowUs - mAnchorTimeRealUs)) + nowUs
mAnchorTimeMediaUs + (nowUs - mAnchorTimeRealUs)是在
getMediaTime_l中计算
mAnchorTimeMediaUs锚点媒体时间戳,可以理解为最开始播放的时候记录下来的第一个媒体时间戳
mAnchorTimeRealUs锚点真正的系统时间戳,
nowUs - mAnchorTimeRealUs即为从开始播放到现在,系统时间经过了多久。
这个时间再加上mAnchorTimeMediaUs,即为“在当前系统时间下,对应的媒体时间戳”,
用分减去这个时间,表示”还有多久该播放这一帧”。
最后再加上一个系统时间,即为这一帧应该显示的时间。
- - - - - - - - - - - - - - - - - - - - - - - -
zhanghui_cuc CSDN
原文:https://blog.csdn.net/nonmarking/article/details/78746671
版权声明:本文为博主原创文章,转载请附上博文链接!
实际就是根据编解码器解出来的分,然后比较音频的锚点值,计算出来当前这视频帧应当延迟多久,锚点时间是在每个音频帧时都计算的,按我自己理解是
(nowUs - mAnchorTimeRealUs)是距离上个音频帧播放有多久
mAnchorTimeMediaUs + (nowUs - mAnchorTimeRealUs)是对应音频帧应该播放的视频帧时间戳
PTS - (mAnchorTimeMediaUs + (nowUs - mAnchorTimeRealUs)) + nowUs这个是分——真正要播放的视频帧时间戳计算出该视频帧要延迟多久再加上当前时间得到绝对时间
mMediaClock→getRealTimeFor (mediaTimeUs,和realTimeUs)==好吧 delayUs=realTimeUs - nowUs; 味精→setWhat (kWhatPostDrainVideoQueue); 味精→post (postDelayUs);
//targetMediaUs PTS outRealUs出参,实际要播放时刻 status_t MediaClock:: getRealTimeFor ( int64_t targetMediaUs int64_t * outRealUs) const { int64_t nowUs=ALooper: GetNowUs (); int64_t nowMediaUs; status_t状态=getMediaTime_l (nowUs, nowMediaUs,真正的/* allowPastMaxTime */); 如果(状态!=好){ 返回状态; } * outRealUs=(targetMediaUs - nowMediaUs)/(双)mPlaybackRate + nowUs; 还好; } status_t MediaClock:: getMediaTime_l ( bool allowPastMaxTime int64_t realUs, int64_t * outMediaUs) const { int64_t mediaUs=mAnchorTimeMediaUs + (realUs - mAnchorTimeRealUs) *(双)mPlaybackRate; 如果(mediaUs比;mMaxTimeMediaUs,,! allowPastMaxTime) { mediaUs=mMaxTimeMediaUs; } 如果(mediaUs & lt;mStartingTimeMediaUs) { mediaUs=mStartingTimeMediaUs; } 如果(mediaUs & lt;0) { mediaUs=0; } * outMediaUs=mediaUs; 还好; }