关于RTP时间戳以及播放器对时间戳的处理

2024-04-19 15:08
文章标签 rtp 处理 时间 播放器

本文主要是介绍关于RTP时间戳以及播放器对时间戳的处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

    首先,了解时间戳几个基本概念:

    时间戳单位:时间戳计算的单位不是秒之类的单位,而是由采样频率所代替的单位,这样做的目的就是为了是时间戳单位更为精准。比如说一个音频的采样频率为8000Hz,那么我们可以把时间戳单位设为1 / 8000。
    时间戳增量:相邻两帧之间的时间差(以时间戳单位为基准)。
    采样频率: 有些地方也叫时钟频率,即 每秒钟抽取样本的次数,例如音频的采样率一般为8000Hz
    帧率:      每秒传输或者显示帧数,例如25f/s
    
    再看看RTP时间戳课本中的定义:

    RTP包头的第2个32Bit即为RTP包的时间戳,Time Stamp ,占32位。
    时间戳反映了RTP分组中的数据的第一个字节的采样时刻。在一次会话开始时的时间戳初值也是随机选择的。即使是没有信号发送时,时间戳的数值也要随时间不断的增加。接收端使用时间戳可准确知道应当在什么时间还原哪一个数据块,从而消除传输中的抖动。时间戳还可用来使视频应用中声音和图像同步。
    在RTP协议中并没有规定时间戳的粒度,这取决于有效载荷的类型。因此RTP的时间戳又称为媒体时间戳,以强调这种时间戳的粒度取决于信号的类型。例如,对于8kHz采样的话音信号,若每隔20ms构成一个数据块,则一个数据块中包含有160个样本(0.02×8000=160)。因此每发送一个RTP分组,其时间戳的值就增加160。

   关于时间戳,归纳为以下几个重要的点:

    首先,时间戳就是一个值,用来反映某个数据块的产生(采集)时间点的,后采集的数据块的时间戳一般大于先采集的数据块的。为什么说一般呢?因为时间戳是一个32位无符号整型,如果一直递增到了一定时间数值就会回滚,所以时间戳只是对数据块先后顺序的一个参考。
    第二,在实时流传输中,数据采集后立刻传递到RTP模块进行发送,那么,其实,数据块的采集时间戳就直接作为RTP包的时间戳(要转换为某个时钟频率)。
    第三,如果用RTP来传输固定的文件,则这个时间戳就是视频文件中每一帧携带的时间戳,但是也需要转换为对应RTP通道的时钟频率。
    第四,时间戳的单位采用的是采样频率的倒数,例如采样频率为8000Hz时,时间戳的单位为1 / 8000 ,在Jrtplib库中,有设置时间戳单位的函数接口,而ORTP库中根据负载类型直接给定了时间戳的单位(音频负载1/8000,视频负载1/90000)
    第五,时间戳增量是指相邻两帧(不一定是相邻两个RTP包)之间的时间间隔。

    如果采样频率为90000Hz,则由上面讨论可知,时间戳单位为1/90000,我们就假设1s钟被划分了90000个时间块,那么,如果每秒发送25帧,那么,每一个帧的发送占多少个时间块呢?当然是 90000/25 = 3600。因此,我们根据定义“时间戳增量是发送第二个RTP包相距发送第一个RTP包时的时间间隔”,故时间戳增量应该为3600。

    下面说一下播放器如何对编码器发送的RTP包的时间戳做处理。这里的编码器是指发送RTP包的服务器,一般是指网络摄像机或RTSP服务器。

    播放器本地建立了一个系统时钟,这个时钟一般根据系统的CPU时间来计算出来,当播放开始,时钟的时间为0。时间戳有分绝对时间和相对时间,收到的RTP包的时间戳为绝对时间,播放器需要把这个RTP时间戳转为播放器本地的相对时间戳,相对时间戳以0为开始,时间戳决定了一帧播放或渲染的时刻。当播放开始时,时钟开始运行,时间戳一直增加,播放器会用系统时钟的时间跟视频帧的时间戳(相对时间戳)进行对比,根据它们的大小关系决定是否马上渲染这帧还是要等待。但是,编码器发过来的时间戳只是一个参考值,有可能是不准的,为什么呢?编码器打时间戳基于的时钟跟播放器的本地时钟是可能不一样的,不同的编码器有不同的打时间戳算法,我只说一下常见的做法,一般地,编码器打时间戳是基于一个简单的规则:每发一个视频帧,PTS就递增一个固定的时间增量。根据TS流和Rtp协议的规定,视频的时钟频率是90000,也就是时间单位是1/90000秒。如果帧率是25帧,则相邻两帧的PTS增量就是3600,也就是每发一个帧,时间戳就增加3600,但是实际上两帧的时间增量应该根据它们实际经过的时间,而不是一个固定的值。实际上,编码器每秒采集图像的帧率并不是绝对固定的(取决于物理时钟的精度以及CPU处理的速度),有一定误差,平均采集帧率是25,但可能编码器某1秒采集了25帧,某一秒采集了24帧,假如都是按固定增量的方式递增时间戳,过一段时间后,编码器的时间戳跟播放器的时钟的时间就有很大差异,可能导致播放不流畅,或者缓冲了很多帧延时加大了。
   所以,解码器不能盲目相信编码器的时间戳,发现时间戳跟本地的时间差异太远需要尽快调整,应该实现一个动态适应的机制:当发现接收缓冲区里的帧数比较多时,要加快渲染速度;当缓冲区的帧数在一个比较低的水平(1-4),则稳定渲染速度。

 

