基于海思媒体库视频H264打包成RTP包

1.首先我们先引用网上介绍RTP数据包

RTP数据包格式:


0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5  6  7  8  9  0  1    

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+    

|V=2|P|X|    CC       |M|            PT            |                  sequence number                  | 

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   

|                                                               timestamp                                                    |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   

                                   synchronization source (SSRC) identifier                           |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   

                                  contributing source (CSRC) identifiers                                |

                                                              ....                                                                  |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   


以上域具体意义如下:
版本(V):2比特 此域定义了RTP的版本.此协议定义的版本是2.(值1被RTP草案版本使用,值0用在最初"vat"语音工具使用的协议中.)
填料(P):1比特 若填料比特被设置,此包包含一到多个附加在末端的填充比特,不是负载的一部分.填料的最后一个字节包含可以忽略多少个填充比特.填料可能用于某些具有固定长度的加密算法,或者在底层数据单元中传输多个RTP包.
扩展(X):1比特 若设置扩展比特,固定头(仅)后面跟随一个头扩展. 

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

标志(M):1比特 标志的解释由具体协议规定.它用来允许在比特流中标记重要的事件,如帧范围.规定该标志在静音后的第一个语音包时置位.

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


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


时间标志timestamp):32比特 时间标志反映了RTP数据包中第一个比特的抽样瞬间.抽样瞬间必须由随时间单调和线形增长的时钟得到,以进行同步和抖动计算.时钟的分辨率必须满足要求的同步准确度,足以进行包到达抖动测量.时钟频率与作为负载传输的数据格式独立,在协议中或定义此格式的负载类型说明中静态定义,也可以在通过非RTP方法定义的负载格式中动态说明.若RTP包周期性生成,可以使用由抽样时钟确定的额定抽样瞬间,而不是读系统时钟.例如,对于固定速率语音,时间标志钟可以每个抽样周期加1.若语音设备从输入设备读取覆盖160个抽样周期的数据块,对于每个这样的数据块,时间标志增加160,无论此块被发送还是被静音压缩.
时间标志的起始值是随机的,如同序列号.多个连续的RTP包可能由同样的时间标志,若他们在逻辑上同时产生.如属于同一个图象帧.若数据没有按照抽样的
顺序发送,连续的RTP包可以包含不单调的时间标志,如MPEG交织图象帧.


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


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

注意:前12个字节出现在每个RTP包中,仅仅在被混合器插入时,才出现CSRC识别符列表.


2.海思媒体库H264打包RTP模式 -- 使用标准RTP库+UDP传输



传输数据中,必须去掉开始码(nalu)0x 00 00 00 01”。

H264打包是标准打包,首先使用UDP传输层,应用层使用RTP打包。

2.1RTP数据包

使用RFC1889标准的RTP库,协议分析(wireshark抓包):

Real-Time Transport Protocol
    [Stream setup by SDP (frame 7929)]
    10.. .... = Version: RFC 1889 Version (2)
    ..0. .... = Padding: False
    ...0 .... = Extension: False
    .... 0000 = Contributing source identifiers count: 0
    1... .... = Marker: True
    Payload type: H264 (99)
    Sequence number: 38172
    [Extended sequence number: 38172]
    Timestamp: 369875998
    Synchronization Source identifier: 0xb5748730 (3044312880)

12字节头:等于96bit

版本:2bit 等于2

填料(P):1bit  等于0

扩展(X): 1bit  等于0

CSRC计数(CC): 4bit  等于0

标志(M): 1bit  等于1

负载类型(PT): 7bit  等于99 h264 

序列号: 16bit 等于 38180

时间戳: 32bit 等于 369881998

同步源(SSRC):32bi

2.2 H.264数据包

