x265中encodeResAndCalcRdSkipCU()分析(版本2.8)

 一. x265幀間skip模式預測編碼:

      skip模式是merge模式的一種特例,按照merge模式得到MV之後,如果編碼器根據某種方法判斷了當前塊和參考塊基本一樣,那麼不需要傳輸殘差數據,只需要傳送MV的索引和一個標誌,來表明當前塊可以直接從參考塊得到。

二. 函數調用關係圖:

三. 源碼註釋分析:

/*
 =============Analysed by: yangxin
 =============Date:        2018.10
 =============Function:    skip模式下的編碼殘差和計算RDcost,以及熵編碼
*/
/* Note: this function overwrites the RD cost variables of interMode, but leaves the sa8d cost unharmed */
void Search::encodeResAndCalcRdSkipCU(Mode& interMode)
{
    CUData& cu = interMode.cu;
    Yuv* reconYuv = &interMode.reconYuv;
    const Yuv* fencYuv = interMode.fencYuv;
    Yuv* predYuv = &interMode.predYuv;
    X265_CHECK(!cu.isIntra(0), "intra CU not expected\n");
    uint32_t depth  = cu.m_cuDepth[0];

    // No residual coding : SKIP mode

    cu.setPredModeSubParts(MODE_SKIP);
    cu.clearCbf();
    cu.setTUDepthSubParts(0, 0, depth);

    reconYuv->copyFromYuv(interMode.predYuv);//--重建圖像直接copy預測圖像

    // Luma
    int part = partitionFromLog2Size(cu.m_log2CUSize[0]);
    interMode.lumaDistortion = primitives.cu[part].sse_pp(fencYuv->m_buf[0], fencYuv->m_size, reconYuv->m_buf[0], reconYuv->m_size);
    interMode.distortion = interMode.lumaDistortion;//--
    // Chroma
    if (m_csp != X265_CSP_I400 && m_frame->m_fencPic->m_picCsp != X265_CSP_I400)
    {
        interMode.chromaDistortion = m_rdCost.scaleChromaDist(1, primitives.chroma[m_csp].cu[part].sse_pp(fencYuv->m_buf[1], fencYuv->m_csize, reconYuv->m_buf[1], reconYuv->m_csize));
        interMode.chromaDistortion += m_rdCost.scaleChromaDist(2, primitives.chroma[m_csp].cu[part].sse_pp(fencYuv->m_buf[2], fencYuv->m_csize, reconYuv->m_buf[2], reconYuv->m_csize));
        interMode.distortion += interMode.chromaDistortion;
    }
    cu.m_distortion[0] = interMode.distortion;//--計算總失真

	//--熵編碼--
    m_entropyCoder.load(m_rqt[depth].cur);
    m_entropyCoder.resetBits();
    if (m_slice->m_pps->bTransquantBypassEnabled)
        m_entropyCoder.codeCUTransquantBypassFlag(cu.m_tqBypass[0]);

    m_entropyCoder.codeSkipFlag(cu, 0);//--編碼skip flag
    int skipFlagBits = m_entropyCoder.getNumberOfWrittenBits();
    m_entropyCoder.codeMergeIndex(cu, 0);//--編碼merge索引

    interMode.mvBits = m_entropyCoder.getNumberOfWrittenBits() - skipFlagBits;//--skip下mv的值爲0
    interMode.coeffBits = 0;
    interMode.totalBits = interMode.mvBits + skipFlagBits;//--總bits

    if (m_rdCost.m_psyRd)
        interMode.psyEnergy = m_rdCost.psyCost(part, fencYuv->m_buf[0], fencYuv->m_size, reconYuv->m_buf[0], reconYuv->m_size);
    else if(m_rdCost.m_ssimRd)
        interMode.ssimEnergy = m_quant.ssimDistortion(cu, fencYuv->m_buf[0], fencYuv->m_size, reconYuv->m_buf[0], reconYuv->m_size, cu.m_log2CUSize[0], TEXT_LUMA, 0);

    interMode.resEnergy = primitives.cu[part].sse_pp(fencYuv->m_buf[0], fencYuv->m_size, predYuv->m_buf[0], predYuv->m_size);
    updateModeCost(interMode);//--更新rdcost
    m_entropyCoder.store(interMode.contexts);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章