JEM的调用结构

     简单记录了最重要函数的调用关系:

    encode()--->encode()--->compressGOP()--->compressSlice()

                      --->compressctu()--->xcompressCU()--->xCheckRDCostIntra()等等;

     主要是对这几个函数的调用关系有些疑问,先记录下来,慢慢学习。

1.int main(int argc, char* argv[])

   { 

        cTAppEncTop.encode();

   }

2.  cTAppEncTop.encode()

   {

      while ( !bEos )//由bEOS控制,循环调用encode对视频帧进行编码,好像是一帧循环一次???;
       {

         bEos = (m_isField && (m_iFrameRcvd == (m_framesToBeEncoded >> 1) )) || ( !m_isField && (m_iFrameRcvd ==             m_framesToBeEncoded) );

        m_cTEncTop.encode();

       }

   }

3. TEncTop::encode()

    {

      m_cGOPEncoder.compressGOP();//以GOP为单位进行compress,所以跟上面矛盾了???;

    }

4. TEncGOP::compressGOP()

   {

      for ( Int iGOPid=0; iGOPid < m_iGopSize; iGOPid++ )//循环次数是GOP中图像的数量,一帧就是一个slice;
       {

              for(UInt nextCtuTsAddr = 0; nextCtuTsAddr < numberOfCtusInFrame; )//循环系数是一帧中CTU的数量;

               {

                m_pcSliceEncoder->compressSlice ();//以slice为单位进行compress,所以与numberOfCtusInFrame矛盾?

               nextCtuTsAddr =bSliceSegmentEnd;

             }

             m_pcSliceEncoder->encodeSlice();

        }

     }

5. TEncSlice::compressSlice()

   {

        //循环次数是一个slice中CTU的数量;

        for( UInt ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ++ctuTsAddr )

        {

         m_pcCuEncoder->compressCtu( pCtu );//以CTU为单位进行compress;

         m_pcCuEncoder->encodeCtu( pCtu );

       } 

   }

6. TEncCu::compressCtu( TComDataCU* pCtu )

   {

            xCompressCU();

            if (pCtu->getSlice()->isIntra())
            {

                 xCompressCU();

            }

  }

7. TEncCu::xCompressCU()

{

 1)  if (bTestHorSplit) //如果要进行二叉树水平划分;
   {

       for (Int iQP=iMinQP; iQP<=iMaxQP; iQP++)
       {

         for ( UInt uiPartUnitIdx = 0; uiPartUnitIdx < 2; uiPartUnitIdx++ )//等于2是因为进行了二叉树划分;
          {

           xCompressCU();

          } 

        xCheckBestMode  (); 

      }

}

2)  if (bTestVerSplit) //如果要进行二叉树垂直划分;
   {

       for (Int iQP=iMinQP; iQP<=iMaxQP; iQP++)
       {

         for ( UInt uiPartUnitIdx = 0; uiPartUnitIdx < 2; uiPartUnitIdx++ )//等于2是因为进行了二叉树划分;
          {

           xCompressCU();

          } 

        xCheckBestMode  (); 

      }

  }

3)if( bQTSplit)//进行四叉树划分;

   {

    for (Int iQP=iMinQP; iQP<=iMaxQP; iQP++)
       {

         for ( UInt uiPartUnitIdx = 0; uiPartUnitIdx < 4; uiPartUnitIdx++ )//等于4是因为进行了四叉树划分;
          {

           xCompressCU();

          } 

         xCheckBestMode  (); 

      }

  }

}

8. xCheckRDCostIntra()

   {

     estIntraPredLumaQT();

     estIntraPredChromaQT();

     xCheckBestMode();

   }

9. estIntraPredLumaQT()(???有很多疑问)

   {

         getIntraDirPredictor();//得到6个MPMs;

        for( Int modeIdx = 0; modeIdx < numModesAvailable; modeIdx++ )//循环结束,从原始35种原始模式中选取5个SADT最小的模式;
       {

         predIntraAng();

         xModeBitsIntra();

         updateCandList();

        }

        for( Int modeIdx = 0; modeIdx < numModesForFullRD; modeIdx++ )//对N中候选列表里的前3种模式用邻近角度模式进行更新;
         {

            for( Int subModeIdx = -1; subModeIdx <= 1; subModeIdx+=2 )

             {

                predIntraAng();

                xModeBitsIntra();

               updateCandList();

             }

          }

           再将3种候选模式和2个MPMs合并;

       for( UInt uiMode = 0; uiMode < numModesForFullRD; uiMode++ )//遍历uiRdModeList里的预测模式,根据RDcost选取一种最好的预测模式;

      {

         xRecurIntraCodingLumaQT();

         if( dPUCost < dBestPUCost )

         {

            uiBestPUMode  = uiOrgMode;
            uiBestPUDistY = uiPUDistY;
            dBestPUCost   = dPUCost;

            xSetIntraResultLumaQT();
         }

     }

}

   10. estIntraPredChromaQT()

    {

       getAllowedChromaDir( uiPartOffset, uiModeList );//获得可用的色度预测模式,uiModeList里有11种候选模式;

   for (UInt uiMode = LM_CHROMA_F1_IDX; uiMode < LM_CHROMA_F1_IDX + LM_FILTER_NUM; uiMode++)//遍历69,70,71,72 4种模式,计算每种模式的代价;
       {

          predLMIntraChroma();//用亮度分量预测Cb分量;

          predLMIntraChroma();//用亮度分量预测Cr分量;

      }

     for( UInt uiMode = uiMinMode; uiMode < uiMaxMode; uiMode++ )//遍历11种帧内预测模式,选出一种最优的预测模式;

     {

          xRecurIntraChromaCodingQT ();

          m_pcRdCost->calcRdCost();

          if( dCost < dBestCost )//如果该模式的代价小于当前的最优代价,则将最优模式等相关数据更新;
          {

            dBestCost   = dCost;
            uiBestDist  = uiDist;
            uiBestMode  = uiModeList[uiMode];
            xSetIntraResultChromaQT( pcRecoYuv, tuRecurseWithPU );//保存最优模式的数据;

           }

       }

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值