不封包情况下H.264(SPS)

    NAL unit header or first byte of the payload
        0... .... = F bit: No bit errors or other syntax violations
        .11. .... = Nal_ref_idc (NRI): 3
        ...0 0111 = Type: NAL unit - Sequence parameter set (7)
    H264 NAL Unit Payload
        0100 1101 = Profile_idc: Main profile (77)
        0... .... = Constraint_set0_flag: 0
        .0.. .... = Constraint_set1_flag: 0
        ..0. .... = Constraint_set2_flag: 0
        ...0 .... = Constraint_set3_flag: 0
        .... 0... = Constraint_set4_flag: 0
        .... .0.. = Constraint_set5_flag: 0
        .... ..00 = Reserved_zero_2bits: 0
        0001 0100 = Level_id: 20 [Level 2.0 2 Mb/s]
        1... .... = seq_parameter_set_id: 0
        .001 01.. = log2_max_frame_num_minus4: 4
        .... ..01  1... .... = pic_order_cnt_type: 2
        .010 .... = num_ref_frames: 1
        .... 1... = gaps_in_frame_num_value_allowed_flag: 1
        .... .000  0101 10.. = pic_width_in_mbs_minus1: 21
        .... ..00  0010 010. = pic_height_in_map_units_minus1: 17
        .... ...1 = frame_mbs_only_flag: 1
        1... .... = direct_8x8_inference_flag: 1
        .0.. .... = frame_cropping_flag: 0
        ..0. .... = vui_parameters_present_flag: 0
        ...1 .... = rbsp_stop_bit: 1
        .... 0000 = rbsp_trailing_bits: 0

 NAL unit header or first byte of the payload :1字节 nal头

   unsigned char TYPE:5;  

   unsigned char NRI:2;

   unsigned char F:1;

   H264 NAL Unit Payload :NAL 单位负载


封包情况下:
H.264
   
FU identifier
        0... .... = F bit: No bit errors or other syntax violations
        .11. .... = Nal_ref_idc (NRI): 3
        ...1 1100 = Type: Fragmentation unit A (FU-A) (28)
    FU Header
    H264 NAL Unit Payload
        1... .... = first_mb_in_slice: 0
        .011 .... = slice_type: I (I slice) (2)
        .... 1... = pic_parameter_set_id: 0
        [Not decoded yet]


FU indicator

F:1bit = 0;

NRI:2bit = 3;

TYPE:5bit =28 ;


FU Header

S:1bit = 1;  1表示第一个包,0为非第一个包,第二到最后也是等于0.

E:1bit = 0;  1表示第最后一个包,0为非最后一个包。

R:1bit = 0;  一直为0.

TYPE:5bit = 1; // 1P帧、5I帧、7SPS8PPS

H264 NAL Unit Payload :NAL 单位负载,


注明:

1)第一个FU-A包的FU indicatorF应该为当前NALU头的F,而NRI应该为当前NALU头的NRIType则等于28,表明它是FU-A包。FU header生成方法:S = 1E = 0R = 0Type则等于NALU头中的Type
2)后续的NFU-A包的FU indicator和第一个是完全一样的,如果不是最后一个包,则FU header应该为:S = 0E = 0R = 0Type等于NALU头中的Type
3)最后一个FU-AFU header应该为:S = 0E = 1R = 0Type等于NALU头中的Type


3.海思媒体库H264打包RTP模式 -- 使用RSTP\RTP + TCP传输

抓包得到的数据:

Frame 1237: 1224 bytes on wire (9792 bits), 1224 bytes captured (9792 bits) on interface 0

    Interface id: 0 (\Device\NPF_{64068394-F7A0-4C91-95CF-0CBBE7FCC234})

    Encapsulation type: Ethernet (1)

    Arrival Time: Apr  1, 2016 16:37:20.133597000 �й���׼ʱ��

    [Time shift for this packet: 0.000000000 seconds]

    Epoch Time: 1459499840.133597000 seconds

    [Time delta from previous captured frame: 0.001000000 seconds]

    [Time delta from previous displayed frame: 0.001998000 seconds]

    [Time since reference or first frame: 11.965179000 seconds]

    Frame Number: 1237

    Frame Length: 1224 bytes (9792 bits)

    Capture Length: 1224 bytes (9792 bits)

    [Frame is marked: False]

    [Frame is ignored: False]

    [Protocols in frame: eth:ethertype:ip:tcp:rtsp:rtsp]

    [Coloring Rule Name: TCP]

    [Coloring Rule String: tcp]

Ethernet II, Src: VisualTe_b6:00:bc (00:00:22:b6:00:bc), Dst: Dell_16:3e:47 (64:00:6a:16:3e:47)

Internet Protocol Version 4, Src: 192.168.0.7, Dst: 192.168.0.105

Transmission Control Protocol, Src Port: 554 (554), Dst Port: 53461 (53461), Seq: 435416, Ack: 225, Len: 1170

[2 Reassembled TCP Segments (1417 bytes): #1234(1264), #1237(153)]

    [Frame: 1234, payload: 0-1263 (1264 bytes)]

    [Frame: 1237, payload: 1264-1416 (153 bytes)]

    [Segment count: 2]

    [Reassembled TCP length: 1417]

    [Reassembled TCP Data: 240005858060038d002b558e0000000a7c81e02212ff0ac1...]

RTSP Interleaved Frame, Channel: 0x00, 1413 bytes

    Magic: 0x24

    Channel: 0x00

    Length: 1413

    Data: 8060038d002b558e0000000a7c81e02212ff0ac199cdfa76...

RTSP Interleaved Frame, Channel: 0x00, 1013 bytes

    Magic: 0x24

    Channel: 0x00

    Length: 1013

    Data: 80e0038e002b558e0000000a7c417c4c12a1da35b63cac60...

 

rtsp rtp标志

rtsp_intereaved->flag = '$';

rtsp_intereaved->channel = 0;

 

80:60:03:8d:00:2b:55:8e:00:00:00:0a:7c:81:e0 分析:

RTP:                         

80 = 1000 000

版本:2bit等于2

填料(P):1bit  等于0

扩展(X): 1bit  等于0

CSRC计数(CC): 4bit  等于0

 

60 = 0110 0000

标志(M): 1bit  等于0。“0”表示封包时表示第一部分,“1”位第二部分

负载类型(PT): 7bit  等于96  H26497为音频

 

03 8d = 0000 0011 1000 1101 序列号

00:2b:55:8e 时间戳

00:00:00:0a 同步源

 

H264 - FU-A 封包

7c = 0111 1100

FU indicator 

F:1bit = 0;

NRI:2bit = 3;

TYPE:5bit =28 ;

 

81 = 1000 0001

FU Header

S:1bit = 1;  1表示第一个包,0为非第一个包,第二到最后也是等于0.

E:1bit = 0;  1表示第最后一个包,0为非最后一个包。

R:1bit = 0;  一直为0.

TYPE:5bit = 1; // 1P帧、5I帧、7SPS8PPS

 

e0 --- 接下来的都是流媒体数据。


4.总结
    以上有两种方式来打包RTP包,第一种的数据包分析是基于机器程序中使用标准的RTP协议库 + UDP网络传输分析的, 在视频电话中,语音、视频数据往往是使用UDP协议传送的,但这种协议传输的数据包在网络层不能保证其发送顺序,需要应用层进行排序。在网络的传输中都会有延时,且随着网络负载的变化,延时的长短也不相同,对于语音数据,如果接收方收到后立即播放,很容易造成语音的抖动。
    其实我们在这里可以使用第二种打包模式,RTSP + 自协议封包RTP,使用TCP网络传输,这部分已经完成了, 这样的话我们就省去了网络包排序问题了。
    这部分是设备端打包工具,在平台或客户端中使用解包时需要做的处理时,当网络差时很容易出现蓝屏或者丢帧花屏现象,这样的话客户端最后采用丢包机制,就是在接收到非完整包时,不要进行解码,宁愿让图像卡顿也不要花屏!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值