RTSP 音视频play同步分析

基础理论

RTSP RTP RTCP SDP基础知识-CSDN博客

关于RTP的时间戳知识点回顾

时间戳单位:时间戳计算的单位不是秒,而是采用采样频率的倒数,这样做的目的是为了使时间戳单位更为精准。比如说一个音频的采样频率为8000Hz,那么我们可以把时间戳单位设为1/8000s。

时间戳增量:相邻两个RTP包之间的时间差(以时间戳单位为基准)

采样频率: 每秒钟抽取样本的次数,例如音频的采样率一般为8000Hz,即每秒采样8000次,产生8000个样本

帧率: 每秒传输或者显示帧数,例如25f/s

    小结:

         时间戳反映了RTP分组中的数据的第一个字节的采样时刻。在一次会话开始时的时间戳初值也是随机选择的。即使是没有信号发送时,时间戳的数值也要随时间不 断的增加。接收端使用时间戳可准确知道应当在什么时间还原哪一个数据块,从而消除传输中的抖动。时间戳还可用来使视频应用中声音和图像同步。

        在RTP协议中并没有规定时间戳的粒度,这取决于有效载荷的类型。因此RTP的时间戳又称为媒体时间戳,以强调这种时间戳的粒度取决于信号的类型。例如,对于8kHz采样的音频信号,若每隔20ms构成一个数据块,则一个数据块中包含有160个样本(0.02×8000=160)。因此每发送一个RTP分组,其时间戳的值就增加160。

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

1,时间戳可用来使视频应用中声音和图像同步,为什么呢?

首先,这个时间戳就是一个值且必须满足大家都来使用这个值,用来反映某个数据块的产生(采集)时间点的, 后采集的数据块的时间戳肯定是大于先采集的数据块的。有了这样一个时间戳,就可以标记数据块的先后顺序。
第二,在实时流传输中,数据采集后立刻传递到RTP 模块进行发送,那么,其实,数据块的采集时间戳就直接作为RTP包的时间戳。
第三,如果用RTP来传输固定的文件,则这个时间戳 就是读文件的时间点,依次递增。这个不再我们当前的讨论范围内,暂时不考虑。

rtsp时间戳类型

在分析音视频同步之前,我们先知道都有哪几类的时间戳。

  • RTP 包中的 rtptime:这是 RTP 协议中用于同步媒体流的关键字段。它表示的是分组中数据的第一个字节的采样时间。RTP 时间戳的初始值是随机的,而且即使没有数据发送,时间戳也会随着时间的推移而增加,这样可以保持媒体流的连续性。RTP 时间戳不能单独用于同步,因为它的初始值是随机的,需要通过 RTCP 协议来同步不同的 RTP 流 。

  • PLAY 请求的 Response 中的 rtp time 和 npt

    • npt (Normal Play Time):这是正常播放时间,它表示流相对于播放开始时的绝对位置。播放开始时的时间定义为 0.0s。这个时间用于客户端请求特定时间点的媒体流,并且可以用于在播放过程中跟踪当前播放的位置 。
    • rtptime:这是发送 PLAY 请求后收到的第一个 RTP 包的时间戳值。它表示的是会话开始的相对时间,用于客户端计算当前播放时间戳 。
    •  npt 是影⽚开始的相对时间,⽽ rtptime 是会话开始的相对时间。
  • RTCP 的 SR (Sender Report) 中的 rtp 和 ntp 时间戳对

    • RTP 时间戳:与数据包中的 RTP 时间戳具有相同的单位和偏移量,但它通常不等于任何临近的 RTP 包中的时间戳 。
    • NTP 时间戳:这是一个 64 位的时间戳,用于在 RTCP 报文中表示发送者报告的绝对时间。NTP 时间戳基于协调世界时(UTC),提供了一个全局的时间参考,使得不同的 RTP 流可以通过 NTP 时间戳同步到同一个时间轴上 。

 流内同步和流间同步 

多媒体通信同步方法,主要有时间戳同步法、同步标记法、多路复用同步法三种。

下面主要讨论时间戳同步法,特别是RTP时间戳同步。内容包括RTP媒体间同步的实现。

1.序列号字段是否可以作为流内的同步标识?

序列号只表示了包发出的先后顺序,它表示不了任何时间上的其它概念,所以严格的说,序列号并不能作为流内的同步标志。但是,由于一般来说,包的发送时间都会有严格限制,比如音频包是每秒种发送30个数据包,也就是说,每个包间隔1000/30MS,而这个时间就可以 作为一个同步时间来播放。也就是说,按照序列号,每1000/30MS间隔播放一个数据包,这样也能保证同步,但是这时候请考虑丢包问题。

2.为什么需要RTCP的NTP时间来实现媒体间同步?没有RTCP,能实现RTP媒体间的同步吗?

        仅仅使用RTP时间戳是无法实现媒体间同步的,根本的原因是音频时间轴和视频时间轴是完全独立的,通过音频帧和视频帧的时间戳,无法确定一个视频帧和一个音频帧的相对时间关系,也就是无法把它们都准确定位在绝对时间轴上。

  要实现RTP媒体间同步,需要借助于RTCP,在RTCP的SR包中,包含有对,音频帧RTP时间戳和视频帧RTP时间戳通过对,都可以准确定位到绝对时间轴NTP上,音频帧和视频帧的相对时间关系就可以确定下来 了。为什么设计了sr包,主要是为了能让音频视频的rtp的时间戳可以有不同的起点,sr包的<rtp ntp>就是为了获取这个不同的起点。

本质而言:如果音频视频时间戳都是同样的起点 就不需要用到ntp。

        基本上可以这么认为。例如,对于RTP实时流,在发送端媒体间就同步的很好,在接收端只需做少许处理,不需要RTCP,就可以实现媒体间同步。当然,这只是少数例外。因为RTP规范并不包括这个假设,所以我们还是按照RTP规范来做吧。

1.流内 时间戳映射关系

npt 和 rtptime 的区别在于 npt 是影⽚开始的相对时间,⽽ rtptime 是会话开始的相对时间。因此在 client 端,需要对这两者进⾏ map 处理。

在 client 端计算播放时间戳的公式如下:

scale 值。在正常播放的情况下为 1 ,快速播放时⼤于 1 ,当处于反向扫描模式时⼩于 -1 .
 

客户端播放时间 = rtp.ts - play.rtp.ts    /  scale +  play.ntp.ts

假设有以下情况:
视频编码格式为 30 fps
PLAY 请求的 Response 中获得:
npt=0.0
rtptime=1000
scale=1.0
现在收到一个 RTP 数据包,其 rtptime=2500 
nptUs   = (2500 - 1000) / 1.0 + 0.0
             = 1500 / 1.0 + 0.0
             = 1.5 seconds  

为了消除网络延迟的影响,可以结合 RTCP SR 报文中提供的 LSR (Last Sender Report) 和 DLSR (Delay Since Last Sender Report) 信息,对 RTP 时间戳进行校正:
corrected_rtpTime = current_rtpTime - (LSR + DLSR)

2.媒体间同步⽅法(不同设备的同步)

上⾯的处理仅仅实现了媒体内的同步,在实现媒体间同步时,还需要进⾏其他的处理⼯作。这就需要⽤到 RTCP 的 SR ( Sender Report )。在 SR 中包含⼀个< rtp , ntp >时间戳对,通过这个时间戳对可以将 ⾳频和视频准确的定位到⼀个绝对时间轴上。

RTP 时间戳对应的 NTP 时间戳,从而将 RTP 流中的事件映射到全局的 NTP 时间轴上。

推导图:

同步流程:
接收端收到 RTCP SR 报文,获取 <rtp, ntp> 时间戳对。
根据 <rtp, ntp> 时间戳对,将不同 RTP 流的时间戳映射到统一的时间轴上。
利用映射后的时间戳值进行媒体间的时间校准和同步播放。

 音视频不是同时产生

发送端的音视频流并没有对齐,但是周期地发送SR包,接收端得到音视频SR包的RTP时间戳、NTP时间戳后通过线性回归得到NTP时间戳Tntp和RTP时间戳Trtp时间戳的对应关系:

  • Tntp_audio = f(Trtp_audio)
  • Tntp_video = f(Trtp_video)

其中Tntp = f(Trtp) = a*kTrtp + b 为线性函数,其中 a 是比例系数, b 是时间偏移量

这样接收端每收到一个RTP包,都可以将RTP时间戳换算成NTP时间戳,从而在同一时间基准下进行音视频同步。

rtp和ntp转换是线性关系:绝对时间 ntp=x+80ms,rtp=80*90=7200;
建立线性关系:则rtp=(ntp-x)*90,RTP时间戳 = (x + 80ms - x) * 90 = 80ms * 90 = 7200

这个示例是一种简单的线性关系:RTP时间戳可以通过NTP时间减去一个基准时间x,再乘以一个比例因子90来计算得出。 不是所以情况都适用

实际情况如下图:

实例分析
问:音频采样率8k,视频帧率25. Audio从头开始,音频时间戳320会在多少ms播放呢?
答:320*1000/8000 =40ms
问:那么收到的视频帧rtp时间戳是7200应该在多少ms播放呢?
答:
因为第一个音频是从0开始播放的,但是第一个视频帧可能是在第1ms开始的,而不是从0ms开始的.
如果视频从1ms开始,rtcp第一个音视频帧 video rtp 是3600,它表示1+40 = 41ms。而audio rtp 是160表示40ms.所以先要计算audio,video的绝对时间差,倒退开始的时间差.
视频同步到音频为例:

  1. diff=(video ntp time)-(audio ntp time)=1ms (rtcp中NTP时间相减).
  2. 对应的rtp时间相减,3600-90=3510.3510就是视频ntp对应的40ms绝对时间(time base).
  3. 后面rtp 7200是多少ms呢?
    7200-3510=7200-(3600-90)=3600+90=40ms+1=41ms;即在播放base 40ms之后的41ms播放,等于81ms的地方播放.
  4. 或者使用线性回归 rtp=(ntp-x)*90     7200 = (ntp - 1)*90 =81ms
    后续的每个audio/video rtp timestamp减去这个base就是播放时间。实现同步.

音频同步到视频原理一样.
 

参考

使用rtcp实现音视频同步 - 知乎 (zhihu.com)

Rtcp实现音视频同步 - 知乎 (zhihu.com)

RTP、RTCP及媒体流同步 - 明明是悟空 - 博客园 (cnblogs.com)

学习资料分享

0voice · GitHub

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

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

相关文章

J1学习打卡

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 # 数据预处理和加载 import torch from torch import nn, optim from torch.utils.data import DataLoader from torchvision import datasets, transforms, …

5.C语言基础入门:数据类型、变量声明与创建详解

C语言基础入门&#xff1a;数据类型、变量声明与创建详解 C语言往期系列文章目录 往期回顾&#xff1a; C语言是什么&#xff1f;编程界的‘常青树’&#xff0c;它的辉煌你不可不知VS 2022 社区版C语言的安装教程&#xff0c;不要再卡在下载0B/s啦C语言入门&#xff1a;解锁…

Github优质项目推荐 - 第六期

文章目录 Github优质项目推荐 - 第六期一、【WiFiAnalyzer】&#xff0c;3.4k stars - WiFi 网络分析工具二、【penpot】&#xff0c;33k stars - UI 设计与原型制作平台三、【Inpaint-Anything】&#xff0c;6.4k stars - 修复图像、视频和3D 场景中的任何内容四、【Malware-P…

小程序项目实践(一)--项目的初始化以及前期的准备工作

目录 1.起步 1.1 uni-app 简介 1.2 开发工具 1.2.1 下载 HBuilderX 1.2.2 安装 HBuilderX 1.2.3 安装 scss/sass 编译 1.2.4 快捷键方案切换 1.2.5 修改编辑器的基本设置 1.3 新建 uni-app 项目 1.4 目录结构 1.5 把项目运行到微信开发者工具 1.6 使用 Git 管理项目 …

leetcode hot100_part3_滑动窗口

滑动窗口是有一个基本的模版的&#xff0c;不要自己想当然哦~ 滑动窗口算法思想&#xff08;附经典例题&#xff09;_滑动窗口的思想-CSDN博客 滑动窗口也叫同向双指针&#xff1b;可以先看一下灵山视频&#xff1a;滑动窗口【基础算法精讲 03】_哔哩哔哩_bilibili 3.无重复字…

7.C++面向对象3(拷贝构造函数,赋值运算符重载)

⭐本篇为C学习第7章&#xff0c;主要了解 拷贝构造函数&#xff0c;赋值运算符重载 ⭐本人Gitee C代码仓库&#xff1a;yzc的c学习: 小川c的学习记录 - Gitee.com 上篇讲了6个默认成员函数的构造函数和析构函数。 重要代码如下&#xff1a; #define _CRT_SECURE_NO_WARNINGS…

Mysql(五) --- 数据库设计

文章目录 前言1.范式1.1.第一范式1.1.1 定义1.1.2.例子 1.2.第二范式1.2.1 定义1.2.2 例子1.2.3.不满足第二范式可能会出现的问题 1.3.第三范式1.3.1 定义2.3.2 示例 2. 设计过程3. 实体-关系图3.1 E-R图的基本组成3.2 关系的类型3.2.1 一对一关系(1:1)3.2.2 ⼀对多关系(1:N)3.…

Pr:视频效果快速参考(合集 · 2024版)

Premiere Pro 自带十七组约一百多个视频效果&#xff0c;涵盖了从变换、颜色控制到风格化等多种用途&#xff0c;帮助用户在视频编辑中实现多样化的视觉表现、进行后期处理以及修正各种画质问题。 提示&#xff1a; 点击下面的效果组名称或截图&#xff0c;即可访问该组里面的效…

SF6气体密度监测仪市场研究:主要企业的市场份额已超过37.13%

