时间戳
定义:当前时刻,单位是时间基。
PTS(Presentation TimeStamp)是渲染用的时间戳,播放器会根据这个时间戳进行渲染播放
DTS(Decoding TimeStamp)解码时间戳,在视频packet进行解码成frame的时候会使用到
编码时一个GOP示例: I P P B P P B P P..
由于有B帧双向参考,在编码之后的帧的时间顺序就会发生变化,导致PTS和DTS不一致。没有B帧时,两者相同。
视频时间戳:一般这个值依赖于帧率,1000/fps为帧间间隔,相当于一个个间隔时间加上去了。
pts = inc++ * (1000/fps); //其中inc是一个静态的,初始值为0,每次打完时间戳加1。
音频时间戳:依赖于音频的sample rate来计算,(1000 / sample_rate)是每个采样多长时间,(frame_size * 1000 / sample_rate)计算出来一个frame_size长度的音频帧的时长:
pts = inc++ * (frame_size * 1000 / sample_rate);
时间基
时间基的表示:用秒来表示,比如(1/25)秒,(1/1M)秒
时间基在ffmpeg中不是统一的,在各层中都不相同,分为:封装层时间基、编解码层时间基
封装层时间基为AVStream->time_base;编解码层时间基为AVCodecContext->time_base
定义:基本时间单位,同常用的时、分、秒、毫秒、微秒本质一样的基本时间单位
时间基的不统一,带来了时间戳之间的转换,为了提高计算精度,ffmpeg中的时间基都是以分数形式表示的有理数类型,即AVRational类型
除了上述封装层和编解码层的时间基,ffmepg还定义了一个内部时间基,AV_TIME_BASE_Q,这是一个极小的值,1微秒
有了时间戳之后,还需要将PTS的时间戳转成以秒为单位的时间。这里就需要用到ffmpeg的时间基来进行计算了。
tbr: 是通常说的帧率
tbn: 视频流的时间基
tbc: 时间解码的时间基
在ffmpeg中,不同的时间戳对应不同的时间基。一般在视频进行渲染的时候渲染的时候用到的就是视频流的时间基tbn,视频流的时间基和帧率有关,每秒30帧,代表一帧需要1/30秒。
// ffmpeg中内部的时间基
define AV_TIME_BASE 1000000
// ffmpeg中分数所表示法
define AV_TIME_BASE_Q (AVRatonal){1, AV_TIME_BASE}
时间戳的转换
存在原因:因为时间基不统一,所以当时间基变化时,需要对时间戳进行转换
转换思路很简单:先将原时间戳以某一中间时间单位(这里取国际通用时间单位:秒)为单位进行转换,然后再以新的时间基为单位进行转换,即得到新的时间戳
具体转换API:由转换思路可知,转换过程即先做个乘法再做个除法,涉及到除法就有除不尽的情况,就有舍入问题,ffmpeg专门为时间戳转换提供了API,即av_rescale_q_rnd(),一定要使用该API,提高转换精度,以免给片源未来的播放带来问题。
时间戳转换为秒
要用到的API:av_q2d(time_base),先将有理数类型的时间基转为double类型
具体转换过程:time_in_second = timestamp * av_q2d(time_base)
原文链接:ffmpeg时间戳和时间基 - 资料 - 我爱音视频网 - 构建全国最权威的音视频技术交流分享论坛
本文福利, C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)↓↓↓↓↓↓见下面↓↓文章底部↓↓