关于H.265中查表估算编码比特数的相关问题

看到在一篇文章中提到
编码器在RDO过程中,需要计算编码后的比特数,但不需要输出真正的码流,所以在x264和x265的RDO中,采用简化方法估算编码比特数。

将所有的pStateIdx对应的概率制作成表,后面就可以通过查表获得比特数了。x265中的表格如下

const uint32_t g_entropyBits[128] =
{
    // Corrected table, most notably for last state
0x07b23, 0x085f9, 0x074a0, 0x08cbc, 0x06ee4, 0x09354, 0x067f4, 0x09c1b, 
0x060b0, 0x0a62a, 0x05a9c, 0x0af5b, 0x0548d, 0x0b955, 0x04f56, 0x0c2a9,
0x04a87, 0x0cbf7, 0x045d6, 0x0d5c3, 0x04144, 0x0e01b, 0x03d88, 0x0e937, 
0x039e0, 0x0f2cd, 0x03663, 0x0fc9e, 0x03347, 0x10600, 0x03050, 0x10f95,
0x02d4d, 0x11a02, 0x02ad3, 0x12333, 0x0286e, 0x12cad, 0x02604, 0x136df, 
0x02425, 0x13f48, 0x021f4, 0x149c4, 0x0203e, 0x1527b, 0x01e4d, 0x15d00,
0x01c99, 0x166de, 0x01b18, 0x17017, 0x019a5, 0x17988, 0x01841, 0x18327,
0x016df, 0x18d50, 0x015d9, 0x19547, 0x0147c, 0x1a083, 0x0138e, 0x1a8a3,
0x01251, 0x1b418, 0x01166, 0x1bd27, 0x01068, 0x1c77b, 0x00f7f, 0x1d18e, 
0x00eda, 0x1d91a, 0x00e19, 0x1e254, 0x00d4f, 0x1ec9a, 0x00c90, 0x1f6e0,
0x00c01, 0x1fef8, 0x00b5f, 0x208b1, 0x00ab6, 0x21362, 0x00a15, 0x21e46, 
0x00988, 0x2285d, 0x00934, 0x22ea8, 0x008a8, 0x239b2, 0x0081d, 0x24577,
0x007c9, 0x24ce6, 0x00763, 0x25663, 0x00710, 0x25e8f, 0x006a0, 0x26a26, 
0x00672, 0x26f23, 0x005e8, 0x27ef8, 0x005ba, 0x284b5, 0x0055e, 0x29057,
0x0050c, 0x29bab, 0x004c1, 0x2a674, 0x004a7, 0x2aa5e, 0x0046f, 0x2b32f, 
0x0041f, 0x2c0ad, 0x003e7, 0x2ca8d, 0x003ba, 0x2d323, 0x0010c, 0x3bfbb
};

请问一下这个表格具体是怎么查的?其中的数值与bit数的关系是怎样的?
pStateIdx的取值范围是0-63,与这个表中的128个值是怎么对应的?
是查表之后的数据右移15位就是对应的bit长度吗?

这个表格是用来估算编码比特数的,其中的数值和bit数之间的关系是比特数的估算值。pStateIdx的取值范围是0-63,这个表中的128个值是通过将这64个pStateIdx的取值进行拓展得到的,可以认为每个pStateIdx对应表格中的两个数值,一个是正数一个是负数。通过查询这个表格,就可以得到一个估算的比特数值。

正常算数编码过程对一个符号(0或者1)编码,输出的比特数应该是-log2(p),p为该符号的概率。编码器为了优化速度,采用了查表方式。 这个数组有128的索引,对应pStateIdx为63到0,其中pStateIdx=63时,代表概率为0.5;pStateIdx=0时,代表概率接近0。所以-log2(p) = (32768 * -log2(p)) >> 15,这个数组里就是预先计算好的32768 * -log2(p)值。计算bit时,直接查表然后右移15位即可。

img

这个表格是用于编码 H.265 的比特数估算的。pStateIdx 的取值范围是 0-63,在这个表格中,pStateIdx 的每个取值对应的是 128 个值的两个值的并,即第 pStateIdx * 2 和第 pStateIdx * 2 + 1 个值。最后查表得到的结果是以 g_entropyBits[pStateIdx * 2] 和 g_entropyBits[pStateIdx * 2 + 1] 的并作为编码后的比特数,这个并可以通过查询这个表格得到。这个并右移 15 位之后可以得到编码后的比特数的长度。

这张表是一个编码比特数的查表表,其中的数值代表某个状态的编码比特数。pStateIdx是用来索引这个表的状态编号,取值范围是0-63。在查表时,pStateIdx的值与这个表中的128个值的对应关系是pStateIdx * 2与pStateIdx * 2 + 1。最后得到的数据右移15位后的结果即为对应的编码比特数。

以下是示例代码片段演示了如何使用上述表格来计算编码比特数:

// pStateIdx is in the range of [0, 63].
uint32_t stateBits = g_entropyBits[pStateIdx];

// stateBits is a 15-bit number representing the number of bits required to encode this state.
uint32_t numBits = stateBits >> 15;

在这个代码片段中,通过查表获取对应状态的编码比特数,并将这个值右移 15 位得到真正的编码比特数。