CABAC状态不一致解决方案

以为我自己的经验来说,编码器开发和优化过程中的不一致主要包括:CABAC 状态不一致、编解码不一致、debug/release 不一致、多次运行不一致、多线程/单线程不一致。本文主要总结在编码器中遇到这些不一致时常见的原因和解决方案。

编码器在做RDO时,会选择cost最低的模式作为最优模式,其中

\(cost = D + \lambda R\)

我们在RDO的过程中要准确的估计当前模式产生的码率,为了得到准确的码率,需要保持CABAC状态的更新和最后编码CTU时CABAC的状态一致,因此在最后编码完CTU时可以进行CABAC的状态的检查,以判断估计过程的CABAC和真实的CABAC状态是否一致,如果不一致可以通过ASSERT()来触发断言,这样在Debug模式下就可以发现是否存在不一致,如果出现不一致,那么RDO选择的结果可能会出现错误。

在做RDO时,一般会把初始的CABAC状态先备份一份,然后在check每个候选的时候,拷贝出初始的CABAC状态,保证在check每个候选的时候,CABAC的初始状态是一致的,如果忘记拷贝,使用的时上个候选更新过的CABAC状态,就会出现不一致的情况。

同时也要保存最优候选的CABAC状态,如果没有保存也会出现不一致。

在估计码率时需要对某些flag进行bits估计,估计的过程会更新对应ctxIdx的CABAC状态,如果少估计了或者多估计了一次或者多次,也会导致CABAC状态的不一致。

解决方案

当出现不一致时,在Debug模式下会触发ASSERT,这个时候可以看到当前出错误的CTU index,以及不一致的CABAC状态的ctxIdx(一般可以关闭WPP和SAO,这样比较好定位是哪个CTU index)。这样我们可以在check每个cu模式之前打印state[ctxIdx]的值,再打印出encode每个cu时state[ctxIdx]的值,找到第一个不一致的cu,然后再Debug确定具体哪个地方改变了state[ctxIdx]的值。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注