SF6气体密度监测仪是一种专用于监测和测量六氟化硫&#xff08;SF6&#xff09;气体密度的设备。SF6气体因其优异的绝缘性能和灭弧能力&#xff0c;被广泛应用于电力行业&#xff0c;尤其是在气体绝缘金属封闭开关设备&#xff08;GIS&#xff09;和断路器等关键设备中。随着电…

【自注意力与Transformer架构在自然语言处理中的演变与应用】

背景介绍 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;序列到序列&#xff08;seq2seq&#xff09;模型和Transformer架构的出现&#xff0c;极大地推动了机器翻译、文本生成和其他语言任务的进展。传统的seq2seq模型通常依赖于循环神经网络&#xff08;RNN&…

微服务Sleuth解析部署使用全流程

目录 1、Sleuth链路追踪 1、添加依赖 2、修改日志配置文件 3、测试 2、zipkin可视化界面 1、docker安装 2、添加依赖 3、修改配置文件 4、查看页面 5、ribbon配置 1、Sleuth链路追踪 sleuth是链路追踪框架&#xff0c;用于在微服务架构下开发&#xff0c;各个微服务之…

刷题 - 分治

面试经典 150 题 - 分治 148. 排序链表⭐️⭐️⭐️ - 快慢指针找中间节点 - 归并排序 伪代码&#xff1a; 将链表拆分成两半&#xff0c;返回右半边头节点&#xff08;左半边头节点就是原始链表头节点&#xff09;对左边进行排序并返回左边头节点对右边进行排序返回右边头节…

使用jenkins将airflow-dbt部署到服务器上

系列文章目录 文章目录 系列文章目录课程地址YT一、jenkins服务器的初始化配置1.1 运行第一个jenkins pipeline二、编写本地dbt项目2.1 克隆git上的初始文件到本地2.2 本地创建虚拟环境2.3 创建airflow的Dockerfile2.4 安装dbt2.5 创建dbt所需要的snowflake数据库2.6 配置docke…

Android开发视频预览效果

Android开发视频预览效果 视频播放不是一个简单的事情&#xff0c;得有暂停&#xff0c;继续播放等功能&#xff0c;屏幕的适配也是头疼的事情 一、思路&#xff1a; 引用的是腾讯播放器TXVodPlayer 二、效果图&#xff1a; 图片不是很直观&#xff0c;也可以看下视频 And…

渗透测试 之 域渗透手法【域内用户枚举】手法 Kerbrute msf pyKerbrute 工具使用详解

说明一下: 域内用户枚举工具使用说说&#xff1a; Kerbrute pyKerbrute MSF模块的使用 域内用户名枚举原理分析&#xff1a; 域内用户枚举攻击防御&#xff1a; 流量检测&#xff1a; 日志层面&#xff1a; 说明一下: 域环境或者内网环境下&#xff0c;可以在没有域环…

npm ERR! PhantomJS not found on PATH

安装phantomj时发生报错 old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js. npm ERR! code 1 npm ERR! path /va…

四、Spring Boot集成Spring Security之认证流程

Spring Boot集成Spring Security之认证流程 一、概要说明二、基于内存的用户名密码1、默认用户名密码2、自定义用户名密码3、为方便测试添加测试接口TestController 三、登录登出重要概念介绍四、登录业务逻辑1、登录业务相关过滤器2、访问业务请求处理流程①、访问业务请求地址…

kubernetes中微服务部署

微服务 问&#xff1a;用控制器来完成集群的工作负载&#xff0c;那么应用如何暴漏出去&#xff1f; 答&#xff1a;需要通过微服务暴漏出去后才能被访问 Service 是一组提供相同服务的Pod对外开放的接口借助Service&#xff0c;应用可以实现服务发现和负载均衡Service 默认只…

初学Qt之环境安装与 hello word

环境&#xff1a; Qt Creator 4.11.0 (Community) Qt 5.14.0 目录 1.Qt环境配置 1.1 下载Qt 5.14.0 1.2 注册Qt账号 1.3 安装Qt 1.4 配置环境变量 2.创建项目 2.1 创建一个项目 2.2 初始代码解析 2.3 可视化GUI ​编辑 2.4 hello word 2.4.1 可视化hello word …

链式二叉树及二叉树各种接口的实现(C)

二叉树的性质 若规定根节点的层数为1&#xff0c;则一棵非空二叉树的第 i i i层上最多有 2 i − 1 2^{i-1} 2i−1个结点.若规定根节点的层数为1&#xff0c;则深度为h的二叉树的最大结点数是 2 h − 1 2^{h}-1 2h−1对任何一棵二叉树&#xff0c;如果度为0其叶结点个数为 n 0 …