cabac編碼過程的解讀

源地址:http://blog.163.com/laorenyuhai126%40126/blog/static/193507792010813822759/

cabac編碼過程的解讀  
        CABAC是H.264/AVC標準中兩種熵編碼方法中的一種,是將自適應的二進制算術編碼與一個設計精良的上下文模型結合起來得到的方法。它很好地利用了語法元素數值之間的高階信息,使得熵編碼的效率得到了進一步提高。它的主要特點有:利用每個語法元素的上下文關係,根據已編碼元素爲待編碼元素選擇概率模型,即上下文建模;根據當前的統計特性自適應地進行概率估計;使用算術編碼。[5]
        在CABAC中編碼一個單獨的句法元素的通用方框圖。這個編碼過程主要由三個基本步驟組成:
1、二值化;
2、上下文建模;
3、基於表格的二進制算術編碼。
        在第一步,一個給出的非二進制值的句法元素唯一地對應到一個二進制序列,叫二進制串。當給出一個二進制值的句法元素時,這一初始步驟將被跳過,如圖1所示。對於每個元素的二進制串或每個二進制值的句法元素,後面會根據編碼模式有一兩個子步驟。
        接下來就是對二元數據進行編碼,標準中有兩種編碼模式可供選擇。在常規編碼模式(regular coding mode)中,一個句法元素的每一個二進值(bin)按其判決產生的順序進入上下文模型器,在這裏,模型器根據已經編碼過的句法元素或二進值爲每一個輸入的二進值分配一個概率模型,這就是上下文模型化。然後該二進值和分配給它的概率模型一起被送進常規算術編碼器進行編碼,此外編碼器還要根據該二元位的值反饋一個信息給上下文模型器,用以更新上下文模型,這就是編碼中的自適應;另一種模式是旁路編碼模式(bypass coding mode),在該模式中,沒有模型器爲每個二進值分配一個特定的概率模型,輸入的二元數據是直接用一個簡單的旁路編碼器進行編碼的,這樣做是爲了加快整個編碼(以及另一端解碼)的速度,當然,該模式只用於某些特殊的二進值。
後面將更加詳細地討論二值化,上下文建模與基於表格的二進制算術編碼這三個主要步驟以及它們之間的相互聯繫。
2.2二值化
        CABAC的二值化方案有四種基本類型:一元碼,截斷一元碼,k階指數哥倫布編碼,與定長編碼。此外,還有基於這些基本類型的聯合的二值化方案與基於查表的二值化方案。

2.2.1 一元碼(Unary)
        對於一個非二進制的無符號整數值符號x≥0,在CABAC中的一元碼碼字由x個“1”位外加一個結尾的“0”位組成。例如,輸入的句法元素值爲4,其二值化結果爲11110。

2.2.2 截斷一元碼(Truncated Unary, TU)
        已知截斷值S。對於一個非二進制的無符號整數值符號0≤x<S,使用一元碼進行二值化。對於等於一個非二進制的無符號整數值符號x=S,其二值化結果全部由1組成,長度爲S。例如,當截斷值S=4時,句法元素值爲3的二值化結果爲1110,而句法元素值爲4的二值化結果爲1111。

2.2.3 k階指數哥倫布編碼(kth order Exp-Golomb, EGk)
         指數哥倫布編碼是由一個前綴和一個後綴的碼字連接組成的。EGk碼字的前綴部分由l(x)=[log2x(x/2k+1)]的值所對應的一元碼組成。EGk碼字的後綴部分可以通過使用長度爲k+l(x)位的x+2k(1-2l(x))的二進值來計算。另外,EGk碼字也可以通過下面的僞C代碼推得。
while(1)
{
  if (x>=(1<<k))
  {
      put(1);
      x=x-(1<<k);
      k++;
   }//EGk的一元碼前綴
  else
  {
    put(0);//前綴的截止位“0”
    while(k--)
    put((x>>k)&0x01); //EGk的後綴
  }
  break;
}

2.2.4 定長編碼(Fixed-Length, FL)
        對用到定長編碼二進化的句法元素值假設了一個有限的字母表 [0,1,2,…,Cmax],編碼的二進制長度爲  。其中,二進制1對應其中重要性最低的符號,隨着重要性的增加,二進制數也會跟着增加。

2.2.5  4位FL與截斷值爲2的TU聯合二值化方案
         前綴使用長度爲4位(Cmax=15)的定長編碼,後綴使用截斷值S=2的一元截斷碼。 

2.2.6  TU與EGk的聯合二值化方案(Unary/kth order Exp-Golomb, UEGk)
         前綴使用一元截斷碼,後綴使用k階哥倫布編碼。對於不同的句法元素值,有不同的截斷值與階數。 

2.2.7 各種句法元素值的二值化
        宏塊跳過標記mb_skip_flag、4*4亮度塊的幀內預測模式標記prev_intra4x4_pred_mode_ flag、8*8亮度塊的幀內預測模式標記prev_intra8x8_pred_mode_ flag、當前宏塊的幀/場模式標記mb_field_decoding_flag、已編碼塊標記coded_block_flag、重要係數標記significant_ coeff_flag、最後一個重要係數標記last_significant_coeff_flag、係數符號位標記coeff_sign_ flag、片結束標記end_of_slice_flag、8*8轉換系數塊標記transform_size_8x8_flag均使用1位的定長編碼。
        運動矢量差的絕對值使用截斷值爲9的UEG3二值化。
        色度幀內預測模式intra_chroma_pred_mode使用截斷值爲3的TU二值化。
        轉換系數的絕對值減1一coeff_abs_level_minus1使用截斷值爲14的UEG0二值化。
        塊編碼模式coded_block_pattern使用4位FL與截斷值爲2的TU聯合二值化方案。該句法元素指定了6個塊,其中4個用於亮度,2個用於色度,表示其中是否含有非零係數。coded_block_pattern=coded_block_patternY+16*nc,首先,亮度部分的coded_block_patternY使用的是4位FL變換,而色度部分nc用的是截止值爲2的TU二進制變換。
        宏塊類型mb_type與子宏塊類型sub_mb_type的二值化通過查表獲得,詳情參見標準。
        各句法元素的二值化方案可以參見標準中的表9-25。

2.2.8 聯合二值化方案編碼實例
       輸入的句法元素值爲幅度的絕對值abs_level=20。則coeff_abs_level_minus1=19,對此使用截斷值S=14,階數k=0的UEG0二值化方案。
先編碼前綴部分,按照編碼規則易得二進制序列爲11 1111 1111 1111(14個1)。再編碼後綴部分,下面分別按照僞C代碼與編碼規則進行編碼:
1、按照僞C代碼進行編碼
x = 19 – S = 5。
進行第一次循環:5>1(即1<<0),因此put(1), x=5-1=4, k+1=1;
進行第二次循環:4>2(即1<<1),因此put(1), x=4-2=2, k+1=2;
進行第三次循環:2<4(即1<<2),因此put(0);
至此得到EG0的前綴一元碼與截斷位0。
進行第一次循環:k-1=1,因爲(x>>k)&0x01=(2>>1)&0x01=1,所以put(1);
進行第二次循環:k-1=0,因爲(x>>k)&0x01=(2>>0)&0x01=0,所以put(0);
至此得到EG0的後綴序列10。
2、按照編碼規則進行編碼
       由x=5得l(x)=[log2x(x/2k+1)]=2,對應的一元碼110即爲EG0前綴。又因爲x+2k(1-2l(x))=5-3=2=(10)2,其中後綴碼字長度爲k+l(x)=2,則EG0後綴爲10。
可見,兩種方法得到的聯合二值化後綴碼字相同,均爲11010,則最終輸出的二進制序列爲11 1111 1111 1111 11010。
2.3上下文建模
        CABAC將片(Slice)作爲算術編碼的生命期。但對具體句法元素的編碼卻是發生在宏塊級。實際上,在同一個宏塊中,不同的句法元素是獨立編碼。但在不同的宏塊中,相鄰宏塊的句法元素的上下文信息(包括概率狀態state與最大概率符號MPS的值)可用於編碼當前宏塊的同一句法元素。

2.3.1 上下文的初始化(包括m,n,pre_state,state,mps)
         在開始編碼一個新的片時,都會對每個上下文模型指定相應的一對變量(m, n),並根據m, n的值計算出每個上下文模型對應的初始概率狀態state與最大概率符號MPS的值。該初始化的過程有以下三個步驟:
