视频编码JVET提案-基于模板的模式内推导TIMD(最全整理)

摘要

        使用最可能模式(MPM)的基于模板的模式内推导(TIMD)方法,对于MPM中的每个帧内预测模式,计算模板的预测样本和重建样本之间的绝对变换差之和(SATD),从而选择具有最小SATD的帧内预测模式作为TIMD模式,并用于当前块的帧内模式预测。

PS: 本文参考了截止2023年7月,JVET提案中与TIMD相关的内容,并进行了汇总整理。相关提案包括:JVET-V0098,JVET-AE0137,JVET-AD0103,JVET-AB0117

一、算法背景

        JVET中提出了一种解码器侧帧内模式推导(DIMD)方法。CU的帧内预测模式是在编码器和解码器处使用基于模板的方法导出的,而不是用信号通知解码器。如图1所示,模板的预测样本是使用每个候选模式的模板的参考样本生成的。成本被计算为模板的预测样本和重建样本之间的SATD。选择成本最小的帧内预测模式作为DIMD模式,并用于CU的帧内预报。候选模式可以是VVC中的67个帧内角度预测模式,也可以扩展到131个帧内角度预测模式。提出了一种渐进模式搜索方法,从所有允许的帧内预测模式中选择DIMD模式,其中每一步的搜索间隔减少到一半。

图1 DIMD中使用的模板及其参考样本

        尽管这种渐进搜索方法可以减少要检查的模式的数量,但对于所有CU,启动模式总是相同的。视频中的不同区域具有不同的特征。通常,最可能模式(MPM)可以提供指示CU的方向信息的线索。因此,建议从MPM中导出当前CU的帧内预测模式。

二、算法内容

        JVET-V0098提出了一种使用MPM的基于模板的模式内推导(TIMD)方法,其中TIMD模式是使用相邻模板从MPM推导出来的,TIMD模式被用作CU的附加帧内预测方法。

1. TIMD模式推导

        对于MPM中的每个帧内预测模式,计算模板的预测样本和重建样本之间的SATD。选择SATD最小的帧内预测模式作为TIMD模式,并用于当前CU的帧内预测。TIMD模式的推导中包括PDPC。

2. TIMD信号

        在序列参数集(SPS)中用信号发送标志以启用/禁用所提出的方法。当该标志为真时,用信号通知CU级标志以指示是否使用所提出的TIMD方法。TIMD标志紧接在MIP标志之后用信号通知。如果TIMD标志等于true,则与亮度帧内预测模式相关的剩余语法元素,包括MRL、ISP和亮度帧内预报模式的正常解析阶段,都被跳过。

3. TIMD模式推导中MPM列表结构的改进

        在MPM列表的构建过程中,相邻块的帧内预测模式在进行帧间编码时被推导为Planar模式。为了提高MPM列表的准确性,当对相邻块进行帧间编码时,使用运动矢量和参考图片导出传播的帧内预测模式,并将其用于MPM列表构建。此修改仅适用于TIMD模式的推导。

        与VTM-11.0相比的编码性能:

4. TIMD融合

        JVET-AE0137提出在TIMD融合过程中,除了两种选择的TIMD模式(IPM1和IPM2)之外,还有条件地引入非角度帧内预测器(DC或Planar)。

TIMD预测器 = 根据SATD成本计算的混合权重融合 IPM1 与 IPM2

        TIMD过程基于模板成本分析,其中测试了几个帧内模式——包括MPM、宽角度、DC、水平、垂直和扩展模式的候选列表。提供最小SATD成本的两个帧内模式(和)在条件下根据它们各自的模板成本在融合过程中被选择和混合。JVET-AE0137对帧内模式选择和融合过程进行了修改。

        如果SATD成本最低的非角度帧内模式(IPM3)不同于两个选定的TIMD帧内模式(IPM1和IPM2),则将其添加到TIMD融合过程中。

        非角度预测激活条件背后的逻辑是基于已经计算的SATD成本。因此,该方法具有非常低的复杂性。

 5. 使用可选模板区域的TIMD

        ECM-7.0上基于模板的帧内模式推导(TIMD)根据当前块的坐标,从T(顶部)+L(左侧)、T和L(顶部和左部)三个区域中隐式地选择要使用的模板区域。例如,如果块位于帧的左边缘(x==0),则仅使用与上侧相邻的模板区域(T);如果块位于帧的顶部(y==0),则使用与左侧相邻的模板区域(L);否则,将同时使用顶部和左侧模板区域(TL)。

        JVET-AD0103提出引入一种机制来显式地选择三种类型的模板区域之一,即使对于不位于帧的顶部或左侧边界的CU也是如此。timd_ref_mode[x0][y0]指定模板区域的模式。阵列索引x0,y0指定所考虑的编码块的左上亮度样本相对于图片的左上亮度样本的位置(x0,y0)。timd_ref_mode的值应在0到2的范围内(包括0到2)。当timd_ref_mode[x0][y0]的值等于0时,如果可用,则使用上模板区域和左模板区域。当timd_ref_mode[x0][y0]的值等于1或2时,分别使用上模板区域或左模板区域。当timd_ref_mode[x0][y0]不存在时,推断为等于0。

 6. 基于模板的定向混合模式内推导TIMD

        JVET-AB0117提出使用定向混合来融合使用基于模板的帧内模式推导(TIMD)确定的预测因子。当使用定向TIMD时,分别使用上面的模板和左边的模板导出两个独立的TIMD模式。这两种模式使用基于采样的权重进行混合。

        考虑两个单独的模板,一个在当前块上方,一个位于当前块左侧。模板由两行或两列已经重建的样本形成。如图2所示:

