FFMPEG 播放时间计算 AVRational 音视频同步问题分析

先问大家一个问题,音频有采样率比如44100,48000等,那视频有采样率吗,是多少?

在解码播放视频的时候是一个packet一个packet的播放的。音频的播放是连续播放的,一个packet播放完毕紧接着就是下一个,断片就会有噪音,并且速率是确定的,要不然就会变调。但是视频的packet呢,就是一张图片,瞬间播完,可快可慢,快点慢点都是感觉不出来的。并且音视频packet传送并不是一个音频packet一个视频packet这样一第一个的传送的,可能是八个音频packet,然后八个视频packet,这样收到packet就播放就有问题了,音频能正常播放,视频就会瞬间播放八个画面等会再瞬间播放八个画面,这样很不流畅,需要控制视频的packet播放的速度。要保证在同时间录制的音频packet跟视频packet同时播放。

要控制在相同时间录制的视频的packet跟音频的packet同时播放就需要给每个packet打上播放速度的标签,这个标签怎么做呢?
是这样的,把一秒钟分成很多相等的时间段,就是时间刻度,比如视频就引入一个东西叫tick,比如tick设置90000,就是要把一秒钟分成90000份,一个视频帧在录制的瞬间是在一秒钟内的第几个刻度瞬间,就把这个刻度瞬间值处理一下赋值个packet作为时间同步标签,就是packet的pts。音频呢,音频有现成的时间刻度,就是采样率,44100,48000等等,就用这个作为音频tick。

那么有时间标签了怎么计算播放时间呢?
在ffmpeg中,主角出场:
要用到AVRational来计算:
FFMPEG的很多结构中有AVRational time_base;这样的一个成员,它是AVRational结构的

typedef struct AVRational{  
    int num; ///< numerator  
    int den; ///< denominator  
} AVRational;  

AVRational这个结构标识一个分数,num为分数,den为分母。
其中num为1,den就是时间刻度,就是所谓的tick(这里可以看出,tick值越大同步就越精确,tick值也可以为帧率那pts就是帧的总数这样时间同步会不太精确),den就是表示要把一秒钟分成多少个相等的时间刻度(一般音频视频是不同的)。

那pts是什么呢?
就是从开始录制瞬间到这个packet录制的所经历的tick的总和。
到这里大家应该明白怎么计算播放时长了吧,有刻度,有刻度总数:
time = packet->pts * (num/den);
packet播放的瞬间的时间值了。
保证视频的time与音频的time最接近的两个packet同时播放音视频就同步了。
当然这个时间如果不是直播还可以作为视频播放时间来使用。

如我做的播放器里面的时间计算,这就能看明白了吧:

double r2d(AVRational r){
    return r.num == 0 || r.den == 0 ? 0.:(double)r.num/(double)r.den;
}
//最后*1000是转换成毫秒输出,不乘单位就是秒
decoder->aFps = (int)((packet.pts * r2d(decoder->pFormatCtx->streams[decoder->audioStreamIndex]->time_base))*1000);

当然r2d这种计算ffmpeg库带的也有默认计算方法如:

static inline double av_q2d(AVRational a){
/**
* Convert rational to double.
* @param a rational to convert
**/
    return a.num / (double) a.den;
}

就是这种没有den非0判断。

最后回答一下开始的问题,视频的采样率是什么?就是帧率,是不是?

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值