1. 程式人生 > >H264編碼器8( H264碼流打包分析(精華))

H264編碼器8( H264碼流打包分析(精華))

來自:https://www.cnblogs.com/lidabo/p/4602422.html

H264碼流打包分析

SODB 資料位元串-->最原始的編碼資料

RBSP 原始位元組序列載荷-->在SODB的後面填加了結尾位元(RBSP trailing bits 一個bit“1”)若干位元“0”,以便位元組對齊。

EBSP 擴充套件位元組序列載荷-- >在RBSP基礎上填加了仿校驗位元組(0X03)它的原因是: 在NALU加到Annexb上時,需要填加每組NALU之前的開始碼 StartCodePrefix,如果該NALU對應的slice為一幀的開始則用4位位元組表示,ox00000001,否則用3位位元組表示 ox000001.為了使NALU主體中不包括與開始碼相沖突的,在編碼時,每遇到兩個位元組連續為0,就插入一個位元組的0x03。解碼時將0x03去掉。 也稱為脫殼操作。

h264的功能分為兩層,視訊編碼層(VCL)和網路提取層(NAL)

        VCL資料即被壓縮編碼後的視訊資料序列。在VCL資料要封裝到NAL單元中之後,才可以用來傳輸或儲存。NAL單元格式如下圖:

   

Nal頭

EBSP

Nal頭

EBSP

Nal頭

EBSP


NAL單元
    每個NAL單元是一個一定語法元素的可變長位元組字串,包括包含一個位元組的頭資訊(用來表示資料型別),以及若干整數字節的負荷資料。一個NAL單元可以攜帶一個編碼片、A/B/C型資料分割或一個序列或影象引數集。

  NAL單元按RTP序列號按序傳送。其中,T為負荷資料型別,佔5bit;R為重要性指示位,佔2個bit;最後的F為禁止位,佔1bit。具體如下:

  (1)NALU型別位

  可以表示NALU的32種不同型別特徵,型別1~12是H.264定義的,型別24~31是用於H.264以外的,RTP負荷規範使用這其中的一些值來定義包聚合和分裂,其他值為H.264保留。

  (2)重要性指示位

  用於在重構過程中標記一個NAL單元的重要性,值越大,越重要。值為0表示這個NAL單元沒有用於預測,因此可被解碼器拋棄而不會有錯誤擴散;值高於0表示此NAL單元要用於無漂移重構,且值越高,對此NAL單元丟失的影響越大。

  (3)禁止位

  編碼中預設值為0,當網路識別此單元中存在位元錯誤時,可將其設為1,以便接收方丟掉該單元,主要 用於適應不同種類的網路環境(比如有線無線相結合的環境)。例如對於從無線到有線的閘道器,一邊是無線的非IP環境,一邊是有線網路的無位元錯誤的環境。假 設一個NAL單元到達無線那邊時,校驗和檢測失敗,閘道器可以選擇從NAL流中去掉這個NAL單元,也可以把已知被破壞的NAL單元前傳給接收端。在這種情 況下,智慧的解碼器將嘗試重構這個NAL單元(已知它可能包含位元錯誤)。而非智慧的解碼器將簡單地拋棄這個NAL單元。NAL單元結構規定了用於面向分 組或用於流的傳輸子系統的通用格式。在H.320和MPEG-2系統中,NAL單元的流應該在NAL單元邊界內,每個NAL單元前加一個3位元組的起始字首 碼。在分組傳輸系統中,NAL單元由系統的傳輸規程確定幀界,因此不需要上述的起始字首碼。一組NAL單元被稱為一個接入單元,定界後加上定時資訊 (SEI),形成基本編碼影象。該基本編碼影象(PCP)由一組已編碼的NAL單元組成,其後是冗餘編碼影象(RCP),它是PCP同一視訊影象的冗餘表 示,用於解碼中PCP丟失情況下恢復資訊。如果該編碼視訊影象是編碼視訊序列的最後一幅影象,應出現序列NAL單元的end,表示該序列結束。一個影象序 列只有一個序列引數組,並被獨立解碼。如果該編碼影象是整個NAL單元流的最後一幅影象,則應出現流的end。 

  H.264採用上述嚴格的接入單元,不僅使H.264可自適應於多種網路,而且進一步提高其抗誤碼能力。序列號的設定可發現丟的是哪一個VCL單元,冗餘編碼影象使得即使基本編碼影象丟失,仍可得到較“粗糙”的影象。

 

 

