文章目录
一. 首先回顾业界的常用的三种方案的优缺点以及实现
这里我们从解码到渲染是这么去做的。视频的帧和音频的帧都会丢到相应的队列中。音频帧是固定时间回调去读取渲染,然后视频队列是单独的视频线程去轮询获取视频帧,去对齐音频帧去渲染。
二. 方案三的实现
最近在想着优化方案三,走入了一些误区。包括很多同学都认为有更好的办法去代替duration方案,其实不然。借此机会和大家分享一下。
基础补充
44100(采样率) / 1024 = 43
AAC 一个包有 1024 个采样
音频是固定的每秒43fps回调。
1. CADisplaylink取代视频线程回调,从视频队列中获取大于且最接近音频pts的一帧,小于这个pts的全部丢弃
av_sync = (last_audio_pts && displaying && avsync_); // 是否音画同步
//从视频队列中获取大于且最接近音频pts的一帧,小于这个pts的全部丢弃
if (av_sync) {
for (unsigned i=0; i<video_frame_queue_.size(); i++){
SP<qgplayer::MediaFrame> videoframe = video_frame_queue_.front();
if(videoframe->pts < last_audio_pts){
video_frame_queue_.pop_front();
-- frame_size;
LOG_WARN("不处理的视频pts:%lld | last_audio_pts:%lld", videoframe->pts, last_audio_pts);
continue;
}
if(last_video_pts_ == videoframe->pts){
return NULL;
}
frame = (SP<qgplayer::MediaFrame>)videoframe;
}
}else{
if(!video_frame_queue_.empty()) {
frame = video_frame_queue_.front();
video_frame_queue_.pop_front();
}
}