【H264/AVC 句法和語義詳解】(四):通過學習"描述子"實現碼流解析的第一步

原文鏈接:https://www.jianshu.com/p/2e6347ff3520

本篇隸屬於文集:《H264/AVC 句法和語義詳解》,查看文集全部文章,請點擊文字鏈接。
想看最新文章,可以直接關注微信公衆號:金架構

在這篇文章中,我們會涉及三個非常重要的問題:

1、如何獲取一條主線和多條輔線,來學習h264解碼器

2、爲什麼描述子,是正確打開碼流解析的第一步

3、學習描述子

在前面幾篇中,我們對h264的碼流結構有了初步的瞭解。但是這還遠遠不夠,因爲我們的目標,是通過學習h264的解碼流程,去探索h264裏面的每個知識點。所以在這個時候,讓讀者明白我們現在身處的位置,是一件至關重要的事情。因爲只有這樣,我們纔不會侷限於某一篇文章,或某一個知識點,而是從全局考慮,爲什麼要這樣做。

而且,我希望看我文章的讀者,看完文章後獲取的,不只是關於音視頻的各個知識點。還有更重要的,那就是思考和自學的能力!在這篇文章結束時,無論新手還是有經驗的同學,都可以從宏觀出發,看出這個系列文章未來十篇的走勢。並且我們還可以共同學習,一起研究。

  1. 如何獲取一條學習主線
    在快餐文化盛行的今天,很多人都在學習零零碎碎的知識,卻沒有將各個知識點,形成一種互相聯繫的知識結構。就比如關於h264,很多人可能知道幀內預測、幀間預測、變換、量化、熵編碼,但如果你問他一個h264編碼器或解碼器該怎麼做,他可能就一頭霧水。

所以這時候一條學習主線就非常重要,這是在你學習過程中,無論遇到什麼困難,都能夠把你拉回到問題本身,並讓你知道現在所處位置的關鍵。

而在h.264裏,這樣的一條學習主線也非常重要,它就是h.264解碼器框架!

1.1 學習主線:H.264解碼器框架
在這裏插入圖片描述
H.264解碼器框架
很多人並不會把流程圖當成一回事,其實一個流程圖,有可能是一篇文章、一個系列文章、書中一個章節或一本書的一個核心。

而根據上圖,我們可以制定兩個學習思路:

(1)根據如圖所示流程,從最右側碼流開始,一步步各個擊破,最終學完解碼器各個知識點。

(2)編碼器和解碼器其實只是步驟相反罷了,一邊學習解碼器各個知識點,一邊反過來思考,編碼過程如何實現。

當然,我們還可以對上述路線進行分段,因爲完整的一條學習主線,會包含一段段進階路線。

1.2 學習主線分段
我個人是這樣進行分段的:
在這裏插入圖片描述
學習主線分段
這樣分段是有根據的,因爲最開始我們手上有的,就是一個後綴爲.h264的碼流文件而已。所以我們首先要做的,就是先把句法元素解析出來。而如圖所示,每一步我們需要學習的技術如下:

(1)h264句法元素的解析:NALU的結構和熵解碼,同時熵解碼又包括指數哥倫布編碼、CAVLC、CABAC。只要掌握了NALU和熵解碼,我們就可以從碼流中解析出各個句法元素的值。即使我們完全是個小白,也可以按照h264協議完成這步。

(2)數據準備:DCT變換、量化、重排序,和它們相關的句法元素及語義。這個過程是爲後面的重建圖像做準備,這時我們已經解析出各個句法元素,實現該過程需要配合各步驟所需要的句法元素。

(3)重建圖像:幀內預測、幀間預測、去塊效應濾波器。這時候碼流數據已經完全解壓縮,就差拿着殘差數據、參考圖像和預測所需的句法元素,預測出預測數據。預測數據經過去塊效應後即可得解碼宏塊,當前圖像的所有宏塊解碼完成,就可以得到重建圖像用於顯示。

所以我們目前所處的位置,即將到達熵解碼階段。

  1. 如何獲取多條學習輔線
    學習輔線這種事情,相當於知識點的各個擊破,也相當於知識點的聯繫和延伸。我們可以一開始就設置多條輔線,而且在學的同時,還可以再設置輔線。就拿h264的解碼學習來說,我們可以設置如下輔線:

