轉自:http://blog.csdn.net/jychen105/article/details/47012099
一、H264是如何通過rtsp發送的
簡單來說,H264就是通過打包到rtp協議的數據部分發送出去的。
H264打包成rtp數據包有三種方式
- 單一封包模式
- 組合封包模式
-
分片模式
要想弄明白這三種打包方式,必須先弄清楚h264的組成結構,或者叫組成單元。
二、H264結構單元
H264數據流最基本的結構單元叫nalu單元。
H264的nalu單元組成:
[start code] + [nalu header] + [nalu paload]
-
start code: 可以為 001 或者 0001, 也就是點3個字節或者4個字節
-
nalu header: 占一個字節
-
nalu paload: 長度不定
每一幀畫面擁有一個或多個nalu單元,每個nalu單元以start code進行分離
nalu header
nalu header占一個字節,它又分了三個部分:F,NRI,TYPE
7 6-5 4-0
F NRI TYPE
- F:一般為0
- NRI:指示nalu單元的重要性,不同編碼器編出來的H264數據不同
- TYPE:nalu類型
TYPE類型:
類型 | 定義 |
---|---|
0 | 未定義 |
1-23 | NAL單元 |
24 | STAP-A 單一時間組合包 |
25 | STAP-B 單一時間組合包 |
26 | MTAP-16 多個時間組合包 |
27 | MTAP-24 多個時間組合包 |
28 | FU-A 分片 |
29 | FU-B 分片 |
30-31 | 未定義 |
特別注意的是7這SPS,8為PPS,發送SDP協議包時需進行base64編碼
25,26,27,29這四種類型基本不會出現
三、H264的RTP打包
前面說過有三種打包方式:單一封包模式,組合封包模式,分片模式
打包原則
單一封包模式: nalu單元長度小於MTU長度(通常是1500,live555定義的是2400)用此種方式封包
組合封包模式: nalu單元實在太小,多個nalu長度和都小於MTU長度
分片模式:nalu單元長度大於MTU長度
以上封包模式是按nalu長度來分的,同時也完全符合nalu單元中TYPE類型來分。
TYPE1-23 單一封包,24組合封包, 28分片封包
打包細則
單一封包:
[RTP header] + [nalu header] + [nalu payload]
組合封包:
[RTP header]+[STAP-A頭(1字節,低5位為24)] +
[第1個nalu長度(2字節)] + [第1個nalu header] + [第1個nalu payload]+
[第2個nalu長度(2字節)] + [第2個nalu header] + [第2個nalu payload]+
[第N個nalu長度(2字節)] + [第N個nalu header] + [第N個nalu payload]
分片模式封包:
此時要切分成多個RTP包
[RTP header]+[FU Indicator(1字節)]+[FU header(1字節)]+[部分nalu payload]
FU Indicator
7 6-5 4-0
F NRI TYPE
F, NRI為nalu中的F,NRI
TYPE:固定為28
FU header
7 6 5 4-0
S E R TYPE
S:開始標志(start)
E:結束標志(end)
R:保留(reserve)
TYPE: nalu中的TYPE
標志 | S | E | R |
---|---|---|---|
分片開始 | 1 | 0 | 0 |
分片中間 | 0 | 0 | 0 |
分片結束 | 0 | 1 | 0 |
RTP包頭的填充
typedef struct
{
/* byte 0 */
unsigned char csrc_len:4; /* CC expect 0 */
unsigned char extension:1; /* X expect 1, see RTP_OP below */
unsigned char padding:1; /* P expect 0 */
unsigned char version:2; /* V expect 2 */
/* byte 1 */
unsigned char payload:7; /* PT RTP_PAYLOAD_RTSP */
unsigned char marker:1; /* M expect 1 */
/* byte 2,3 */
unsigned short seq_no; /*sequence number*/
/* byte 4-7 */
unsigned long timestamp; /*time stamp*/
/* byte 8-11 */
unsigned long ssrc; /* stream number is used here. */
} RTPHeader;/*12 bytes*/
各項值填充:
符號 | 位數 | 定義 | 數值 |
---|---|---|---|
V | 2bit | 版本號 | 2 |
P | 1bit | 填充位 | 0 |
X | 1bit | 擴展位 | 0 |
CC | 4bit | CSRC數目 | 0 |
M | 1bit | 標志位 | 單一封包為1; 分片封包最后一個包為1,其余為0; |
PT | 7bit | 載荷類型 | 96(h264為96) |
SeqNum | 16bit | 序列號 | 每發一個包加1 |
Timestamp | 32bit | 時間戳 | 單一封包 +采樣率,h264為3600; 分片封包第一個加采樣率,后續不變 |
SSRC | 32bit | 同步源標識 | 任意指定,標准是一個MD5算法值,未明 |
CSRC | 0bit | 貢獻源列表 | CC為0,所以此項沒有 |
組合模式的M跟Timestamp未調查清楚,但是可以討巧,打包的時候不采用組合模式,采用單一模式。