H.266代码学习:xIntraCodingTUBlockTM及其调用的重要函数

本文深入探讨H.266编码中的xIntraCodingTUBlockTM函数,该函数涉及TM匹配的帧内预测。文章提出对KLT变换只能针对TM匹配预测的疑问,并详述函数内部调用的AMT、SDT变换以及KLT训练过程。同时,分析了包括getTargetTemplate、candidateSearchIntra、generateTMPrediction和calcKLTIntra在内的关键函数,解析了H.266与HM的主要区别。
摘要由CSDN通过智能技术生成

之前在 H.266代码学习:transformNxN函数 中提到,帧内KLT的入口函数是xIntraCodingTUBlockTM,今天就来对他进行详细学习。

这里本人存在一点疑问,先写出来:
从代码中看,帧内预测中使用KLT变换,必须使用TM匹配进行预测,为什么KLT只能针对TM匹配预测进行变换?TM匹配替代了原帧内预测,原HEVC中应该是没有的,为什么JEM中没有提到新增使用TM匹配的帧内预测?

希望大家看的时候能注意一下,如果可以,麻烦给解答一下,谢谢。我也将在后续对这两个问题进行学习,得出答案时会进行补充说明。

xIntraCodingTUBlockTM

xIntraCodingTUBlockTM的功能是使用TM匹配的帧内预测,和xIntraCodingTUBlock是同一级的函数,两者是竞争关系。xRecurIntraCodingLumaQT会调用xIntraCodingTUBlock进行使用AMT多核变换和原HEVC变换的帧内预测,如果开启usbKLT,则在完成xIntraCodingTUBlock之后,会进行xIntraCodingTUBlockTM进行使用SDT(详见 H.266变换编码:信号决定变换SDT)的帧内预测,两者选最优者。

JEM与HM主要区别有:
JEM新增的信号决定变换SDT,HM中是没有的。

流程如下:
xIntraCodingTUBlockTM流程和xIntraCodingTUBlock比较相似,只是将帧内预测换成了TM匹配预测。在之前的 H.266代码学习:transformNxN函数 中已经简单总结了流程,这里来详细分析一下:
一、初始化参数。
二、训练KLT:
 1.使用getTargetTemplate获取模板。
 2.使用candidateSearchIntra进行帧内搜索找最优匹配块。
 3.使用generateTMPrediction生成TM预测块。
 4.使用calcKLTIntra来训练KLT,并返回KLT是否可用。
三、计算残差。
四、变换量化。
 1.设置lambda。
 2.调用smoothResidual进行残差平滑滤波。
 3.调用transformNxN进行KLT变换量化。
五、调用invTransformNxN进行KLT反变换量化。
六、用预测信号+残差生成重构信号,然后进行双边滤波。
七、更新失真信息。

代码分析:

#if VCEG_AZ08_INTRA_KLT
//帧内KLT
Bool TEncSearch::xIntraCodingTUBlockTM(TComYuv*    pcOrgYuv,
    TComYuv*    pcPredYuv,
    TComYuv*    pcResiYuv,
    Distortion& ruiDist,
    const ComponentID compID,
    TComTU&     rTu
    DEBUG_STRING_FN_DECLARE(sDebug)
#if COM16_C806_EMT
    , UInt*      puiSigNum
#endif
    , Int tmpred0_tmpredklt1_ori2
    )
{
    /******************* 一、初始化,删除了此部分代码,不详细说了*******************/

    //===== init availability pattern =====
    DEBUG_STRING_NEW(sTemp)

    /******************* 二、训练KLT*******************/
#if VCEG_AZ08_INTRA_KLT
    Bool useKLT = false;        //KLT初始为false
    if (tmpred0_tmpredklt1_ori2 != 2 && bIsLuma)        //默认TMPRED0_TMPREDKLT1_ORI2=1;  0: Template matching prediction; 1: TM prediction + KLT; 2: Original method
    {
        UInt uiBlkSize = uiWidth;       //宽度
        UInt uiTarDepth = g_aucConvertToBit[uiBlkSize];
        UInt uiTempSize = g_uiDepth2IntraTempSize[uiTarDepth];
        m_pcTrQuant->getTargetTemplate(pcCU, uiAbsPartIdx, uiBlkSize, uiTempSize);  //获取模板
        m_pcTrQuant->candidateSearchIntra(pcCU, uiAbsPartIdx, uiBlkSize, uiTempSize);       //进行帧内搜索找最优匹配块

        Int foundCandiNum;
        Bool bSuccessful = m_pcTrQuant->generateTMPrediction(piPred, uiStride, uiBlkSize, uiTempSize, foundCandiNum);       //生成TM预测块
        if (bSuccessful == false || foundCandiNum < 1)
        {
            return false;
        }
        if (1 == tmpred0_tmpredklt1_ori2 && bSuccessful)
        {
            useKLT = m_pcTrQuant->calcKLTIntra(piPred, uiStride, uiBlkSize);        //训练KLT,并返回KLT是否可用
        }
    }
#endif

    /******************* 三、计算残差 *******************/  
    //===== get residual signal =====
    {
        // get residual
        Pel*  pOrg = piOrg;
        Pel*  pPred = piPred;
        Pel*  pResi = piResi;

        for (UInt uiY = 0; uiY < uiHeight; uiY++)
        {
            for (UInt uiX = 0; uiX < uiWidth; uiX++)
            {
                pResi[uiX] = pOrg[uiX] - pPred[uiX];
            }

            pOrg += uiStride;
            pResi += uiStride;
            pPred += uiStride;
        }
    }

    //===== transform and quantization =====
    //--- init rate estim
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值