嵌入式流媒体SRT协议:send buffer和窗口延迟机制

Handshake Packets:

握手控制包(“包类型”位 = 1)用于在点对点的 SRT 会话中建立两个对等体之间的连接。早期版本的 SRT 依赖于握手扩展来在连接建立后立即交换某些参数,但自 1.3 版本起,集成机制确保所有参数作为握手的一部分进行交换。有关详细信息,请参阅本文档后面的握手部分。

1db76d738cbe3751a5ded0ab12476c15.png13670d541aa7b7ce932de28d589cf498.png

KM Error Response Packets(key message 错误响应包):

密钥消息错误响应控制包(“包类型”位 = 1)用于在对等体之间交换错误状态消息。有关详细信息,请参阅本文档后面的加密部分 。

8163b7efc2d010b852264dd208c299d8.png

ACK Packets:

确认(ACK)控制包(“包类型”位 = 1)用于提供数据包传输状态和往返时间(RTT)信息。有关详细信息,请参阅本文档后面的 SRT 数据传输和控制部分。

6f29a4fe46733da74c1d5bc1393ab28a.png

Keep-alive Packets:

保持连接(Keep-alive)控制包(“包类型”位 = 1)大约每 10 毫秒交换一次,以便在连接丢失后自动恢复 SRT 流  。

936ebe0877e3f373f9ae732f84fb96df.png

NAK Control Packets:

负确认(NAK)控制包(“包类型”位 = 1)用于表示数据包传输失败。有关详细信息,请参阅本文档后面的 SRT 数据传输和控制部分。

4223d87ddd38a4d2919ea5510c0eb44f.png

SHUTDOWN Control Packets:

关闭(Shutdown)控制包(“包类型”位 = 1)用于启动 SRT 连接的关闭过程:

000be62a699d557c14c64a822919b93a.png

ACKACK Control Packets:

ACKACK 控制包(“包类型”位 = 1)用于确认接收到 ACK,并在持续计算往返时间(RTT)中起重要作用。有关详细信息,请参阅本文档后面的 SRT 数据传输和控制部分:

f6a6bafcbd82bf0b8387e9e3266df22f.png

Extended Control Message Packets:

扩展控制消息包(“包类型”位 = 1)是从原始 UDT 用户控制包重新用途的。它们用于 SRT 扩展握手,可以通过单独的消息或在握手内部实现。请注意,这些包不用于用户扩展 :

fef2dc06e9efb29af8df51603cae1bed.png

SRT Data Exchange :

下图提供了在点对点 SRT 会话中两个对等体之间数据交换(包括控制数据)的高级概览。请注意,在会话过程中,对等体的角色会发生变化。例如,对等体在握手期间可能以呼叫者和监听者的身份开始,但在数据传输部分会变成发送者和接收者。

139752440638366957a4d650e3347984.png

SRT Data Transmission and Control:

本节描述了在音视频直播过程中处理控制包和数据包的关键概念。

Buffers:

当一个应用程序(例如编码器)向 SRT 提供数据包进行传输时,这些数据包会被存储在一个循环发送缓冲区中。所有数据包都会分配一个序列 ID。数据包会一直保留在缓冲区中,直到它们被确认,以防需要重传。每个数据包都有一个基于连接时间的时间戳(在握手期间确定,在第一个数据包发送之前)。

这里解释一下, 基于连接时间的时间戳”指的是在 SRT 连接建立时(即在握手过程完成后)确定的一个参考时间点。这个参考时间点通常是连接成功建立的时间,也可以理解为连接的起始时间。此后,所有传输的数据包都会以这个参考时间点为基础,生成一个相对时间戳。具体来说,这个时间戳表示的是数据包相对于连接建立时间的发送时间。例如,如果连接在某个时刻 T0 建立,而某个数据包在 T0 + 100ms 发送,那么这个数据包的时间戳就会标记为相对于 T0 的 100ms。 使用这种基于连接时间的时间戳有助于接收方按照正确的时间顺序处理数据包,特别是在直播流媒体传输中,这样可以更好地管理数据包的重组和播放时间,即使在发生网络抖动或延迟的情况下,也能保持流的连贯性和同步性。