1、計算 pre_state=((m*(QP-12))>>4)+n;//qp由下面的式子產生
PS:slice_qp_delta表示用於條帶中的所有宏塊的的QPy的初始值,該值在宏塊層將被mb_qp_delta的值修改,該條帶初始QPy量化參數按下面的公式計算:SliceQPy=26+pic_init_qp_minus26+slice_qp_delta
slice_qp_delta應該受限,這樣SliceQPy的值將在-QpBdOffsetY到+51之間;
2、對於P和B幀圖像限制pre_state在[0,101]內,對於I幀圖像,限制pre_state在[27,74]內,即pre_state= min(101, max(0, pre_state))(對P 和B幀),pre_state=min (74,max(27, pre_state))(對I幀);
3、將pre_state按以下規則映射到數組{state, MPS}:如果pre_state<=50,{state=50- pre_state, MPS=0},否則{state= pre_state-51, MPS=1}
對於不同上下文模型的(m, n)分配參看標準。

2.3.2 上下文模型的分類
       上下文模型大概可以分成4種。
       第一種上下文模型包含當前要編碼的句法元素的 兩個相鄰塊的已編碼句法元素 的信息,其中相鄰塊的具體位置就要看句法元素了,一般是根據左邊與上邊的相鄰塊。
       第二種上下文模型只對mb_type與sub_mb_type的句法元素有定義。對於這種上下文模型,之前已編碼的二進串的值(b0, b1, b2,…, bi-1)是用來爲一個索引爲i的二進制句法元素值選擇模型的。
       第三與第四種上下文模型都是隻應用在殘差數據上。與其它上下文模型不同,這兩種類型都是依賴於不同塊種類的上下文範圍,如下文所示。
其中,第三種類型並不依賴於已編碼數據,而是待編碼數據在掃描路徑上的位置。對於第四種類型,首先在前面已編碼(已解碼)的變換系數幅度中,統計出具有某個特定值的變換系數幅度出現的總次數,然後根據這個數值來爲當前變換系數中的二進值確定上下文模型。
除了這些基於條件概率的上下文模型,還有固定的概率模型映射到爲那些已在常規模式被編碼的所有二進串的,以及先前沒有指定範圍的的上下文模型可以用到的二進值索引。
2.3.3 上下文模型的分配與確定
       通常,每個句法元素的上下文模型根據上下文索引偏移量與上下文增量來確定。其中,上下文索引偏移量對於特定類型片中的特定句法元素是唯一確定的,可以在標準中通過查表獲得。而上下文增量,則是根據相鄰塊的編碼情況(也就是上下文信息)得出。
       對於不同的句法元素,所需相鄰塊的信息不同,但一般包括可用性(如當前塊在片的邊緣上,則相鄰快可能由於不是在同一片中而不可用)與同一句法元素的編碼值。
通常用於計算上下文增量的上下文建模函數爲ctx_var_spat=cond_term(A,B),A和B表示當前塊的相鄰塊。其中cond_term()表示的是一種函數關係,有以下3種具體情況:
ctx_var_spat1=cond_term(A) + cond_term(B);
ctx_var_spat2=cond_term(A) + 2*cond_term(B);
ctx_var_spat3=cond_term(A)
       另外,對於利用先前bin值(已編碼值)的上下文建模函數爲ctx_var_bin[k] = cond_term (b1, …, bk-1)
       各句法元素的上下文增量的具體推導過程參見標準。
2.4二進制算術編碼
       算術編碼是基於區間劃分的,CABAC的算術編碼有以下3個明顯性質:
