午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

H.264 NAL層解析(0x00000001,編碼,打包,NALU)

 zhanganl 2014-06-10

H.264 NAL層解析(0x00000001,編碼,打包,NALU)

 

1.引言

H.264的主要目標(biāo):

1.高的視頻壓縮比

2.良好的網(wǎng)絡(luò)親和性

解決方案:

VCL  video codinglayer       視頻編碼層

NAL  network abstraction layer  網(wǎng)絡(luò)提取層

VCL:核心算法引擎,塊,宏塊及片的語(yǔ)法級(jí)別的定義

NAL:片級(jí)以上的語(yǔ)法級(jí)別(如序列參數(shù)集和圖像參數(shù)集),同時(shí)支持以下功能:獨(dú)立片解碼,起始碼唯一保證,SEI以及流格式編碼數(shù)據(jù)傳送

VCL設(shè)計(jì)目標(biāo):盡可能地獨(dú)立于網(wǎng)絡(luò)的情況下進(jìn)行高效的編解碼

NAL設(shè)計(jì)目標(biāo):根據(jù)不同的網(wǎng)絡(luò)把數(shù)據(jù)打包成相應(yīng)的格式,將VCL產(chǎn)生的比特字符串適配到各種各樣的網(wǎng)絡(luò)和多元環(huán)境中。

NALU頭結(jié)構(gòu):NALU類型(5bit)、重要性指示位(2bit)、禁止位(1bit)。

NALU類型:1~12由H.264使用,24~31由H.264以外的應(yīng)用使用。

重要性指示:標(biāo)志該NAL單元用于重建時(shí)的重要性,值越大,越重要。

禁止位:網(wǎng)絡(luò)發(fā)現(xiàn)NAL單元有比特錯(cuò)誤時(shí)可設(shè)置該比特為1,以便接收方丟掉該單元。

 

 

2.NAL語(yǔ)法語(yǔ)義

NAL層句法:

在編碼器輸出的碼流中,數(shù)據(jù)的基本單元是句法元素。

句法表征句法元素的組織結(jié)構(gòu)。

語(yǔ)義闡述句法元素的具體含義。

分組都有頭部,解碼器可以很方便的檢測(cè)出NAL的分界,依次取出NAL進(jìn)行解碼。

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

如果編碼數(shù)據(jù)是存儲(chǔ)在介質(zhì)上的,由于NAL是依次緊密相連的,解碼器就無(wú)法在數(shù)據(jù)流中分辨出每個(gè)NAL起始位置和終止位置

解決方案:在每個(gè)NAL前添加起始碼:0X000001

在某些類型的介質(zhì)上,為了尋址的方便,要求數(shù)據(jù)流在長(zhǎng)度上對(duì)齊,或某個(gè)常數(shù)的整數(shù)倍。所以在起始碼前添加若干字節(jié)的0來(lái)填充。

檢測(cè)NAL的開(kāi)始:

0X000001和0X00000001

我們必須考慮當(dāng)NAL內(nèi)部出現(xiàn)了0X000001和0X000000

如果NALU對(duì)應(yīng)的Slice為一幀的開(kāi)始,則用4字節(jié)表示,即0x00000001;否則用3字節(jié)表示,0x000001。 

 

解決方案:為了防止NAL內(nèi)部出現(xiàn)0x000001的數(shù)據(jù),h.264又提出'防止競(jìng)爭(zhēng) emulation prevention"機(jī)制,在編碼完一個(gè)NAL時(shí),如果檢測(cè)出有連續(xù)兩個(gè)0x00字節(jié),就在后面插入一個(gè)0x03,則在NAL數(shù)據(jù)內(nèi)肯定不會(huì)存在NAL起始碼0x000001。當(dāng)解碼器在NAL內(nèi)部檢測(cè)到0x000003的數(shù)據(jù),就把0x03拋棄,恢復(fù)原始數(shù)據(jù)。   
  0x000000  >>>>>>  0x00000300(結(jié)束碼)

   0x000001 >>>>>>  0x00000301(起始碼)

   0x000002 >>>>>>  0x00000302(保留)

   0x000003 >>>>>>  0x00000303(保證解碼器正常工作)

 

H.264提出了“防止競(jìng)爭(zhēng)”機(jī)制:

0X000000——0X00000300

0X000001——0X00000301

0X000002——0X00000302

0X000003——0X00000303

為此,我們可以知道:

在NAL單元中,下面的三字節(jié)序列不應(yīng)在任何字節(jié)對(duì)齊的位置出現(xiàn)

0X000000

0X000001

0X000002

 

Forbidden_zero_bit=0;