實現RTP協議的H.264視訊傳輸系統

 

1.  引言
       隨著資訊產業的發展,人們對資訊資源的要求已經逐漸由文字和圖片過渡到音訊和視訊,並越來越強調獲取資源的實時性和互動性。但人們又面臨著另外一種不可避免的尷尬,就是在網路上看到生動清晰的媒體演示的同時,不得不為等待傳輸檔案而花費大量時間。為了解決這個矛盾,一種新的媒體技術應運而生,這就是流媒體技術。流媒體由於具有啟動時延小、節省客戶端儲存空間等優勢,逐漸成為人們的首選,流媒體網路應用也在全球範圍內得到不斷的發展。其中實時流傳輸協議 RTP 詳細說明了在網際網路上傳遞音訊和視訊的標準資料包格式,它與傳輸控制協議 RTCP 配合使用,成為流媒體技術最普遍採用的協議之一。 
        H.264/AVC 是ITU-T 視訊編碼專家組(VCEG)和ISO/IEC 動態影象專家組(MPEG )聯合組成的聯合視訊組(JVT)共同努力制訂的新一代視訊編碼標準,它最大的優勢是具有很高的資料壓縮比率,在同等影象質量的條件下,H.264 的壓縮比是MPEG-2 的2 倍以上,是 MPEG-4的1.5~2 倍。同時,採用視訊編碼層(VCL)和網路提取層(NAL )的分層設計,非常適用於流媒體技術進行實時傳輸。本文就是基於 RTP 協議,對 H.264 視訊進行流式打包傳輸,實現了一個基本的流媒體伺服器功能,同時利用開源播放器VLC 作為接收端,構成一個完整的H.264 視訊傳輸系統。

2.  RTP 協議關鍵引數的設定

         RTP 協議是 IETF 在 1996 年提出的適合實時資料傳輸的新型協議。RTP 協議實際上是由實時傳輸協議RTP(Real-time Transport Protocol)和實時傳輸控制協議RTCP(Real-time Transport Control Protocol)兩部分組成。RTP 協議基於多播或單播網路為使用者提供連續媒體資料的實時傳輸服務;RTCP 協議是 RTP 協議的控制部分,用於實時監控資料傳輸質量,為系統提供擁塞控制和流控制。RTP 協議在RFC3550 中有詳細介紹。每一個 RTP 資料包都由固定包頭(Header )和載荷(Payload)兩個部分組成,其中包頭前12個位元組的含義是固定的,而載荷則可以是音訊或視訊資料。RTP 固定包頭的格式如圖1所示: 

  



       

 其中比較關鍵的引數設定解釋如下:
      (1)標示位(M ):1 位,該標示位的含義一般由具體的媒體應用框架(profile )定義, 目的在於標記處RTP 流中的重要事件。
     (2)載荷型別(PT):7 位,用來指出RTP負載的具體格式。在RFC3551中,對常用的音視訊格式的RTP 傳輸載荷型別做了預設的取值規定,例如,型別2 表明該RTP資料包中承載的是用ITU G.721 演算法編碼的語音資料,採用頻率為 8000HZ,並且採用單聲道。
    (3)序號:16 位,每傳送一個 RTP 資料包,序號加 1。接受者可以用它來檢測分組丟失和恢復分組順序。
   (4)時間戳:32 位,時間戳表示了 RTP 資料分組中第一個位元組的取樣時間,反映出各RTP 包相對於時間戳初始值的偏差。對於RTP 傳送端而言,取樣時間必須來源於一個線性單調遞增的時鐘。
       從 RTP 資料包的格式不難看出,它包含了傳輸媒體的型別、格式、序列號、時間戳以及是否有附加資料等資訊。這些都為實時的流媒體傳輸提供了相應的基礎。而傳輸控制協議RTCP為 RTP傳輸提供了擁塞控制和流控制,它的具體包結構和各欄位的含義可參考RFC3550,此處不再贅述。

3.  H.264 基本流結構及其傳輸機制

3.1  H.264 基本流的結構

