編輯:關於Android編程
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識別符列表.
傳輸數據中,必須去掉開始碼頭(nalu頭)“0x 00 00 00 01”。
H264打包是標准打包,首先使用UDP傳輸層,應用層使用RTP打包。
使用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
不封包情況下H.264(SPS):
NAL unit header or first byte of the payload
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 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; // 1為P幀、5為I幀、7為SPS、8為PPS。
H264 NAL Unit Payload :NAL 單位負載,
注明:
1)第一個FU-A包的FU indicator:F應該為當前NALU頭的F,而NRI應該為當前NALU頭的NRI,Type則等於28,表明它是FU-A包。FU header生成方法:S = 1,E = 0,R = 0,Type則等於NALU頭中的Type。
2)後續的N個FU-A包的FU indicator和第一個是完全一樣的,如果不是最後一個包,則FU header應該為:S = 0,E = 0,R = 0,Type等於NALU頭中的Type。
3)最後一個FU-A包FU header應該為:S = 0,E = 1,R = 0,Type等於NALU頭中的Type。
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 H264、97為音頻
038d= 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; // 1為P幀、5為I幀、7為SPS、8為PPS。
e0--- 接下來的都是流媒體數據。
4.總結 以上有兩種方式來打包RTP包,第一種的數據包分析是基於機器程序中使用標准的RTP協議庫 + UDP網絡傳輸分析的,在視頻電話中,語音、視頻數據往往是使用UDP協議傳送的,但這種協議傳輸的數據包在網絡層不能保證其發送順序,需要應用層進行排序。在網絡的傳輸中都會有延時,且隨著網絡負載的變化,延時的長短也不相同,對於語音數據,如果接收方收到後立即播放,很容易造成語音的抖動。 其實我們在這裡可以使用第二種打包模式,RTSP + 自協議封包RTP,使用TCP網絡傳輸,這部分已經完成了,這樣的話我們就省去了網絡包排序問題了。 這部分是設備端打包工具,在平台或客戶端中使用解包時需要做的處理時,當網絡差時很容易出現藍屏或者丟幀花屏現象,這樣的話客戶端最後采用丟包機制,就是在接收到非完整包時,不要進行解碼,寧願讓圖像卡頓也不要花屏!通過央視報道,曝光了2個跟智能手機有關的內容,一個是手機偷跑流量,另外一個則是預裝軟件難卸載問題。通過測試獲取到實際數據對比,最後結果顯示,有9款手機的流量
github:https://github.com/zarics/ZrcListView先貼一個自己畫的ZrcListView的UML類圖(學習ing。。。)滾動的實現想
RecyclerView 是 android-support-v7-21 版本中新增的一個 Widgets, 還有一個 CardView 會在下次介紹使用。官方介紹 Re
在Android應用開發中,滑動側邊欄經常使用,今天我也試著自己進行了一個簡單的實踐,雖然功能還不是很強大,但是可以保留下來為以後的開發使用,有需要時在進行簡單的修改。實