Nal_ref_idc:表示NAL的優(yōu)先級(jí)。0~3,取值越大,表示當(dāng)前NAL越重要,需要優(yōu)先受到保護(hù)。如果當(dāng)前NAL是屬于參考幀的片,或是序列參數(shù)集,或是圖像參數(shù)集這些重要的單位時(shí),本句法元素必需大于0。

Nal_unit_type:當(dāng)前NAL 單元的類型

 標(biāo)識(shí)NAL單元中的RBSP數(shù)據(jù)類型,其中,nal_unit_type為1, 2, 3, 4, 5的NAL單元稱為VCL的NAL單元,其他類型的NAL單元為非VCL的NAL單元。

§    0:未規(guī)定

§    1:非IDR圖像中不采用數(shù)據(jù)劃分的片段

§    2:非IDR圖像中A類數(shù)據(jù)劃分片段

§    3:非IDR圖像中B類數(shù)據(jù)劃分片段

§    4:非IDR圖像中C類數(shù)據(jù)劃分片段

§    5:IDR圖像的片段

§    6:補(bǔ)充增強(qiáng)信息(SEI)

§    7:序列參數(shù)集(SPS

§    8:圖像參數(shù)集(PPS

§    9:分割符

§    10:序列結(jié)束符

§    11:流結(jié)束符

§    12:填充數(shù)據(jù)

§    13:序列參數(shù)集擴(kuò)展

§    14:帶前綴的NAL單元

§    15:子序列參數(shù)集

§    16 –18:保留

§    19:不采用數(shù)據(jù)劃分的輔助編碼圖像片段

§    20:編碼片段擴(kuò)展

§    21 –23:保留

§    24 –31:未規(guī)定

 

 

3.H.264的NAL層處理

結(jié)構(gòu)示意圖:

NAL以NALU(NAL unit)為單元來(lái)支持編碼數(shù)據(jù)在基于分組交換技術(shù)網(wǎng)絡(luò)中傳輸。它定義了符合傳輸層或存儲(chǔ)介質(zhì)要求的數(shù)據(jù)格式,同時(shí)給出頭信息,從而提供了視頻編碼和外部世界的接口。

NALU:定義了可用于基于分組和基于比特流系統(tǒng)的基本格式

 

 

RTP封裝:只針對(duì)基于NAL單元的本地NAL接口。

三種不同的數(shù)據(jù)形式:

SODB 數(shù)據(jù)比特串-->最原始的編碼數(shù)據(jù) (raw

RBSP 原始字節(jié)序列載荷-->在SODB的后面填加了結(jié)尾比特(RBSP trailing bits一個(gè)bit“1”)若干比特“0”,以便字節(jié)對(duì)齊

EBSP 擴(kuò)展字節(jié)序列載荷-->在RBSP基礎(chǔ)上填加了仿校驗(yàn)字節(jié)(0X03)它的原因是: 在NALU加到Annexb上時(shí),需要添加每組NALU之前的開(kāi)始碼StartCodePrefix,如果該NALU對(duì)應(yīng)的slice為一幀的開(kāi)始則用4位字節(jié)表示,0x00000001,否則用3位字節(jié)表示0x000001.為了使NALU主體中不包括與開(kāi)始碼相沖突的,在編碼時(shí),每遇到兩個(gè)字節(jié)連續(xù)為0,就插入一個(gè)字節(jié)的0x03。解碼時(shí)將0x03去掉。也稱為脫殼操作

 

 

處理過(guò)程

1.將VCL層輸出的SODB封裝成nal_unit, Nal_unit是一個(gè)通用封裝格式,可以適用于有序字節(jié)流方式和IP包交換方式

2.針對(duì)不同的傳送網(wǎng)絡(luò)(電路交換|包交換),將nal_unit 封裝成針對(duì)不同網(wǎng)絡(luò)的封裝格式。

 

第一步的具體過(guò)程:

VCL層輸出的比特流SODB(String OfData Bits),到nal_unit之間,經(jīng)過(guò)了以下三步處理:

1.SODB字節(jié)對(duì)齊處理后封裝成RBSP(RawByte Sequence Payload)。

 

2.為防止RBSP的字節(jié)流與有序字節(jié)流傳送方式下的SCP(start_code_prefix_one_3bytes,0x000001)出現(xiàn)字節(jié)競(jìng)爭(zhēng)情形,循環(huán)檢測(cè)RBSP前三個(gè)字節(jié),在出現(xiàn)字節(jié)競(jìng)爭(zhēng)時(shí)在第三字節(jié)前加入emulation_prevention_three_byte0x03

具體方法

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. 防字節(jié)競(jìng)爭(zhēng)處理后的RBSP再加一個(gè)字節(jié)的header(forbidden_zero_bit+ nal_ref_idc+ nal_unit_type),封裝成nal_unit.

 

 

第二步的具體過(guò)程:

 

case1:有序字節(jié)流的封裝

 

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等傳輸系統(tǒng),傳輸NAL作為有序連續(xù)字節(jié)或比特流,同時(shí)要依靠數(shù)據(jù)本身識(shí)別NAL單元邊界。在這樣的應(yīng)用系統(tǒng)中,H.264/AVC規(guī)范定義了字節(jié)流格式,每個(gè)NAL單元前面增加3個(gè)字節(jié)的前綴,即同步字節(jié)。在比特流應(yīng)用中,每個(gè)圖像需要增加一個(gè)附加字節(jié)作為邊界定位。還有一種可選特性,在字節(jié)流中增加附加數(shù)據(jù),用做擴(kuò)充發(fā)送數(shù)據(jù)量,能實(shí)現(xiàn)快速邊界定位,恢復(fù)同步

Case2:IP網(wǎng)絡(luò)的RTP打包封裝

分組打包的規(guī)則

    (1)額外開(kāi)銷要少,使MTU尺寸在100~64k字節(jié)范圍都可以;

    (2)不用對(duì)分組內(nèi)的數(shù)據(jù)解碼就可以判別該分組的重要性;

    (3)載荷規(guī)范應(yīng)當(dāng)保證不用解碼就可識(shí)別由于其他的比特丟失而造成的分組不可解碼;

    (4)支持將NALU分割成多個(gè)RTP分組

    (5)支持將多個(gè)NALU匯集在一個(gè)RTP分組中。

    RTP的頭標(biāo)可以是NALU的頭標(biāo),并可以實(shí)現(xiàn)以上的打包規(guī)則。

    一個(gè)RTP分組里放入一個(gè)NALU,將NALU(包括同時(shí)作為載荷頭標(biāo)的NALU頭)放入RTP的載荷中,設(shè)置RTP頭標(biāo)值。為了避免IP層對(duì)大分組的再一次分割,片分組的大小一般都要小于MTU尺寸。由于包傳送的路徑不同,解碼端要重新對(duì)片分組排序,RTP包含的次序信息可以用來(lái)解決這一問(wèn)題。

 NALU分割

        對(duì)于預(yù)先已經(jīng)編碼的內(nèi)容,NALU可能大于MTU尺寸的限制。雖然IP層的分割可以使數(shù)據(jù)塊小于64千字節(jié),但無(wú)法在應(yīng)用層實(shí)現(xiàn)保護(hù),從而降低了非等重保護(hù)方案的效果。由于UDP數(shù)據(jù)包小于64千字節(jié),而且一個(gè)片的長(zhǎng)度對(duì)某些應(yīng)用場(chǎng)合來(lái)說(shuō)太小,所以應(yīng)用層打包是RTP打包方案的一部分。

    新的討論方案(IETF)應(yīng)當(dāng)符合以下特征:

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

    (2)能夠標(biāo)記第一個(gè)和最后一個(gè)NALU分塊;

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

 NALU合并

    一些NALU如SEI、參數(shù)集等非常小,將它們合并在一起有利于減少頭標(biāo)開(kāi)銷。已有兩種集合分組:

    (1)單一時(shí)間集合分組(STAP),按時(shí)間戳進(jìn)行組合;

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

NAL規(guī)范視頻數(shù)據(jù)的格式,主要是提供頭部信息,以適合各種媒體的傳輸和存儲(chǔ)。NAL支持各種網(wǎng)絡(luò),包括:

1.任何使用RTP/IP協(xié)議的實(shí)時(shí)有線和無(wú)線Internet 服務(wù)

2.作為MP4文件存儲(chǔ)和多媒體信息文件服務(wù)

3.MPEG-2系統(tǒng)

4.其它網(wǎng)

NAL規(guī)定一種通用的格式,既適合面向包傳輸,也適合流傳送。實(shí)際上,包傳輸和流傳輸?shù)姆绞绞窍嗤?,不同之處是傳輸前面增加了一個(gè)起始碼前綴

在類似Internet/RTP面向包傳送協(xié)議系統(tǒng)中,包結(jié)構(gòu)中包含包邊界識(shí)別字節(jié),在這種情況下,不需要同步字節(jié)。

 

NAL單元分為VCL和非VCL兩種

VCL NAL單元包含視頻圖像采樣信息,

非VCL包含各種有關(guān)的附加信息,例如參數(shù)集(頭部信息,應(yīng)用到大量的VCL NAL單元)、提高性能的附加信息、定時(shí)信息等

 

參數(shù)集:

參數(shù)集是很少變化的信息,用于大量VCL NAL單元的解碼,分為兩種類型:

1.序列參數(shù)集,作用于一串連續(xù)的視頻圖像,即視頻序列。兩個(gè)IDR圖像之間為序列參數(shù)集。IDR和I幀的區(qū)別見(jiàn)下面。

2.圖像參數(shù)集,作用于視頻序列中的一個(gè)或多個(gè)個(gè)別的圖像序列和圖像參數(shù)集機(jī)制,減少了重復(fù)參數(shù)的傳送,每個(gè)VCL NAL單元包含一個(gè)標(biāo)識(shí),指向有關(guān)的圖像參數(shù)集,每個(gè)圖像參數(shù)集包含一個(gè)標(biāo)識(shí),指向有關(guān)的序列參數(shù)集的內(nèi)容因此,只用少數(shù)的指針信息,引用大量的參數(shù),大大減少每個(gè)VCL NAL單元重復(fù)傳送的信息。

序列和圖像參數(shù)集可以在發(fā)送VCL NAL單元以前發(fā)送,并且重復(fù)傳送,大大提高糾錯(cuò)能力。序列和圖像參數(shù)集可以在“帶內(nèi)”,也可以用更為可靠的其他“帶外”通道傳送。

 

存儲(chǔ)單元:

一組指定格式的NAL單元稱為存儲(chǔ)單元,每個(gè)存儲(chǔ)單元對(duì)應(yīng)一個(gè)圖像。每個(gè)存儲(chǔ)單元包含一組VCL NAL單元,組成一個(gè)主編碼圖像,VCL NAL單元由表示視頻圖像采樣的像條所組成。存儲(chǔ)單元前面可以加一個(gè)前綴,分界存儲(chǔ)單元,附加增強(qiáng)信息(SEI)(如圖像定時(shí)信息)也可以放在主編碼圖像的前面。主編碼圖像后附加的VCL NAL單元,包含同一圖像的冗余表示,稱為冗余編碼圖像,當(dāng)主編碼圖像數(shù)據(jù)丟失或損壞時(shí),可用冗余編碼圖像解碼。

 

 

編碼視頻序列:

一個(gè)編碼視頻序列由一串連續(xù)的存儲(chǔ)單元組成,使用同一序列參數(shù)集。每個(gè)視頻序列可獨(dú)立解碼。編碼序列的開(kāi)始是即時(shí)刷新存儲(chǔ)單元(IDR)。IDR是一個(gè)I幀圖像,表示后面的圖像不用參考以前的圖像。一個(gè)NAL單元流可包含一個(gè)或更多的編碼視頻序列。

 

 

I幀和IDR幀的區(qū)別:

1.在 H.264 中 I 幀并不具有隨機(jī)訪問(wèn)的能力,這個(gè)功能由 IDR 承擔(dān)。以前的標(biāo)準(zhǔn)中由 I 幀承擔(dān)。

2.IDR 會(huì)導(dǎo)致 DPB (參考幀列表——這是關(guān)鍵所在)清空,而 I 不會(huì)。

3.I和IDR幀其實(shí)都是I幀,都是使用幀內(nèi)預(yù)測(cè)的。但是IDR幀的作用是立刻刷新,使錯(cuò)誤不致傳播,從IDR幀開(kāi)始,重新算一個(gè)新的序列開(kāi)始編碼。

4.IDR圖像一定是I圖像,但I(xiàn)圖像不一定是IDR圖像。一個(gè)序列中可以有很多的I圖像,I圖像之后的圖像可以引用I圖像之間的圖像做運(yùn)動(dòng)參考。

 

 

 

 

關(guān)于h264拆包,按照FU-A方式說(shuō)明:

1)第一個(gè)FU-A包的FU indicator:F應(yīng)該為當(dāng)前NALU頭的F,而NRI應(yīng)該為當(dāng)前NALU頭的NRI,Type則等于28,表明它是FU-A包。FU header生成方法:S = 1,E = 0,R = 0,Type則等于NALU頭中的Type。
     2)后續(xù)的N個(gè)FU-A包的FU indicator和第一個(gè)是完全一樣的,如果不是最后一個(gè)包,則FU header應(yīng)該為:S = 0,E= 0,R = 0,Type等于NALU頭中的Type。
     3)最后一個(gè)FU-A包FU header應(yīng)該為:S = 0,E= 1,R = 0,Type等于NALU頭中的Type。
     因此總結(jié)就是:同一個(gè)NALU分包厚的FU indicator頭是完全一致的,F(xiàn)U header只有S以及E位有區(qū)別,分別標(biāo)記開(kāi)始和結(jié)束,它們的RTP分包的序列號(hào)應(yīng)該是依次遞增的,并且它們的時(shí)間戳必須一致,而負(fù)載數(shù)據(jù)為NALU包去掉1個(gè)字節(jié)的NALU頭后對(duì)剩余數(shù)據(jù)的拆分,這點(diǎn)很關(guān)鍵,你可以認(rèn)為NALU頭被拆分成了FU indicator和FU header,所以不再需要1字節(jié)的NALU頭了。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多