当前位置: 首页 > 工具软件 > PTS > 使用案例 >

音视频pts计算

别子实
2023-12-01

视频pts计算

  • PTS(Presentation Time Stamp):即显示时间戳,这个时间戳用来告诉播放器该在什么时候显示这一帧的数据。
  • DTS(Decoding Time Stamp):即解码时间戳,这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据。

需要注意的是:虽然 DTS、PTS 是用于指导播放端的行为,但它们是在编码的时候由编码器生成的。当视频流中没有 B 帧时,通常 DTS 和 PTS 的顺序是一致的。但如果有 B 帧时,就回到了我们前面说的问题:解码顺序和播放顺序不一致了。

视频pts是每帧递增,假如fps是25帧的,时间基为fps的倒数1/25,那么pts递增+1即可。

      //pts计算需要参考time_base, time_base代表的是时间单位,此处单位根据帧率,即25个单位一秒
      video_stream_->time_base = (AVRational) {1, 25};

      //对应到每秒25帧,即每帧一个单位,故pts计算是每帧加1
      - 第一帧:pts=1
      - 第二帧:pts=2
      - 第三帧:pts=3
      - 第n帧的pts = n * ((1 / timbase)/ fps);
      //算法即是通过time_base知道一秒有25个时间单位,帧率是25帧每秒,所以每个帧占一个时间单位

音频pts计算

  • 音频有采样率概念,8000,16000,32000, 44100, 48000 即每秒采样多少次,有多少个样本。

rtp时间戳

  • rtp中时间单位与采样率一致,以pcmu为例,每个rtp之间的时间相差160,每个rtp中pcmu长度为160.
  • 如果是AAC,AAC的frame_size=1024,如果每帧一个包的话,每个rtp之间时间差为1024

文件时间戳

   //以8000采样率示例,AAC编码,s16,单音频
   audio_stream_->time_base = (AVRational) { 1, 8000};

   AAC nb_samples = 1024  frame_size=1024

   即每秒有 8000/1024 个 AAC帧,每帧占用的时间单位根据tiem_base换算

   num = 8000/1024

   每帧时间单位 pts = 8000*1/num 

   pts = n * ((1 / timbase)/ num);
   pts = n * 1024

总结

  • 文件中计算音视频pts,都是根据每秒算出有多少个音视频帧, 然后根据time_base,算出每帧占有多少个时间单位,即为pts差值
  • rtp传输中时间单位与采样率一致,传输多少个样本即为增加多少时间
  • 重点理解time_base是一种度量单位,pts是基于此种单位的数值计算

补充
1.IPB帧

  1. I帧关键帧,帧内压缩,包含完整的画面
  2. P帧差别帧,与上一个关键帧的差别,需要缓存上一帧才能得到完整画面
  3. B帧双向差别帧,与前后两帧的差别,需要缓存上一帧和下一帧才能得到完整画面

2.判断帧的类型?

AVFrame->pict_type
AVPacket->flags & AV_PKT_FLAG_KEY

3.DTS和PTS

DTS:Decoding Time stamp 解码时间戳
PTS: Presentation Time Stamp 显示时间戳

流 I P B
DTS 1 2 3
PTS 1 3 2

4.FFmpeg中的时间单位

time_base 时间单位(时间基)
不同的结构体,有不同的时间单位
AVStream *stream;
time = stream->duration * stream->time_base;

5.音视频同步的三种方案

音频同步视频
视频同步音频
标准时间(视频已经播放了多长时间)

6.时间换算单位

s(秒)、ms(毫秒)、μs(微秒)、ns(纳秒),其中:1s=1000ms,1 ms=1000μs,1μs=1000ns

1秒=1000毫秒(ms) 所以4秒=4000毫秒(ms)
还有一些其它的时间单位换算,我罗列一下:
1毫秒=1/1,000秒(s)
1秒=1,000,000 微秒(μs)
1微秒=1/1,000,000秒(s)
1秒=1,000,000,000 纳秒(ns)
1纳秒=1/1,000,000,000秒(s)
1秒=1,000,000,000,000 皮秒(ps)
1皮秒=1/1,000,000,000,000秒(s)

7.对pts的计算记录

pts = inc++ *(1000/fps);
inc:第几帧,从0开始,每次加1
fps为帧率:每秒显示多少针,1000/fps == 一帧需要多少毫秒

在ffmpeg,中的代码为:
pkt.pts= m_nVideoTimeStamp++ * (m_VCtx->time_base.num * 1000 / m_VCtx->time_base.den);

音频pts计算:
1000*1024/44100=23.21995464852607709750566893424 ms

音频采样率44100HZ:录音设备在一秒钟内对声音信号的采样次数
1000/44100 = 每一次采样需要多少毫秒
1024:每一帧有多少次采样,AAC一般为1024

在ffmpeg中的代码为 pkt.pts= m_nAudioTimeStamp++ * (m_ACtx->frame_size * 1000 / m_ACtx->sample_rate);
 类似资料: