zoukankan      html  css  js  c++  java
  • 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的统计可能需要大量样本参与。

  • 相关阅读:
    CodeForces 7B
    CodeForces 4D
    离散化
    线段树入门
    洛谷 P3951 小凯的疑惑(赛瓦维斯特定理)
    Codeforces 1295D Same GCDs (欧拉函数)
    Codeforces 1295C Obtain The String (二分)
    Codeforces 1295B Infinite Prefixes
    Codeforces 1295A Display The Number(思维)
    Codeforces 1294F Three Paths on a Tree(树的直径,思维)
  • 原文地址:https://www.cnblogs.com/gaozehua/p/2684153.html
Copyright © 2011-2022 走看看