[rtsp学习]-264rtp打包结构学习笔记

本篇是对博客H264码流格式解析及RTP打包规则整理的学习笔记,不同的地方在于加上了个人的理解。

名词解析:
264/265的NAL单元
裸码流中由4个字节的起始码和NAL单元组成。拿段裸码流看下16进制的数据,你会发现一个规律就是隔一段就能看到00 00 00 01,总是重复,那么这4个字节就是起始码。被这起始码分割的或包围的就是一个个的NAL单元。
再具体些,一个P帧就是一个NAL单元,I帧由4个NAL单元组成:sps、pps、idr、sei。sei辅助的不常用。可以结合下面图。

0.264码流结构及rtp通用打包结构

rtp通用打包结构所谓通用,就是说是基类,rtp包的基础形式,可以把该基类当做抽象类或接口类,其他变种都是派生的子类,某些虚方法当然要重写覆盖基类。——相当于画了个圈,你在这圈里可以再画圈,只要不出这个圈就行了。如上图。

1.264 单元NAL包结构

NAL单元结构每个264的NAL单元打成一个NAL单元——啥意思?说人话!—— 其实大白话很简单:一个264的NAL单元只打成一个rtp包,然后通过tcp/udp发送出去。
你看一个P帧就一个NAL单元,那打一个rtp包出来就够了。但是一个P帧可能大的时候十几KB或几十KB甚至几百KB,你这搞一个包也太懒了。那更不要说I帧了——I帧一般3个NAL单元组成:sps、pps、idr。还有个sei辅助的不常用。sps、pps不说了,idr的NAL可是很大的,往往几百甚至上千KB的。
优点: 打包简单,相对rtp通用打包结构没啥变化,只是type取值范围限定了——也就是和264的NALU头一样了。
也就是说一个rtp包的header里的mark就置1了(一个就是最后一个)。
缺点: 如果NAL包超过了MSS了,tcp或udp就要把数据传输多次,tcp能保证顺序和不丢包(除非处理来不及),udp就难以保证顺序和不丢包了,并且若重传要把整个都重传,极端条件下你最后一个数据丢了你还要重传整个,效率太低了!

2.264 FU-A分片包结构

为了解决单元NAL结构可能出现的低效率问题,分片结构来了。
rtp-FU-A264的一个NALU单元太大了,超出了MSS(一般1400-1464字节)和MTU(MTU一般1500字节),所以最好分成片——264的一个NAL单元打成很多个RTP包,和单NAL打包相比,一个P帧如果超出MSS则分成片,每片都打一个RTP包发送出去,也即一个P帧或I帧会打成很多个RTP包发送出去。rtp包分片有两种FU-A和FU-B,如上图是FU-A。同一帧分片的时间戳一样——收到流组成一帧时就是这么判断的。
这有个比喻: tcp/udp是个货车,容量MSS,264/265的NAL单元是货物,当货物太大,货车一次装不下,就把货物以MSS为单位切割成一片一片的打成一个个的RTP包,然后分好多次拉走。
那么和第1节讲的单NAL单元打包结构对比下,哪个好?第1节相当于整个货物不分割整个的打成一个rtp包,然后让tcp/udp小货车一次次拉走(每次也是只能发送MSS大小)。但这种方式的话,问题就来了:udp方式下,你一股脑地丢到socket缓存(buffer)里,如果udp发送最后一个数据时出现了错误,那么又要把整个的rtp包再重发下,假设这次是I帧,200KB,相对分片你说效率低不低?虽然分片在udp下也可能丢包或顺序不对但是重发只需重发丢的包就行了也就1.5KB。

另外注意下,在TCP下,FU-A分片rtp包结构又在rtp包的前面增加了4个字节用以区分是视频数据、rtcp数据、音频数据或rtsp报文。因为tcp用的端口是同一个,这些数据交织在一起,所以要区分下。
0x24是“$”符号(叫法是英文单词dollar)。

缺点: 264的每个超过MSS的NAL都分成了一个个的rtp包,rtp包头是需要消耗内存空间的。像I帧一般都是要打成几百上千个rtp包,每个包都得有12字节的头。
优点: 效率高——udp丢一个包重传一次也就1.5KB,不像单NAL重传可是整个NAL(大的可能几百上千KB)。安全可靠。分片保证了不管一个NAL有多大,每个分片都是极限利用tcp或udp的MSS载荷数据长度,保证了每个tcp或udp载荷数据都是rtp数据包。

3.组合rtp包结构

264的NAL太小了,足够把多个264的NAL单元放到一个rtp包里。
rtp包结构就是通用的rtp包结构。
这个不常用,略。

4.发现下规律

从各个rtp包的结构可以知道:
(1)各种rtp包结构都没有逃出rtp包的通用结构——任何rtp包结构里的rtp载荷数据的第一个字节都是一样的结构形式——是不是发现有很多头结构,总是分不清,还得需要重新过去查?其实先记住一点:各种头都是对264的NAL头的变种——其中不变的是低5个位(bit0-bit4)——表示负载类型,只不过各头的取值范围不同。 ——在裸码流的NAL头里是1-23,在rtp头里根据不同打包结构取值范围也不一样,单NAL打rtp包自然和264取值范围一样,分片的就是24-29了。
也就是说rtp包通用结构规定了一个大圈,它们那些变种都没有逃脱这个圈——就孙猴子给唐僧画了一个圈——只要不出圈就没事。

(2)不同的是,变种是在圈里再划小圈。像FU-A分片的rtp包结构形式,它呀,在rtp载荷数据的第2个字节又规定了下——又画了个圈——其实这也很像网络数据层次划分—— 网络链路头|IP头|TCP头|TCP载荷数据—— 每个头都画一个圈。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值