H.264 的基本流(elementary stream,ES)的結構分為兩層,包括視訊編碼層(VCL)和網路適配層(NAL)。視訊編碼層負責高效的視訊內容表示,而網路適配層負責以網路所要求的恰當的方式對資料進行打包和傳送。引入NAL並使之與VCL分離帶來的好處包括兩方面:其一、使訊號處理和網路傳輸分離,VCL 和NAL 可以在不同的處理平臺上實現;其二、VCL 和NAL 分離設計,使得在不同的網路環境內,閘道器不需要因為網路環境不同而對VCL位元流進行重構和重編碼。
       H.264 的基本流由一系列NALU (Network Abstraction Layer Unit )組成,不同的NALU資料量各不相同。H.264 草案指出[2],當資料流是儲存在介質上時,在每個NALU 前新增起始碼:0x000001,用來指示一個 NALU的起始和終止位置。在這樣的機制下,*在碼流中檢測起始碼,作為一個NALU得起始標識,當檢測到下一個起始碼時,當前NALU結束。每個NALU單元由一個位元組的 NALU頭(NALU Header)和若干個位元組的載荷資料(RBSP)組成。其中NALU 頭的格式如圖2 所示:

                                                                                                                   
        F:forbidden_zero_bit.1 位,如果有語法衝突,則為 1。當網路識別此單元存在位元錯誤時,可將其設為 1,以便接收方丟掉該單元。 
        NRI:nal_ref_idc.2 位,用來指示該NALU 的重要性等級。值越大,表示當前NALU越重要。具體大於0 時取何值,沒有具體規定。

 Type:5 位,指出NALU 的型別。具體如表1 所示:

                                                                                    
      需要特別指出的是,NRI 值為 7 和 8 的NALU 分別為序列引數集(sps)和影象引數集(pps)。引數集是一組很少改變的,為大量VCL NALU 提供解碼資訊的資料。其中序列引數集作用於一系列連續的編碼影象,而影象引數集作用於編碼視訊序列中一個或多個獨立的影象。如果*沒能正確接收到這兩個引數集,那麼其他NALU 也是無法解碼的。因此它們一般在傳送其它 NALU 之前傳送,並且使用不同的通道或者更加可靠的傳輸協議(如TCP)進行傳輸,也可以重複傳輸。

 

3.2  適用於 H.264 視訊的傳輸機制
       前面分別討論了RTP 協議及H.264基本流的結構,那麼如何使用RTP協議來傳輸H.264視訊了?一個有效的辦法就是從H.264視訊中剝離出每個NALU,在每個NALU前新增相應的RTP包頭,然後將包含RTP 包頭和NALU 的資料包傳送出去。下面就從RTP包頭和NALU兩方面分別闡述。
      完整的 RTP 固定包頭的格式在前面圖 1 中已經指出,根據RFC3984[3],這裡詳細給出各個位的具體設定。 
      V:版本號,2 位。根據RFC3984,目前使用的RTP 版本號應設為0x10。 
      P:填充位,1 位。當前不使用特殊的加密演算法,因此該位設為 0。 
      X:擴充套件位,1 位。當前固定頭後面不跟隨頭擴充套件,因此該位也為 0。 
      CC:CSRC 計數,4 位。表示跟在 RTP 固定包頭後面CSRC 的數目,對於本文所要實現的基本的流媒體伺服器來說,沒有用到混合器,該位也設為 0x0。
       M:標示位,1 位。如果當前 NALU為一個接入單元最後的那個NALU,那麼將M位置 1;或者當前RTP 資料包為一個NALU 的最後的那個分片時(NALU 的分片在後面講述),M位置 1。其餘情況下M 位保持為 0。 
       PT:載荷型別,7 位。對於H.264 視訊格式,當前並沒有規定一個預設的PT 值。因此選用大於 95 的值可以。此處設為0x60(十進位制96)。
      SQ:序號,16 位。序號的起始值為隨機值,此處設為 0,每傳送一個RTP 資料包,序號值加 1。 
      TS:時間戳,32 位。同序號一樣,時間戳的起始值也為隨機值,此處設為0。根據RFC3984, 與時間戳相應的時鐘頻率必須為90000HZ。 
      SSRC:同步源標示,32 位。SSRC應該被隨機生成,以使在同一個RTP會話期中沒有任何兩個同步源具有相同的SSRC 識別符。此處僅有一個同步源,因此將其設為0x12345678。
      對於每一個NALU,根據其包含的資料量的不同,其大小也有差異。在IP網路中,當要傳輸的IP 報文大小超過最大傳輸單元MTU(Maximum Transmission Unit )時就會產生IP分片情況。在乙太網環境中可傳輸的最大 IP 報文(MTU)的大小為 1500 位元組。如果傳送的IP資料包大於MTU,資料包就會被拆開來傳送,這樣就會產生很多資料包碎片,增加丟包率,降低網路速度。對於視訊傳輸而言,若RTP 包大於MTU 而由底層協議任意拆包,可能會導致接收端播放器的延時播放甚至無法正常播放。因此對於大於MTU 的NALU 單元,必須進行拆包處理。

