从零开始精通RTSP之深入理解RTCP协议

2024-04-23 08:04

本文主要是介绍从零开始精通RTSP之深入理解RTCP协议,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

概述

        RTCP,即实时控制协议,英文全称为RTP Control Protocol,是RTP的配套协议。与RTP不同,RTCP本身不传输实时数据,而是用于提供有关RTP会话的统计信息和控制功能。RTCP的主要目标是提供数据传输质量的反馈,帮助参与者了解会话状态,并实现会话中的松散控制。

工作机制

        RTCP在RTP会话中以较低的速率定期发送数据包,通常是RTP数据速率的5%至10%。这种低速率传输是为了减少对网络带宽的占用,同时仍然能够提供有效的反馈和控制信息。在多点传输环境中,所有参与方都会定期发送和接收RTCP报文,形成双向的信息交换机制。

        RTCP的一个重要功能是:计算RTP会话的参与者数量。通过RTCP数据包中的信息,每个参与者都能够了解当前会话中的其他参与者数量,从而动态地调整RTCP数据包的发送速率,确保反馈信息的有效性。RTCP还用于估算RTP数据流的往返时间(RTT),这对于拥塞控制和同步至关重要。通过测量RTCP数据包的往返时间,发送者可以调整其发送速率,以避免网络拥塞并保持流畅的传输。

        RTCP与RTP是相辅相成的协议,RTP负责实时数据的传输,而RTCP则提供关于RTP会话的反馈和控制信息。RTCP数据包中的统计信息和控制消息有助于RTP发送者优化其传输策略,比如:通过调整发送速率、改变编码方式等来提高传输质量。同时,RTCP还提供了会话管理的功能,比如:通过BYE消息来优雅地关闭RTP会话。这种协同工作使得RTP和RTCP成为实时流媒体传输中不可或缺的协议组合。

报文格式

        RTCP报文具有统一的二进制格式,用于在实时流媒体传输中提供服务质量监控、反馈控制和同步协调等功能。一般而言,一个RTCP报文包含一个固定的报文头和一个或多个分组。

        报文头是所有RTCP报文共有的部分,它位于报文的起始位置,包含了基本信息以便识别和解析后续的报文内容。RTCP报文头的字段如下。

        Version (V): 占2位,固定为2,表示当前使用的RTCP版本为版本2。

        Padding (P): 占1位,若值为1,表明报文尾部包含填充字节,以确保报文长度为32位的整数倍。填充字节的个数存储在报文最后一个有效字节的最低4位。

        Reception Report Count (RC): 占5位,表示紧跟在报文头后的接收报告块(Reception Report Block)的数量。此字段仅在RR(Receiver Report)报文中有效,其他类型的RTCP报文可能没有接收报告块。

        Packet Type (PT): 占8位,标识RTCP报文的类型。常见的PT值包括:

          200: Sender Report (SR)

          201: Receiver Report (RR)

          202: Source Description (SDES)

          203: Goodbye

          204: Application-Defined (APP)

        Length: 占16位,表示报文长度(不包括报文头),以32位字(4字节)为单位。因此,整个报文(包括报文头)的总长度为4 × (Length + 1)个字节。

        RTCP报文的实际内容由一个或多个RTCP分组组成,每个RTCP分组通常包含以下字段。

        类型(Type):指明该分组的类型,与报文头部的分组类型字段相对应。

        长度(Length):表示该分组的长度,通常以32位字为单位,但某些情况下可能以字节为单位,具体取决于分组类型。

        数据(Data):包含分组的具体数据,其格式和内容根据分组类型而定。

SSRC和CSRC列表

        在RTCP报文中,SSRC、CSRC列表通常出现在每个RTCP分组的开始部分,用于标识该分组所属的RTP流。接收端可以根据SSRC来区分不同的流,并进行相应的处理。在RTCP分组中,SSRC和CSRC列表是重要的组成部分,尤其在SR(发送者报告)和RR(接收者报告)等类型的RTCP分组中。

        SSRC

        SSRC,即同步源标识符,是一个32位的标识符,用于唯一标识RTP流的来源。在同一个RTP会话中,每个同步源都必须有一个唯一的SSRC。这个标识符是随机选择的,通常使用MD5随机算法来生成,以确保其全局唯一性。

        CSRC列表

        CSRC,即贡献源标识符,也是一个32位的标识符,用于标识对一个RTP混合器产生的新包有贡献的所有RTP包的源。当多个RTP流通过一个混合器合并成一个新的RTP流时,混合器会将每个原始流的SSRC添加到CSRC列表中,并生成一个新的SSRC来标识合并后的流。在多点传输(比如:混音会议)中,RTP包可能包含CSRC列表,记录参与混合的同步源。接收端据此识别混合源的身份,实现多路媒体流的正确解码和显示。CSRC列表跟随在SSRC之后,是一个可变长度的列表,包含了所有对该RTP流有贡献的源的SSRC。这种设计使得RTCP能够准确地追踪和报告多媒体会话中的多个源,尤其是在存在混合器或其他流媒体处理设备的复杂网络环境中。

常见报文类型

        RTCP数据包有几种不同的类型,每种类型都有其特定的用途,常见的RTCP报文类型如下。

        Sender Report (SR) (PT = 200)

        发送者报告报文,由活动的RTP发送者定期发送,提供了关于该发送者所发送数据的统计信息,比如:发送的RTP数据包数量、累积的RTP时间戳、以及发送数据所用的时间间隔等。SR报文还包含了多个接收者报告块(Reception Report Block),每个块描述了发送者接收到其他参与者数据的接收质量情况。

        SR报文的Payload部分包含了一系列关于发送者自身RTP数据传输的统计信息,以及针对其他接收者的接收质量报告,具体结构如下。

        1、NTP Timestamp (Network Time Protocol timestamp): 64位字段,表示发送SR报文时的绝对时间(以NTP时间表示)。这个时间戳通常用于精确的时间同步,使得所有参与方能够对RTP时间戳有一个共同的理解。

        2、RTP Timestamp: 32位字段,与发送者最近发送的RTP数据包的时间戳相对应。这个字段用于RTP流内部的时间同步,确保媒体数据的正确播放顺序和同步。

        3、Sender's Packet Count: 32位字段,表示发送者自会话开始以来发送的RTP数据包总数。这个数值用于计算发送速率、丢包率等统计信息。

        4、Sender's Octet Count: 32位字段,表示发送者自会话开始以来发送的RTP数据总字节数。该值有助于计算平均带宽使用情况。

        5、Reception Report Blocks (RRBs): 一系列接收报告块,每个块描述了发送者对接收到的某个特定同步源(SSRC)数据的接收质量统计。每个RRB包含以下字段:

        SSRC of source: 32位,标识该报告块所描述的源的SSRC。

        Fraction Lost: 8位,以1/256的比例表示从上一次发送SR或RR以来丢包的比例。

        Cumulative Number of Packets Lost: 24位,自上次SR或RR以来累计丢失的数据包数量(不包括本次报告期间新丢失的包)。

        Extended Highest Sequence Number Received: 32位,接收到的最大序列号,包括高位扩展位,用于检测并纠正序列号回绕。

        Interarrival Jitter: 32位,表示接收到的数据包间隔的抖动,用于评估网络延迟变化情况。

        Last SR (LSR) Timestamp: 32位,接收者最近一次收到的SR报文的RTP时间戳。

        Delay Since Last SR (DLSR) Interval: 32位,从接收者收到最近一个SR报文到发送此RR报文的时间间隔(以秒为单位,精度为1/65536秒)。

        Receiver Report (RR) (PT = 201)

        接收者报告报文,由非活动发送者(即仅接收RTP数据但不发送数据的参与者)或者作为对SR报文响应的一部分发送。RR报文包含一系列接收者报告块,每个块描述了发送者对某个特定同步源(SSRC)数据的接收统计,比如:接收到的数据包数量、丢包数量、最大延时、抖动等,这些信息有助于评估网络状况和调整传输参数。

        Source Description (SDES) (PT = 202)

        源描述报文,包含了一系列关于参与者的文本性元数据项,比如:用户名称、电子邮件地址、电话号码等。其中最重要的SDES项是CNAME(Canonical Name),它是一个永久且全局唯一的标识符,用于关联同一用户在不同会话或不同网络条件下的不同SSRC。

        Goodbye (PT = 203)

        BYE(有时也写作BYB)报文,用于通知所有参与者某个同步源已经离开会话。它包含了要离开的SSRC列表,使得其他参与者能够清理相关状态,并停止向这些SSRC发送数据。

        Application-specific Function (APP) (PT = 204)

        应用特定功能报文,允许在RTCP框架内扩展以支持特定应用的需求。这类报文携带应用程序定义的数据,可能用于传递特定服务质量(QoS)信息、媒体元数据或其他与会话管理相关的控制信息。

        Picture Loss Indication (PLI) 和 Full Intra Request (FIR)

        虽然不是标准的RTCP报文类型,但PLI和FIR是通过RTCP APP报文实现的两种常用的视频流控制机制。PLI用于请求发送方重新发送关键帧(I帧),通常在检测到视频失序或严重错误时发送。FIR则更具体地要求接收方发送一个完整的I帧刷新,以恢复解码器状态或改善视频质量。

        Negative Acknowledgment (NACK)

        NACK报文,同样不是标准RTCP报文类型,而是通过RTCP APP扩展实现的,用于请求重新发送丢失或损坏的RTP数据包。NACK报文中包含丢失数据包的序列号信息,使得发送方能够针对性地重传缺失的内容。

总结

        RTCP作为RTP的配套协议,在实时流媒体传输中发挥着至关重要的作用。它通过提供统计信息和控制功能,帮助RTP发送者优化传输策略、管理会话状态,并确保实时数据在复杂的网络环境中能够高效、可靠地传输。通过深入理解RTCP协议,我们可以更好地掌握实时流媒体技术,并开发出更加稳定、高效的实时通信和流媒体应用。

这篇关于从零开始精通RTSP之深入理解RTCP协议的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

一文带你深入了解Python中的GeneratorExit异常处理

《一文带你深入了解Python中的GeneratorExit异常处理》GeneratorExit是Python内置的异常,当生成器或协程被强制关闭时,Python解释器会向其发送这个异常,下面我们来看... 目录GeneratorExit:协程世界的死亡通知书什么是GeneratorExit实际中的问题案例

Qt 中集成mqtt协议的使用方法

《Qt中集成mqtt协议的使用方法》文章介绍了如何在工程中引入qmqtt库,并通过声明一个单例类来暴露订阅到的主题数据,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一,引入qmqtt 库二,使用一,引入qmqtt 库我是将整个头文件/源文件都添加到了工程中进行编译,这样 跨平台

深入解析Spring TransactionTemplate 高级用法(示例代码)

《深入解析SpringTransactionTemplate高级用法(示例代码)》TransactionTemplate是Spring框架中一个强大的工具,它允许开发者以编程方式控制事务,通过... 目录1. TransactionTemplate 的核心概念2. 核心接口和类3. TransactionT

深入理解Apache Airflow 调度器(最新推荐)

《深入理解ApacheAirflow调度器(最新推荐)》ApacheAirflow调度器是数据管道管理系统的关键组件,负责编排dag中任务的执行,通过理解调度器的角色和工作方式,正确配置调度器,并... 目录什么是Airflow 调度器?Airflow 调度器工作机制配置Airflow调度器调优及优化建议最

一文带你理解Python中import机制与importlib的妙用

《一文带你理解Python中import机制与importlib的妙用》在Python编程的世界里,import语句是开发者最常用的工具之一,它就像一把钥匙,打开了通往各种功能和库的大门,下面就跟随小... 目录一、python import机制概述1.1 import语句的基本用法1.2 模块缓存机制1.

深入理解C语言的void*

《深入理解C语言的void*》本文主要介绍了C语言的void*,包括它的任意性、编译器对void*的类型检查以及需要显式类型转换的规则,具有一定的参考价值,感兴趣的可以了解一下... 目录一、void* 的类型任意性二、编译器对 void* 的类型检查三、需要显式类型转换占用的字节四、总结一、void* 的

深入理解Redis大key的危害及解决方案

《深入理解Redis大key的危害及解决方案》本文主要介绍了深入理解Redis大key的危害及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一、背景二、什么是大key三、大key评价标准四、大key 产生的原因与场景五、大key影响与危

深入理解C++ 空类大小

《深入理解C++空类大小》本文主要介绍了C++空类大小,规定空类大小为1字节,主要是为了保证对象的唯一性和可区分性,满足数组元素地址连续的要求,下面就来了解一下... 目录1. 保证对象的唯一性和可区分性2. 满足数组元素地址连续的要求3. 与C++的对象模型和内存管理机制相适配查看类对象内存在C++中,规

Java如何接收并解析HL7协议数据

《Java如何接收并解析HL7协议数据》文章主要介绍了HL7协议及其在医疗行业中的应用,详细描述了如何配置环境、接收和解析数据,以及与前端进行交互的实现方法,文章还分享了使用7Edit工具进行调试的经... 目录一、前言二、正文1、环境配置2、数据接收:HL7Monitor3、数据解析:HL7Busines

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06