音视频中的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();
            }

        }
    }

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/625475.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

导图解房(04)验房流程总结

本章主要是对模型 流程的使用,雷老板也说过:99%的问题实际上都有明确的解决方案和流程,只要问一问就好了,验房这件事而也是如此。 1 验三书一表一证 验房第一步并不是直接看房,而是看三书一表一证,先确保…

基于SPI的插件式开发实现方案之@AutoService+ServiceLoader介绍及Dolphinscheduler中的实际应用

1.插件化开发概述 插件化开发模式正在很多编程语言或技术框架中得以广泛的应用实践,比如大家熟悉的jenkins,docker可视化管理平台rancher,以及日常编码使用的编辑器idea,vscode等。 实现服务模块之间解耦的方式有很多&#xff0…

PHP中excel带图片数据导入

前提:有个需求需要实现带图片的excel数据导入数据库中,发现PHPExcel - Excel 操作库已经停止维护,在PHP8的版本中,有些语法不支持,报错一堆,改了一堆,又还有一堆。所以决定找个替代的扩展&#…

【wow-ts】前端学习笔记Typescript基础语法(一)

项目地址是https://github.com/datawhalechina/wow-ts。 我选择的是ts前端课程 Typescript笔记 TypeScript 入门介绍基础数据类型TypeScript 基础数据结构TypeScript 变量声明变量作用域 TypeScript 入门介绍 第一次接触ts,先去了解了下ts的内容,复制内…

22.实战演练--记住密码和登录状态

在登录注册案例的基础上,实现一个相对完整的登录注册模块 (1).记住密码 (2).记住登录状态(自动登录) (3).注册成功,登录成功,退出登录时的页面跳转

Java基础面试题(一)

Java 语言有哪些特点? 简单易学;面向对象(封装,继承,多态);平台无关性( Java 虚拟机实现平台无关性);支持多线程( C 语言没有内置的多线程机制,…

雍禾医疗好医生:雍禾植发张华医生立志服务好毛发患者

作为中国领先的专门从事毛发医疗服务的医疗集团,雍禾医疗提供诊疗、植发、养固等一站式毛发医疗服务,旗下拥有由专业植发品牌“雍禾植发”、医疗养固品牌“史云逊”、女性美学植发品牌“雍禾发之初”及医学假发品牌“哈发达”等组成的全产业链品牌矩阵。…

MySQL 协议(非常详细适合小白学习)

MySQL 查询过程 MySQL 查询过程大致如下: 1)客户端与服务器端建立连接; 2)客户端登陆 MySQL; 3)客户端向服务器端发起一条请求; 4)服务器端先检查查询缓存,如果命中缓…

哈希(hash)

目录 一、什么是哈希 二、哈希冲突 三、哈希函数 3.1、哈希函数设计原则 3.2、常见的哈希函数 四、哈希冲突解决 4.1、闭散列 4.2、开散列 五、哈希表的模拟实现 5.1、哈希表的功能模拟实现 5.2、测试模拟实现: 一、什么是哈希 如果构造一种存储结构&…

2024年腾讯云服务器购买优惠活动

腾讯云有很多活动,腾讯云服务器网整理的关于云服务器的活动的大全: 1、官方主活动会场:https://curl.qcloud.com/oRMoSucP2、云服务器买赠专区:txyfwq.com/go/huodong3、云服务器满减券:txyfwq.com/go/vouchers4、海外…

实例分割模型Mask2Former解析

Masked2Former是在mask rcnn基础上改进的一个实例分割模型,参考了一些经典模型的思想,如DETR,实验表明效果很好。 论文:《Masked-attention Mask Transformer for Universal Image Segmentation》 https://arxiv.org/abs/2112.0…

新手必看:腾讯云服务器购买详细图文教程

腾讯云服务器购买流程很简单,有两种购买方式,直接在官方活动上购买比较划算,在云服务器CVM或轻量应用服务器页面自定义购买价格比较贵,但是自定义购买云服务器CPU内存带宽配置选择范围广,活动上购买只能选择固定的活动…

【极光系列】Windows安装Mysql8.0版本

【极光系列】Windows安装Mysql8.0版本 一.mysql服务端 下载地址:https://dev.mysql.com/downloads/mysql/ 二.解压二进制包 解压到 E:\mysql-8.0.35-winx64目录下,记住你解压后的目录,后续要使用三.创建my.ini文件 tips:mys…

nvcc -V显示command not found

出现这个问题,不仅是 nvcc -V会显示command not found,nvidia-smi同样也会显示 解决方法如下: 1)这里首先转换到CUDA所在位置,一般是在这个位置 cd /usr/local 2)打开、编辑环境变量的配置文件 vim ~/.bashrc …

使用HTTP/2在Linux上的Nginx服务器进行优化

随着互联网的发展,HTTP/2协议逐渐成为主流。与传统的HTTP/1.1相比,HTTP/2提供了更高的传输效率和更好的安全性。在Linux上使用Nginx服务器进行优化,我们可以充分利用HTTP/2的优势,提高网站的性能和用户体验。 1. 安装Nginx并启用…

日志采集传输框架之 Flume,将监听端口数据发送至Kafka

1、简介 Flume 是 Cloudera 提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传 输的系统。Flume 基于流式架构,主要有以下几个部分组成。 主要组件介绍: 1)、Flume Agent 是一个 JVM 进程&#xf…

【JupyterLab】在 conda 虚拟环境中 JupyterLab 的安装与使用

【JupyterLab】在 conda 虚拟环境中 JupyterLab 的安装与使用 1 JupyterLab 介绍2 安装2.1 Jupyter Kernel 与 conda 虚拟环境 3 使用3.1 安装中文语言包(Optional)3.2 启动3.3 常用快捷键3.3.1 命令模式下 3.4 远程访问个人计算机3.4.1 局域网下 1 JupyterLab 介绍 官方文档: …

15.鸿蒙HarmonyOS App(JAVA)进度条与圆形进度条

15.鸿蒙HarmonyOS App(JAVA)进度条与圆形进度条 progressBar2.setIndeterminate(true);//设置无限模式,运行查看动态效果 //创建并设置无限模式元素 ShapeElement element new ShapeElement(); element.setBounds(0,0,50,50); element.setRgbColor(new RgbColor(255,0,0)); …

C# Math.Floor与Math.Round

Math.Floor方法 会将给定的数值向下舍入到最接近的整数。对于12.5,向下舍入就是12。然后通过类型转换 (int) 将结果转换为整数类型。 Math.Round方法 会将给定的数值进行四舍五入。默认情况下,当参数为double时,四舍五入的行为是根据具体实…

Nginx——强化基础配置

1、牢记Context Context是Nginx中每条指令都会附带的信息,用来说明指令在哪个指令块中使用,可以将Context 理解为配置环境。 每个指令都拥有自己的配置环境,如果把配置环境记错了,或者在设计时未考虑配置环境的作用,…