VTM10.0代码学习16:estIntraPredChromaQT()

这篇博客详细探讨了VTM10.0编码器中色度帧内预测QT过程,包括estIntraPredChromaQT()函数的实现,如模式候选列表的SAD和SATD计算、RDcost评估以及xRecurIntraChromaCodingQT()的递归划分和D计算。文章还涉及了Cb和Cr的独立处理、JCCR(联合色度块滤波)的开启及测试策略。
摘要由CSDN通过智能技术生成

此系列是为了记录自己学习VTM10.0的过程,目前正在看编码端。主要的参考文档有JVET-S2001-vH和JVET-S2002-v1。由于本人水平有限,出现的错误恳请大家指正,欢迎与大家一起交流进步。


前两篇博文(VTM10.0代码学习14VTM10.0代码学习15)讲述了如何抉择出亮度的最佳帧内模式,本篇博文就来看看色度部分的函数estIntraPredChromaQT(),会比亮度部分简单一些


1. estIntraPredChromaQT

const ChromaFormat format   = cu.chromaFormat;
const uint32_t    numberValidComponents = getNumberValidComponents(format);
CodingStructure &cs = *cu.cs;
const TempCtx ctxStart  ( m_CtxCache, m_CABACEstimator->getCtx() );

cs.setDecomp( cs.area.Cb(), false );

double    bestCostSoFar = maxCostAllowed;//色度目前最佳帧内模式的RDcost
bool      lumaUsesISP   = !cu.isSepTree() && cu.ispMode;//色度和亮度划分一致且当前CU开启ISP模式
PartSplit ispType       = lumaUsesISP ? CU::getISPType( cu, COMPONENT_Y ) : TU_NO_ISP;//ISP划分类型
auto &pu = *cu.firstPU;

bestCostSoFar:色度目前最佳帧内模式的RDcost

lumaUsesISP:色度和亮度划分一致且当前CU开启ISP模式

ispType:ISP划分类型


uint32_t       uiBestMode = 0;//色度最佳帧内模式
Distortion uiBestDist = 0;//当前CU最佳帧内模式下的失真(色度和亮度或单独色度)
double     dBestCost = MAX_DOUBLE;//色度分量的最佳RDcost

uint32_t chromaCandModes[ NUM_CHROMA_MODE ];
PU::getIntraChromaCandModes( pu, chromaCandModes );//获得色度预测模式候选列表

uiBestMode:色度最佳帧内模式

uiBestDist:当前CU最佳帧内模式下的失真(色度和亮度或单独色度)

dBestCost:色度分量的最佳RDcost

chromaCandModes:色度预测模式候选列表


CodingStructure &saveCS = *m_pSaveCS[0];
saveCS.pcv      = cs.pcv;
saveCS.picture  = cs.picture;
saveCS.area.repositionTo( cs.area );
saveCS.clearTUs();

if( !cu.isSepTree() && cu.ispMode )
{
   
    saveCS.clearCUs();
    saveCS.clearPUs();
}

暂时的cs,用于存储最佳模式下的cs


if( cu.isSepTree() )
{
   
    if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) )
    {
   
        partitioner.splitCurrArea( TU_MAX_TR_SPLIT, cs );

        do
        {
   
            cs.addTU( CS::getArea( cs, partitioner.currArea(), partitioner.chType ), partitioner.chType ).depth = partitioner.currTrDepth;
        } while( partitioner.nextPart( cs ) );

        partitioner.exitCurrSplit();
    }
    else
        cs.addTU( CS::getArea( cs, partitioner.currArea(), partitioner.chType ), partitioner.chType );
}

如果是dual tree或local dual tree,色度分量需要单独添加TU


std::vector<TransformUnit*> orgTUs;

if( lumaUsesISP )
{
   
    CodingUnit& auxCU = saveCS.addCU( cu, partitioner.chType );
    auxCU.ispMode = cu.ispMode;
    saveCS.sps = cu.cs->sps;
    saveCS.addPU( *cu.firstPU, partitioner.chType );
}


// create a store for the TUs
for( const auto &ptu : cs.tus )
{
   
    // for split TUs in HEVC, add the TUs without Chroma parts for correct setting of Cbfs
    if( lumaUsesISP || pu.contains( *ptu, CHANNEL_TYPE_CHROMA ) )
    {
   
        saveCS.addTU( *ptu, partitioner.chType );
        orgTUs.push_back( ptu );
    }
}
if( lumaUsesISP )
{
   
    saveCS.clearCUs();
}

orgTUs:存放当前模式下的色度TU

这里主要是向saveCS添加TU和设置orgTUs


int satdModeList[NUM_CHROMA_MODE];//存储着模式候选列表的模式
int64_t satdSortedCost[NUM_CHROMA_MODE];//存储着模式候选列表的SAD和SATD的组合失真
for (int i = 0; i < NUM_CHROMA_MODE; i++)
{
   
    satdSortedCost[i] = 0; // for the mode not pre-select by SATD, do RDO by default, so set the initial value 0.
    satdModeList[i] = 0;
}
//表示对应模式是否可以进行RDcost计算
bool modeIsEnable[NUM_INTRA_MODE + 1]; // use intra mode idx to check whether enable
for (int i = 0; i < NUM_INTRA_MODE + 1; i++)
{
   
    modeIsEnable[i] = 1;
}
DistParam distParamSad;
DistParam distParamSatd;
pu.intraDir[1] = MDLM_L_IDX; // temporary assigned, just to indicate this is a MDLM mode. for luma down-sampling operation.

//初始化帧内预测参数并获取参考像素,如果需要则对参考像素进行滤波
initIntraPatternChType(cu, pu.Cb());
initIntraPatternChType(cu, pu.Cr());
xGetLumaRecPixels(pu, pu.Cb());//获取亮度的重建值

satdModeList:存储着模式候选列表的模式

satdSortedCost:存储着模式候选列表的SAD和SATD的组合失真

modeIsEnable:表示对应模式是否可以进行RDcost计算


for (int idx = uiMinMode; idx <= uiMaxMode - 1; idx++)
{
   
    int mode = chromaCandModes[idx];
    satdModeList[idx] = mode;
    if (PU::isLMCMode(mode) && !PU::isLMCModeEnabled(pu, mode))
    {
   
        continue;
    }
    if ((mode == LM_CHROMA_IDX) || (mode == PLANAR_IDX) || (mode == DM_CHROMA_IDX)) // only pre-check regular modes and MDLM modes, not including DM ,Planar, and LM
    {
   
        continue;
    }
    pu.intraDir[1] = mode; // temporary assigned, for SATD checking.

    int64_t sad = 0;
    int64_t sadCb = 0;
    int64_t satdCb = 0;
    int64_t sadCr = 0;
    int64_t satdCr = 0;
    CodingStructure& cs = *(pu.cs);

    CompArea areaCb = pu.Cb();
    PelBuf orgCb = cs.getOrgBuf(areaCb);
    PelBuf predCb = cs.getPredBuf(areaCb);
    m_pcRdCost->setDistParam(distParamSad, orgCb, predCb, pu.cs->sps->getBitDepth(CHANNEL_TYPE_CHROMA), COMPONENT_Cb, false);
    m_pcRdCost->setDistParam(distParamSatd, orgCb, predCb, pu.cs->sps->getBitDepth(CHANNEL_TYPE_CHROMA), COMPONENT_Cb, true);
    distParamSad.applyWeight = false;
    distParamSatd.applyWeight = false;
    if (PU::isLMCMode(mode))
    {
   
        predIntraChromaLM(COMPONENT_Cb, predCb, pu, areaCb, mode);
    }
    else
    {
   
        initPredIntraParams(pu, pu.Cb(), *pu.cs->sps);
        predIntraAng(COMPONENT_Cb, predCb, pu);
    }
    sadCb = distParamSad.distFunc(distParamSad) * 2;
    satdCb = distParamSatd.distFunc(distParamSatd);
    sad += std::min(sadCb, satdCb);

    CompArea areaCr = pu.Cr();
    PelBuf orgCr = cs.getOrgBuf(areaCr);
    PelBuf predCr = cs.getPredBuf(areaCr);
    m_pcRdCost->setDistParam(distParamSad, orgCr, predCr, pu.cs->sps->getBitDepth(CHANNEL_TYPE_CHROMA), COMPONENT_Cr, false)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值