如何在 HM(HEVC 测试模型)中添加新的语法元素

How to add a new syntax element in HM (HEVC test Model)

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

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

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

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

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

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

PS:即使是等概率信号(即不使用 CABAC 上下文)也是有用的。我只想和平的送上这面flag!

提前致谢。

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

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

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

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

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

希望对您有所帮助。