三者的位分配編碼都主要是使用Range Coding(Opus是CELT和SILK拼出來的)。
那么有如下問題:
1.有什么區別。還是一樣?
2.把AAC的Huffman Coding換成Range Coding怎么樣
首先分析,SILK,
SILK里面的Range Coding比較簡單,SILK里面有2個全部
1. SILK 全部參數使用RC。
2. SILK 全部參數都有自己的積累概率函數CDF。
SILK 里面 RC統一調用SKP_Silk_range_encoder進行編碼,3個參數,第一個是數據結構指針,第二個CDF,第三個是CDF的定點長度。
SILK能全部使用RC編碼的原因是,SILK是語音編碼,參數的動態幅值比較固定且小,統計CDF時容易收斂。
然后分析,CELT,
相比SILK, CELT的熵編碼比較復雜。
CELT的不僅僅是用了RC編碼也使用了動態位編碼。
並且CELT的RC和為了進行RC的算法設計比較靈活,比如RC編碼uint數據。
特點如下
1.CELT使用了動態位編碼是因為,在編碼fine quant 參數時,這個參數的位分配和動態幅值比較大,統計CDF比較困難,所以是用了編碼和解碼同時計算位分配參數,根據位分配參數編碼和提取fine quant 參數。
在這點上,CELT對fine quant的編碼方式有點類似AC3對mantissa的編碼方式,但是AC3的 mantissa編碼是用掩蔽參數計算出來的,這點又不同。另外AC3的mantissa是類似量化殘差的參數。而fine quant是類似ac3中exp參數或是aac的scalefactor參數。
2.CELT的RC對UINT數據進行了靈活的編碼方法,比如在編碼pitch的gain 的octave參數時,編碼pulse參數,編碼立體聲角度的時候。都是用了ec_enc_uint函數編碼
該函數一方面使用傳統的RC處理一方面調用ec_enc_bits對固定位或指定位長數據進行編碼。
3.CELT對RC進行了分類,分別實現ec_encode_bin(傳統的RC),ec_enc_bit_prob(指對一個位進行編碼)。ec_encode(傳統的RC)。
ec_encode和ec_encode_bin的區別是
ec_encode_bin要指對CDF的定點長度。ec_encode不需要。
而ec_enc_bit_prob和ec_encode_bin/ec_encode的區別是
ec_enc_bit_prob只編碼一個位用一個_prob就可以表示,不比向傳統RC一樣傳遞2個CDF參數(前一個CDF和當前的CDF參數)。
在Opus中,SILK的SKP_Silk_range_encoder函數變為了ec_enc_icdf函數。並把CELT的RC函數加入Opus里面,僅此而已。
2. 對AAC和MP3的參數編碼方式進行改造是可行的。
但是有2點要注意,
1.由於可能存在的參數動態幅值不確定(如量化殘差,最大8192級)不容易收斂,CDF的統計比較復雜要如何處理。判斷哪些參數做RC.如何合理使用RC。
2.CDF的統計可能需要大量樣本參與。