RFC3984 給出了3 中不同的RTP 打包方案:

(1)Single NALU Packet:在一個RTP 包中只封裝一個NALU,在本文中對於小於 1400位元組的NALU 便採用這種打包方案。
       (2)Aggregation Packet:在一個RTP 包中封裝多個NALU,對於較小的NALU 可以採用這種打包方案,從而提高傳輸效率。 
       (3)Fragmentation Unit:一個NALU 封裝在多個RTP包中,在本文中,對於大於1400位元組的NALU 便採用這種方案進行拆包處理。

4.  H.264 流媒體傳輸系統的實現

      一個完整的流媒體傳輸系統包含伺服器端和客戶端兩個部分[5][6]。對於伺服器端,其主要任務是讀取H.264 視訊,從碼流中分離出每個NALU 單元,分析NALU 的型別,設定相應的 RTP 包頭,封裝 RTP 資料包併發送。而對於客戶端來說,其主要任務則是接收 RTP資料包,從RTP 包中解析出NALU 單元,然後送至*進行解碼播放。該流媒體傳輸系統的框架如圖3 所示。

 

                                                                                                

5. 結論

本文所設計的流媒體傳輸系統伺服器端執行在Windows XP 系統,用VLC 播放器作為客戶端接收H.264 視訊RTP 資料包。經測試,客戶端在經過2 秒的緩衝過後即能流暢播放,傳輸速度設為 30 幀每秒的情況下,未出現丟包拖影等現象,視訊主觀質量良好,與本地播放該H.264 視訊無明顯區別。

AnyChat採用國際領先的視訊編碼標準H.264(MPEG-4 part 10 AVC /H.264)編碼,H.264/AVC 在壓縮效率方面有著特殊的表現,一般情況下達到 MPEG-2 及 MPEG-4 簡化類壓縮效率的大約 2 倍。H.264具有許多與舊標準不同的新功能,它們一起實現了編碼效率的提高。特別是在幀內預測與編碼、幀間預測與編碼、可變向量塊大小、四分之一畫素運動估計、多參考幀預測、自適應環路去塊濾波器、整數變換、量化與變換系數掃描、熵編碼、加權預測等實現上都有其獨特的考慮。

 佰銳科技採用先進去馬賽克技術,保障在視訊通訊過程中不出現花屏、馬賽克等現象。免費測試下載地址:
http://www2.bairuitech.com/downloads/bairuisoft/AnyChatCoreSDK_V3.0.rar

 

H264 視訊檔案 幀格式 傳輸封裝等 雜碎

rfc3984 
Standards Track [Page 2] RFC 3984 RTP Payload Format for H.264 Video February 2005 1.
按照RFC3984協議實現H264視訊流媒體

nalu單元 包起始 0x 00 00 00 01

H.264 NAL格式及分析器
http://hi.baidu.com/zsw%5Fdavy/b ... c409cc7cd92ace.html
http://hi.baidu.com/zsw_davy/blo ... 081312c8fc7acc.html

----------------------------------位元流資訊----------------------------------------------

