CELT和SILK以及Opus的位分配方法


三者的位分配編碼都主要是使用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的統計可能需要大量樣本參與。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM