音视频中的DTS和PTS区别

一、什么是PTS、DTS

1.PTS:即显示时间戳,用来告诉播放器在什么时候显示这一帧数据

2.DTS:即解码时间戳,用来告诉播放器在什么时间来解码这一帧的数据

3.GOP:MPEG使用的一种视频压缩技术

总的来说PTS和DTS用于指导播放器端的行为

二,了解视频采集到编码推流

        在视频采集的时候是录制一帧就编码一帧发送一帧,在编码的时候会生成PTS,在通常情况下,编码器在编码一个I帧,然后向前跳过几个帧,用编码I帧作为基准对一个未来帧P帧进行编码,然后跳回到I帧之后的下一个帧。编码的I帧和P帧之间的帧被编码为B帧。之后编码器会再次跳过几个帧,使用第一个P帧作为一个基准帧编码另外一个P帧,然后再次跳回,用B帧填充显示序列的空隙。这个过程不断继续,每12到15个p帧和B帧内插入一个新的I帧。P帧由前一个I帧或P帧图像来预测,而B帧由前后的两个P帧或一个I帧和一个P帧来预测。如下图所示:

假设采集到的帧是这样的:

I B B P B B P

那么它的PTS对应的是1234567

编码顺序是 1423756

推流顺序也是按照编码顺序去推的即

I P B B P B B

那么接受端的视频流也就是

I P B B P B B

这时候去解码,也是按照收到的视频流一帧一帧去解得了,接收一帧解码一帧,所以解码的顺序的这样的

I P B B P B B

DTS:1234567

PTS:1423756

可看到解码出来对应PTS不是顺序的,为了正确显示视频流,这时候我们必须按照PTS调整解码后的帧,即

I B B P B B P

DTS:1342675

PTS:   1234567

其实就是把PTS按照顺序递增的方式排列下

总而言之,在音视频中,PTS通常是按照递增顺序排列的,以保证正确的时间顺序和播放同步。

三、应用实例

        在没有B帧的情况下,DTS和 PTS 的输出顺序是一样的,一旦存在 B 帧,则顺序不一样。 这里,我们只需要关心 PTS ,即显示时间戳。通过 MediaCodec.BufferInfo 的 presentationTimeUs 可以拿到当前的 pts 时间戳,单位是微妙,它是相对于0开始播放的时间,所以,我们可以使用系统时间差来模仿两帧的时间差,这样当解码过来的 pts 比这个时间差快,则延时以下再输出到 Surface ,如果不是,则直接显示到 Surface 中

 // 用于对准视频的时间戳
 private long startMs = -1;
if (outputId >= 0){
     if (mStartMs == -1) {
            mStartMs = System.currentTimeMillis();
      }
    //矫正pts
     sleepRender(info, startMs);
     //释放buffer,并渲染到 Surface 中
     mediaCodec.releaseOutputBuffer(outputId, true);
 }
#sleepRender
    /**
     * 数据的时间戳对齐
     **/
    private void sleepRender(MediaCodec.BufferInfo info, long startMs) {
        /**
         * 注意这里是以 0 为出事目标的,info.presenttationTimes 的单位为微秒
         * 这里用系统时间来模拟两帧的时间差
         */
        long ptsTimes = info.presentationTimeUs / 1000;
        long systemTimes = System.currentTimeMillis() - startMs;
        long timeDifference = ptsTimes - systemTimes;
        // 如果当前帧比系统时间差快了,则延时以下
        if (timeDifference > 0) {
            try {
                Thread.sleep(timeDifference);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

使用上面的代码示例,可以达到让播放器以正常速度解码视频,不会出现倍速播放的效果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值