首页 > 其他分享 >RTP封包

RTP封包

时间:2024-03-10 11:22:33浏览次数:28  
标签:封装 FU AAC AU RTP 封包 Unit

一、前言

RTP(Real-time Transport Protocol),即实时传输协议,RTP协议定义了在网络上传输音频和视频的标准数据包的格式。通常RTP和RTSP协议一起用于流媒体传输系统。RTP标准中包含了两个子协议,RTP和RTCP。当网络为UDP传输方式的时候RTP通常和RTCP协议配合使用,实现流媒体音视频质量的保证,通常RTP的端口为偶数,使用的RTCP的端口号为RTP的端口加1,端口号范围通常为1024 - 65535。本文将简单介绍音视频(H264/H265/AAC)码流如何封装为RTP包的,以及如何解封装。

 

二、RTP基本格式介绍

在RTSP的流媒体服务器中音视频的传输通过RTP封装将音视频帧封装为若干个RTP包;每个RTP包由RTP Header和音视频载荷(Payload)组成;RTP Header包含固定头和扩展头;如下图所示,蓝色块是RTP Herder部分,绿色块是音视频载荷,外围的绿色框表示分成的多个RTP包体。

1、RTP 固定头

RTP Header分为固定头和扩展头;RTP固定头是RTP包中必不可少的部分,其大小通常为12个字节;而 RTP扩展头对RTP包来说不是必需的,其大小通常可变;RTP固定头定义如下图所示,占用至少12个字节。

RTP Fixed Header Fields

V(version) :表示RTP版本号,当前版本为2。占用2bit大小;

P(padding) :表示填充标志,为1则在该RTP尾部填充一个或多个额外的8bit数据。占用1bit大小;

X(extension) :表示扩展头标志,为1则表示在该RTP Header后面跟随一个扩展头。占用1bit大小;

CC(CSRC count) :CSRC计数器,表示CSRC的个数。占用4个bit;

M(marker) :表示一个标识,视频与音频包中该值具有不同的含义。RTP包为视频包时候,若该值为1则表示视频一帧的结束(该包是当前帧的最后一个RTP包);RTP包为音频包的时候,若该值为1则表示音频会话的开始;占用1bit大小;

PT(payload type) :表示载荷类型;用于说明RTP包中的媒体文件类型;该值的定义在RFC3551RFC 3551: RTP Profile for Audio and Video Conferences with Minimal Control。由于H264、H265、AAC编码标准出现的较晚所以没有出现在RFC3551的详细定义中,通常使用96-127(动态序号),如H264的PT使用96,PT值通常在RTSP信令SDP中指定。占用7bit的大小;

timestamp : 时间戳,表示当前数据的采样时刻;同一个帧,不同RTP包的时间戳应该相同;当RTP包为视频时候时间戳的基准则为90KH(90000)。RTP包为音频则通常按照音频采样率为时间基准,时间基准通常在RTSP信令SDP中指定;当传输的音视频帧是按照固定周期生成(固定帧率),则时间戳采用累加的时间,而不是获取系统时间,如视频固定帧率25帧,则时间戳的增量为90000/25=3600,第一帧时间戳采用系统时间或者随机时间,第二帧时间戳则在第一帧的基础上加3600;占用32bit大小;

SSRC :同步信源标识符;指产生媒体流的信源;在同一个RTP会话中不会出现两个相同SSRC标识符的信源;占用32bit大小;

CSRC 列表 :提供信源标识符列表,一共可以包含最大16(0~15)个提供信源标识符;每个CSRC标识了包含在当前RTP报文有效载荷中的所有提供信源;例如音频(混音器)RTP混合了不同的同步信源RTP包后,经过混合后产生一个新的组合RTP包,并产生新的混合RTP包的SSRC,将原来所有的SSRC都作为CSRC传送给接收者,让接受者知道组成组合RTP包的所有SSRC;每个CSRC占用32bit大小。

2、RTP 扩展头

当RTP固定头中的X字段为1则需要在RTP固定头后添加RTP扩展头 ;RTP扩展头定义如下;至少包含32bit。