StartTime 是指应用程序创建 SRT 套接字的时间。时间戳是指从 StartTime 到数据包被添加到发送缓冲区之间的时间。

11332c1d09610fbdaffaca742f6254f3.png

注意:这里的时间从左到右显示,最新的数据包位于最右侧。

接收方有一个对应的缓冲区。数据包会在该队列中保留,直到最旧的数据包被输出为止。当配置的延迟与数据包2对齐时,数据包1会被传递给应用程序。

5a253c71e17c361327933a237a6dabfa.png

时间戳是相对于连接的。传输不是基于绝对时间进行的。计划的执行时间基于实际的时钟时间。系统维护一个时间基准,用于将每个数据包的时间戳转换为本地时钟时间。数据包的时间戳是相对于发送方的 StartTime 的。任何基于本地 StartTime 的时间参考都会被维护,并考虑往返时间 (RTT)、时区以及由纳秒截断和其他测量所引起的漂移 。

Send Buffer Management:

发送队列(SndQ,send queue)是一个动态大小的列表,包含了指向发送方缓冲区内容的引用。当发送缓冲区有数据要发送时,会将该引用添加到 SndQ 中。SndQ 对于共享同一通道(UDP 套接字)的多个缓冲区来说是通用的。( 这就是复用器:多个 SRT 套接字共享同一个 UDP 套接字 )。

下面的图表展示了一个与 SRT 套接字(CUDT)关联的发送缓冲区。SndQ 中的条目包含对套接字、时间戳以及位置索引的引用,其中位置索引是该条目在 SndQ 中的位置。这个引用对象是 SndQ 对象的一部分。

3cf8feda7e1adc100081d5f197613c2e.png

发送队列(SndQ)是一个双向链表,其中的每个条目指向发送缓冲区的发送节点(CSnode)。CSnode 是 SndQ 类的一个对象(SndQ 是一个队列,但该类中还有其他成员)。CSnode与缓冲区的内容无关。它包含一个指向其套接字的指针、一个时间戳以及一个位置(即它在 SndQ 中被插入的位置)。

SndQ 有一个发送线程,用于检查是否有数据包需要发送。基于条目中包含的数据,线程决定哪个套接字有准备好发送的数据包。它会检查时间戳引用,查看数据包是否确实已准备好发送。如果没有准备好,它会将其保留在列表中。如果已准备好,线程会将其从列表中移除。

每次发送线程发送一个数据包时,它会将该数据包重新插入列表中。然后,它请求发送缓冲区中的下一个数据包。该数据包的时间戳决定了它在 SndQ 中重新插入的位置,SndQ 按时间戳顺序排序。

控制包直接发送,它们不会经过发送缓冲区或 SndQ。SndQ 会更新用于跟踪数据包添加位置(ACKPOS)和最后确认位置(LASTPOS)的变量。

简单总结:

  • CUDT:CUDT 代表的是 UDT(UDP-based Data Transfer Protocol)对象。UDT 是一种基于 UDP 的可靠数据传输协议,常用于高带宽、长延迟网络中的数据传输。CUDT 是该协议的一个实例,它通过封装 UDP 以提供可靠的传输服务。CUDT 维护了整个发送过程中的状态和控制信息。

  • Send Buffer:这是 CUDT 实例中的发送缓冲区。它存储了即将被发送的数据包,等待发送线程(Send Thread)将数据放入发送队列(SndQ)中。缓冲区的作用是确保数据在发送时有序并且不会丢失。

  • CSnode:这是 CUDT 结构中的一个子结构,代表了一个与发送操作相关的节点。该节点可能保存了关于某次发送操作的具体信息,便于数据的管理和状态跟踪。

  • SndQ:这是发送队列,图中显示了该队列的内容。发送线程会将数据从 Send Buffer 中取出,依次放入 SndQ 中,等待进一步发送。SndQ 可能用来维护多个不同的数据块的顺序,确保数据能够按照正确的次序发送。

  • Send Thread:这是一个线程,负责处理数据的发送工作。它从 CUDT 的 Send Buffer 中读取数据,并将其放入 SndQ 中,然后通过网络接口将数据发送出去。这个线程负责确保发送过程中的可靠性和效率。