1、概率估計是對小概率符號LPS(Plps<0.5)的概率而言的,是通過基於表格中64個不同概率狀態{Pk|0≤k<64}之間的相互轉換而實現的。
2、區間長度R通過一組預先量化的值{Q1,Q2,Q3,Q4}進行量化以計算新的間隔區間。通過儲存一個二維表格TabRangeLPS來決定LPS的新的子間隔範圍Rlps,表格包含所有64*4預計算值Qi * Pk,通過快速查表這樣就可以免除算術編碼中的乘法運算了。
3、對近似均勻分佈(Plps=0.5)的句法元素,在編碼和譯碼時選擇旁路方式,可以免除上下文建模,提高編碼速度。
2.4.1 概率估計
       在H.264/AVC中的免除乘法的二進制編碼基本思想依賴於一個假設:每一個上下文模型估計的概率可以用一個有效的有限的特徵值集合來表徵。對於CABAC,對LPS有64個特徵概率值 。
       伸縮因子 ,N=64
       一方面想要獲得快速的自適應 N要小;另一方面,如果想獲得更加穩定更加精確的估計,則需要更大的N。注意在MQ編碼中,在CABAC方法中,不需要對LPS的概率值進行表格化。在算術編碼中,每一個概率僅僅用其相關的索引作爲地址。
       這樣設計的結果導致,CABAC中的每一個上下文模型可以有兩個參數完全決定:LPS概率當前估計值()和MPS的值 (0或者1)。這樣,在CABAC的概率估計中有128個不同的狀態,每一個狀態用一個7位整型數來表達。
       實際上,有一個狀態的索引()對應着LPS的最小概率值,但它並沒有被納入CABAC的概率估計和更新的範圍,這個值被用作特殊的場合,傳達特殊的信息。比如,當解碼器檢測到當前區間的劃分依據是這個概率值時,認爲這表示當前流的結束。因此只有126個有效概率狀態。另外,有一個狀態的索引()對應LPS的最小概率值,它對應的更新值是它自身,當MPS連續出現,LPS的概率持續減小,直到保持不變。
       概率估計指的是上下文的更新,因此只發生在編碼不同塊中同一句法元素或者其它上下文發生改變的時候,它是通過在LPS的64個概率狀態之間互相轉移而實現的。
對於一個給定概率狀態,概率的更新取決於狀態索引和已經編碼的符號值(MPS or LPS)。更新過程導致一個新的概率狀態,潛在的LPS概率修正,如果有必要需要修改MPS的值。如果當state=0時,也就是LPS的概率已經達到了最大值0.5,輸入的是一個小概率符號LPS,那麼MPS和LPS就要互換,因爲state=0時,Plps=0.5。
在I片中,有:
           if(decision==MPS)
                            state<-next_state_MPS_intra(state)
           else              

                             state<-next_state_LPS(state)
在其他片中,有:
          if(decision==MPS)
                            state<-next_state_MPS (state)
          else               

                            state<-next_state_LPS(state)
  
2.4.2 算術編碼器的總體描述
       CABAC編碼器由兩個子編碼器組成,一個用於常規編碼模式,另一個稱爲旁路編碼器用於符號的快速編碼。下面對常規編碼器具體的編碼過程進行描述,編碼過程必須與後面介紹的譯碼過程相匹配(H.264標準文件中給出了譯碼流程,沒給出具體的編碼流程,下面給出的是可參考的編碼流程,必須與譯碼流程匹配)
1、首先是編碼器的初始化
       該過程是發生在編碼片的第一個宏塊之前,在編碼I_PCM宏塊的數據元素pcm_alignment_zero_bit和所有pcm_byte數據之後的。此過程中,輸出的是算術編碼器中的相關參數,區間下限codILow設置爲0,區間長度codIRange設置爲0x01FE,另外的firstBitFlag設置爲1,計數器(用於防止相關寄存器溢出)bitsOutstangding和symCnt都被設置爲0。
2、編碼決定
       此過程輸入的是Binval(語法元素經過二進制化後的值),context_id(上下文模型)和編碼器的環境codirange,codilow和symCnt,輸出的值是codirange,codilow和symCnt。如圖2.2所示。
該過程可以分爲4個步驟
(1)通過當前編碼器區間範圍codiRange計算Qi的索引值i,然後利用狀態索引(由上下文模型得到)和i進行查表得出Rlps的概率。
(2)根據要編碼的符號是否MPS來更新算術編碼中的概率區間下限和概率區間範圍。
(3)上下文模型概率狀態的更新(參考前文)
(4)重整化處理,具體操作在後文給出。 
3、重整化處理
       在區間劃分結束後,如果新的區間範圍R不在合法範圍[28   29]之內,那麼就需要進行重整化操作,輸出1位或多位。其中用到的PutBit程序。
4、旁路編碼模式
        首先,概率估計和更新過程的旁路被建立;
       其次,間隔細分被執行 
       最後,編碼完片內所有宏塊的句法元素後,寫入end_of_slice_flag的標誌,然後進行字節壓縮,在編碼完一幅圖像的所有元素後,所有輸出的二進制位都會進行封裝,成爲適合NAL層的傳輸單位。

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