RTP封裝h264

網(wǎng)絡(luò)抽象層單元類型 (NALU):

NALU頭由一個(gè)字節(jié)組成,它的語法如下:

Paste_Image.png

F: 1個(gè)比特. forbidden_zero_bit. 在 H.264 規(guī)范中規(guī)定了這一位必須為 0.
NRI: 2個(gè)比特. nal_ref_idc. 取00~11,似乎指示這個(gè)NALU的重要性,如00的NALU解碼器可以丟棄它而不影響圖像的回放.
Type: 5個(gè)比特. nal_unit_type. 這個(gè)NALU單元的類型.簡述如下:

Paste_Image.png

h264僅用1-23,24以后的用在RTP H264負(fù)載類型頭中


不同類型的NALU的重要性指示如下表所示:

Paste_Image.png

RTP 頭的結(jié)構(gòu):

Paste_Image.png

V: RTP協(xié)議的版本號(hào),占2bits,當(dāng)前協(xié)議版本號(hào)為2
P: 填充標(biāo)志,占1bit,如果P=1,則在該報(bào)文的尾部填充一個(gè)或多個(gè)額外的八位組,它們不是有效載荷的一部分。
X: 擴(kuò)展標(biāo)志,占1bit,如果X=1,則在RTP報(bào)頭后跟有一個(gè)擴(kuò)展報(bào)頭
CC: CSRC計(jì)數(shù)器,占4位,指示CSRC 標(biāo)識(shí)符的個(gè)數(shù)
M: 1bit,標(biāo)記解釋由設(shè)置定義,目的在于允許重要事件在包流中標(biāo)記出來。如不同的有效載荷有不同的含義,對(duì)于視頻,標(biāo)記一幀的結(jié)束;對(duì)于音頻,標(biāo)記會(huì)話的開始。
負(fù)載類型 Payload type(PT): 7bits
注:rfc里面對(duì)一些早期的格式定義了這個(gè)payload type。但是后來的,如h264并沒有分配,那就用96來代替。因此現(xiàn)在96以上都不表示特定的格式,具體表示什么要用sdp或者其他協(xié)議來協(xié)商。
序列號(hào) Sequence number(SN): 16bits,用于標(biāo)識(shí)發(fā)送者所發(fā)送的RTP報(bào)文的序列號(hào),每發(fā)送一個(gè)報(bào)文,序列號(hào)增1,序列號(hào)的初始值是隨機(jī)產(chǎn)生的??梢杂糜跈z查丟包以及進(jìn)行數(shù)據(jù)包排序。
時(shí)間戳 Timestamp: 32bits,必須使用90kHz時(shí)鐘頻率。
同步信源(SSRC)標(biāo)識(shí)符: 32bits,用于標(biāo)識(shí)同步信源。該標(biāo)識(shí)符是隨機(jī)隨機(jī)產(chǎn)生的,參加同一視頻會(huì)議的兩個(gè)同步信源不能有相同的SSRC。
特約信源(CSRC)標(biāo)識(shí)符: 每個(gè)CSRC標(biāo)識(shí)符占32bits,可以有0~15個(gè)。每個(gè)CSRC標(biāo)識(shí)了包含在該RTP報(bào)文有效載荷中的所有特約信源。

上面介紹了NALU和RTP header的基本結(jié)構(gòu),下面介紹的全部都是RTP PayLoad的部分
Rtp負(fù)載第一個(gè)字節(jié)的結(jié)構(gòu)如下,它和H.264的NALU頭結(jié)構(gòu)一致,可以把它認(rèn)為是RTP h264負(fù)載類型字節(jié),完全是多增加的一個(gè)字節(jié),不影響后面的NALU結(jié)構(gòu)

Paste_Image.png

封包介紹:

單一NAL單元模式

對(duì)于 NALU 的長度小于 MTU 大小的包, 一般采用單一 NAL 單元模式. 對(duì)于一個(gè)原始的 H.264 NALU 單元常由 [Start Code] [NALU Header] [NALU Payload] 三部分組成, 其中 Start Code 用于標(biāo)示這是一個(gè)
NALU 單元的開始, 必須是 "00 00 00 01" 或 "00 00 01", NALU 頭僅一個(gè)字節(jié), 其后都是 NALU 單元內(nèi)容. 打包時(shí)去除 "00 00 01" 或 "00 00 00 01" 的開始碼, 把其他數(shù)據(jù)封包的 RTP 包即可.

Paste_Image.png

例: 如有一個(gè) H.264 的 NALU 是這樣的:
[00 00 00 01 67 42 A0 1E 23 56 0E 2F ... ]
這是一個(gè)序列參數(shù)集 NAL 單元. [00 00 00 01] 是四個(gè)字節(jié)的開始碼, 67 是 NALU 頭, 42 開始的數(shù)據(jù)是 NALU 內(nèi)容.
封裝成 RTP 包將如下:
[ RTP Header ] [ 67 42 A0 1E 23 56 0E 2F ]
即只要去掉 4 個(gè)字節(jié)的開始碼就可以了.

組合封包模式

其次, 當(dāng) NALU 的長度特別小時(shí), 可以把幾個(gè) NALU 單元封在一個(gè) RTP 包中.

Paste_Image.png

這里只介紹STAP-A模式,如果是STAP-B的話會(huì)多加入一個(gè)DON域,另外還有MTAP16、MTAP24,具體不介紹,可以看rfc文檔,文章尾貼一個(gè)鏈接可以去看。
轉(zhuǎn)載的話注明一下作者:jwybobo2007 出處:http://blog.csdn.net/jwybobo2007/article/details/7054140
例:


如有一個(gè) H.264 的 NALU 是這樣的:
[00 00 00 01 67 42 A0 1E 23 56 0E 2F ... ]
[00 00 00 01 68 42 B0 12 58 6A D4 FF ... ]
封裝成 RTP 包將如下:
[ RTP Header ] [78 (STAP-A頭,占用1個(gè)字節(jié))] [第一個(gè)NALU長度 (占用兩個(gè)字節(jié))] [ 67 42 A0 1E 23 56 0E 2F ] [第二個(gè)NALU長度 (占用兩個(gè)字節(jié))] [68 42 B0 12 58 6A D4 FF ... ]

FU-A

當(dāng)NALU的長度超過MTU時(shí),就必須對(duì)NALU單元進(jìn)行分片封包.也稱為Fragmentation Units(FUs)。
本荷載類型允許分片一個(gè)NAL單元到幾個(gè)RTP包中。下圖 表示FU-A的RTP荷載格式。FU-A由1字節(jié)的分片單元指示,1字節(jié)的分片單元頭,和分片單元荷載組成。


FU指示字節(jié)有以下格式:



FU指示字節(jié)的類型域的28,29表示FU-A和FU-B。F的使用在5。3描述。NRI域的值必須根據(jù)分片NAL單元的NRI域的值設(shè)置。

注意:這是第一個(gè)字節(jié)FU indicator,NRI為 幀重要程度 00 可以丟 ,11不能丟。F一般設(shè)置0。這一個(gè)字節(jié)用來表示當(dāng)前包為分片F(xiàn)U-A包。

FU頭的格式如下:


S: 1 bit
當(dāng)設(shè)置成1,開始位指示分片NAL單元的開始。當(dāng)跟隨的FU荷載不是分片NAL單元荷載的開始,開始位設(shè)為0。
E: 1 bit
當(dāng)設(shè)置成1, 結(jié)束位指示分片NAL單元的結(jié)束,即, 荷載的最后字節(jié)也是分片NAL單元的最后一個(gè)字節(jié)。當(dāng)跟隨的
FU荷載不是分片NAL單元的最后分片,結(jié)束位設(shè)置為0。
R: 1 bit
保留位必須設(shè)置為0,接收者必須忽略該位。
Type: 5 bits
NAL單元荷載類型定義在[1]的表7-1.

注意:這是第二個(gè)字節(jié),用來表示開始結(jié)束和NAL幀的類型。

示例代碼:

if (iLen > iSize) { //超過MTU
        const unsigned char s_e_r_Start = 0x80;
        const unsigned char s_e_r_Mid = 0x00;
        const unsigned char s_e_r_End = 0x40;
        //獲取幀頭數(shù)據(jù),1byte
        unsigned char naluType = *((unsigned char *) pcData) & 0x1f; //獲取NALU的5bit 幀類型

        unsigned char nal_ref_idc = *((unsigned char *) pcData) & 0x60; //獲取NALU的2bit 幀重要程度 00 可以丟 11不能丟
        //nal_ref_idc = 0x60;
        //組裝FU-A幀頭數(shù)據(jù) 2byte
        unsigned char f_nri_type = nal_ref_idc + 28;//F為0 1bit,nri上面獲取到2bit,28為FU-A分片類型5bit
        unsigned char s_e_r_type = naluType;
        bool bFirst = true;
        bool mark = false;
        int nOffset = 1;
        while (!mark) {
            if (iLen < nOffset + iSize) {           //是否拆分結(jié)束
                iSize = iLen - nOffset;
                mark = true;
                s_e_r_type = s_e_r_End + naluType;
            } else {
                if (bFirst == true) {
                    s_e_r_type = s_e_r_Start + naluType;
                    bFirst = false;
                } else {
                    s_e_r_type = s_e_r_Mid + naluType;
                }
            }
            memcpy(aucSectionBuf, &f_nri_type, 1);
            memcpy(aucSectionBuf + 1, &s_e_r_type, 1);
            memcpy(aucSectionBuf + 2, (unsigned char *) pcData + nOffset, iSize);
            nOffset += iSize;
            makeH264Rtp(aucSectionBuf, iSize + 2, mark, uiStamp);
        }
    } else {
        makeH264Rtp(pcData, iLen, true, uiStamp);
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 國家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說閱讀 12,309評(píng)論 6 13
  • 視頻壓縮編碼的目標(biāo)1)保證壓縮比例2)保證恢復(fù)的質(zhì)量3)易實(shí)現(xiàn),低成本,可靠性 壓縮的出發(fā)點(diǎn)(可行性)1)時(shí)間相關(guān)...
    rogerwu1228閱讀 4,334評(píng)論 0 11
  • 概念 RTP: Real-time Transport Protocol,實(shí)時(shí)傳輸協(xié)議,一般用于多媒體數(shù)據(jù)的傳輸。...
    睡后3k閱讀 14,398評(píng)論 1 10
  • 使用RTP傳輸H264的時(shí)候,需要用到sdp協(xié)議描述,其中有兩項(xiàng):Sequence Parameter Sets ...
    rogerwu1228閱讀 4,299評(píng)論 0 8
  • 原來愛上你目錄 上一章:原來愛上你(十八):愛的緊箍咒 “小白,走了嗎?”康偉走到許小白身旁。 “馬上就好了。”許...
    洋阿洋閱讀 510評(píng)論 0 0

友情鏈接更多精彩內(nèi)容