从零开始精通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协议,我们可以更好地掌握实时流媒体技术,并开发出更加稳定、高效的实时通信和流媒体应用。

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

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

相关文章

【计算机毕业设计】大学校园图书角管理系统——后附源码

🎉**欢迎来到我的技术世界!**🎉 📘 博主小档案: 一名来自世界500强的资深程序媛,毕业于国内知名985高校。 🔧 技术专长: 在深度学习任务中展现出卓越的能力,包括但不限于…

【Flutter】One or more plugins require a higher Android SDK version.

问题描述 项目里多个组件需要更高版本的Android SDK One or more plugins require a higher Android SDK version.解决方案: 报错提示requires Android SDK version 34 按提示修改android项目app里build.gradle的compileSdkVersion 为34 android {compileSdkVe…

Spring 数据脱敏实现方式

1、前言 当前互联网中,越来越重视数据安全,数据脱敏在实际应用中越来越多。 2 、脱敏方式 2.1 数据库sql 语句脱敏 sql 语句脱敏是比较传统通用的,例子如下所示: select CONCAT(LETF(mobile,3),"*****",RIGHT(mobile,…

node.js-包

包的概念 包:将模块,代码,其他资料聚合成的一个文件夹 包分类: 1.项目包:主要用于编写项目和业务逻辑的文件夹 2.软件包:封装工具和方法供开发者使用(一般使用npm管理) 1&#…

证明:每次循环执行i = (i-1)s可以枚举s表示集合的所有子集i

状态压缩:使用二进制数表示一个集合的情况,第i位为1表示第i元素在集合中,为0表示不在集合中。 已知i表示的集合是s表示的集合的子集,枚举s的所有子集i可以写为 for(int i s; i ! 0; i (i-1)&s){}证明:每次循环执…

SpringBoot之JdbcTemplate输出完整SQL日志

applicatio.yml开启日志功能 jdbc-log:# 开启完整SQL日志输出功能enabled: truelogging:level:# 切面类路径,日志级别为DEBUG,因为SpringBoot默认日志级别为INFOcom.xxx.xxx.JdbcTemplateAspect: DEBUG日志切面 import lombok.extern.slf4j.Slf4j; imp…

mysql的DDL语言和DML语言

DDL语言: 操作数据库,表等(创建,删除,修改); 操作数据库 1:查询 show databases 2:创建 创建数据库 create database 数据库名称 创建数据库,如果不存在就创建 crea…

造成并发安全的三大源头:可见性、原子性、有序性

缓存导致的可见性问题 一个线程对共享变量的修改,另外一个线程能够立刻看到,我们称为 可见性 如果是单核cpu,cpu之间的线程共享一个缓存,这个时候不会出现缓存与内存数据一致性的问题,同样的线程之间具备可见性 如果…

MySQL—一条查询SQL语句的完整执行流程

MySQL—一条查询SQL语句的完整执行流程 表结构和数据如下: 我们分析的sql语句如下: select tb_id,tb_name,tb_address from tb_user where tb_id 66;大体来说,MySQL可以分为Server层和存储引擎层两部分: Server层 包括:连接器、查询缓存、…

使用Java实现动态心形图案

一、引言 在计算机图形学中,动态图案的生成和显示一直是一个令人兴奋的话题。心形图案作为情感表达的一种常见方式,在编程领域也颇受欢迎。本文将介绍如何使用Java编程语言实现动态心形图案,并附上相应的代码片段。 二、心形曲线的数学表达…

如何使用 ArcGIS Pro 快速为黑白地图配色

对于某些拍摄时间比较久远的地图,限于当时的技术水平只有黑白的地图,针对这种情况,我们可以通过现在的地图为该地图进行配色,这里为大家讲解一下操作方法,希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微…

dubbo3-01.helloworld

项目结构 - dubbo-examples- consumer-service- provider-interface- provider-servicepom 文件 dubbo-examples 的 pom.xml <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <arti…

使用大卫的k8s监控面板(k8s+prometheus+grafana)

问题 书接上回&#xff0c;对EKS&#xff08;AWS云k8s&#xff09;启用AMP&#xff08;AWS云Prometheus&#xff09;监控AMG(AWS云 grafana)&#xff0c;上次我们只是配通了EKSAMPAMG的监控路径。这次使用一位大卫老师的grafana的面板&#xff0c;具体地址如下&#xff1a; ht…

Cargo 使用教程

什么是 Cargo&#xff1f; Cargo 是 Rust 的构建系统和包管理器&#xff0c;它提供了创建项目、编译代码、管理依赖和发布包等功能。使用 Cargo&#xff0c;你可以轻松地构建 Rust 程序&#xff0c;而不必深入了解底层的构建细节。 安装 Cargo 在开始之前&#xff0c;确保你…

汽车IVI中控开发入门及进阶(十五):AUTOSAR

前言: 随着汽车四化的进行,汽车电子系统standard标准化和coperation互操作性变得重要, AUTOSAR(AUTomotive Open System Architecture 汽车开放系统架构)框架已成为汽车行业的基础支柱。 AUTOSAR始自2000年,当时认识到标准化是有必要

Redis入门到通关之Redis数据结构-Set篇

文章目录 ☃️概述☃️数据结构☃️源码☃️其他 &#x1f308; 欢迎莅临我的个人主页&#x1f448;这里是我静心耕耘深度学习领域、真诚分享知识与智慧的小天地&#xff01;&#x1f387; &#x1f393; 博主简介&#xff1a; 我是请回答1024&#xff0c;一名Java领域深耕多年…

深入了解 Spring Boot 的加载过程

Spring Boot 的加载过程可以大致分为以下几个阶段&#xff1a; 类加载&#xff1a;首先&#xff0c;Java 虚拟机会加载必要的类&#xff0c;包括 Spring Boot 的核心类和应用程序的相关类。配置解析&#xff1a;Spring Boot 会解析各种配置&#xff0c;如 application.properti…

解读币安Megadrop:如何参加第一期BounceBit活动?

币安推出新的代币发行平台 Megadrop&#xff0c;第一期为 BounceBit。 跟 launchpool 相比&#xff0c; 主要不同是 1&#xff09;锁仓 bnb 有收益的倍数加成 2&#xff09;做任务有收益加成。 我认为核心目的有两个&#xff1a; 1&#xff09;更多收益给 BNB 长期持有者&am…

数仓建模—数据模型

数仓建模—数据模型 前面我们讲了什么是数据仓库,以及数据仓库的发展历史,从这里开始我们讲解数仓建模,在开始之前我们先了解一下什么是数据模型,以及常见的数据模型都有哪些 什么是数据模型 在详细探讨数据模型之前,我们需要明确什么是数据。从本质上讲,数据由收集、…

【运维】docker-compose部署mysql5.7、mysql 8,单节点,双主

一、docker-composemysql 5.7 单机版mysql 5.7 ## docker-compose config ## 检查当前目录docker-compose.yml文件配置是否正确 ## docker-compose up -d ## -d 为后台启动 ## docker-compose up -d --force-rereate ## 强制重新创建容器…