RTP Header Extension

defined by profile :表示扩展数据类型,通常自定义;占用16bit大小;

length :扩展数据长度,不包含defined by profile和length所占用大小。占用16bit大小;

header extension :扩展数据内容,可以为空,即大小最小可以为0。

3、RTP 载荷

在RTSP等实时流传输中常见的编码格式是H264/H265以及音频AAC;不同的编码格式在RTP包中的封装过程有所不同,比如H264和H265需要去掉码流中的启始码(0x000001),音频AAC需要去掉AAC的头部字段ADTS数据,在H264封装RTP包过程需要去掉1个字节的NAL Unit 头,在H265封装过程需要去掉2个字节的NAL Unit 头。关于起始码和NAL Unit 头的介绍可以参考下面的文章。<H264视频码流结构分析>、<H265视频码流结构分析>。下面的章节将详细介绍H264、H265、AAC码流封装RTP以及RTP解封装过程。

RTP协议资料链接:RFC 3550: RTP: A Transport Protocol for Real-Time Applications

三、RTP封装H264

RTP封装H264的载荷结构由很多种,如单一包、聚合包、分片包等;如下图所示。

【相关学习资料推荐,点击下方链接免费报名,先码住不迷路~】

音视频免费学习地址:FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发

【免费分享】音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击788280672加群免费领取~

1、封装包类型

单一包

 

主要包含 single NAL unit packet;对应的Type为1~23;单一包的载荷定义如下图,前8个bit为H264中Nal Unit的第一字节(在下面切片包会详细讲述),接下来的就是H264的Nal Unit原始字节流数据(不包含启始码和Nal Unit)。

聚合包:

 

主要包含STAP-A,STAP-B,MTAP16,MTAP24;对应的Type为24~27;聚合包的定义如下图所示,前8个bit为H264中Nal Type(在下面切片包会详细讲述),接下来的就是一个或者多个聚合单元数据;STAP-A,STAP-B,MTAP16,MTAP24个字的聚合单元定义有所不同。

切片包 FU-A

 

切片包类型包含FU-A、FU-B;对应的Type分别为28、29。通常H264的一帧里面包含一个或者多个Nal Unit单元(如SPS、PPS、ISlice、PSlcie),FU-A、FU-B可以将不同的Nal Unit单独打包发送。FU-A和FU-B载荷的定义有所差异。FU-A的定义如下图。FU-A的载荷主要有4部分组成:分片单元标识(FU indicator)、分片单元头(FU header)和分片载荷数据(FU payload)、RTP填充数据。

分片单元标识(FU indicator)

 

主要包含3个字段:F、NRI、Type;如下图所示,左侧是FU indicator的定义,右侧红色框内是H264 Nal Unit 的第一个字节的定义,两者的含义一样。F占1bit值为0;NRI表示当前NAL单元的优先级,占用2bit,取值0-3,数值越大优先级越高若当前包丢掉之后解码越容易出现异常;Type 表示包的类型,类型为FU-A时候值为28。

分片单元头(FU header) : 包含4个字段,S、E、R、Type;定义如下图所示。

S:为1表示分片的开始,即表示一个编码帧的分片第一个包;占用1bit。

 

E:为表示分片的结束,即表示一个编码帧分片的最后一个包;占用1bit;在H264码流中ISlice或者PSlice通常比较大,会大于一个MTU(网络最大传输单元1500字节)此时会将ISlice分成多个片,S为1表示当前的RTP包为ISlice/PSlice切的第一片数据;E为1表示当前的RTP包为ISlice/PSlice切的最后一片数据。

R:保留位,为0;占用1bit;

Type: 表示H264的Nal Unit Type。

分片载荷数据(FU payload): 去掉起始码、和Nal Unit 第一个字节之后的原始字节序列载荷。

切片包 FU-B

定义如下图所示;分为5个部分:分片单元标识(FU indicator)、分片单元头(FU header)、DON(Decoding Order Number)和分片载荷数据(FU payload)、RTP填充数据。与FU-A相比较FU-B多了一个DON( 解码顺序号);DON 用来 指示 NAL 单元的解码顺序,它允许 H264 NAL 单元的传输顺序和 NAL 单元的解码顺序不同 。在切片包 FU-B的类型包中FU indicator的Type 值固定为29。

RTP打包H254说明资料:RFC 6184 - RTP Payload Format for H.264 Video

 

四、RTP封装H265

RTP封装H265的载荷结构也有很多种:单一包(Single NAL unit packet);聚合包(Aggregation Packet);分片包(Fragmentation Unit)等。每一种封包类型中都有PayloadHdr(载荷头);PayloadHdr和H265视频帧的Nal Uint头的定义对比如下图; 左侧是PayloadHdr右侧是H265视频帧的Nal Uint头;F字段和forbidden_zero_bit一样都是1bit大小,正常情况值都为0;LayerId和nuh_layer_id含义一样,通常值也是0;TID和nuh_temporal_id_plus1表示当前Nal所在时域层的标识号+1;PayloadHdr中的Type值和封装类型有关,封装类型不同取值不同;当封装类型为单一包的时候Type取值和H265中的nal_unit_type的取值是相同,其他封装类型取值不同(具体看下文截图所示)。

1、封装包类型

单一包(Single NAL unit packet)

单一包是将一个Nal Unit封装到一个RTP包中,通常较小的视频帧可以采用这种方式。单一包的结构定义如下图,主要有4部分:载荷头(PayloadHdr),DONL(Decoding Order Number),Nal Unit 载荷数据,填充数据。

聚合包(Aggregation Packet)

通常是将多个很小的Nal Unit封装到一个RTP包中,来降低RTP包的开销;在聚合包中载荷头(PayloadHdr)中的Type 取值为48。聚合包的定义如下图所示,主要有载荷头(PayloadHdr)、两个或者多个聚合单元、填充数据。

分片包(Fragmentation Unit)

有些Nal Unit的大小比较大(大于MTU),如H265的ISlice/PSlice会将大的Nal Unit分成多个RTP包,分开封装发送。分片包主要包含5个部分:PayloadHdr(载荷头)、分片单元头(FU header)、

DONL(解码顺序)、载荷、填充字段。PayloadHdr(载荷头)中的Type取值为49。

分片包分片单元头(FU header) 的定义如下图所示,有3个字段:S,E、FuType。

S: 为1的时候表示当前RTP包是Nal Unit中分片的第一个片。占用1bit;

E: 为1的时候表示当前RTP包是Nal Unit中分片的最后一个片。占用1bit。通常较大的Nal Unit在封装RTP包的时候会切成多个片,每个片单独的封装为RTP;根据S和E的值来区分当前分片的位置。

FuType: 表示Nal Unit的类型、和h265中的nal_unit_type取值相同,占用用6个bit。

RTP打包H265说明资料:RFC 7798 - RTP Payload Format for High Efficiency Video Coding (HEVC)

五、RTP封装AAC

RTP封装AAC的协议采用MPEG-4格式的封装协议,RTP在封装AAC包通常和RTSP信令SDP的AAC音频信息的填充有一定关系,接下来会详细介绍。

通常根据AAC码率大小可以分为Low Bit-rate AAC以及High Bit-rate AAC模式。在Low Bit-rate下规定AAC的一帧大小最大不超过63字节。在Low Bit-rate AAC模式下其对应的SDP(示例)信息如下所示;SDP中的mode=AAC-lbr,表示RTP封包的AAC采用Low Bit-rate AAC的模式;sizeLength则表示AAC编码帧长这一参数占用的bit数,sizeLength=6则表示AAC帧长这一参数中占6bit所以编码帧长取值最大是63(取值范围0-63),即AAC编码帧长最大63字节。

m=audio 49230 RTP/AVP 96
a=rtpmap:96 mpeg4-generic/22050/1
a=fmtp:96 streamtype=5; profile-level-id=14; mode=AAC-lbr; config=
1388; sizeLength=6; indexLength=2; indexDeltaLength=2;
constantDuration=1024; maxDisplacement=5

