图解DTS和PTS

图解DTS和PTS

FFmpeg里有两种时间戳:DTS(Decoding Time Stamp,解码时间戳)和PTS(Presentation Time Stamp,显示时间戳)。
由于把视频编码成I,B,P等帧,如下图:
视频编码成I,B,P
假设现在有I,B,P帧,那么要传输和显示呢?
如果按照显示顺序传输的话:
传输顺序就是I->B>P
当对B帧进行解码后,由于B帧无法单独显示,只能等待后面的P帧

如果不按照顺序传输,按照解码顺序传输的话:
传输顺序就是I->P->B

无论用哪种方式传输和显示,一旦有了B帧这个东西,就都需要告诉对方什么时候该显示这帧
于是就有了PTS和DTS,即Presentation Time Stamp和Decode Time Stamp

PTS告诉对方什么时候该显示这帧,而DTS则告诉什么时候该解码这帧

如果没有B帧的情况,PTS和DTS都是一样的:
在这里插入图片描述
有B帧的情况下,PTS和DTS才会不一致:
在这里插入图片描述
例如,视频25帧每秒,则按毫秒计,1000/25=40ms,在首帧pts上进行累加。
音频根据采样率及样本个数,在同一时间基上累加, 例如,1024个样本,44100采样率,毫秒计。
1000*1024/44100=23.21995464852607709750566893424 ms
基本理论是这样,但实际的同步远没有这么简单,掉线,断网,弱网,丢帧,跳帧,等一系列均对你的同步进行阻挠,需要根据具体情况做同步,坐等高手给出较为鲁棒的同步措施。

固定帧率

1. 视频时间戳

pts = inc++ *(1000/fps); 其中inc是一个静态的,初始值为0,每次打完时间戳inc加1. 在ffmpeg,中的代码为 pkt.pts= m_nVideoTimeStamp++ * (m_VCtx->time_base.num * 1000 / m_VCtx->time_base.den);

2. 音频时间戳

pts = inc++ * (frame_size * 1000 / sample_rate) 在ffmpeg中的代码为 pkt.pts= m_nAudioTimeStamp++*(m_ACtx>frame_size*1000/m_ACtx>sample_rate);
采样频率是指将模拟声音波形进行数字化时,每秒钟抽取声波幅度样本的次数。 。正常人听觉的频率范围大约在20Hz~20kHz之间,根据奈奎斯特采样理论,为了保证声音不失真,采样频率应该在40kHz左右。常用的音频采样频率有8kHz、11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz、48kHz等,如果采用更高的采样频率,还可以达到DVD的音质 对采样率为44.1kHz的AAC音频进行解码时,一帧的解码时间须控制在23.22毫秒内。 背景知识:
(一个AAC原始帧包含一段时间内1024个采样及相关数据) 分析:

  1. AAC
    音频帧的播放时间=一个AAC帧对应的采样样本的个数/采样频率(单位为s) 一帧 1024个 sample。采样率Samplerate 44100KHz,每秒44100个sample, 所以根据公式 音频帧的播放时间=一个AAC帧对应的采样样本的个数/采样频率 当前AAC一帧的播放时间是= 1024*1000000/44100= 22.32ms(单位为ms)
  2. MP3
    mp3 每帧均为1152个字节,则:
    frame_duration = 1152 * 1000000 / sample_rate
    例如:sample_rate = 44100HZ时,计算出的时长为26.122ms,这就是经常听到的mp3每帧播放时间固定为26ms的由来。
    二可变帧率 有很多的采集卡,摄像头,在做采集的时候,明明设置的25FPS,但实际采集数据回调过来,发现并不是40毫秒的间隔,而是50,60,甚至100不等的时间间隔。 这就给编码后打时间戳带来很大的困难。

参考文章:
链接: https://www.cnblogs.com/linyilong3/p/9940230.html.
I,P,B帧和PTS,DTS的关系: https://www.cnblogs.com/qingquan/archive/2011/07/27/2118967.html.
DTS和PTS的解释: https://blog.csdn.net/ai2000ai/article/details/77367481.

猜你喜欢

转载自blog.csdn.net/qq_39825430/article/details/116229082