1
朱曉蓉 南京鐵道職業技術學院 |
摘 要:本文主要介紹H.264標準中的分層技術:視頻編碼麈(VCL:Video Coding Layer): ‘網絡提取層(NAL:Network Abstraction Layer)。 關鍵詞:H.264標準分層技術 視頻編碼層網絡提取層 |
H.264的算法在概念上可以分爲兩層:視頻編碼層(VCL:Video Coding Layer)負責高效的視頻 內容表示,網絡提取層(NAL:Network Abstraction Layer)負責以網絡所要求的恰當的方式對數據 進行打包和傳送。 1. NAL層 NAL層的設計主要是爲了提供“友好網絡”,使得VCL層中內容能夠簡單而有效應用於各種各樣的 系統中。NAL層可把VCL層的數據封裝成以下傳輸層: ·爲各種實時的有線和無線網絡服務的RTP/TP協議 ·文件格式如ISO MP4存貯格式和MMS格式 ·爲有線和無線會話服務的H32X協議 ·爲廣播服務的MPEG-2系統 (1)NAL單元的定義 NAL層是由NAL單元(NAL unit)所構成。每個NAL單元第一個字節是頭信息,說明NAL單元的數 據類型。接下來是負載數據,它包含整數個編碼的圖像數據字節。在負載中也有可能包含仿效阻止字 節(emulation prevention bytes),用來避免負載數據中包含有起始碼前綴(start code prefix)。 在標準中定義了兩種傳輸NAL單元結構的流格式,分別爲面向數據包的傳輸格式和麪向比特流的 傳輸格式。在比特流格式中,每個NAL單元都是由稱爲起始碼前綴(start code prefix)的三個字節 流(Ox000001)開始。爲了在NAL單元中只有一個唯一起始碼前綴,負載數據中如果包含有此二個字 節就在第三個字節前插入仿效阻止字節(Ox03)。這樣可把起始碼前綴作爲對NAL單元的唯一標識。在 每個NAL單元最後字節也許包含附加數據,用於負載數據字節同步。具體闡述可見標準中附錄B(包含 有NAL單元語法和解碼過程)。在數據包格式中,編碼的圖像數據將被封裝到傳輸協議(如RTP)包中, 在此數據包中將不包含起始碼前綴。NAL層定義在標準中的語法爲表1。 |
傳送NAL單元流分類代碼在main()函數中是利用switch—case結構來實現的。其中在input一>FileFormat結構中存放着用戶對文檔格式設置的參數,當爲O時表示比特流的格式,爲1時爲RTP數據包格式。input->infile表示需要打開的視頻文件。當文件格式爲比特流時,其NAL單元中就應包含了起始碼前綴(start code prefix)並作爲與其他NAL單元相區別唯一標識。其在標準附錄B中的語法爲表2。
在實際應用中代碼首先是找起始碼前綴三個字節(Ox000001),由上邊語法可知也許在此三個字節 前可能有許多個0字節,必須先要剔除了。然後再找下一個起始碼前綴,此時整個NAL單元就應爲第二個起始碼前綴前面字節到前一個起始碼前綴後面字節之間的字節數。接着讀取NAL單元第一個字節,具體語法可見上面NAL定義語法。操作是在函數GetAnnexbNALU中。其程序框圖如圖l: |
(2) NAL單元的分類
NAL單元可分爲VCL單元和非VCL單元。VCL單元中包含着圖像數據的抽樣值。非VCL單元包含着與圖像數據相關的附加信息,如參數設置信息(作爲圖像解碼的頭信息)和增強信息(時間信息等)。參數設置信息作爲VCL單元解碼的信息。它包括兩種參數設置:(1)序列參數設置信息(2)圖像參數設置信息。對於每個VCL單元都對應有這兩種參數設置。參數設置信息能夠提供強大糾錯能力,阻止數據的流失。在某些應用中參數設置信息可以和傳輸VCL單元信息公用一個信道(稱爲“帶內”傳輸),在另一些應用中,如圖2參數設置信息可利用比傳輸VCL單元信息更可靠的“帶外”信道進行傳輸。在
標準中根據NAL單元第一字節中nal_unit_type,把NAL單元又進行具體細分。 |
|
其中nal_unit_type爲O和13~31不作說明,1~5類型的NAL單元爲VCL單元,6~10類型的NAL 單元爲非VCL單元。 它在JM-7.5b中用了switch—case結構實現的,代碼爲: switch(nalu->nal_unit_type) { case NALU_TYPE_SLICE: case NALU_TYPE-IDR: (略) case NALU_TYPE_DPA: (略) |
case NALUJYPE_DPB: (略) case NALUJYPE_DPC: (略) case NALU_TYPE_SEI: case NALU_TYPE_PPS: ProcessPPS(nalu)://獲取圖像參數設置信息給pps結構,並保存在PicParSet[id] break: case NALU_TYPE_SPS: ProcessSPS(nalu)://獲取序列參數設置信息給sps結構,並保存在SeqParSet[id] |
break:
case NALU—TYPE_PD: (略) |
case NALU TYPE—EOSEQ: (略) |
case NALUJYPE_EOSTREAM: (略) |
case NALU_TYPE_FILL: (毋各) default: |
printf(”Found NALU type%d, len%d undefined, ignore NALU,moving on\n”, |
nalu一>nal_unit_type , nalu->len): |
這段代碼是在函數read_new_slice()中。 |
NAL單元典型碼見表3。 |
66
1
(3)NAL單元的結構 從上面對NAL單元的語法分析可知,NAL單元除了第一字節說明本單元的屬性外,還有就是負載部 分,它在標準中是以RBSP數據結構封裝着。而RBSP結構中又包含SODB數據結構,它與RBSP結構區 別爲: ①如果SODB結構中數據爲0字節,RBSP結構也將不存在。 ②否則,在RBSP結構中,緊接在SODB後一個比特,在標準中稱爲rbsp_stop_one_bit等於1。然 後加O使得字節對齊。圖3畫出NAL單元結構框圖: NAL單元 |
|
圖3 NAL單元結構框圖 |
對於在JM一7.5b中從RBSP數據結構中獲取SODB結構的代碼爲: int RBSPtoSODB(byte*streamBuffer,int last_byte_pos) { int ctr_bit,bitoffset: ’ bitoffset=O: //發現rbsp_stop_one_bit(1) ctr_bit=(streamBuffer[1ast_byte_pos一1]&(OxOl<<bitoffset)): while(ctr_bit==0) { bitoffset++: if(bitoffset==8) { if(1ast_byte_pos==0) printf(”Panic:A11 zero data sequence in RBSP\n”): assert(1ast_byte_pos!=O): last_byte_pos一=1: bitoffset=0: ) |
ctr bit。streamBuffer[1ast_byte_pos-1]&(0xOl<<(bitoffset)): ) |
函數參數last_byte pos爲NAL單元字節數減去第一個字節,streambuffer爲存放NAL單元內容 的第2字節的地址。 |
2. NAL單元流的結構 在NAL單元流中可能包含有一個或一個已編碼好的圖像序列,每個序列是由一系列的接入單元 (Access Units),它們使用同樣序列參數設置信息,能夠獨立於其他序列進行解碼。 |
開始 |
元所組成,其中包含圖像抽樣值條或條數據分片信息。隨後冗餘編碼圖像信息(redundant coded
77
結束 接入單元的結構 圖4接入單元結構 |
每個接入單元組成可見下圖4,它由一組NAL單元所形成,其包含一幅圖像的信息,解碼後可構成 一幅圖像。由圖可知在接入單元可包含接入單元定界符(access unit del imiter)幫助確定接入單元 的開始,也可包含輔助增強信息如時間信息。這裏主編碼圖像(primary coded picture)是由VCL單 |
picture)包含與主編碼圖像信息一樣的圖像內容,主要用於數據的丟失或衰變後恢復,在解碼中不作 要求。最後,如果當前接入單元(圖像)是圖像序列中最後一幀圖像,就在本接入單元中加入序列尾 (end of sequence)。如果當前接入單元(圖像)是整個NAL單元流中最後一幅圖像,則在本接入單 元后還需加入傳輸流尾(end of stream)。在每個編碼圖像序列開始第一接入單元總是IDR (instantaneous decoding refresh)接入單元。這種接入單元(圖像)屬於幀內編碼圖像,不需要 其他圖像作爲參考圖像就可以解碼。對於編碼圖像序列結構參見框圖5。 |
非vcL單元 非vcL單元 非vcL單元 非VcL單元 |
E-mai 1:summerOlOl@126.com 南京鐵道職業技術學院通信工程系 郵政編碼:210015 13851557305 |
|
接入單元 圖像序列的結構囝 |
圖5圖像序列結構 |