图2 左侧和上方的定向TIMD模板

         在两个模板上分别执行两个模式内搜索。仅在左侧模板上执行第一搜索,仅在上模板上执行第二搜索。用于每次搜索的帧内候选列表由当前块的MPM候选形成,SATD用作失真度量。当在左模板上搜索时,在所有候选模式中确定失真最小的模式minSATD_{L},表示为dirTimdMode_{L}。当在上模板上搜索时,与最优左模式相邻的两个方向帧内预测模式,即dirTimdMode_{L}+1dirTimdMode_{L}-1,也被添加到候选列表中;再次在所有候选模式中确定失真最小的模式minSATD_{A},表示为dirTimdMode_{A}。只考虑正常的帧内方向,不考虑扩展的角模式细化。

        这两个失真 minSATD_{L} 和 minSATD_{A} 根据模板中的样本数量进行缩放。如果在两次TIMD搜索之后,当dirTimdMode_{L}=dirTimdMode_{A}时,为两个模板选择相同的模式。如果minSatd_{L}>minSatd_{A},则替换dirTimdMode_{L},否则替换dirTimdMode_{A}。在模板的帧内模式搜索期间确定的第二最佳模式被用作替换。如果两个模板中的一个不可用,则只对可用模板执行一次搜索。生成的模式用作定向TIMD的帧内模式,并且不使用混合。如果两个模板都不可用,则使用Planar 模式。

        然后使用具有基于样本的权重的定向混合来计算和融合两个定向TIMD预测因子dirTimdMode_{L}dirTimdMode_{A}。基于样本的权重被定义为使得对于上面的预测器dirTimdMode_{A},在块的上部使用更高的权重,并且对于左边的预测器dirTimdMode_{L}在块的左边部分使用更高权重。特别地,对于大小HxW的块,上述预测器的权重可以定义为:

         可以进一步调整基于样本的权重,以考虑两个缩放的SATD中的一个或比另一个大得多的情况。在这种情况下,较高的权重被分配给具有较低SATD的预测器。特别是,预先定义一个因子K。如果minSatd_{A}>KminSatd_{L},则:

         相反地,当minSatd_{L}>KminSatd_{A}时,则:

         最后,左预测器dirTimdMode_{L}的权重可以定义为:

         该模式的使用通过CABAC编码的CU级别标志来发出信号。其中包括一个新的CABAC上下文来支持这一点。当涉及到信令时,定向TIMD被认为是TIMD的一个子模式。也就是说,只有当TIMDflag=1时,才用信号通知定向TIMD标志。定向TIMD可作为可选择TIMD的所有CU的选项。

 三、ECM相关代码

1. 宏定义JVET_W0123_TIMD_FUSION

        JVET-W0123实际是V0098的延伸,基础算法在V0098中有描述。TIMD主要在xCheckRDCostIntra函数中进行,xCheckRDCostIntra函数后续调用estIntraPredlumaQT,estIntraPredlumaQT开启亮度模式的RDO过程。