整体流程:

  • 1、数据首先进入 Send Buffer,由 CUDT 维护。

  • 2、Send Thread 从 Send Buffer 中提取数据,并将其传递到 SndQ。

  • 3、最后,数据在 SndQ 中按顺序排队,准备通过网络发送出去。

此图的重点是展示了 CUDT 结构中发送数据的流程,Send Buffer 和 SndQ 之间通过线程的调度将数据有序传输。

SRT Buffer Latenc(SRT缓冲延迟):

发送端和接收端在SRT代码中定义了大缓冲区(这些缓冲区未公开)。在发送端,延迟是指SRT为了在维持接收端发送速率的同时,给数据包提供成功传输的机会而将其保留的时间。延迟对发送端的影响较小,因为它主要是在ACK(确认消息)丢失或延迟的情况下用于丢弃数据包的。而在接收端,延迟的影响更加明显。

延迟(Latency)是以毫秒为单位的一个值。在高比特率的情况下,这个延迟值可能覆盖数百甚至数千个数据包。可以将延迟看作一个随着时间推移而滑动的窗口,在这个窗口内会发生一系列的活动。

例如,在下图中,数据包 #2 是最早发送的,它位于接收端队列的最前面(数据包 #1 已经被成功传递出去)。

0584f5adfc3a9fa8efb16f4f25148549.png

延迟的“窗口”会沿着队列从左向右滑动。当数据包 #2 从这个窗口滑出时,它会被传递给接收端的应用程序(例如解码器)。

设想一个接收缓冲区,它存储着一系列数据包。假设我们定义的延迟覆盖相当于传输六个数据包的时间。这种延迟可以看作是一个长度为六个数据包的窗口,随着时间的推移而滑动。

在该延迟窗口内恢复数据包的能力取决于传输之间的时间间隔。延迟窗口实际上定义了哪些数据包是可恢复的,或者基于往返时延(RTT),一个数据包可以恢复的次数  。

b6f5c5e6296803cdb838481a43f05eeb.png

在适当的时刻,接收端的缓冲区会将第一个数据包释放给输出应用程序。当延迟窗口滑动到覆盖下一个数据包的时间间隔时,接收端的缓冲区会将第二个数据包释放给应用程序,依此类推。

