大家好,由于最近工作上碰到一些关于音视频不同步的问题,比如音频跟不上视频的播放速度;基于此,今天给大家分享一篇关于音视频同步的问题,本系列文章会分为几篇来分享,先从基础的音视频同步理论开始,然后再进行基于ffplay里面的源码实战来加深音视频同步的理解!
首先我们先来了解一下什么是音视频同步,相信之前看过前面几期关于ffplay源码解析的文章的朋友应该知道,在一个播放器进行解码拿到数据这个环节里面,音频和视频各自有自己的线程进行处理各自对应的数据!
那么在这个环节就可能会出现问题,比如说,音频线程和视频线程可能不会同时解出音视频和视频帧,那么这就会造成后面的播放出现不同问题!也就会出现音视频不同的问题,直白的说,音视频同步就好比我们平时用一个播放器去播放一个视频文件(包括音频和视频!),会出现视频画面和视频画面人物说话的声音对应不上,这就会造成非常差的体验感。
所以为了今后更好的解决实际开发问题,我们在此之前需要掌握一些基础理论知识,下面我们来看一下什么是PTS和DTS、timebase,先来说一下理论概念,后期再通过实战来理解它,当前你只要知道有这三个东西就行:
double audio_pts = 0.020;
同时在ffplay里面,timebase的类型是结构体AVRational(其中一个结构体成员是表示分子,另外一个是表示分母!),具体代码如下:
typedef struct AVRational{
int num;
int den;
}AVRational;
那么通过这个如何来计算出PTS的显示时间呢?
比如说timebase={1,100},表示100毫秒,如果pts=1000,那么1000*1/100=10秒,意思就是这帧数据需要在第10秒的时候被显示出来!
因此在ffmpeg里面有一个关于把AVRational转变成double类型的接口实现,我们利用这个接口来计算pts的显示时间就非常方便了:
/**
* Convert an AVRational to a `double`.
* @param a AVRational to convert
* @return `a` in floating-point form
* @see av_d2q()
*/
static inline double av_q2d(AVRational a){
return a.num / (double) a.den;
}
所以显示时间戳的时间计算就等于:
pts * av_q2d(参数);
一般有三种解决方法:
今天的内容就简单分享到这里,更多的是咋们在实际开发过程中,如果遇到类似问题,该如何快速把这种问题解决掉才是关键,这也是需要咋们平时基础的积累!
下期,我们继续!