RTP協議解析及H264/H265 音影片RTP打包分析

一 概述

實時傳輸協議(Real-time Transport Protocol或簡寫RTP)是一個網路傳輸協議,它是由IETF的多媒體傳輸工作小組1996年在RFC 1889中公布的。
RTP協議詳細說明了在互聯網上傳遞音頻和影片的標準數據包格式。它一開始被設計為一個多播協議,但後來被用在很多單播應用中。RTP協議常用於流媒體系統(配合RTSP協議),影片會議和一鍵通(Push to Talk)系統(配合H.323或SIP),使它成為IP電話產業的技術基礎。RTP協議和RTP控制協議RTCP一起使用,而且它是創建在UDP協議上的。
當RTSP會話建立成功,並開始傳輸時,音影片數據以RTP協議打包發送給客戶端;

二 RTP報頭解析

RTP报头
V:RTP協議的版本號,佔2位,當前協議版本號為2
P:填充標標誌,佔1位,如果P=1,則在該報文的尾部填充一個或多個額外的八位組,它們不是有效載荷的一部分。
X:擴展標誌,佔1位,如果X=1,則在RTP報頭後跟有一個擴展報頭
CC:CSRC計數器,佔4位,指示CSRC 標識符的個數
M:標記,佔1位,不同的有效載荷有不同的含義,對於影片,標記一幀的結束;對於音頻,標記會話的開始
PT:有效載荷類型,佔7位,用於說明RTP報文中有效載荷的類型,如GSM音頻、JPEM影像等
sequence number:序列號,佔16位,用於標識發送者所發送的RTP報文的序列號,每發送一個報文,序列號增1。接收者通過序列號來檢測報文丟失情況,重新排序報文,恢複數據
timestamp:時間戳,佔32位,時戳反映了該RTP報文的第一個八位組的取樣時刻。接收者使用時戳來計算延遲和延遲抖動,並進行同步控制
SSRC:同步信源標識符,佔32位,用於標識同步信源。該標識符是隨機選擇的,對弈同一個影片源,每個會話都有自己獨立的同步信源
CSRC:特約信源標識符,每個CSRC信源佔32位,可以有0-15個,具體數量由CC決定,每個CSRC標識了包含在該RTP報文有效載荷中的所有特約信源

三 H264/H265 RTP打包分析1.RTP包頭的封裝

打包時,每幀數據包均需要添加二中所述RTP包頭,對於每路影片流,RTP包頭除序列號外,基本保持不變;另一個要注意的時,由於包頭需要按位填充,當填充/發送數據時,應注意發送端數據的大小端限制。2.數據流的包頭
此處以h264,h265,aac,g711來舉例說明
g711數據在發送時,不需要額外的頭部資訊,其他三種數據流,在rtp包頭後,應按格式封裝自己的數據頭
其中h264為一個位元組,h265為兩個位元組,aac數據為四個位元組
1.h264打包
影片包時需要考慮到MTU的大小,每包數據不能超過MTU的大小,通常情況下,設備是不知道當前網路的MTU大小的。
因此都會在程式碼中指定一個大小,開發時,可以參考ffmpeg中給定該值的大小
H264數據打包格式如下:
RTP頭+h264位元組頭+影片數據幀
h264位元組頭為兩個位元組,格式如下
第一個位元組
h264第一个字节
根據ffmpeg程式碼,F為0,此處type為28,
nri = buff[0] & 0x60;
buff[0] 為影片幀的第一個數據
第二個位元組
h264第二个字节
此處type = buff[0] & 0x1f;
其中S E R的解釋如下,
SER
注意當數據包被分成多包數據後,處S E R三位,其他均與第一包保持一致,不得改變
2.h265打包
打包和h264過程類似,區別就是H265的數據頭為三個位元組,
h265的三個位元組,結構如下:
第一第二個位元組
h265第一第二个字节
參考ffmpeg程式碼 此處F為0,Type為49,LayerId為0,TID為1
第三個位元組
h265第三个字节

其中FuType = (buf[0] >> 1) & 0x3F;
S E的用法和h264中相同,此處不再敘述3.aac打包
aac在打包為RTP數據包時,每幀數據前還應該由四個位元組頭,即格式如下
RTP包頭+AAC位元組頭+AAC數據
當AAC數據前由ADTS頭時, 打包時應該跳過7位元組的ADTS頭
AAC位元組頭定義如下
位元組1:0x00
位元組2:0x01
位元組3:(data_len & 0x1fe0) >> 5
位元組4:(data_len &0x1f) << 3

四 參考程式碼

ffmpeg程式碼 rtpenc_h264_hevc.c文件
void ff_rtp_send_h264_hevc(AVFormatContext *s1, const uint8_t *buf1, int size);
此處注意,該函數將h264和h265的nalu打包放在了同一個函數中,注意根據判斷語句來區分。

Tags: