1

我一直在研究 HM 参考软件一段时间,以改进帧内预测部分的某些内容。现在在代码中添加了一个新的帧内预测算法,我让编码器在我的算法和 HM 的默认算法之间进行选择(RDCost当然是根据)。

我现在需要的是为每个 PU 发出一个标志信号,以便解码器能够执行与编码器在速率失真循环中决定的算法相同的算法。

我想知道我应该怎么做才能正确地将这一位标志添加到流中,而不会破坏代码中的任何内容。

假设我想使用 CABAC 上下文模型来跟踪我的标志的统计信息,我还应该做什么:

  1. ContextModel3DBuffer m_cCUIntraAlgorithmSCModel在文件中添加一个新的上下文模型TEncSbac.h
  2. 通过查看 HM 如何初始化其他上下文模型来正确初始化模型(在编码器和解码器端)。
  3. 分别在编码器端和解码器端调用函数m_pcBinIf->encodeBin(myFlag, cCUIntraAlgorithmSCModel)和。m_pcTDecBinIfdecodeBin(myFlag, cCUIntraAlgorithmSCModel)

我采取了这三个步骤,但显然它破坏了一些东西。

PS:即使是等概率信号(即不使用 CABAC 上下文)也会很有用。我只想和平地送出这面旗帜!

提前致谢。

4

1 回答 1

0

我终于可以解决这个问题了。这是 CABAC 上下文初始化中的错误。

但我想分享这种经验,因为很多人可能想做同样的事情。

我解释的三个步骤本质上是添加新语法元素所必需的,但以下步骤可能会非常小心:

  1. 一开始,您需要决定是否要为语法元素使用单独的上下文模型?或者您想使用现有的?在 CABAC 分离的情况下,您应该定义一个ContextModel3DBuffer并且最好的方法是:在代码中找到相似的语法元素;然后在代码中复制它的“ContextModel3DBuffer”定义和所有它的出现。这样可以确保您正在考虑一切。
  2. 每个语法元素的编码发生在两个不同的地方:首先,在 RDO 循环中做出“决定”,其次,在实际编码阶段和决定被编码时(例如encodeCtu函数)。
  3. 编码/解码语法元素的顺序在编码器/解码器端应该相同。例如,如果您的新语法元素在编码器端之后splitFlag和之前predMode进行编码,则您应该在解码器端之间splitFlag和之前对其进行准确predMode解码。
  4. 上下文模型实现为 3D 矩阵,以便分别跟踪不同块大小、组件等的语法元素的统计信息。这意味着当您要调用该函数encodeBin时,您可以确保使用了正确的索引. 我在这部分犯了愚蠢的错误!

除了上面的注释,我发现了一个getState对调试非常有用的函数。当您可以访问它时,此函数会在代码的任意位置返回您的 CABAC 上下文模型的状态。当出现不匹配时,比较编码器和解码器同一位置的状态非常有用。例如,经常发生您对 a 进行编码1但对 a 进行解码的情况0。在这种情况下,您需要在编码和解码之前检查 CABAC 上下文的状态。他们应该是一样的。如果它们不相同,则回溯错误以找到不匹配的第一个位置。

我希望它是有帮助的。

于 2017-05-31T16:00:06.653 回答