从 HEVC 参考软件中获取一些信息

Get some information from HEVC reference software

我是 HEVC 的新手,我现在正在了解参考软件(现在正在查看帧内预测)。

编码后需要获取如下信息

我知道 CTU 的决定是在 TEncSlice.cpp 中调用 m_pcCuEncoder->compressCtu( pCtu ) 时做出的。但我究竟从哪里可以获得这些具体信息呢?有人可以帮我弄这个吗?

p.s。我也在学习 C++(我有 Java 背景)。

编辑:post 是编码器端的解决方案。然而,解码器端的解决方案远没有那么复杂。

如果您不熟悉代码,那么在编码器处获取 CTU 信息(分区等)有点棘手。但我会尽力帮助你。 我要告诉你的一切都是基于 JEM 代码而不是 HM,但我很确定你也可以将它们应用到 HM。

您可能已经注意到,每个 CTU 的 compression/encoding 有两个完全独立的阶段:

  1. RDO 阶段:首先是 "make the decisions" 的率失真优化循环。在这个阶段,几乎所有可能的参数组合都会被测试(例如,不同的分区、内部模式、过滤器等)。在此阶段结束时,RDO 确定最佳组合并将它们传递到第二阶段。
  2. 编码阶段:此处编码器执行实际的最终编码步骤。这包括根据在 RDO 阶段确定的参数将所有 bin 写入比特流。

在CTU级别,这两个阶段分别由m_pcCuEncoder->compressCtu( pCtu )m_pcCuEncoder->encodeCtu( pCtu )函数执行,都在TEncSlice.cpp文件的compressSlice()函数中.

鉴于以上信息,您必须在第二阶段而不是第一阶段中寻找您要寻找的东西(你可能已经知道这些东西,但我怀疑你可能正在看第一阶段)。

所以,现在这是我获取您的信息的建议。这不是最好的方法,但在这里更容易解释。 您首先在 HM 代码中转到这一点:

compressGOP() -> encodeSlice() -> encodeCtu() -> xEncodeCU()

然后找到预测模式(intra/inter)编码的行:

m_pcEntropyCoder->encodePredMode()

此时,您可以访问 pcCU 对象,其中包含所有最终决策,包括您在第一阶段做出的查找信息。在代码的这一点上,您正在处理单个 CU 而不是整个 CTU。但是如果你想要整个 CTU 的信息,你可以返回

compressGOP() -> encodeSlice() -> encodeCtu()

并找到第一次调用xEncodeCU()函数的那一行。在那里,您将有权访问 pCtu 对象。

提醒:每个TComDataCU对象(pcCU如果你在CU级别,或者pCtu如果你在CTU级别)大小 WxH 被拆分为大小 4x4NumPartition=(W/4)x(H/4) 个分区。每个分区都可以通过指示其 Z 扫描顺序的索引 (uiAbsPartIdx) 访问。例如,<x=8,y=0> 处分区的 uiAbsPartIdx 为 4。

现在,您执行以下步骤:

  1. 通过调用 pCtu->getTotalNumPart() 获取 pCtu 中的分区数 (NumPartition)。

  2. 遍历所有 NumPartition 分区并调用函数 pCtu->getWidth(idx)pCtu->getHeight(idx)pCtu->getCUPelX(idx)pCtu->getCUPelY(),其中 idx 是你的循环迭代器。这些函数 return 每个 CU 的以下信息与 idx 处的 4x4 分区重合:宽度、高度、positionX、positionY。 [两个位置都是相对于帧的像素<0,0>]

  3. 以上信息足以推导出当前pCtu的CTU分区!所以最后一步就是写一段代码来做到这一点。

这是如何在第二阶段(即编码阶段)提取 CTU 分区信息的示例。但是,您可以调用一些适当的函数来获取第二个问题中的其他信息。例如,要获得选定的亮度帧内模式,您可以调用 pCtu->getIntraDir(CHANNEL_TYPE_LUMA, idx),而不是 getWidth()/getHeight() 函数。或pCtu->getQP(CHANNEL_TYPE_LUMA, idx)获取QP值。

您始终可以在 TComDataCU class (TComDataCU.cpp) 中找到提供 pCtu 级别有用信息的函数列表。

希望对您有所帮助。如果没有,请告诉我!

祝你好运,