现在我们来看一下当一个数据包未被接收到时会发生什么(在这个例子中是数据包 #4)。随着延迟窗口的滑动,该数据包本应准备好交给应用程序,但却不可用。这就导致了一个数据包被跳过。这个数据包无法被恢复,因此它会从丢失列表中移除,并且不会再被请求重传。

83a92df889c2f5310b8ab14566e4f584.png

滑动的延迟窗口可以看作是一个SRT接收端能够恢复(大部分)数据包的区域。

在发送端,发送缓冲区也有一个延迟窗口。随着时间的推移,超出延迟窗口的最早的数据包将不再可恢复——即使这些数据包被发送出去,它们也会因为到达时间过晚而无法被接收端成功处理。

如果滑动的延迟窗口已经越过了尚未发送(接收未被确认)的数据包,那么再发送这些数据包就为时已晚。它们会在接收端的传输窗口之外——即使它们此时到达,也会被丢弃。因此,这些数据包可以从发送缓冲区中移除。

发送端和接收端的延迟值必须相同,以协调数据包的及时到达(或丢弃)。在早期版本的SRT中,发送端会在握手过程中向接收端提议一个延迟值。如果接收端配置的延迟值更大,它会将该值放入一个数据包并发送回响应。在SRT 1.3.x版本中,握手时双方可以同时配置延迟值(无需响应步骤)。

当延迟窗口随时间滑动时,从发送端的延迟窗口中滑出的数据包是那些已经发送但从未被确认的数据包。这些数据包曾在发送端的延迟窗口内,但ACKPOS(确认位置)并未前移(ACKPOS指向最后一个被确认接收的数据包之后的下一个数据包)。当延迟窗口前移,最早的数据包滑出窗口时,它们可以被移除。对发送队列(SndQ)的清理会人为地将ACKPOS移动到延迟窗口内的下一个数据包。

发送缓冲区中的所有数据包都有预留位置,并配置了一个长度(7个188字节的单元加上开销 = 1316字节,加上一个头部)。实际上有许多发送缓冲区,每个缓冲区都按顺序包含连续的数据包。发送缓冲区是一个循环队列,起点和终点可以在任何给定点,但它们永远不会相遇。协议通过ACK来保持顺序。在传输过程中,数据包中的序列号可以远高于实际的缓冲区位置。发送端的缓冲区按位置工作。缓冲区中的一个项目有一个起始位置(STARTPOS)。发送缓冲区中的位置与序列号之间存在转换关系,随着两者增加而变化。

最常见的以太网MTU(最大传输单元)是1500。为VLAN(虚拟局域网)分配4个字节后,剩下1496字节。一个MPEG单元等于188字节,考虑到协议头的情况下,7个TS(传输流)单元是能装入1500字节的最大数量(1316字节的数据加上头部等于1360字节)。请注意,SRT(安全可靠传输)发送器的UDP输出数据包大小(MTU)可以通过API使用SRTO_MSS(最大段大小)来设置,其中包括28+16位的IP/UDP/SRT头部。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Python使用YOLOv5图像识别教程包成功-以识别桥墩缺陷详细步骤分享

前置环境资源下载 提示:要开外网才能下载的环境我都放在了网盘里,教程中用到的环境可从这里一并下载: https://pan.quark.cn/s/f0c36aa1ef60 1. 下载YOLOv5源码 官方地址:GitHub - ultralytics/yolov5: YOLOv5 🚀 …

9。maven必备小技巧

(1)配置Maven加速时,除了settings之外,还可如下图所示,配置如下: 若想实现Maven加速,最重要的即User settings file。(先修改settings.xml) (2)当…

哪个牌子的头戴式耳机性价比高?四大爆款性价比品牌推荐!

随着科技的不断进步和发展,头戴式耳机已经成为音乐爱好者和专业人士不可或缺的设备。进入2024年,市场上涌现出了一批性能卓越、音质优秀的新产品。这些新品不仅在音质上有了显著的提升,还在设计、舒适度和功能性上进行了全面的优化&#xff0…

(科普篇)公司防止泄密,应该做到哪些?教你10个方法有效阻止泄密事件发生!

公司防止泄密,应该做到哪些? 世事如棋局局新,信息之海波涛汹涌! 甲曰:"企业之基,在于保密。泄密之祸,猛于虎也,如何防患于未然。吾友,可有良策?" …

lettuce引起的Redis command timeout异常

项目使用Lettuce,在自己的环境下跑是没有问题的。在给客户做售前压测时,因为客户端环境比较恶劣,service服务和中间件服务不在同一机房。服务启动后不一会就会出现Redis command timeout异常。 经过差不多两周的追查,最后没办法把…

机器学习的应用领域

机器学习在许多领域有广泛的应用,下面列出了一些主要的应用领域及其典型应用: 1. 图像识别 人脸识别:用于解锁手机、自动标记照片、监控安全系统。物体识别:应用于自动驾驶汽车、机器人、医疗影像分析中,帮助机器理解…

三分钟 ChatGPT 接入钉钉机器人

前言 ChatGPT 大家应该都已经用了一段时间了,功能非常强大,作为开发人员,我用它写文档、写日报、润色 OKR,知识搜索等等,它给我带来了极大的帮助,但我在使用过程中最大的痛点就是网络。 痛点 由于国内不…

Java_Se--方法

方法就是一个代码片段. 类似于 C 语言中的 "函数"。方法存在的意义(不要背, 重在体会): 1. 是能够模块化的组织代码 ( 当代码规模比较复杂的时候 ). 2. 做到代码被重复使用 , 一份代码可以在多个位置使用 . 3. 让代码更好理解更简单 . 4. 直接调用现有方法开…

搭建WSL2+Ubuntu22.04 LTS环境

一、BIOS 开启虚拟化支持 现在的主板一般都默认开启的,也可以检查和开启BIOS虚拟化支持 二、windows开启子系统及虚拟化 打开控制面板 选择 程序 -> 启用或关闭 Windows功能 勾选 Hyper-V、适用于 Linux的 Windows子系统和虚拟机平台 点击确定 重启计算…

【近源攻击】badusb上线cs

❤️博客主页: iknow181 🔥系列专栏: 网络安全、 Python、JavaSE、JavaWeb、CCNP 🎉欢迎大家点赞👍收藏⭐评论✍ 0x01 实验前提 攻击设备:badusb cs服务器:公网部署了 cs 服务端 0x02 实验步骤 …

【计算机网络】理解应用层协议HTTP

目录 HTTP协议认识URLHTTP协议的请求如果我们想获得请求报文的完整内容,怎么办? HTTP协议的响应HTTP的方法GETvsPOST HTTP的状态码HTTP常见HeaderHTTP版本实现一个简单的HTTP服务器 HTTP协议 HTTP协议是一种超文本传输协议,它定义了客户端与…

Kafka 3.0.0集群部署教程

1、集群规划 主机名 ip地址 node.id process.roles kafka1 192.168.0.29 1 broker,controller Kafka2 192.168.0.30 2 broker,controller Kafka3 192.168.0.31 3 broker,controller 将kafka包上传以上节点/app目录下 mkdir /app 解压kafka包 tar -zxvf kafka_…

java之斗地主部分功能的实现

今天我们要实现斗地主中发牌和洗牌这两个功能,该如何去实现呢? 1.创建牌类:52张牌每一张牌包含两个属性:牌的大小和牌的花色。 故我们优先创建一个牌的类(Card):包含大小和花色。 public class Card { //单张牌的大小及类型/…

伊犁-linux 硬盘添加,分区,格式化

主要是linux 下操作硬盘分区,格式化 这样1个sata 盘就添加成功了 !  继续添加三块 sata1 hda sata hdb sata hdc sata hdd scsi sda 作为启动盘 进行操作系统的引导 如果scsi 往下调整 先敲enter 在用- 号往下 如果是往上调整敲…

【IDEA】使用IDEA连接MySQL数据库并自动生成MySQL的建表SQL语句

前言: 在软件开发过程中,数据库的设计与实现是至关重要的一环。IntelliJ IDEA作为一款强大的集成开发环境(IDE),提供了丰富的数据库工具,使得连接MySQL数据库并自动生成建表SQL语句变得简单快捷。本文将详细…

《python语言程序设计》2018版第8章18题几何circle2D类(上部)

一、利用第7章的内容来做前5个点 第一章之1--从各种角度来测量第一章之2--各种结果第二章之1--建立了针对比对点在圆内的几段第二章之2--利用建立的对比代码,得出的第2点位置 第一章之1–从各种角度来测量 class Circle2D:def __init__(self, x, y, radius):self._…

Stable Diffusion绘画 | ControlNet应用-qrcode 二维码控制器:艺术二维码来啦

qrcode 二维码控制器,是一款专用于生成艺术二维码的控制器, 需要单独下载,下载后,将文件放置在:SD安装目录\extensions\sd-webui-controlnet\models 实操 开启第一个 ControlNet,上传一个二维码图片&…

【24华为杯数模研赛赛题思路已出】国赛E题第二套思路丨附参考代码丨免费分享

2024年数模研赛E题解题思路 在高速公路建设中,通常会设置应急车道,以便应对救援和医疗需求。应急车道一般不允许占用,但在某些情况下,如监测到某路段即将拥堵且没有事故时,合理使用应急车道可以帮助降低车流密度&…

对不起,放弃了wiki.js转向了obsidian

wifi.js可以满足我的以下要求: 支持文档在线编辑支持浏览器编辑支持二进制文件上传和下载支持历史记录和回滚支持用户账号分权支持数据和nas同步支持markdown的预览模式 但是wiki.js不能满足如下: markdown编辑无法做到图片复制粘贴无法查看pdf无法独立于文档上传…

影刀RPA实战:网页爬虫之药品数据

1 实战目标 这次给大家带来的实战示例是采集中国医药信息平台上的药品数据,主要获取药品名称,介绍,药品类型,处方类型,医保类型,参考价格,药品成分,性状,适应病症&#…