这篇关于关于RTP时间戳以及播放器对时间戳的处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/917886

相关文章

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

python处理带有时区的日期和时间数据

《python处理带有时区的日期和时间数据》这篇文章主要为大家详细介绍了如何在Python中使用pytz库处理时区信息,包括获取当前UTC时间,转换为特定时区等,有需要的小伙伴可以参考一下... 目录时区基本信息python datetime使用timezonepandas处理时区数据知识延展时区基本信息

Python的time模块一些常用功能(各种与时间相关的函数)

《Python的time模块一些常用功能(各种与时间相关的函数)》Python的time模块提供了各种与时间相关的函数,包括获取当前时间、处理时间间隔、执行时间测量等,:本文主要介绍Python的... 目录1. 获取当前时间2. 时间格式化3. 延时执行4. 时间戳运算5. 计算代码执行时间6. 转换为指

Python Transformers库(NLP处理库)案例代码讲解

《PythonTransformers库(NLP处理库)案例代码讲解》本文介绍transformers库的全面讲解,包含基础知识、高级用法、案例代码及学习路径,内容经过组织,适合不同阶段的学习者,对... 目录一、基础知识1. Transformers 库简介2. 安装与环境配置3. 快速上手示例二、核心模

一文详解Java异常处理你都了解哪些知识

《一文详解Java异常处理你都了解哪些知识》:本文主要介绍Java异常处理的相关资料,包括异常的分类、捕获和处理异常的语法、常见的异常类型以及自定义异常的实现,文中通过代码介绍的非常详细,需要的朋... 目录前言一、什么是异常二、异常的分类2.1 受检异常2.2 非受检异常三、异常处理的语法3.1 try-

Java中字符串转时间与时间转字符串的操作详解

《Java中字符串转时间与时间转字符串的操作详解》Java的java.time包提供了强大的日期和时间处理功能,通过DateTimeFormatter可以轻松地在日期时间对象和字符串之间进行转换,下面... 目录一、字符串转时间(一)使用预定义格式(二)自定义格式二、时间转字符串(一)使用预定义格式(二)自

Python使用getopt处理命令行参数示例解析(最佳实践)

《Python使用getopt处理命令行参数示例解析(最佳实践)》getopt模块是Python标准库中一个简单但强大的命令行参数处理工具,它特别适合那些需要快速实现基本命令行参数解析的场景,或者需要... 目录为什么需要处理命令行参数?getopt模块基础实际应用示例与其他参数处理方式的比较常见问http

Java Response返回值的最佳处理方案

《JavaResponse返回值的最佳处理方案》在开发Web应用程序时,我们经常需要通过HTTP请求从服务器获取响应数据,这些数据可以是JSON、XML、甚至是文件,本篇文章将详细解析Java中处理... 目录摘要概述核心问题:关键技术点:源码解析示例 1:使用HttpURLConnection获取Resp

Java中Switch Case多个条件处理方法举例

《Java中SwitchCase多个条件处理方法举例》Java中switch语句用于根据变量值执行不同代码块,适用于多个条件的处理,:本文主要介绍Java中SwitchCase多个条件处理的相... 目录前言基本语法处理多个条件示例1:合并相同代码的多个case示例2:通过字符串合并多个case进阶用法使用