bool EncCu::xCheckRDCostIntra(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode, bool adaptiveColorTrans)
{
//...
#if JVET_W0123_TIMD_FUSION
  int timdMode = 0;
  int timdModeSecondary = 0;
  bool timdIsBlended = false;
  int  timdFusionWeight[2] = { 0 };
#endif
//...
#if JVET_W0123_TIMD_FUSION
  bool timdDerived = false; //默认置为false
#endif
//...
#if JVET_W0123_TIMD_FUSION
          cu.timd = false;
          if (isLuma(partitioner.chType) && cu.slice->getSPS()->getUseTimd())
          {
            if (cu.lwidth() * cu.lheight() > 1024 && cu.slice->getSliceType() == I_SLICE)
            {
              timdDerived = true; //尺寸满足条件且在I帧进行
            }
            if (!timdDerived)
            {
              const CompArea &area = cu.Y();

#if JVET_AB0155_SGPM
              cu.timdMode = m_pcIntraSearch->deriveTimdMode(bestCS->picture->getRecoBuf(area), area, cu, true, true);
#else
              cu.timdMode = m_pcIntraSearch->deriveTimdMode(bestCS->picture->getRecoBuf(area), area, cu);
#endif
              timdMode = cu.timdMode;
              timdDerived = true;
              timdModeSecondary = cu.timdModeSecondary;
              timdIsBlended     = cu.timdIsBlended;
//...
              timdFusionWeight[0] = cu.timdFusionWeight[0];
              timdFusionWeight[1] = cu.timdFusionWeight[1];
#if JVET_AB0155_SGPM
              timdHorMode = cu.timdHor;
              timdVerMode = cu.timdVer;
#endif
            }
            else
            {
              cu.timdMode = timdMode;
              cu.timdModeSecondary = timdModeSecondary;
              cu.timdIsBlended     = timdIsBlended;
              cu.timdFusionWeight[0] = timdFusionWeight[0];
              cu.timdFusionWeight[1] = timdFusionWeight[1];
#if JVET_AB0155_SGPM
              cu.timdHor = timdHorMode;
              cu.timdVer = timdVerMode;
#endif
            }
          }
#endif
//...
 tempCS->interHad    = interHad;

          m_bestModeUpdated = tempCS->useDbCost = bestCS->useDbCost = false;

          bool validCandRet = false;
          if( isLuma( partitioner.chType ) )
          {
            //ISP使用迄今为止最佳成本的值(如果是快速版本,则为亮度)来避免测试非必要的子分区
            {
              bestCostSoFar = encTestMode.maxCostAllowed;
            }
            validCandRet = m_pcIntraSearch->estIntraPredLumaQT(cu, partitioner, bestCostSoFar, mtsFlag, startMTSIdx[trGrpIdx], endMTSIdx[trGrpIdx], (trGrpIdx > 0), !cu.colorTransform ? bestCS : nullptr);
            if ((!validCandRet || (cu.ispMode && cu.firstTU->cbf[COMPONENT_Y] == 0)))
            {
              continue;
            }
#if JVET_W0123_TIMD_FUSION
            PU::spanIpmInfoIntra(*cu.firstPU); // 获得TIMD的帧内预测模式IPM
#endif
//...
#if JVET_W0123_TIMD_FUSION
            if (m_pcEncCfg->getUseFastISP() && validCandRet && !mtsFlag && !lfnstIdx && !cu.colorTransform && !cu.timd)
#else
            if (m_pcEncCfg->getUseFastISP() && validCandRet && !mtsFlag && !lfnstIdx && !cu.colorTransform)
#endif
            {
              m_modeCtrl->setISPMode(cu.ispMode);
              m_modeCtrl->setISPLfnstIdx(cu.lfnstIdx);
              m_modeCtrl->setMIPFlagISPPass(cu.mipFlag);
#if JVET_V0130_INTRA_TMP
			        m_modeCtrl->setTPMFlagISPPass(cu.tmpFlag);
#endif
              m_modeCtrl->setBestISPIntraModeRelCU(cu.ispMode ? PU::getFinalIntraMode(*cu.firstPU, CHANNEL_TYPE_LUMA) : UINT8_MAX);
              m_modeCtrl->setBestDCT2NonISPCostRelCU(m_modeCtrl->getMtsFirstPassNoIspCost());
            }

            if (sps.getUseColorTrans() && m_pcEncCfg->getRGBFormatFlag() && !CS::isDualITree(*tempCS) && !cu.colorTransform)
            {
              double curLumaCost = m_pcRdCost->calcRdCost(tempCS->fracBits, tempCS->dist);
              if (curLumaCost > bestCS->cost)
              {
                continue;
              }
            }

            useIntraSubPartitions = cu.ispMode != NOT_INTRA_SUBPARTITIONS;
//...
            {
              tempCS->lumaCost = m_pcRdCost->calcRdCost( tempCS->fracBits, tempCS->dist );
              if( useIntraSubPartitions )
              {
                //the difference between the best cost so far and the current luma cost is stored to avoid testing the Cr component if the cost of luma + Cb is larger than the best cost
                maxCostAllowedForChroma = bestCS->cost < MAX_DOUBLE ? bestCS->cost - tempCS->lumaCost : MAX_DOUBLE;
              }
            }

            if (m_pcEncCfg->getUsePbIntraFast() && tempCS->dist == std::numeric_limits<Distortion>::max()
                && tempCS->interHad == 0)
            {
              interHad = 0;
              // JEM assumes only perfect reconstructions can from now on beat the inter mode
              m_modeCtrl->enforceInterHad( 0 );
              continue;
            }
//...
            {
              if (!cu.colorTransform)
              {
//...
                cu.cs->picture->getPredBuf(cu.Y()).copyFrom(cu.cs->getPredBuf(COMPONENT_Y));
              }
              else
              {
//...
                cu.cs->picture->getPredBuf(cu).copyFrom(cu.cs->getPredBuf(cu));
              }
            }
          }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值