①NALU(Network Abstract Layer Unit):兩標準中的位元流都是以NAL為單位,每個NAL單元包含一個RBSP,NALU的頭資訊定義了RBSP所屬型別。型別一般包括序列引數集(SPS)、影象引數集(PPS)、增強資訊(SEI)、條帶(Slice)等,其中,SPS和PPS屬於引數集,兩標準採用引數集機制是為了將一些主要的序列、影象引數(解碼影象尺寸、片組數、參考幀數、量化和濾波引數標記等)與其他引數分離,通過解碼器先解碼出來。此外,為了增強影象的清晰度,AVS-M添加了影象頭(Picture head)資訊。讀取NALU流程中,每個NALU前有一個起始碼0x000001,為防止 內部0x000001序列競爭,H.264編碼器在最後一位元組前插入一個新的位元組——0x03,所以解碼器檢測到該序列時,需將0x03刪掉,而AVS-M只需識別出起始碼0x000001。


②讀取巨集塊型別(mb type)和巨集塊編碼模板(cbp):編解碼影象以巨集塊劃分,一個巨集塊由一個16*16亮度塊和相應的一個8*8cb和一個8*8cr色度塊組成。


(a) 兩標準的幀內、幀間預測時巨集塊的劃分是有區別的。H.264中,I_slice亮度塊有Intra_4*4和Intra_16*16兩種模式,色度塊只有8*8模式;P_slice巨集塊分為16*16、16*8、8*16、8*8、8*4、4*8、4*4共7種模式。而AVS-M中,I_slice亮度塊有I_4*4和I_Direct兩模式,P_slice時巨集塊的劃分和H.264中的劃分一致。


(b) 兩標準的巨集塊cbp值計算也不相同。H.264中,Intra_16*16巨集塊的亮度(色度)cbp直接通過讀mb type得到;非Intra_16*16巨集塊的亮度cbp=coded_block_pattern%16,色度cbp=coded_block_pattern/16 。其中,亮度cbp最低4位有效,每位決定對應巨集塊的殘差係數能不能為0;色度cbp為0時,對應殘差係數為0,cbp為1時,DC殘差係數不為0,AC係數為0,cbp為2時,DC、AC殘差係數都不為0。AVS-M中,當巨集塊型別不是P_skip時,直接從碼流中得到cbp的索引值,並以此索引值查表得到codenum值,再以codenum查表分別得到幀內/幀間cbp。此cbp為6位,每位代表巨集塊按8*8劃分時能不能包含非零係數,當變換系數不為0時,需進一步讀cbp_4*4中每位值來判斷一個8*8塊中4個4*4塊的係數能不能為0。
---------------------------------------------------------------------------------------------
總的來說H264的碼流的打包方式有兩種,一種為annex-b byte stream format的格式,這個是絕大部分編碼器的預設輸出格式,就是每個幀的開頭的3~4個位元組是H264的start_code,0x00000001或者0x000001。
另一種是原始的NAL打包格式,就是開始的若干位元組(1,2,4位元組)是NAL的長度,而不是start_code,此時必須藉助某個全域性的資料來獲得編碼器的profile,level,PPS,SPS等資訊才可以解碼。
----------------------------------------------------------------------------
AVC vs. H.264
AVC and H.264 are synonymous. The standard is known by the full names "ISO/IEC 14496-10" and "ITU-T Recommendation H.264". In addition, a number of alternate names are used (or have been) in reference to this standard. These include:

 

  • MPEG-4 part 10
  • MPEG-4 AVC
  • AVC
  • MPEG-4 (in the broadcasting world MPEG4 part 2 is ignored)
  • H.264
  • JVT (Joint Video Team, nowadays rarely used referring to actual spec)
  • H.26L (early drafts went by this name)


All of the above (and those I've missed) include the Annex B byte-stream format. Unlike earlier MPEG1/2/4 and H.26x codecs, the H.264 specification proper does not define a full bit-stream syntax. It describes a number of NAL (Network Abstraction Layer) units, a sequence of which can be decoded into video frames. These NAL units have no boundary markers, and rely on some unspecified format to provide framing.

Annex B of of the document specifies one such format, which wraps NAL units in a format resembling a traditional MPEG video elementary stream, thus making it suitable for use with containers like MPEG PS/TS unable to provide the required framing. Other formats, such as ISO base media based formats, are able to properly separate the NAL units and do not need the Annex B wrapping.

The H.264 spec suffers from a deficiency. It defines several header-type NAL units (SPS and PPS) without specifying how to pack them into the single codec data field available in most containers. Fortunately, most containers seem to have adopted the packing used by the ISO format known as MP4.

1. H.264起始碼
   在網路傳輸h264資料時,一個UDP包就是一個NALU,解碼器可以很方便的檢測出NAL分界和解碼。但是如果編碼資料儲存為一個檔案,原來的解碼器將無法從資料流中分別出每個NAL的起始位置和終止位置,為此h.264用起始碼來解決這一問題。

   H.264編碼時,在每個NAL前新增起始碼 0x000001,解碼器在碼流中檢測到起始碼,當前NAL結束。為了防止NAL內部出現0x000001的資料,h.264又提出'防止競爭 emulation prevention"機制,在編碼完一個NAL時,如果檢測出有連續兩個0x00位元組,就在後面插入一個0x03。當解碼器在NAL內部檢測到0x000003的資料,就把0x03拋棄,恢復原始資料。
0x000000   >>>>>>   0x00000300
0x000001   >>>>>>   0x00000301
0x000002   >>>>>>   0x00000302
0x000003   >>>>>>   0x00000303

附上h.264解碼nalu中檢測起始碼的演算法流程  
for(;;) 
{
if next 24 bits are 0x000001 

       startCodeFound = true 
       break; 

else 

       flush 8 bits  

}// for(;;) 
if(true == startCodeFound) 

    //startcode found 
    // Flush the start code found 
    flush 24 bits  
    //Now navigate up to next start code and put the in between stuff 
    // in the nal structure. 
    for(;;)
    { 
      get next 24 bits & check if it equals to 0x000001 
      if(false == (next 24 bits == 000001)) 
      { 
         // search for pattern 0x000000 
         check if next 24 bits are 0x000000 
         if(false == result) 
         { 
                // copy the byte into the buffer 
                copy one byte to the Nal unit             
         } 
         else 
         { 
                break; 
         } 
      } 
      else 
      { 
             break; 
      } 
   }//for(;;)
}

   2. MPEG4起始碼
       MPEG4的特色是VOP,沒有NALU的概念,仍使用startcode對每幀進行分界。MPEG4的起始碼是0x000001. 另外MPEG4中很多起始碼也很有用,比如video_object_sequence_start_code 0x000001B0 表示一個視訊物件序列的開始,VO_start_code 0x000001B6 表示一個VOP的開始. 0x000001B6之後的兩位,是00表示 I frame, 01 表示 P frame, 10 表示 B frame.

1.引言

H.264的主要目標:

1.高的視訊壓縮比

2.良好的網路親和性

解決方案:

VCL   video coding layer    視訊編碼層

NAL   network abstraction layer   網路提取層

VCL:核心演算法引擎,塊,巨集塊及片的語法級別的定義

NAL:片級以上的語法級別(如序列引數集和影象引數集),同時支援以下功能:獨立片解碼,起始碼唯一保證,SEI以及流格式編碼資料傳送

VCL設計目標:儘可能地獨立於網路的情況下進行高效的編解碼

NAL設計目標:根據不同的網路把資料打包成相應的格式,將VCL產生的位元字串適配到各種各樣的網路和多元環境中。

NALU頭結構:NALU型別(5bit)、重要性指示位(2bit)、禁止位(1bit)。 

NALU型別:1~12由H.264使用,24~31由H.264以外的應用使用。 

重要性指示:標誌該NAL單元用於重建時的重要性,值越大,越重要。 

禁止位:網路發現NAL單元有位元錯誤時可設定該位元為1,以便接收方丟掉該單元。 

2.NAL語法語義

NAL層句法:

在編碼器輸出的碼流中,資料的基本單元是句法元素。

句法表徵句法元素的組織結構。

語義闡述句法元素的具體含義。

分組都有頭部,解碼器可以很方便的檢測出NAL的分界,依次取出NAL進行解碼。

但為了節省碼流,H.264沒有另外在NAL的頭部設立表示起始位置的句法元素。

如果編碼資料是儲存在介質上的,由於NAL是依次緊密相連的,解碼器就無法在資料流中分辨出每個NAL的起始位置和終止位置。

解決方案:在每個NAL前新增起始碼:0X000001

