日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

RTP之H264封包和解包

發(fā)布時間:2024/4/11 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 RTP之H264封包和解包 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

RTP之H264封包和解包


目錄

  • H264打包RTP的方法
  • 打包方式之Single NAL Unit
  • 打包方式之FU-A
  • FU indication
  • FU header

  • 1. H264打包RTP的方法

  • RTP的特點不僅僅?持承載在UDP上,這樣利于低延遲?視頻數(shù)據(jù)的傳輸,另外?個特點是它允許通過其它協(xié)議接收端和發(fā)送端協(xié)商?視頻數(shù)據(jù)的封裝和編解碼格式,這樣固定頭的playload type字段就?較靈活。截??前為?,RTP是我?過傳輸?視頻數(shù)據(jù)類型最多的,具體參考:https://en.wikipedia.org/wiki/RTP_payload_formats
  • 以H264裸碼流NALU為例,進(jìn)?H264的打包,其中H264打包的詳細(xì)?法要參考RFC6184?檔。
  • H.264標(biāo)準(zhǔn)協(xié)議定義了兩種不同的類型:?種是VCL即Video Coding Layer , ? 種 是 NAL 即Network Abstraction Layer。其中前者就是編碼器吐出來的原始編碼數(shù)據(jù),沒有考慮傳輸和存儲問題。后?這種就是為了展現(xiàn)H.264的?絡(luò)親和性,對VCL輸出的slice?數(shù)據(jù)進(jìn)?了封裝為NALUs(NAL Units),然后再封裝為RTP包進(jìn)?傳輸,這些都是H.264的基礎(chǔ),?后續(xù)?章。
  • NALU的基本格式是:NALU Header + NALU Data,其中NALU的頭由?個字節(jié)組成如下所示:
  • +---------------+|0|1|2|3|4|5|6|7|+-+-+-+-+-+-+-+-+|F|NRI| Type |+---------------+
  • 其中
  • F (1bit):如果是壞幀,則置1,其余H.264固定為0。
  • NRI(2 bit):?來指示該NALU 的重要性等級。值越?,表示當(dāng)前NALU越重要。具體?于0 時取何值,沒有具體規(guī)定。
    例如:如果是00,則表示此幀即使丟失了,也不影響解碼;其他值則表示此幀如果丟失了,會影響解碼,這個字段指明了該NALU的重要性,但是實際我們不太關(guān)?這個字段。
  • Nalu_Type(5 bit):NAL Unit的類型,這個值指明了NALU的類型,其中NALU的類型?下表
  • Nalu_TypeNALU內(nèi)容備注
    0未指定
    1?IDR圖像編碼的slice?如普通I、P、B幀
    2編碼slice數(shù)據(jù)劃分A2類型時,只傳遞?中最重要的信息,如?頭,?中宏塊的預(yù)測模式等;?般不會?到;
    3編碼slice數(shù)據(jù)劃分B3類型是只傳輸殘差;?般不會?到;
    4編碼slice數(shù)據(jù)劃分C4時則只可以傳輸殘差中的AC系數(shù);?般不會?到;
    5IDR圖像中的編碼sliceIDR幀,IDR?定是I幀但是I幀不?定是IDR幀。
    6SEI補充增強信息單元可以存?些私有數(shù)據(jù)等;
    7SPS 序列參數(shù)集編碼的參數(shù)配置
    8PPS 圖像參數(shù)集編碼的參數(shù)配置
    9接?單元定界符
    10序列結(jié)束
    11碼流結(jié)束
    12填充數(shù)據(jù)
    24STAP-A Single-time aggregation packet單?時間聚合包模式,意味著?個RTP包可以傳輸多個NALU,但是這些NALU的編碼時間要?樣才能聚合到?個RTP。
    25STAP-B Single-time aggregation packet單?時間聚合包模式,?STAP-B多?個DON
    26MTAP 16 Muti-time aggregation packet多個時間聚合包模式:意味著?個RTP包可以傳輸多個NALU,但是這些NALU的編碼時間有可能不?樣。
    27MTAP 24 Muti-time aggregation packet多個時間的聚合包模式
    28FU-A Fragmentation unit分包模式:當(dāng)?個RTP容納不下?個NALU時,就需要FUs這種格式。
    29 FU-BFragmention unit分包模式
    30-31未指定,保留
  • 參考?檔:https://tools.ietf.org/html/rfc6184
  • 我們看到1-11就是NALU的單個包類型,但是?個NALU的??是不?樣的,如果是?視頻數(shù)據(jù)的SPS PPS才??個字節(jié),對于IDR幀,則有可能??KB。
  • 這樣把NALU打包到RTP?式就很多,分為:
  • ?個RTP包承載?個NALU;
  • 多個NALU合并到?個RTP;
  • ?個?的NALU切分成多個RTP
  • 同時由于時間戳的問題,就有了24-29?種類型。
  • 但是對于發(fā)送端組RTP包的??來說,盡可能找簡單的打包?式。對于接受端則需要適配各種發(fā)送端的打包?式,因為?法決定輸?源的打包?式。這?先分享下我們的打包?式,?較簡單(打包的時候不要搞太復(fù)雜的模式):
  • 我們對于NALU的?度<=1400(rtp payload size)的則采?的是單?NALU打包到單?的RTP包中;
  • 我們對于NALU的?度>1400的則采?了FU-A的?式進(jìn)?了打包,這種就是把?個?的NALU進(jìn)?了切分,最后接收?則進(jìn)?了合并,把多個RTP包合并成?個完整的NALU即可;
  • 為什么NALU的?度?于1400字節(jié)就要進(jìn)?FU-A切?,是因為底層MTU??值固定為1500,從傳輸效率講,這??1400作為切分條件。
  • 同時我們發(fā)現(xiàn)現(xiàn)在視頻監(jiān)控領(lǐng)域攝像頭通過RTP 傳輸碼流的打包?式都是基本這種,這種打包?案簡單容易實現(xiàn),?滿?需要。
  • 28、29、30三個RTP分別傳輸?shù)腟PS、PPS、SEI這三種NALU,其中?個NALU分到?個RTP包,這是單?打包?式;
  • 31、32三個RTP包分別傳輸了IDR幀的NALU單元,由于?較?,發(fā)送?采?了FU-A的打包?式;
  • 上圖還顯示了SPS、PPS、SEI的RTP包固定頭,Seq初始值不為0,為隨機值,并且?個RTP包就順序+1,這跟上?分析的?致;
  • 上?SPS、PPS、SEI本身不涉及時間戳,但是這?頭填充為和??后?的第?個RTP保持?致,同樣IDR的NALU切分的不同RTP包時間戳也是?樣的;
  • RTP一般一個包的大小是140bbyte左右,指的是RTP payload,不包含RTP header
  • udp每個包有大小限制,MTU一般是1500byte,sendto一次不能發(fā)送超過1500byte的數(shù)據(jù)
  • RTP包有大小之分
  • SPS:25byte左右
  • PPS:5byte左右
  • SEI:600byte左右
  • I幀:1080p為200K字節(jié)左右,一個RTP包發(fā)送不完一個I幀
  • 同一個NALU劃分成多個RTP包進(jìn)行發(fā)送,比如I幀拆分成多個RTP包
  • 一個RTP包也可以發(fā)送多個NALU,比如:sps和pps、sei幀一起發(fā)送,很多時候,為了簡化程序,sps,pps,sei幀還是發(fā)送獨立的包。
  • 那么到底將單?的NALU打包到RTP或者把?較?的NLAU打包到多個RTP即FU-A?式是怎么操作的呢?
  • 1. 打包方式之Single NAL Unit

  • 就是?個RTP包打包?個單獨的NALU?式,其實最好理解,就是在RTP固定頭后?直接填充NLAU單元數(shù)據(jù)即可,即:
  • RTP Header + NALU Header + NALU Data; (不包括startcode)
  • 進(jìn)?抓包和寫?件,我們發(fā)現(xiàn)寫?件的SPS和抓包RTP包固定頭后?的負(fù)載完全是?致的,寫?件中的SPS:
  • 抓包中的RTP固定頭后?的SEI:
  • 2. 打包方式之FU-A

  • 這種打包?式也不復(fù)雜,為了解釋清楚,需要了解下?兩個數(shù)據(jù)包頭即FU indicator和Fu header
  • 1. FU indication
    +---------------+|0|1|2|3|4|5|6|7|+-+-+-+-+-+-+-+-+|F|NRI| Type |+---------------+
  • 這??的的F和NRI已經(jīng)在NALU的Header解釋清楚了,就是NALU頭的前?三個bit位,后?的TYPE就是NALU的FU-A類型28,這樣在RTP固定頭后?第?字節(jié)的后?5bit提取出來就確認(rèn)了該RTP包承載的不是?個完整的NALU,是其?部分。
  • 那么問題來了,?個NALU切分成多個RTP包傳輸,那么到底從哪?開始哪?結(jié)束呢?可能有?說RTP包固定頭不是有mark標(biāo)記么,注意區(qū)分那個是以幀圖像的結(jié)束標(biāo)記,這?要確定是NALU結(jié)束的標(biāo)記,其次NALU的類型呢?那么就需要RTP固定12字節(jié)后?的Fu Header來進(jìn)?區(qū)分。
  • 2. FU header
    +---------------+|0|1|2|3|4|5|6|7|+-+-+-+-+-+-+-+-+|S|E|R| Type |+---------------+
  • 字段解釋:

  • 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單元的最后?個字節(jié),當(dāng)跟隨的FU荷載不是分?NAL單元的最后分?,結(jié)束位設(shè)置為0。也就是說?個NALU切?時,第?個切?的SE是10,然后中間的切?是00,最后?個切?時01。
  • R: 1 bit,保留位必須設(shè)置為0,接收者必須忽略該位。
  • Type: 5 bits:此處的Type就是NALU頭中的Type,取1-23的那個值,表示 NAL單元荷載類型定義。
  • 綜上所述:

  • 對于?較?的NLAU進(jìn)?FU-A切?時,其中NALU的Header字段在RTP打包時劃分為兩個字節(jié)

  • NALU header的前3bit為RTP固定頭后?第?個字節(jié)FU-indication的前3bit,后?5bit后?跟了FU-A打包這種類型28;
  • NALU header的后?5bit變成了RTP固定頭第?字節(jié)的后?5bit,其中前3bit標(biāo)識了分?的開始和結(jié)束
  • 為了驗證這種打包?式,我們同樣進(jìn)?了寫?件和抓包,對第?個IDR幀的NLAU采取的這種分?進(jìn)?了研究。

  • 第?個IDR幀的NALU第?個切?:

  • FU indication ?六機制:0x7C ?進(jìn)制:0111 1100 FU header ?六進(jìn)制:0x85 ?進(jìn)制:1000 0101 這?的SE是10,則說明該RTP包承載的NALU的第?個切?
  • 這樣我們提取FU indication字節(jié)的前3bit位和Fu header字節(jié)后5bit位則為0110 0101即0x65這剛好符合IDR幀的NALU Header定義,后?的88 84 00 2f等?進(jìn)制就是NALU的DATA字段。
  • 第?個IDR幀的NALU第?個切?:
  • FU indication ?六機制:0x7C ?進(jìn)制:0111 1100 FU header ?六進(jìn)制:0x05 ?進(jìn)制:0000 0101 這?的SE是00,則說明該RTP包承載的NALU的中間切?。
  • 按照同樣?法提取,則NALU Header的?進(jìn)制為0110 0101即0x65,同樣說明是IDR幀類型,類似這種的中間切?有很多,從31-56RTP包都是中間切?,直到最后?個NALU的切?。
  • 第?個IDR幀的NALU最后?個切?:
  • FU indication ?六機制:0x7C ?進(jìn)制:0111 1100 FU header ?六進(jìn)制:0x45 ?進(jìn)制:0100 0101 這?的SE是01,則說明該RTP包承載的NALU的最后?個切?
  • 當(dāng)然通過抓包你還可以到IDR幀時?較?的,?后?的P幀就相對?較?,因為?個NALU切?4次就完了,同樣能看到時間戳的變化值等信息。
  • 我們可以看到發(fā)送端?般采?Single NAL Unit和FU-A打包?式就基本可以將H264數(shù)據(jù)發(fā)送到接收端了,對于AAC?頻來說,直接將ADTS頭部去掉以1024字節(jié)組成?幀直接塞到RTP即可,打包并不難。
  • 總結(jié)

    以上是生活随笔為你收集整理的RTP之H264封包和解包的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。