從零開始寫一個發送h264的rtsp服務器(下)


轉自: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未調查清楚,但是可以討巧,打包的時候不采用組合模式,采用單一模式。

版權聲明:本文為博主原創文章,轉載請注明出處 http://blog.csdn.net/jychen105/article/details/47012099


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM