H264码流打包分析
来源:互联网 发布:python黑帽子原码 编辑:程序博客网 时间:2024/06/04 21:52
SODB 数据比特串-->最原始的编码数据
RBSP 原始字节序列载荷-->在SODB的后面填加了结尾比特(RBSP trailing bits 一个bit“1”)若干比特“0”,以便字节对齐。
EBSP 扩展字节序列载荷-- >在RBSP基础上填加了仿校验字节(0X03)它的原因是: 在NALU加到Annexb上时,需要填加每组NALU之前的开始码 StartCodePrefix,如果该NALU对应的slice为一帧的开始则用4位字节表示,ox00000001,否则用3位字节表示 ox000001.为了使NALU主体中不包括与开始码相冲突的,在编码时,每遇到两个字节连续为0,就插入一个字节的0x03。解码时将0x03去掉。 也称为脱壳操作。
h264的功能分为两层,视频编码层(VCL)和网络提取层(NAL)
NAL单元
每个NAL单元是一个一定语法元素的可变长字节字符串,包括包含一个字节的头信息(用来表示数据类型),以及若干整数字节的负荷数据。一个NAL单元可以携带一个编码片、A/B/C型数据分割或一个序列或图像参数集。
NAL单元按RTP序列号按序传送。其中,T为负荷数据类型,占5bit;R为重要性指示位,占2个bit;最后的F为禁止位,占1bit。具体如下:
(1)NALU类型位
可以表示NALU的32种不同类型特征,类型1~12是H.264定义的,类型24~31是用于H.264以外的,RTP负荷规范使用这其中的一些值来定义包聚合和分裂,其他值为H.264保留。
(2)重要性指示位
用于在重构过程中标记一个NAL单元的重要性,值越大,越重要。值为0表示这个NAL单元没有用于预测,因此可被解码器抛弃而不会有错误扩散;值高于0表示此NAL单元要用于无漂移重构,且值越高,对此NAL单元丢失的影响越大。
(3)禁止位
编码中默认值为0,当网络识别此单元中存在比特错误时,可将其设为1,以便接收方丢掉该单元,主要 用于适应不同种类的网络环境(比如有线无线相结合的环境)。例如对于从无线到有线的网关,一边是无线的非IP环境,一边是有线网络的无比特错误的环境。假 设一个NAL单元到达无线那边时,校验和检测失败,网关可以选择从NAL流中去掉这个NAL单元,也可以把已知被破坏的NAL单元前传给接收端。在这种情 况下,智能的解码器将尝试重构这个NAL单元(已知它可能包含比特错误)。而非智能的解码器将简单地抛弃这个NAL单元。NAL单元结构规定了用于面向分 组或用于流的传输子系统的通用格式。在H.320和MPEG-2系统中,NAL单元的流应该在NAL单元边界内,每个NAL单元前加一个3字节的起始前缀 码。在分组传输系统中,NAL单元由系统的传输规程确定帧界,因此不需要上述的起始前缀码。一组NAL单元被称为一个接入单元,定界后加上定时信息 (SEI),形成基本编码图像。该基本编码图像(PCP)由一组已编码的NAL单元组成,其后是冗余编码图像(RCP),它是PCP同一视频图像的冗余表 示,用于解码中PCP丢失情况下恢复信息。如果该编码视频图像是编码视频序列的最后一幅图像,应出现序列NAL单元的end,表示该序列结束。一个图像序 列只有一个序列参数组,并被独立解码。如果该编码图像是整个NAL单元流的最后一幅图像,则应出现流的end。
H.264采用上述严格的接入单元,不仅使H.264可自适应于多种网络,而且进一步提高其抗误码能力。序列号的设置可发现丢的是哪一个VCL单元,冗余编码图像使得即使基本编码图像丢失,仍可得到较“粗糙”的图像。
实现RTP协议的H.264视频传输系统
1. 引言
随着信息产业的发展,人们对信息资源的要求已经逐渐由文字和图片过渡到音频和视频,并越来越强调获取资源的实时性和互动性。但人们又面临着另外一种不可避免的尴尬,就是在网络上看到生动清晰的媒体演示的同时,不得不为等待传输文件而花费大量时间。为了解决这个矛盾,一种新的媒体技术应运而生,这就是流媒体技术。流媒体由于具有启动时延小、节省客户端存储空间等优势,逐渐成为人们的首选,流媒体网络应用也在全球范围内得到不断的发展。其中实时流传输协议 RTP 详细说明了在互联网上传递音频和视频的标准数据包格式,它与传输控制协议 RTCP 配合使用,成为流媒体技术最普遍采用的协议之一。
H.264/AVC 是ITU-T 视频编码专家组(VCEG)和ISO/IEC 动态图像专家组(MPEG )联合组成的联合视频组(JVT)共同努力制订的新一代视频编码标准,它最大的优势是具有很高的数据压缩比率,在同等图像质量的条件下,H.264 的压缩比是MPEG-2 的2 倍以上,是 MPEG-4的1.5~2 倍。同时,采用视频编码层(VCL)和网络提取层(NAL )的分层设计,非常适用于流媒体技术进行实时传输。本文就是基于 RTP 协议,对 H.264 视频进行流式打包传输,实现了一个基本的流媒体服务器功能,同时利用开源播放器VLC 作为接收端,构成一个完整的H.264 视频传输系统。
(1)标示位(M ):1 位,该标示位的含义一般由具体的媒体应用框架(profile )定义, 目的在于标记处RTP 流中的重要事件。
(2)载荷类型(PT):7 位,用来指出RTP负载的具体格式。在RFC3551中,对常用的音视频格式的RTP 传输载荷类型做了默认的取值规定,例如,类型2 表明该RTP数据包中承载的是用ITU G.721 算法编码的语音数据,采用频率为 8000HZ,并且采用单声道。
(3)序号:16 位,每发送一个 RTP 数据包,序号加 1。接受者可以用它来检测分组丢失和恢复分组顺序。
(4)时间戳:32 位,时间戳表示了 RTP 数据分组中第一个字节的采样时间,反映出各RTP 包相对于时间戳初始值的偏差。对于RTP 发送端而言,采样时间必须来源于一个线性单调递增的时钟。
从 RTP 数据包的格式不难看出,它包含了传输媒体的类型、格式、序列号、时间戳以及是否有附加数据等信息。这些都为实时的流媒体传输提供了相应的基础。而传输控制协议RTCP为 RTP传输提供了拥塞控制和流控制,它的具体包结构和各字段的含义可参考RFC3550,此处不再赘述。
H.264 的基本流由一系列NALU (Network Abstraction Layer Unit )组成,不同的NALU数据量各不相同。H.264 草案指出[2],当数据流是储存在介质上时,在每个NALU 前添加起始码:0x000001,用来指示一个 NALU的起始和终止位置。在这样的机制下,*在码流中检测起始码,作为一个NALU得起始标识,当检测到下一个起始码时,当前NALU结束。每个NALU单元由一个字节的 NALU头(NALU Header)和若干个字节的载荷数据(RBSP)组成。其中NALU 头的格式如图2 所示:
F:forbidden_zero_bit.1 位,如果有语法冲突,则为 1。当网络识别此单元存在比特错误时,可将其设为 1,以便接收方丢掉该单元。
NRI:nal_ref_idc.2 位,用来指示该NALU 的重要性等级。值越大,表示当前NALU越重要。具体大于0 时取何值,没有具体规定。
需要特别指出的是,NRI 值为 7 和 8 的NALU 分别为序列参数集(sps)和图像参数集(pps)。参数集是一组很少改变的,为大量VCL NALU 提供解码信息的数据。其中序列参数集作用于一系列连续的编码图像,而图像参数集作用于编码视频序列中一个或多个独立的图像。如果*没能正确接收到这两个参数集,那么其他NALU 也是无法解码的。因此它们一般在发送其它 NALU 之前发送,并且使用不同的信道或者更加可靠的传输协议(如TCP)进行传输,也可以重复传输。
前面分别讨论了RTP 协议及H.264基本流的结构,那么如何使用RTP协议来传输H.264视频了?一个有效的办法就是从H.264视频中剥离出每个NALU,在每个NALU前添加相应的RTP包头,然后将包含RTP 包头和NALU 的数据包发送出去。下面就从RTP包头和NALU两方面分别阐述。
完整的 RTP 固定包头的格式在前面图 1 中已经指出,根据RFC3984[3],这里详细给出各个位的具体设置。
V:版本号,2 位。根据RFC3984,目前使用的RTP 版本号应设为0x10。
P:填充位,1 位。当前不使用特殊的加密算法,因此该位设为 0。
X:扩展位,1 位。当前固定头后面不跟随头扩展,因此该位也为 0。
CC:CSRC 计数,4 位。表示跟在 RTP 固定包头后面CSRC 的数目,对于本文所要实现的基本的流媒体服务器来说,没有用到混合器,该位也设为 0x0。
M:标示位,1 位。如果当前 NALU为一个接入单元最后的那个NALU,那么将M位置 1;或者当前RTP 数据包为一个NALU 的最后的那个分片时(NALU 的分片在后面讲述),M位置 1。其余情况下M 位保持为 0。
PT:载荷类型,7 位。对于H.264 视频格式,当前并没有规定一个默认的PT 值。因此选用大于 95 的值可以。此处设为0x60(十进制96)。
SQ:序号,16 位。序号的起始值为随机值,此处设为 0,每发送一个RTP 数据包,序号值加 1。
TS:时间戳,32 位。同序号一样,时间戳的起始值也为随机值,此处设为0。根据RFC3984, 与时间戳相应的时钟频率必须为90000HZ。
SSRC:同步源标示,32 位。SSRC应该被随机生成,以使在同一个RTP会话期中没有任何两个同步源具有相同的SSRC 识别符。此处仅有一个同步源,因此将其设为0x12345678。
对于每一个NALU,根据其包含的数据量的不同,其大小也有差异。在IP网络中,当要传输的IP 报文大小超过最大传输单元MTU(Maximum Transmission Unit )时就会产生IP分片情况。在以太网环境中可传输的最大 IP 报文(MTU)的大小为 1500 字节。如果发送的IP数据包大于MTU,数据包就会被拆开来传送,这样就会产生很多数据包碎片,增加丢包率,降低网络速度。对于视频传输而言,若RTP 包大于MTU 而由底层协议任意拆包,可能会导致接收端播放器的延时播放甚至无法正常播放。因此对于大于MTU 的NALU 单元,必须进行拆包处理。
(2)Aggregation Packet:在一个RTP 包中封装多个NALU,对于较小的NALU 可以采用这种打包方案,从而提高传输效率。
(3)Fragmentation Unit:一个NALU 封装在多个RTP包中,在本文中,对于大于1400字节的NALU 便采用这种方案进行拆包处理。
- H264码流打包分析
- H264码流打包分析
- H264码流打包分析
- H264码流打包分析
- H264码流打包分析
- H264码流打包分析
- H264码流打包分析
- H264码流打包分析
- H264码流打包分析
- H264码流打包分析
- H264码流打包分析
- H264码流打包分析(zz)
- H264码流打包分析(精华)
- H264码流打包分析.整理
- H264码流打包分析(精华)
- H264码流结构分析和rtp打包结构详解
- H264码流结构分析和rtp打包结构详解
- H264码流分析
- kafka0.8--0.11各个版本特性预览介绍
- 简单成绩判断
- 【微信】微信开发(3)不要掉进Cookie的坑!
- 15款Cocos2d-x游戏源码
- CppCMS — C++ Web Framework
- H264码流打包分析
- 设计模式的艺术之道--设计模式的基本概念
- 前端之js d3
- iOS NSString 转换编码格式ISO-8859-1
- Spring中使用单元测试--探索
- java位运算符 : 与(&)、非(~)、或(|)、异或(^)
- java Book
- Arrays.sort源码分析
- 逆序输出数值