X265帧间预测

前言

前文x265预测入口说到,在X265中,根据事先设定的RDO级别会有不同优化级别的帧间预测函数,但大体流程上是一致的,无非是使用了提前终止的快速优化方法。本文以最高的RD级别对应的Analysis::compressInterCU_rd5_6为例讲解X265帧间预测的代码实现

帧间预测入口

代码如下:

SplitData Analysis::compressInterCU_rd5_6(const CUData& parentCTU, const CUGeom& cuGeom, int32_t qp)
{
   ......
    bool bHEVCBlockAnalysis = (m_param->bAnalysisType == AVC_INFO && cuGeom.numPartitions > 16);
    bool bRefineAVCAnalysis = (m_param->analysisReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1]));
    bool bNooffloading = !(m_param->bAnalysisType == AVC_INFO);

    if (bHEVCBlockAnalysis || bRefineAVCAnalysis || bNooffloading)
    {
        ......
      
        /* Step 1. Evaluate Merge/Skip candidates for likely early-outs */
        //计算当前CTU对应各个帧间预测模式代价
        if ((mightNotSplit &&  !md.bestMode && !bCtuInfoCheck) ||
            (m_param->bAnalysisType == AVC_INFO && m_param->analysisReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1])))
        {
            ......
            checkMerge2Nx2N_rd5_6(md.pred[PRED_SKIP], md.pred[PRED_MERGE], cuGeom);//skip/merge模式帧间预测
            ......
            checkInter_rd5_6(md.pred[PRED_2Nx2N], cuGeom, SIZE_2Nx2N, refMasks);//其它帧间预测模式
            checkBestMode(md.pred[PRED_2Nx2N], cuGeom.depth);//挑选最佳模式

            if (m_param->bEnableRecursionSkip && depth && m_modeDepth[depth - 1].bestMode)
                skipRecursion = md.bestMode && !md.bestMode->cu.getQtRootCbf(0);
        }
        if (m_param->bAnalysisType == AVC_INFO && md.bestMode && cuGeom.numPartitions <= 16 && m_param->analysisReuseLevel == 7)
            skipRecursion = true;
        // estimate split cost
        /* Step 2. Evaluate each of the 4 split sub-blocks in series */
        //递归计算当前CU四叉树划分的下一深度帧间预测代价
        if (mightSplit && !skipRecursion)
        {
            ......

            for (uint32_t subPartIdx = 0; subPartIdx < 4; subPartIdx++)
            {
                const CUGeom& childGeom = *(&cuGeom + cuGeom.childOffset + subPartIdx);
                if (childGeom.flags & CUGeom::PRESENT)
                {
                  ......
                    splitData[subPartIdx] = compressInterCU_rd5_6(parentCTU, childGeom, nextQP);//递归计算,用splitData数组记录对应CU对应的代价

                    // Save best CU and pred data for this sub CU
                   ......
                }
                else
                {
                    splitCU->setEmptyPart(childGeom, subPartIdx);
                }
            }
           ......
        }
        /* If analysis mode is simple do not Evaluate other modes */
        if (m_param->bAnalysisType == AVC_INFO && m_param->analysisReuseLevel == 7)
        {
            if (m_slice->m_sliceType == P_SLICE)
            {
                if (m_checkMergeAndSkipOnly[0])
                    skipModes = true;
            }
            else
            {
                if (m_checkMergeAndSkipOnly[0] && m_checkMergeAndSkipOnly[1])
                    skipModes = true;
            }
        }
        /* Split CUs
         *   0  1
         *   2  3 */
        allSplitRefs = splitData[0].splitRefs | splitData[1].splitRefs | splitData[2].splitRefs | splitData[3].splitRefs;
        /* Step 3. Evaluate ME (2Nx2N, rect, amp) and intra modes at current depth */
        //在当前深度对各种划分方式计算运动估计代价和帧内模式代价
        if (mightNotSplit)
        {
            ......
            if (!skipModes)
            {
                ......

                if (m_slice->m_sliceType == B_SLICE)
                {
                    md.pred[PRED_BIDIR].cu.initSubCU(parentCTU, cuGeom, qp);
                    checkBidir2Nx2N(md.pred[PRED_2Nx2N], md.pred[PRED_BIDIR], cuGeom);//B帧双向预测,2Nx2N
                    if (md.pred[PRED_BIDIR].sa8dCost < MAX_INT64)
      
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值