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

编码后,我需要获取以下信息。


给定CTU的CU结构
对于计算过程中的每个CU,其信息(例如QP值,Luma的选定模式,色度的选定模式,CU是否处于CTU拆分决策的最终CU结构中等)


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

ps我也在学习C ++(我有Java背景)。

最佳答案

编辑:这篇文章是编码器方面的解决方案。但是,解码器方面的解决方案要简单得多。

如果您是新手,获取编码器的CTU信息(分区等)在编码器上会有些棘手。但我会尽力帮助您。
我要告诉您的所有内容都是基于JEM代码而不是HM,但是我很确定您也可以将它们应用于HM。

您可能已经注意到,每个CTU的压缩/编码有两个完全独立的阶段:


RDO阶段:首先是“速率失真优化”循环以“做出决定”。在此阶段,将测试所有可能的参数组合(例如,差分分区,帧内模式,过滤器等)。在此阶段结束时,RDO确定最佳组合,并将其传递到第二阶段。
编码阶段:在这里,编码器执行实际的最终编码步骤。这包括根据RDO阶段确定的参数将所有bin写入比特流。


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

鉴于以上信息,您必须在第二阶段而不是第一阶段中寻找所需的内容(您可能已经知道这些事情,但是我怀疑您可能正在寻找第一阶段)。

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

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

然后,找到对预测模式(内部/内部)进行编码的行:

m_pcEntropyCoder->encodePredMode()

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

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

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

提醒:大小为TComDataCU的每个pcCU对象(如果处于CU级别,则为pCtu;如果处于CTU级别,则为WxH)被拆分为大小为NumPartition=(W/4)x(H/4)4x4分区。每个分区均可通过索引(uiAbsPartIdx)进行访问,该索引指示其Z扫描顺序。例如,位于uiAbsPartIdx的分区的<x=8,y=0>为4。

现在,您执行以下步骤:


通过调用NumPartition获取pCtu中的分区数(pCtu->getTotalNumPart())。
循环遍历所有NumPartition分区,并调用函数pCtu->getWidth(idx)pCtu->getHeight(idx)pCtu->getCUPelX(idx)pCtu->getCUPelY(),其中idx是循环迭代器。这些函数针对与CU分区在4x4处的每个idx返回以下信息:宽度,高度,positionX,positionY。 [两个位置都相对于帧的像素<0,0>]
以上信息足以推导当前pCtu的CTU分区!因此,最后一步是编写一段代码来做到这一点。


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

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

我希望这可以帮助你。如果没有,请告诉我!

祝好运,

关于video-encoding - 从HEVC引用软件获取一些信息,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47744464/

10-09 06:15