本篇隸屬于文集:《H264/AVC 句法和語義詳解》陪竿,查看文集全部文章,請點擊文字鏈接屠橄。
想看最新文章族跛,可以直接關注微信公眾號:金架構
上一篇解析到,我們從h264裸流中锐墙,提取出一個個的NALU礁哄,并且解析出NALU的第一個字節(jié):NALU Header。下面我們就從NALU Header的下一個字節(jié)開始溪北,分析NALU剩余的數(shù)據(jù)部分桐绒,也即NALU的主體部分。
NALU的主體涉及到三個重要的名詞之拨,分別為EBSP茉继、RBSP和SODB。其中EBSP完全等價于NALU主體蚀乔,而且它們?nèi)齻€的結構關系為:
EBSP包含RBSP烁竭,RBSP包含SODB。
其中SODB就是最原始的編碼數(shù)據(jù)乙墙。
1. EBSP和RBSP
上篇我們說颖变,NALU的組成部分為:
NALU = NALU Header + RBSP
其實嚴格來說生均,這個等式是不成立的,因為RBSP并不等于NALU刨去NALU Header腥刹。嚴格來說马胧,NALU的組成部分應為:
NALU = NALU Header + EBSP
其中的EBSP為擴展字節(jié)序列載荷(Encapsulated Byte Sequence Payload),而RBSP為原始字節(jié)序列載荷(Raw Byte Sequence Payload)衔峰。那為什么我們上篇中佩脊,沒有使用2式而使用了1式呢?那是因為垫卤,在h264的文檔中威彰,并沒有EBSP這一名詞出現(xiàn),但是在h264的官方參考軟件JM里穴肘,卻使用了EBSP歇盼。
而且在我們下面的分析中,我們會看到评抚,使用EBSP是很易于理解的豹缀。
1.1 防止競爭
EBSP相較于RBSP,多了防止競爭的一個字節(jié):0x03慨代。
我們知道邢笙,NALU的起始碼為0x000001或0x00000001,同時H264規(guī)定侍匙,當檢測到0x000000時氮惯,也可以表示當前NALU的結束。那這樣就會產(chǎn)生一個問題想暗,就是如果在NALU的內(nèi)部妇汗,出現(xiàn)了0x000001或0x000000時該怎么辦?
所以H264就提出了“防止競爭”這樣一種機制江滨,當編碼器編碼完一個NAL時铛纬,應該檢測NALU內(nèi)部厌均,是否出現(xiàn)如下左側的四個序列唬滑。當檢測到它們存在時,編碼器就在最后一個字節(jié)前棺弊,插入一個新的字節(jié):0x03晶密。
圖中0x000000和0x000001前面介紹了,0x000002是作為保留使用模她,而0x000003稻艰,則是為了防止NALU內(nèi)部,原本就有序列為0x000003這樣的數(shù)據(jù)侈净。
這樣一來尊勿,當我們拿到EBSP時僧凤,就需要檢測EBSP內(nèi)是否有序列:0x000003,如果有元扔,則去掉其中的0x03躯保。這樣一來,我們就能得到原始字節(jié)序列載荷:RBSP澎语。
2. RBSP和SODB
得到RBSP之后途事,我們迫切想做的,就是從RBSP中擅羞,提取出原始編碼數(shù)據(jù)SODB(String Of Data Bits)尸变。這就涉及到RBSP與SODB的關系:
RBSP = SODB + RBSP尾部
而且RBSP的尾部,在規(guī)定中有兩種减俏,我們分別介紹召烂。
2.1 RBSP尾部
其中大多數(shù)類型的NALU,使用這種尾部娃承。
其中:
rbsp_stop_one_bit 占1個比特位骑晶,值為1
rbsp_alignment_zero_bit 值為0,目的是為了進行字節(jié)對齊草慧,占據(jù)若干比特位
所以RBSP就等于桶蛔,SODB在它的最后一個字節(jié)的最后一個比特后,緊跟值為1的1個比特漫谷,然后增加若干比特的0仔雷,以補齊這個字節(jié)。
2.2 條帶RBSP尾部
另一種尾部舔示,就是當NALU類型為條帶時碟婆,也即nal_unit_type等于1~5時,這時RBSP使用下面這種尾部:
可以看到惕稻,rbsp_slice_trailing_bits()默認情況下竖共,就是2.1介紹的第一種尾部。只是當entropy_coding_mode_flag值為1俺祠,也即當前采用的熵編碼為CABAC公给,而且more_rbsp_trailing_data()返回為true,也即RBSP中有更多數(shù)據(jù)時蜘渣,添加一個或多個0x0000淌铐。
所以我們拿到RBSP,只需要按照上述語法蔫缸,去掉RBSP的尾部腿准,就可以得到SODB。然后就可以對照對應類型的NALU的句法拾碌,解析出語法元素的值吐葱。
總結上篇和這篇街望,H264的碼流結構如下:
3. H264句法元素解析流程
而當我們拿到RBSP或SODB之后,就可以對照各類型的NALU弟跑,去解析它們的語法元素它匕,進而再根據(jù)語法元素,重建圖像窖认。其中解析語法元素的框圖如下:
由圖可見豫柬,解析NALU的各個句法元素并不難,只要根據(jù)h264文檔對應章節(jié)的句法扑浸,并配合相應的編解碼算法解析即可烧给。而相應的編解碼算法如指數(shù)哥倫布編碼、CAVLC喝噪、CABAC础嫡、算術編碼,我們會一步步涉獵酝惧。