High Bit-rate AAC下规定一帧大小最大不超过8191字节。在High Bit-rate AAC其对应的SDP(示例)信息如下;SDP中mode=AAC-hbr,表示RTP封包的AAC采用High Bit-rate AAC的模式;sizeLength则表示AAC编码帧长这一参数占用的bit数,sizeLength=13则表示AAC编码帧长这一参数中占13bit所以取值最大是8191(取值范围0-8191),即AAC帧长最大8191字节。

m=audio 49230 RTP/AVP 96
a=rtpmap:96 mpeg4-generic/48000/6
a=fmtp:96 streamtype=5; profile-level-id=16; mode=AAC-hbr;
config=11B0; sizeLength=13; indexLength=3;
indexDeltaLength=3; constantDuration=1024

AACRTP打包AAC(MPEG-4)说明资料:RFC 3640 - RTP Payload Format for Transport of MPEG-4 Elementary Streams

1、封包结构

RTP封装AAC的数据结构定义如下图;主要包含4个部分:RTP Header(前面介绍过这里就不介绍了)、AU Header、Auxiliary Section(附件信息、基本用不到)、Access Unit Data Section。

AU Header Section:主要定义了 Access Unit Data Section的信息。AU Header 的定义如下图所示;主要包含了AU Header的长度信息以及若干个AU Header。

AU-headers-length表示的是AU Header所占用的bit数,如AU-headers-length为16表示AU Header会占用2个字节的存储空间。

AU-header的定义如下图所示。AU-header的定义字段很多,但是常用的就是AU-size、AU-Index/AU-Index-delta;其他参数可以不需要。

AU-size:表示的是AAC编码帧的长度;其占用的bit数和SDP中isizeLength这个参数一致;如如在High Bit-rate AAC模式下isizeLength=13表示AU-size占用13个bit。

AU-Index/AU-Index-delta:表示AUData数据的索引参数,一个RTP中包含多个AAC的数据片时候才有意义,当一个RTP包只有一帧AAC数据载荷的时候AU-Index/AU-Index-delta的值为0。AU-Index/AU-Index-delta占用bit数和SDP中indexLength/indexDeltaLength这两个参数一致;如在High Bit-rate AAC模式下indexLength=3;indexDeltaLength=3分别表示AU-Index占用3个bit,iAU-Index-delta占用3个bit。如下代码是RTP封装AAC的代码示例。

