首页 > 其他分享 >RTP协议之Header结构解析(转)

RTP协议之Header结构解析(转)

时间:2023-06-05 19:23:02浏览次数:111  
标签:SSRC 比特 扩展 Header CSRC RTP 解析 size

原文:https://blog.csdn.net/yu_yuan_1314/article/details/9849581

作者:MultiMedia之旅

  实时传输协议 RTP,RTP 提供带有实时特性的端对端数据传输服务,传输的数据如:交互式的音频和视频。那些服务包括有效载荷类型定义,序列号,时间戳和传输监测控制。应用程序在 UDP 上运行 RTP 来使用它的多路技术和 checksum 服务。2 种协议都提供传输协议的部分功能。不过,RTP 可能被其他适当的下层网络和传输协议使用。如果下层网络支持,RTP 支持数据使用多播分发机制转发到多个目的地。

注意 RTP 本身没有提供任何的机制来确保实时的传输或其他的服务质量保证,而是由低层的服务来完成。它不保证传输或防止乱序传输,它不假定下层网络是否可靠,是否按顺序传送数据包。RTP 包含的序列号允许接受方重构发送方的数据包顺序,但序列号也用来确定一个数据包的正确位置,例如,在视频解码的时候不用按顺序的对数据包进行解码。

但是 RTP 原先的设计是用来满足多参与者的多媒体会议的需要,它没有限定于专门的应用。连续数据的储存,交互分布式仿真,动态标记,以及控制和测量应用程序也可能会适合使用 RTP。

1. RTP 固定头结构

RTP 固定头结构如图2所示。

图1 RTP固定头格式

前 12 个字节出现在每个 RTP 包中,仅仅在被混合器插入时,才出现 CSRC 识别符列表。各个域的含义如下所示:

(1)版本(V):2 比特,此域定义了 RTP 的版本。此协议定义的版本是 2。(值 1 被 RTP 草案版本使用,值 0 用在最初"vat"语音工具使用的协议中。)

(2)填充(P):1 比特,若填料比特被设置,则此包包含一到多个附加在末端的填充比特,填充比特不算作负载的一部分。填充的最后一个字节指明可以忽略多少个填充比特。填充可能用于某些具有固定长度的加密算法,或者用于在底层数据单元中传输多个 RTP 包。

(3)扩展(X):1 比特,若设置扩展比特,固定头(仅)后面跟随一个头扩展。

(4)CSRC 计数(CC):4 比特,CSRC 计数包含了跟在固定头后面 CSRC 识别符的数目。

(5)标志(M):marker,1 比特,标志的解释由具体协议规定。它用来允许在比特流中标记重要的事件,如帧边界。1表示帧结束,0表示未结束。

(6)负载类型(PT):payload type,7 比特,此域定义了负载的格式,由具体应用决定其解释,协议可以规定负载类型码和负载格式之间一个默认的匹配。其他的负载类型码可以通过非 RTP 方法动态定义。RTP发送端在任意给定时间发出一个单独的 RTP 负载类型;此域不用来复用不同的媒体流。

(7)序列号(sequence number):16 比特,每发送一个 RTP 数据包,序列号加 1,接收端可以据此检测丢包和重建包序列。序列号的初始值是随机的(不可预测),以使即便在源本身不加密时(有时包要通过翻译器,它会这样做),对加密算法泛知的普通文本攻击也会更加困难。

(8)时间戳(timestamp) :32 比特,时间戳反映了 RTP 数据包中第一个字节的采样时间。时钟频率依赖于负载数据格式,并在描述文件(profile)中进行描述。也可以通过 RTP 方法对负载格式动态描述。

如果 RTP 包是周期性产生的,那么将使用由采样时钟决定的名义上的采样时刻,而不是读取系统时间。例如,对一个固定速率的音频,采样时钟将在每个周期内增加 1。如果一个音频从输入设备中读取含有 160 个采样周期的块,那么对每个块,时间戳的值增加 160。时间戳的初始值应当是随机的,就像序号一样。几个连续的 RTP 包如果是同时产生的,它们的timestamp相同。如:属于同一个视频帧的 RTP 包,将有相同的timestamp。

不同媒体流的 RTP 时间戳可能以不同的速率增长。而且会有独立的随机偏移量。因此,虽然这些时间戳足以重构一个单独的流的时间,但直接比较不同的媒体流的时间戳不能进行同步。对于每一个媒体,我们把与采样时刻相关联的 RTP 时间戳与来自于参考时钟上的时间戳(NTP)相关联。因此参考时钟的时间戳就是数据的采样时间。(即:RTP 时间戳可用来实现不同媒体流的同步,NTP 时间戳解决了 RTP 时间戳有随机偏移量的问题。)参考时钟用于同步所有媒体的共同时间。这一时间戳对(RTP 时间戳和 NTP 时间戳),用于判断 RTP 时间戳和 NTP 时间戳的对应关系,以进行媒体流的同步。它们不是在每一个数据包中都被发送,而在发送速率更低的 RTCP 的 SR(发送者报告)中。

如果传输的数据是存贮好的,而不是实时采样得到的,那么会使用从参考时钟得到的虚的表示时间线(virtual presentation timeline)。以确定存贮数据中的每个媒体下一帧或下一
个单元应该呈现的时间。此种情况下 RTP 时间戳反映了每一个单元应当回放的时间。真正的回放将由接收者决定。

(9)SSRC:32 比特,用以识别同步源。标识符被随机生成,以使在同一个 RTP 会话期中没有任何两个同步源有相同的 SSRC 识别符。尽管多个源选择同一个 SSRC 识别符的概率很低,所有 RTP 实现工具都必须准备检测和解决冲突。若一个源改变本身的源传输地址,必须选择新的SSRC 识别符,以避免被当作一个环路源。

RTP 包流的源,用 RTP 报头中 32 位数值的SSRC 标识符进行标识,使其不依赖于网络地址。一个同步源的所有包构成了相同计时和序列号空间的一部分,这样接收方就可以把一个同步源的包放在一起,来进行重放。

举些同步源的例子,像来自同一信号源的包流的发送方,如麦克风、摄影机、RTP 混频器就是同步源。一个同步源可能随着时间变化而改变其数据格式,如音频编码。SSRC 标识符是一个随机选取的值,它在特定的 RTP 会话中是全局唯一(globally unique)的。参与者并不需要在一个多媒体会议的所有 RTP 会话中,使用相同的 SSRC 标识符;SSRC 标识符的绑定通过RTCP。如果参与者在一个 RTP 会话中生成了多个流,例如来自多个摄影机,则每个摄影机都必须标识成单独的同步源。

(10)CSRC 列表:0 到 15 项,每项 32 比特,CSRC 列表识别在此包中负载的所有贡献源。识别符的数目在 CC 域中给定。若有贡献源多于 15 个,仅识别 15 个。CSRC 识别符由混合器插入,并列出所有贡献源的 SSRC 识别符。例如语音包,混合产生新包的所有源的 SSRC 标识符都被列出,以在接收端处正确指示参与者。

若一个 RTP 包流的源,对由 RTP 混频器生成的组合流起了作用,则它就是一个作用源。对特定包的生成起作用的源,其 SSRC 标识符组成的列表,被混频器插入到包的 RTP 报头中。这个列表叫做 CSRC 表。相关应用的例子如,在音频会议中,混频器向所有的说话人(talker)指出,谁的话语(speech)将被组合到即将发出的包中,即便所有的包都包含在同一个(混频器的)SSRC 标识符中,也可让听者(接收者)可以清楚谁是当前说话人。

2. RTP扩展头结构

RTP 提供扩展机制以允许实现个性化:某些新的与负载格式独立的功能要求的附加信息在RTP 数据包头中传输。设计此方法可以使其它没有扩展的交互忽略此头扩展。RTP扩展头格式如图2所示。

图2 RTP扩展头格式

若 RTP 固定头中的扩展比特位置 1,则一个长度可变的头扩展部分被加到 RTP 固定头之后。头扩展包含 16 比特的长度域,指示扩展项中 32 比特字的个数,不包括 4 个字节扩展头(因此零是有效值)。RTP 固定头之后只允许有一个头扩展。为允许多个互操作实现独立生成不同的头扩展,或某种特定实现有多种不同的头扩展,扩展项的前 16 比特用以识别标识符或参数。这 16 比特的格式由具体实现的上层协议定义。基本的 RTP 说明并不定义任何头扩展本身。

3. RTP包解析

RTP包解析示例如下所示:

static int parsingRTPPacket(uint8_t *data, size_t size) {
    if (size < 12) {
        //Too short to be a valid RTP header.
        return -1;
    }
 
    if ((data[0] >> 6) != 2) {
        //Currently, the version is 2, if is not 2, unsupported.
        return -1;
    }
 
    if (data[0] & 0x20) {
        // Padding present.
        size_t paddingLength = data[size - 1];
        if (paddingLength + 12 > size) {
            return -1;
        }
        size -= paddingLength;
    }
 
    int numCSRCs = data[0] & 0x0f;
    size_t payloadOffset = 12 + 4 * numCSRCs;
 
    if (size < payloadOffset) {
        // Not enough data to fit the basic header and all the CSRC entries.
        return -1;
    }
 
    if (data[0] & 0x10) {
        // Header extension present.
        if (size < payloadOffset + 4) {
            // Not enough data to fit the basic header, all CSRC entries and the first 4 bytes of the extension header.
            return -1;
        }
 
        const uint8_t *extensionData = &data[payloadOffset];
        size_t extensionLength = 4 * (extensionData[2] << 8 | extensionData[3]);
 
        if (size < payloadOffset + 4 + extensionLength) {
            return -1;
        }
        payloadOffset += (4 + extensionLength);
    }
 
    uint32_t rtpTime = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
    uint32_t srcId = data[8] << 24 | data[9] << 16 | data[10] << 8 | data[11];
    uint32_t seqNum = data[2] << 8 | data[3];
 
    return 0;
}

 

标签:SSRC,比特,扩展,Header,CSRC,RTP,解析,size
From: https://www.cnblogs.com/ajianbeyourself/p/17458748.html

相关文章

  • python解析
    关于beautifulsoupBeautifulSoup用来从HTML或XML文件中提取数据现在最新的版本是beautifulsoup3已经停止开发,现在最新推荐使用的是beautifulsoup4安装pipinstallbeautifulsoup4beautifulsoup要用起来还需要一个解析器的东西,官网列出了主要的一些解析器除了第一个标......
  • 1.2 Java基础 数据类型(Integer源码解析)
    Java数据类型和Integer源码解析1.2.1基本数据类型1.2.2什么是拆装箱1.2.3拆装箱是如何实现的1.2.4Integer继承关系1.2.5Integer源码解析1.2.1基本数据类型       如大家所知,Java是一门面向对象的语言,但是java并非完全面向对象,Java中的数据类型分为了       ......
  • 二分查找的循环不变量全面解析
    二分查找的循环不变量全面解析原理二分查找的bug模版二分法变种寻找左侧/右侧元素的二分查找查找大于key的最小值upper查找小于key的最大值lower大于等于key的最小索引lower_ceil实践69.x的平方根215.数组中的第K个最大元素704.二分查找875.爱吃香蕉的珂珂1011.在......
  • spring中默认标签alias、import标签解析
    1、Alias标签在bean标签里边有一个alias属性和name属性,可以指定bean的别名,但是有的场景下,在定义bean的时候就把他的别名都指定好是不适用的。比如这个Bean在组件A中,想把他叫做componentA,但是在组件B中又想把他叫做componetB,所以还有一个单独的标签:<alias>专门解决上述场景的。<......
  • Jwt生成和解析工具类(万用版,可作为数据存储容器来传输)
    packagecom.ciih.authcenter.client.util.jwt;importcom.alibaba.fastjson.JSON;importcom.auth0.jwt.JWT;importcom.auth0.jwt.JWTCreator;importcom.auth0.jwt.JWTVerifier;importcom.auth0.jwt.algorithms.Algorithm;importcom.auth0.jwt.interfaces.Claim;......
  • 深度解析iOS应用程序的生命周期
     摘要:iOS应用程序一般都是由自己编写的代码和系统框架组成,系统框架提供一些基本infrastructure给App来运行,而开发者则自己编写代码定制App的外观和行为,了解iOSInfrastructure及其如何工作对编写App很有帮助。iOS应用程序一般都是由自己编写的代码和系统框架(systemframeworks)组成......
  • response.setHeader()的用法
    response.setHeader()的用法response.setHeader()下载中文文件名乱码问题收藏 1.HTTP消息头(1)通用信息头即能用于请求消息中,也能用于响应信息中,但与被传输的实体内容没有关系的信息头,如Data,Pragma主要:Cache-Control,Connection,Data,Pragma,Trailer,Transfer-E......
  • Spring MVC文件上传 文件上传解析 Spring MVC文件上传详解
    首先我要说的是springmvc的核心控制器DispachServlet,这个控制器主要是用来起调度作用,他里面默认就带了一个文件上传的视图解析器,叫multipartResolver,而这个视图解析器SpringMVC又提供了一个默认的实现,叫CommonMultipartResolver,说白了这个实现底层用的就是common-fileupload,......
  • dubbo源码学习(四)初始化过程细节:解析服务
    今天将真正去看dubbo内部的实现过程,看dubbo的源码前我先把dubbo的用户指南和开发指指南大概的看了一遍,这样再看dubbo源码比较轻松。从用户指南和开发指指南可以找到相应的切入点,今天将介绍的是dubbo的初始化解析bean的过程:解析服务基于dubbo.jar内的META......
  • python基础学习-XPath解析html
    参考地址:Python-Core-50-Courses/第33课:用Python解析HTML页面.mdatmaster·jackfrued/Python-Core-50-Courses(github.com) XPath是在XML(eXtensibleMarkupLanguage)文档中查找信息的一种语法,XML跟HTML类似也是一种用标签承载数据的标签语言,不同之处在于XML的标签......