本節會依序介紹在 4.2 所提到 Bitstream Parser 中的各模組之實作設計,並列出一 些重要的訊號作說明。
4.3.1 Bitstream Parser Control
Bitstream Parser Control 主要可以分為三大部分,分別是 Bitstream Parser FSM、
Suntax Decoder 及 Consumed Bits Caculator,如 Figure 23 所示,Bitstream Parser FSM
Figure 23 Bitstream Parser Control 架構圖
27
模組包含了解碼流程中所有進行訊號控制的狀態機,而 Consumed Bits Caculator 中有 實作一個 Pc Decoder,當 Bitstream 經過如固定長度、Exp-Golomb 或者是 CAVLC 解 碼時,都會將消耗的 Bit 數傳給 Pc Decoder,而 Pc Decoder 負責根據這些資訊更新目 前解碼到的 Buffer 位置後傳給 Bitstream Buffer,Bitstream Buffer 再依此判斷是否需要 繼續向 SDRAM 索取新的 Bitstream Data,至於經過解碼或者計算得到的重要參數都 會被儲存在 Syntax Decoder,接下來會分別對這三個部分做完整介紹。
Figure 24 Bitstream Parser FSM 控制流程圖
Bitstream Parser FSM 內含許多不同的狀態機,在解碼的時候根據目前解碼到的 部分進入相對應的狀態機進行控制,Figure 24 表示 Bitstream Parser FSM 中各個狀態 機運作的流程,圖中的數字代表先後順序,接下來會針對各步驟介紹控制該步驟的狀 態機。在解碼器在 bitstream 發現到 start code prefix(0x0001)後就會進入步驟 1 的 NAL Unit State,NAL Unit State 的過程主要是藉由解碼 NAL header 來判斷當前 NAL 的種 類,在實作中我們將 NAL 的種類分成 SPS、PPS、IDR 以及 Non-IDR 四種,如果發 現目前解碼的 NAL 是 SPS 或者 PPS,則會分別進入 SPS state 跟 PPS state 去做參數的 解碼。NAL Unit State 的狀態變化如 Figure 25,而 SPS state 跟 PPS state 的狀態變化 分別如 Figure 26、Figure 27 所示。
28
Figure 25 NAL Unit State
IDLE
Figure 26 SPS State
IDLE
Figure 27 PPS State
29
而當發現目前解碼的 NAL 是 IDR 或者 Non-IDR,則會進入步驟 3 的 Slice Header 進行 Slice 參數的解碼,解碼出需要的參數後就會開始進入步驟 4 的 Slice Date State,
在 Residual Data State 解碼出當前 MB 重建所需的資訊後,狀態機會停在一個叫做 Residual 的 state,此時開始進行步驟 5 的 Residual Data State,而 Residual Data State 所控制的步驟 6~8 就相當於 3.1 節 Figure 1 的 MB loop,Bitstream Parser FSM 這個模
Figure 28 Slice Header State
IDLE
Figure 29 Slice Data State
30
接下來介紹 Consumed Bits Caculartor 跟 Syntax Decoder,參照 Figure 23 中 Consumed Bits Caculartor 的部分,可以發現 Consumed Bits Caculartor 是由 Bitstream Buffer、Heading One Detector、Exp-Golomb Decoder、Dependent Variable Decoding 及 Pc Decoding 所實作而成。Bitstream Buffer 的部分由兩個不同的 circular buffer 所組 成,一個是 Beha_Bitstream_ram,容量是 32 個 words,透過 BUS 所取得的 bitstream data 會 先 存 放 於 此 , 另 外 一 個 是 Bitstream Buffer , 用 來 將 bitstream data 從 Beha_Bitstream_ram 讀取到解碼器中供其他元件進行解碼,容量為 128 bits,解碼器開 始運作前會先讀取 128 bits 使 buffer 填滿,此時 BitStream_buffer_valid_n 訊號會 active low,然後解碼器才會正式開始解碼,Bitstream Buffer 藉由 pc_previous 跟 pc 訊號之 間的關係控制讀取 bitstream 的時機以及 BitStream_ram_addr 的改變,一次讀取 64 bits 的 bitstream data。而 Heading One Detector 這個模組的運算很單純,就只是找出目前 bitstream 開頭的第一個 1 的位置,稱做 heading_one_pos,而之所有要有這項資訊就是 因為 Exp-Golomb 解碼的過程需要這項資訊來決定 CodeNum 的值,如 Figure 30 所示。
Figure 30 Exp-Golomb 解碼架構
在 3.3 節有詳細介紹 Exp-Golomb 各類解碼的方式,在此就不多加敘述,不過要 特別說明的是,此處的 exp-golomb-sel 並不包括 me,也就是說 Exp-Golomb Decoer 並不包括 me 的解碼,因為 me 只會在解碼 CodedBlockPattern(CBP)時使用,所以就只 實作在 CodedBlockPattern Decoder 中,而 Dependent Variable Decoding 只有在解碼 slice header 中的特定參數才會使用,至於 Pc Decoding 就是把包含 Exp-Golomb 及 CAVLC 等各種熵解碼後消耗的 bits 數紀錄下來產生 pc 訊號,以供 Bitstream Buffer 判斷 bitstream 的讀取時機與 buffer address 的變化。
31
4.3.2 QP(Quantization Parameter) Decoder
QP Decoder 這個模組的目的在於計算出作反量化所需要的參數 QPy 與 QPc,會 先計算出 QPy,QPy 計算公式如下:
QPy = 26 + pic_init_qp_minus26 + slice_qp_delta
其中 pic_init_qp_minus26 這個參數在 PPS State 就會先解碼出來,到了 Slice Header State 為 slice_qp_delta 時會得到 slice_qp_delta 這個參數,進而求出 QPy,接著每當 Slice Data State 為 mb_qp_delta 時會再更新一次 QPy,更新公式如下:
Qpy = QPy + mb_qp_delta
而有了 QPy 後,就可以產生用於查表的 QPi,QPi 的產生公式如下:
QPi = QPy + chroma_qp_index_offset
其中 chroma_qp_index_offset 也是在 PPS state 就解碼出來的參數,得到 QPi 後就可透 過查表得到 QPc,查表過程如 Table 4 所示。得到 QPy 與 QPc 後將兩者傳入位於 Vedio Reconstruction 中的 IQIT 模組就能夠進行反量化,QP Decoder 的架構如 Figure 31 所 示。
Table 4 QPi 與 QPc 之對照表
Figure 31 QP Decoder 架構圖
32
4.3.3 CodedBlockPattern Decoder
CodedBlockPattern(CBP) 是針對 non-skip 且非 Intra 16x16 的預測模式的 MB 來使 用,對於每個適用的 16x16MB,CBP 的數值決定目前解碼的 MB 中每個 8x8 block 是 否含有非零的轉化系數,如 Table 5 所示。
Table 5 CodedBlockPattern Example
在 4.3.1 小節有提到 CBP 的解碼是採用 Exp-Golomb 中的 me,在得到 CodeNum 後根據 3.3 小節 Table 3 的 me 的對應表得到 CBP 的值,而 CBP 的值共有 6 個 bits,
前面兩個 bits 是 CPB Chroma,後四個 bits 是 CBP Luma,分別表示 MB 中 Chroma 與 Luma 部分的非零轉換系數存在情況,所以在實作上拆成 CodedBlockPatternLuma 及 CodedBlockPatternChroma 兩個訊號,兩個訊號的產生方式如下:
CodedBlockPatternLuma = CodedBlockPattern[3:0]
CodedBlockPatternChroma = CodedBlockPattern >> 4
當得到 CodedBlockPatternLuma 及 CodedBlockPatternChroma 後便可將這兩個訊號傳 入下一節的 CAVLC Decoder 中進行 Residual Data 的解碼,CodedBlockPattern Decoder 的架構如 Figure 32 所示。
33
Figure 32 CodedBlockPattern Decoder 流程圖
4.3.4 CAVLC Decoder
接下來介紹 Bitstream Parser 核心模組之一的 CAVLC Decoder,CAVLC Decoder 是負責 3.3 介紹的熵解碼中的 CAVLC 解碼部分,此部分解碼單位為 4x4 的 sub-block,
這個模組負責將 residual data 的資訊從 bitstream 中解碼出來,在計算出必要資訊後透 過 zig-zag order 的方式傳給 Vedio Reconstruction 中的 IQIT 模組,搭配 4.3.2 小節提到 的 QPy 與 QPc 即可進行完整的反量化與反轉化,整個 CAVLC 的架構圖如 Figure 33 所示。
Figure 33 CAVLC Decoder 架構圖
接下來介紹 CAVLC Decoder 的運作方式,在運作 CAVLC Decoder 之前,須先根 據 CodedBlockPattern 來判斷當前的 block 是否存在非零轉換系數,若有則才需要進行 接下來的 CAVLC Decode,而本解碼電路為 CAVLC 解碼流程設計一個名為 CAVLC Decoder State 的狀態機控制 CAVLC 解碼過程,本狀態機實作於 4.3.1 小節
34
Figure 34 CAVLC Decoder State 狀態變化圖
介紹的 Bitstream Parser FSM 中,其狀態變化如 Figure 34 所示,而 CAVLC Decoder 內的主要模組有 nC Decoding、NumCoeffTrailingOne Decoding、Level Decoding、Total Zero Decoding 以及 Run Decoding,其中 nC Decoding 模組的目的是為了產生出 nC 這 個參數,過程中,會先判斷目前解碼 block 的 A、B block 是否可以使用,A、B block 分別代表位於目前解碼 block 的左跟上的 block,若判斷可以使用,則將 A、B block 的 TotalCoeff 值取出,此時若 A、B block 跨 16x16MB 則使用儲存在 block RAM 的值 判斷,取出後的值當作 nA、nB 使用,此部分是為 nAnB Decoding,而有了 nA、nB 後就可算出 nC,求出 nC 後進入 nC Decoding 計算目前 Total Coeff 的值,之後 state 換到 trailing one 中,屬於 trailing one 的編碼方式相當單純,直接選取單一 bit 視作 sign bit,0 表示 level 為 1,1 則表示 level 值為-1,讀取 TrailingOne 個數的 bits 值之後進 入 Level Prefix state,一個 Level 表示的值可分為兩部分,在 heading one bit 前面非零 的數量為 level prefix,level prefix 後面所接的字串為 level suffix,若是 level 的值能夠 以 level Prefix 就能表示的話就無須進入 Level Suffix state,求出 level suffix 值,解碼 完非零數值的 residual 資料後,進入 Total zeros state 讀取 Total zero,之後進入 Run before state 讀取一連串的 run before 的值之後,進入 Level Produce state 重建出 4x4 block residual difference 的值,3.3 熵解碼的 CAVLC 部分附有此部分的解碼範例可供 參考。
35
4.3.5 IntraPredMode Decoder
IntraPredMode Decoder 所實作的部分 3.4 節所提到的 Intra Prediction Mode 的計 算,Figure 35 為 IntraPredMode Decoder 的架構圖,而過程中的一些重要訊號及其說 明整理在 Table 6 中,Intra Prediction Mode 需要據目前解碼的 MB 之左方區塊(Block A) 及上方區塊(Block B)之 Intra Prediction Mode 來產生,若所採用的 A、B Block 超出目 前 16x16MB 的範圍,則需要向 Intra PredMode RAM 來取值,若是 A、B Block 其一 不可用,或者是 Inter Block 且 PPS 中的 constrained_intra_pred_flag 值為 1,則當前的 block 採用 DC mode 進行預測,另外,就算 A、B Block 皆可用,也要判斷 bitstream 中 的 prev_intra4x4_pred_mode_flag 是 否 為 0 , 若 為 0 則 Prediction Mode 要 從 rem_intra4x4_pred_mode 中產生,若 prev_intra4x4_pred_mode_flag 為 1 則用取 A、B Block 中 Intra Prediction Mode 較小者作為當前 block 的 Intra Prediction Mode,Intra Prediction Mode 產生後會傳到 Vedio Reconstruction 中的 Intra Prediction 做畫面內預測。
Figure 35 Intra PredMode Decode 架構圖
36
Table 6 Intra PredMode Decode 各重要參數
4.3.6 Motion Vector Decoder
為了減少壓縮過後的資訊量,H.264/AVC 在 bitstream 中只存入 Motion Vector Difference(MVD) , 而 要 完 整 還 原 MV 需 要 進 行 3.6 節 所 提 過 的 Motion Vector Reconstruction(MVR),Motion Vector Decoder 這個模組就是在處理 MVR 的過程,再 將還原好的 MV 傳給 Vedio Reconstruction 中的 Inter Prediction 進行畫面間預測,值得 一 提 的 是 , 本 論 文 主 要 貢 獻 之 一 : 使 解 碼 電 路 支 援 多 框 架 參 考 預 測 (multe-frame reference)就是在此模組實作完成。
首先介紹 MVR 的過程,在 Slice Data Stare 為 mb_pred_state 時,會先從 bitstream 取出 MB type,當 MB type 為 Inter 相關的類型時,會開始 MVR 的流程,一開始會根 據不同的 MB type 讀取各個 sub-block 的 Reference Index(refidx)與 MVD,refidx 代表 目前的 block 所參考的 block 是位於由前幾張解碼完成的 Frame 所組成的 Reference Frame List 中的編號,而 MVD 則是組成 MV 的必要資料,refidx 的最小單位為 8x8 block,而 MVD 與 MV 的最小單位都是 4x4 block,由於本解碼器採取的是 baseline profile,所以各個 block 都只會有一組 refidx 與 MV,而要進行 MVR,除了自身的 refidx 外,還需要周圍 block 的 refidx 與 MV,MVR 最多同時參考 3 個周圍的 block,其中 一般情況只參考 Block A、B、C,Block D 則是在 Block C 不可使用的情況下作為候 補。在繼續介紹 MVR 過程之前,必須先釐清 Block A、B、C、D 的定義,我們取當
37
Figure 36 Inter block 之參考 block 示意圖
前 block 的左上角的點稱為 UL,右上角的點稱為 UR,我們取 UL 左邊的 block 做為 Block A,取 UL 上方的 block 做為 Block B,取 UL 左上對角的 Block 做為 Block D,
取 UR 右上對角的 block 當作 Block C,如 Figure 36 所示,而 Figure 37、38 提供兩 個周圍都有不同大小的 block 時 Block A、B、C、D 的選取例子。
Figure 37 (a) blockA~D 選取範例 1
Figure 38 blockA~D 選取範例 2
38
在確定了周圍的參考區塊後,開始介紹 MVR 流程,在有了當前 block 跟周圍 block 的 refidx 後,就可根據規則來計算出 Motion Vector Prediction(MVP),MVP 計算規則 中有判斷的優先順序之分,首先,如果當前的 MB type 為 Inter16x8 或者 Inter8x16 的 話,則要先根據以下規則判斷:
39
Figure 40 Motion Vector Reconstruction 示意圖
由 MVR 的過程可發現,我們需要保存當前解碼的 16x16 MB 之左上方、上方、
右上方及左方之 MB 的 refidx 與 MV 才能夠完整實作 MVR 的流程,左方 MB 的資 訊較好保存,因為解碼是由左而右,只需要在解碼完當前 16x16 MB 後,將上述資訊
右上方及左方之 MB 的 refidx 與 MV 才能夠完整實作 MVR 的流程,左方 MB 的資 訊較好保存,因為解碼是由左而右,只需要在解碼完當前 16x16 MB 後,將上述資訊