nt rtp_pakc_aac(unsigned char *ptr,int bytes,unsigned char *rtpPkt)
{
    if (0xFF == ptr[0] && 0xF0 == (ptr[1] & 0xF0) && bytes > 7)
	{
		// skip ADTS header
		assert(bytes == (((ptr[3] & 0x03) << 11) | (ptr[4] << 3) | ((ptr[5] >> 5) & 0x07)));
		ptr += 7;
		bytes -= 7;
	}
 
    int rtpHeadLen = rtp_pack_header(rtpPkt);//RTP Header
    
    unsigned char * header = rtpPkt + rtpHeadLen;
    // 3.3.6. High Bit-rate AAC
	// SDP fmtp: mode=AAC-hbr;sizeLength=13;indexLength=3;indexDeltaLength=3;
    header[0] = 0;
    header[1] = 16; // 16-bits AU headers-length
    header[2] = (uint8_t)(bytes >> 5); 
    header[3] = (uint8_t)(bytes & 0x1f) << 3;//13bit AU-size、3bit AU-Index/AU-Index-delta
    unsigned char * pPayload = rtpPkt + rtpHeadLen + 4;
    memcpy(pPayload, ptr,bytes);
    
    return bytes + rtpHeadLen + 4;



标签:封装,FU,AAC,AU,RTP,封包,Unit
From: https://www.cnblogs.com/cnhk19/p/18063885

相关文章

  • RTP报文头中的SSRC和CSRC
    以下内容转载自http://www.360doc.com/content/11/1009/15/496343_154624612.shtml和https://www.cnblogs.com/yoyotl/p/5650101.html同步信源(SSRC)标识符:占32位,用于标识同步信源。该标识符是随机选择的,参加同一视频会议的两个同步信源不能有相同的SSRC。·特约信源(CSRC)标识......
  • ZLmediakit的TCP主动接收RTP数据
    当我们使用openRtpServer接口的时候,一般都是别人主动向port或者默认端口(默认1000)上推数据;这种属于ZLM的socket被动接收连接(TCP),ZLM的RTPserver作为服务端,监听端口,有别人过来链接之后,握手建立连接,传输数据;如果我们想主动去链接对方,告诉对方给我发数据要怎么处理呢?首先,发送数据端......
  • How to unlock Nissan Altima 2019-2022 Smart Remote 5 Buttons 433MHz Keys with Sm
    Howtounlock Nissan Altima2019-2022Smart Remote 5Buttons433MHzKeyswithSmartPro5000U-Plusfirst,youneedhavea SmartPro5000U-PlusProgrammer,ifyoudonothaveaSmartPro5000U-Plus,youcanbuyonefromchinaobd2.com.https://www.chinaobd2.co......
  • [PJADV] 封包结构分析
    [PJADV]封包结构分析目标游戏:ティンクル☆くるせいだーすPSSv.1.19这篇就详细写一下,后面就全当读者有相关背景知识,因为这样写实在很累(假设结构先正常安装游戏,并打上更新补丁(如果太乱可以先不打更新补丁,视情况而定)(是不是可以观察一下打补丁前后变化?补丁本身?)先浏览一遍游戏......
  • 流媒体通信中RTP/RTCP在项目中的应用
    一概述:本文档描述RTC通信中RTP/RTCP的应用以及当前项目中的使用策略。二RTP/RTCP协议简介2.1协议标准RTP由IETF(http://www.ietf.org/)定义在RFC3550和3551中。RTP被定义为传输音频、视频、模拟数据等实时数据的传输协议,与传统的注的高可靠的数据传输的运输层协议相比,它......
  • crtp 接口声明
    #include<vector>#include<utility>//对于std::move#include<type_traits>#include<iostream>usingnamespacestd;template<typenameT>structA{A&f(){return*this;}//T&f(){returnstatic_cast<T&a......
  • 10 信息打点——APP&小程序篇&抓包封包&XP框架&反编译&资产提取
    一、APP资产收集对APP进行资产收集,不但要用Fiddler等抓包工具,对外在资产进行分析收集;还要使用AppInfoScanner等工具,对内在资产(源码)进行反编译分析。安卓APP入手1、APP-外在资产收集1.将APP安装在模拟器中,修改模拟器代理设置,使用Fiddler、Burpsuite、Charles等抓包工具抓......
  • 我是如何解决java.security.cert.CertPathValidatorException异常的
    在rocky8.5上,有个jdk8跑的程序连接windows上SQLServer2012失败了,环境如下:[zcm@rockymicroService]$cat/etc/redhat-releaseRockyLinuxrelease8.5(GreenObsidian)[root@rockysecurity]#java-versionopenjdkversion"1.8.0_302"OpenJDKRuntimeEnvironment(......
  • Smartproxy代理IP,提升效率的绝佳之法
    在过去几周的时间里,我花费了一些时间测试不同的IP代理,以深入了解它们的性能和特点。以下是我整理和评估的几家代理服务商的优缺点,旨在为大家提供详尽而准确的信息。这些测试经验使我更全面地了解了不同代理在实际应用中的表现。通过分享这些经验,我希望能够为大家在选择IP代理时提供......
  • PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderExce
    由于接口是HTTPS,本地没有证书,导致报PKIXpathbuildingfailed:sun.security.provider.certpath.SunCertPathBuilderException:unabletofindvalidcertificationpathtorequestedtarget导出证书Chrome浏览器导出HTTPS证书创建一个Java信任库创建一个Java信任库(Trusts......