(1)h.264 POC的計算

(2)h.264的加權預測

(3)h.264 FMO

(4)h.264參考圖像列表

(5)加權預測

(6)量化

(7)幀內預測

(8)片、宏塊之間的關係

(9)片類型與宏塊類型

(10)NALU

(11)指數哥倫布編碼

(12)熵編碼

(13)YUV顏色空間

(14)殘差

這些問題,可以是各個知識點,也可以是自己問自己的問題,它們的意義,在於在學習主線上,一路設置哨崗,相當於摸着石頭過河。要知道學習新知識的重大突破,就是你得有石頭可摸!

  1. 爲什麼描述子是正確打開碼流解析的第一步
    爲了要清楚的解釋這個問題,我們得先知道什麼是描述子?

3.1 什麼是描述子?
還記得在NALU Header的解析中,我們說過,forbidden_zero_bit的值對應1個bit,nal_ref_idc的值對應2個bit,nal_unit_type的值對應5個bit。但是我沒說,我是怎麼知道哪個句法元素的值,對應幾個bit的?或者說,我是怎麼知道,句法元素的值是怎麼計算的?

這就是描述子的作用,比如我們之前計算過的NALU Header的句法元素,它在h.264協議中規定如下:
在這裏插入圖片描述
NALU Header句法
右側標紅框的,就是各句法元素對應的描述子,它表示了,這個句法元素的值是如何計算的。其中f(1)、u(2)、u(5)功能一樣,爲順序讀取1、2和5個bit位,作爲句法元素的值。所以我們才說,forbidden_zero_bit、nal_ref_idc、nal_unit_type的值,分別對應1、2、5個bit。

3.2 描述子種類
那是不是所有的語法元素都是以,連續讀取接下來的n個比特這種模式來計算的呢?不是的,在h.264協議中,規定有如下描述子:
在這裏插入圖片描述
h.264協議規定的全部描述子
描述子乍一看很多,其實我們可以把它們分爲三類:

(1)連續讀取n(包含b(8))個比特:b(8)、f(n)、i(n)、u(n),其中只有i(n)爲有符號整數,並且幾乎用不到,其他情況則順序從左至右,讀取固定數量的n個bit即可。如上面所講的NALU Header的句法元素

(2)指數哥倫布編碼:ue(v)、me(v)、se(v)、te(v),這四個描述子,都是指數哥倫布編碼。注意到它們使用的變量是v而不是n,它們的值,並不是直接等於讀取固定長度的比特。而是先根據其他句法元素的值,來確定讀取多少比特,然後再將讀取到的比特,進行轉換才能得到所求句法元素的值。

關於它們,我們後面會單獨開幾篇來介紹。

(3)CAVLC、CABAC:ae(v)、ce(v),同指數哥倫布編碼一樣,CAVLC和CABAC也屬於變長編碼,這也是我們需要學習的一大重點。

3.3 利用描述子解析句法元素
所以這時,只要我們懂得,各個描述子是如何計算的,我們就能根據它們解析出句法元素的值。不過需要注意的是,有時候我們會看到這種情況:
在這裏插入圖片描述
句法元素對應兩個描述子的情況
可以看到,在解析宏塊層mb_type的時候,該句法元素對應了兩個描述子,分別爲ue(v)和ae(v),並且它們之間用豎線 “|” 分隔開。

H.264協議規定,出現這種情況,得根據另一句法元素entropy_coding_mode_flag 的值來判斷:

如果entropy_coding_mode_flag等於0,則使用左邊的描述子,這時爲ue(v)。

如果entropy_coding_mode_flag等於1,則使用右邊的描述子,這時爲ae(v)。

3.4 爲什麼描述子是正確打開碼流解析的第一步
這個時候,我們就可以來回答最開始這個問題了。

如1.2學習主線分段所說,我們如果要進行碼流解析,第一步則是進行句法元素的解析,而句法元素的解析,又依賴於剛纔所講的那幾種描述子。通過剛纔的學習我們也知道,學習描述子,其實就相當於學習熵編碼。

所以我們接下來,就從學習描述子開始。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章