在某些型別的介質上,為了定址的方便,要求資料流在長度上對齊,或某個常數的整數倍。所以在起始碼前新增若干位元組的0來填充。

檢測NAL的開始:

0X000001和0X000000

我們必須考慮當NAL內部出現了0X000001和0X000000

解決方案:

H.264提出了“防止競爭”機制:

0X000000——0X00000300

0X000001——0X00000301

0X000002——0X00000302

0X000003——0X00000303

為此,我們可以知道:

在NAL單元中,下面的三位元組序列不應在任何位元組對齊的位置出現

0X000000

0X000001

0X000002

Forbidden_zero_bit =0;

Nal_ref_idc:表示NAL的優先順序。0~3,取值越大,表示當前NAL越重要,需要優先受到保護。如果當前NAL是屬於參考幀的片,或是序列引數集,或是影象引數集這些重要的單位時,本句法元素必需大於0。

Nal_unit_type:當前NAL 單元的型別

3.H.264的NAL層處理

結構示意圖:

NAL以NALU(NAL unit)為單元來支援編碼資料在基於分組交換技術網路中傳輸。

它定義了符合傳輸層或儲存介質要求的資料格式,同時給出頭資訊,從而提供了視訊編碼和外部世界的介面。

NALU:定義了可用於基於分組和基於位元流系統的基本格式

RTP封裝:只針對基於NAL單元的本地NAL介面。

三種不同的資料形式:

SODB 資料位元串-->最原始的編碼資料

RBSP 原始位元組序列載荷-->在SODB的後面填加了結尾位元(RBSP trailing bits 一個bit“1”)若干位元“0”,以便位元組對齊

EBSP 擴充套件位元組序列載荷-->在RBSP基礎上填加了仿校驗位元組(0X03)它的原因是: 在NALU加到Annexb上時,需要新增每組NALU之前的開始碼StartCodePrefix,如果該NALU對應的slice為一幀的開始則用4位位元組表示,ox00000001,否則用3位位元組表示ox000001.為了使NALU主體中不包括與開始碼相沖突的,在編碼時,每遇到兩個位元組連續為0,就插入一個位元組的0x03。解碼時將0x03去掉。也稱為脫殼操作

處理過程:

1.   將VCL層輸出的SODB封裝成nal_unit, Nal_unit是一個通用封裝格式,可以適用於有序位元組流方式和IP包交換方式。

2.   針對不同的傳送網路(電路交換|包交換),將nal_unit 封裝成針對不同網路的封裝格    式。



第一步的具體過程:

VCL層輸出的位元流SODB(String Of Data Bits),到nal_unit之間,經過了以下三步處理:

1.SODB位元組對齊處理後封裝成RBSP(Raw Byte Sequence Payload)。

2.為防止RBSP的位元組流與有序位元組流傳送方式下的SCP(start_code_prefix_one_3bytes,0x000001)出現位元組競爭情形,迴圈檢測RBSP前三個位元組,在出現位元組競爭時在第三位元組前加入emulation_prevention_three_byte (0x03),具體方法:

nal_unit( NumBytesInNALunit ) {

forbidden_zero_bit

nal_ref_idc

nal_unit_type

NumBytesInRBSP = 0

for( i = 1; i < NumBytesInNALunit; i++ ) {

if( i + 2 < NumBytesInNALunit && next_bits( 24 ) = = 0x000003 ) {

rbsp_byte[ NumBytesInRBSP++ ]

rbsp_byte[ NumBytesInRBSP++ ]

i += 2

emulation_prevention_three_byte /* equal to 0x03 */

} else

rbsp_byte[ NumBytesInRBSP++ ]

}

}

3. 防位元組競爭處理後的RBSP再加一個位元組的header(forbidden_zero_bit+ nal_ref_idc+ nal_unit_type),封裝成nal_unit.

第二步的具體過程:



case1:有序位元組流的封裝



