slice header解析
slice data主要存放了該slice所有宏塊資訊以及殘差資料。
slice data文法結構
slice data解析流程如下:
- 擷取目前宏塊位置CurMbAddr;
-
如果目前slice不是I slice,則存在skip 宏塊。是以需要根據熵編碼類型解析skip宏塊标記。
1)對于cavlc,mb_skip_run表示目前宏塊與上一宏塊位置的內插補點,如果內插補點大于1,則梁洪快間存在skip宏塊;
2)對于cabac,每一個宏塊都存在一個mb_skip_flag表示該宏塊是否為skip宏塊;
- 解析宏塊層資訊
- 判斷是否還有更多資料,如果有更多資料,則繼續解碼下一個宏塊資訊,否則該slice解碼結束。
宏塊層文法結構
宏塊層的解析步驟如下:
1.解析mb_type
mb_type表示宏塊類型,具體可參考文章宏塊類型
2. 解析I_PCM資料
如果目前宏塊為I_PCM宏塊,則解碼的pcm_sample資料為重建後的宏塊資料,不需要再進行後續的變換、預測、和重建,但需要執行的blocking。解析完目前宏塊的pcm_sample資料後,該宏塊文法解析結束。
3. 解析預測模式
3.1 解析可以分成4個8x8塊的非I宏塊(P_8x8/p_8x8ref0/B_8x8)預測模式
通過sub_mb_pred文法解析每個8x8 子塊資訊,包括每個8x8塊類型sub_mb_type、每個8x8塊參考幀索引 ref_idx_l0和ref_idx_l1 以及8x8塊内每一個劃分塊的mvd;
假設一個8x8塊劃分為4個4x4塊,則編碼的資訊包括一個sub_mb_type, 1組參考幀索引(ref_idx_l0/ref_idx_l1)和8組mvd(4個分塊亮度、色度分量分别編碼)。亮度分量和色度分量共用參考幀索引,但mvd不一樣。
3.2 解析I宏塊預測模式
- Intra_16x16的預測模式由mb_type決定,不需要額外編碼
-
Intra_4x4/Intra_8x8為節省碼流,需要通過相鄰塊計算目前塊預測模式,隻編碼了prev_pred_mode_flag和rem_pred_mode這兩個變量。
計算過程可以簡單描述為:
1)從相鄰塊mbAddrA和mbAddrB的預測模式中選取較小的一個作為預先定義模式。
2)如果prev_pred_mode_flag為1,則預先定義模式就是目前塊的預測模式;
3)如果标志位prev_pred_mode_flag為0,則根據碼流中解析出的文法元素 rem_pred_mode判斷。如果rem_intra4x4_pred_mode的值小于預定義模式的值則選用rem_pred_mode;如果大于等于預定義模式,則目前塊的預測模式設為rem_pred_mode + 1。
3.3 解析其他P/B宏塊預測方式
根據目前16x16宏塊的劃分塊個數,解析每個子塊的參考幀索引和mvd。亮度分量和色度分量共用參考幀索引,但mvd不一樣。
4. 解析殘差資料
根據cbp資訊解析殘差資料,子塊對應的cbp大于0,該子塊才存在殘差資料,否則資料全為0.
在baseline profile下,隻支援4x4大小DCT變換,是以宏塊按照4x4大小劃分殘差塊。對于平坦區域,以8x8大小做DCT變換壓縮率會更高,是以從main profile開始引入了變量transform_size_8x8_flag用于表示該宏塊使用8x8大小DCT變換。
殘差系數包括DC系數和AC系數.
4.1 解析Intra_16x16亮度塊
Intra_16x16宏塊亮度塊編碼時,先劃分為16個4x4塊,分别對4x4塊做DCT變換量化後,把16個DC系數提取出來組成一個4x4大小的DC塊,再對DC塊做hadarmad變換。
解碼流程如下:
-
解析16個DC系數,反掃描,反hadamard變換,反量化
其中16個DC系數的掃描順序與4x4塊掃描順序一緻,如下圖所示,是以解碼過程需要反掃描後再反hadard變換
- 解析每個4x4塊中15個AC系數,與DC系數組成4x4塊參數,反量化,反變換得到殘差資料塊
4.2 解析transform_size_8x8_flag=1的亮度塊
transform_size_8x8_flag=1,說明該塊使用的DCT變換為8x8大小,是以16x16亮度塊劃分為4個8x8塊。
其解碼流程根據熵編碼分為兩種情況如下:
-
CABAC
1)解析每個8x8塊的1個DC系數和63個AC系數;
2) 對8x8系數塊反量化反變換得到殘差系數塊
-
CAVLC
由于CAVLC熵編碼一次隻能支援16個參數編碼,是以對于8x8殘差資料塊也必須分成4個4x4分别進行熵編碼。8x8塊劃分方式為交錯存放,比如8x8塊第一個參數作為第一個4x4塊的第一個參數,8x8塊第二個參數作為第二個4x4塊的第一個參數,8x8塊第三個參數作為第三個4x4塊的第一個參數…
1)解析每個4x4塊的系數,把4個4x4塊系數組成一個8x8塊
2)對8x8系數塊反量化反變換得到殘差系數塊
4.3 解析色度分量塊
色度塊編碼時,先将2個8x8色度塊分别劃分為4個4x4塊,分别對4x4塊做DCT變換量化後,把4個DC系數提取出來組成一個2x2大小的DC塊,再對DC塊做hadarmad變換。
解碼流程如下:
- 解析4個DC系數,反hadamard變換
- 解析每個4x4塊中15個AC系數,與DC系數組成4x4塊參數,反量化,反變換得到殘差資料塊
4.4 其他情況
其他情況則是把16x16亮度塊先劃分為16個4x4塊,分别對4x4塊做DCT變換量化。
其解碼流程如下:
1)解析每個4x4塊的1個DC系數和15個AC系數;
2) 對4x4系數塊反量化反變換得到殘差系數塊