您的位置:首页 > 理论基础 > 计算机网络

RTP Over RTSP Over TCP

2017-02-28 10:40 1476 查看
说明:从各帖子收集了一些资料,结合自己抓包,整理而来

socket接收到RTSP包结构:
        [Magic][Channel][0x00][0x00]

        Magic:0x24

        Channel取值由RTSP协议中Setup阶段设置的interleaved来决定,默认0-1,0代表后面的是RTP包,1代表RTCP包

        例如,设置TCP隧道传输RTP:
             SETUP rtsp://user:pwd@192.168.1.45:554/trackID=1 RTSP/1.0

             CSeq:2

             Transport:RTP/AVP/TCP;unicast;interleaved=0-1 
        后面两个[0x00][0x00]字节是RTP或RTCP包的长度 

----------------------------------------------------------------------------------

RTP包由RTP报头和RTP Payload(有效载荷)构成,结构:

        [0x00][0x00][0x00][0x00]         V(2bit)P(1bit)X(1bit)CC(4bit)M(1bit)PT(7bit)sequence number(16bit)   
                                                        版本号、填充标记、扩展标记、CSRC计数器、有关有效载荷的标记、有效载荷类型(Payload                                                          Type)、序列号
        [0x00][0x00][0x00][0x00]         time stamp                                   时间戳
        [0x00][0x00][0x00][0x00]         synchronization source (SSRC) identifier     同步信源
        [0x00][0x00][0x00][0x00]         contributing source (CSRC) identifiers       特约信源
        ………………………………
        [Payload........................][Padding]

        V:2bit,版本号

        P:1bit,Padding标记,取值0-1,0表示Payload后面没有填充,1代表Payload后跟有1个或最多8个字节的填充,如果有填充,

             RTP包最后一个字节是填充计数器,表示包含自身在内的填充的字节数

        X:1bit,扩展标记

        CSRC:4bit,Contributing Source identifiers Count,CSRC计数器 ,特约信源计数器
        M:标记,取值0-1,0代表不是一帧的结束,1代表一帧数据的结束,该值是由h264定义的NAL单元传输三个结构中

             的FU(Fragmentation unit 分片单元) 结构的Header中E结束位决定的
        PT:7bit,有效载荷类型,Payload Type

        Seq:16bit,sequence number序列号,在前包的seq上自增1 

        如果没有扩展,RTP包除去前面12个字节的报头后,就是Payload,如果有Padding,还要减去后面的填充
 -------------------------------------------------------------------------------------
 RTP Payload的结构,是由h264协议定义的,可能会有三种情况:
        1.当NAL单元小于MTU时,可以传输一个完整的NAL单元,即Payload就是原始的h264 NAL单元

        2.当NAL单元特别小时,可以同时传送两个或多个NAL单元,即组合封包模式
        3.当NAL单元大于MTU是,就分两个或多个RTP包发送,即分片封包 (Fragmentation Units)

H.264的功能分为两层,视频编码层(VCL)和网络提取层(NAL),VCL数据即被压缩编码后的视频数据序列。在VCL数据要封装到NAL单元中之后,才可以用来传输或存储。

对于一个原始的 H.264 NALU 单元常由 [Start Code] [NALU Header] [NALU Payload] 三部分组成, 其中 Start Code 用于标示这是一个NALU 单元的开始, 必须是 "00 00 00 01" 或 "00 00 01", NALU 头仅一个字节, 其后都是 NALU 单元内容。打包时去除 "00 00 01" 或 "00 00 00 01" 的开始码, 把其他数据封包的 RTP 包即可。

    如有一个 H.264 的 NALU 是这样的:

        [00 00 00 01 67 42 A0 1E 23 56 0E 2F ... ]

        这是一个序列参数集 NAL 单元. [00 00 00 01] 是四个字节的开始码, 67 是 NALU 头, 42 开始的数据是 NALU 内容.

        封装成 RTP 包将如下:

        [ RTP Header ] [ 67 42 A0 1E 23 56 0E 2F ]

        即只要去掉 4 个字节的开始码就可以了.

 NALU 头的格式:
      +---------------+
      |0|1|2|3|4|5|6|7|
      +-+-+-+-+-+-+-+-+
      |F|NRI|  Type   |
      +---------------+ 
      F:禁止位 

            编码中默认值为0,当网络识别此单元中存在比特错误时,可将其设为1,以便接收方丢掉该单元,主要 用于适应不同种

            类的网络环境(比如有线无线相结合的环境)。
      NRI:重要性指示位 

      用于在重构过程中标记一个NAL单元的重要性,值越大,越重要。值为0表示这个NAL单元没有用于预测,因此可被解码

           器抛弃而不会有错误扩散;值高于0表示此NAL单元要用于无漂移重构,且值越高,对此NAL单元丢失的影响越大。 
     Type:NAL 单元的类型

      这个字段和 H.264 中类型字段的区别是, 当 type的值为 24 ~ 31 表示这是一个特别格式的 NAL 单元, 

            而 H.264 中, 只取 1~23 是有效的值. 
        0:undefine

        1:不分区、非IDR图像的片  ---主要是P帧

        2:分片区A

        3:分片区B

        4:分片区C

        5:IDR图像中的片                ---I帧 
        6:补充增强信息单元(SEI)

        7:序列参数集

        8:图像参数集

        9:分界符

        10:序列结束

        11:码流结束

        12:填充

        24:STAP-A   单一时间的组合包
        25:STAP-B   单一时间的组合包
        26:MTAP16   多个时间的组合包
        27:MTAP24   多个时间的组合包
        28:FU-A     分片的单元
        29:FU-B     分片的单元
        30-31 undefine
------------------------------------------------------------------------------------

从RTP包中得到H264数据

        单个NAL包单元
                12字节的RTP头后面的就是音视频数据,比较简单。一个封装单个NAL单元包到RTP的NAL单元流的RTP序号必须

                符合NAL单元的解码顺序 
        FU-A的分片格式 
                数据比较大的H264视频包,被RTP分片发送。12字节的RTP头后面跟随的就是FU-A分片:
             FU indicator有以下格式:
             +---------------+
             |0|1|2|3|4|5|6|7|
             +-+-+-+-+-+-+-+-+
             |F|NRI|  Type   |
             +---------------+
            FU指示字节的类型域 Type=28表示FU-A。。NRI域的值必须根据分片NAL单元的NRI域的值设置。 
            FU header的格式如下:
            +---------------+
            |0|1|2|3|4|5|6|7|
            +-+-+-+-+-+-+-+-+
            |S|E|R|  Type   |
            +---------------+
           S: 1 bit
           当设置成1,开始位指示分片NAL单元的开始。当跟随的FU荷载不是分片NAL单元荷载的开始,开始位设为0。
           E: 1 bit
           当设置成1, 结束位指示分片NAL单元的结束,即, 荷载的最后字节也是分片NAL单元的最后一个字节。当跟随的FU荷载

           不是分片NAL单元的最后分片,结束位设置为0。
           R: 1 bit
           保留位必须设置为0,接收者必须忽略该位。
           Type: 5 bits
    拆包和解包 
             拆包:当编码器在编码时需要将原有一个NAL按照FU-A进行分片,原有的NAL的单元头与分片后的FU-A的单元头有如下关系:
               原始的NAL头的前三位为FU indicator的前三位,原始的NAL头的后五位为FU header的后五位,FU indicator与FU header的

               剩余位数根据实际情况决定。
 
           解包:当接收端收到FU-A的分片数据,需要将所有的分片包组合还原成原始的NAl包时,FU-A的单元头与还原后的NAL的关系如下:
                还原后的NAL头的八位是由FU indicator的前三位加FU header的后五位组成,即:
                nal_unit_type = (fu_indicator & 0xe0) | (fu_header & 0x1f) 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  rtp rtsp tcp