byte_stream_nal_unit( NumBytesInNALunit ) { 

while( next_bits( 24 ) != 0x000001 ) 

zero_byte /* equal to 0x00 */ 

if( more_data_in_byte_stream( ) ) { 

start_code_prefix_one_3bytes /* equal to 0x000001 */ nal_unit( NumBytesInNALunit )





類似H.320和MPEG-2/H.222.0等傳輸系統,傳輸NAL作為有序連續位元組或位元流,同時要依靠資料本身識別NAL單元邊界。在這樣的應用系統中,H.264/AVC規範定義了位元組流格式,每個NAL單元前面增加3個位元組的字首,即同步位元組。在位元流應用中,每個影象需要增加一個附加位元組作為邊界定位。還有一種可選特性,在位元組流中增加附加資料,用做擴充發送資料量,能實現快速邊界定位,恢復同步

Case2:IP網路的RTP打包封裝

分組打包的規則 

(1)額外開銷要少,使MTU尺寸在100~64k位元組範圍都可以; 

(2)不用對分組內的資料解碼就可以判別該分組的重要性; 

(3)載荷規範應當保證不用解碼就可識別由於其他的位元丟失而造成的分組不可解碼; 

(4)支援將NALU分割成多個RTP分組; 

    (5)支援將多個NALU彙集在一個RTP分組中。 

RTP的頭標可以是NALU的頭標,並可以實現以上的打包規則。 

一個RTP分組裡放入一個NALU,將NALU(包括同時作為載荷頭標的NALU頭)放入RTP的載荷中,設定RTP頭標值。為了避免IP層對大分組的再一次分割,片分組的大小一般都要小於MTU尺寸。由於包傳送的路徑不同,解碼端要重新對片分組排序,RTP包含的次序資訊可以用來解決這一問題。

NALU分割 

對於預先已經編碼的內容,NALU可能大於MTU尺寸的限制。雖然IP層的分割可以使資料塊小於64千位元組,但無法在應用層實現保護,從而降低了非等重保護方案的效果。由於UDP資料包小於64千位元組,而且一個片的長度對某些應用場合來說太小,所以應用層打包是RTP打包方案的一部分。

新的討論方案(IETF)應當符合以下特徵: 

(1)NALU的分塊以按RTP次序號升序傳輸; 

(2)能夠標記第一個和最後一個NALU分塊; 

(3)可以檢測丟失的分塊。 

NALU合併 

一些NALU如SEI、引數集等非常小,將它們合併在一起有利於減少頭標開銷。已有兩種集合分組: 

(1)單一時間集合分組(STAP),按時間戳進行組合; 

(2)多時間集合分組(MTAP),不同時間戳也可以組合。

NAL規範視訊資料的格式,主要是提供頭部資訊,以適合各種媒體的傳輸和儲存。NAL支援各種網路,包括:

1.任何使用RTP/IP協議的實時有線和無線Internet 服務

2.作為MP4檔案儲存和多媒體資訊檔案服務

3.MPEG-2系統

4.其它網 

NAL規定一種通用的格式,既適合面向包傳輸,也適合流傳送。實際上,包傳輸和流傳輸的方式是相同的,不同之處是傳輸前面增加了一個起始碼字首

在類似Internet/RTP面向包傳送協議系統中,包結構中包含包邊界識別字節,在這種情況下,不需要同步位元組。

NAL單元分為VCL和非VCL兩種

VCL NAL單元包含視訊影象取樣資訊,

非VCL包含各種有關的附加資訊,例如引數集(頭部資訊,應用到大量的VCL NAL單元)、提高效能的附加資訊、定時資訊等

引數集:

引數集是很少變化的資訊,用於大量VCL NAL單元的解碼,分為兩種型別:

1.序列引數集,作用於一串連續的視訊影象,即視訊序列。

兩個IDR影象之間為序列引數集。IDR和I幀的區別見下面。

2.   影象引數集,作用於視訊序列中的一個或多個個別的影象

序列和影象引數集機制,減少了重複引數的傳送,每個VCL NAL單元包含一個標識,指

向有關的影象引數集,每個影象引數集包含一個標識,指向有關的序列引數集的內容

因此,只用少數的指標資訊,引用大量的引數,大大減少每個VCL NAL單元重複傳送的資訊。

序列和影象引數集可以在傳送VCL NAL單元以前傳送,並且重複傳送,大大提高糾錯能力。序列和影象引數集可以在“帶內”,也可以用更為可靠的其他“帶外”通道傳送。

 

FROM:http://blog.csdn.net/cosmoslife/article/details/7619077