H.266中的熵编码

感觉在视频编码中熵编码是个很神奇的存在,现在 对这方面还不太懂,先记录一下H266中关于上下文模型的函数。

CABAC中上下文模型中的上下文关系大概可以分为4种情况。

第一种上下文模型根据它相邻的一编码块的语法元素构成,一般是用其左边和上边块的对应语法元素来建立相应的概率模型,对当前语法元素进行模型预测。

第二种上下文模型仅局限于对块类型和子块类型的应用,其中第 n比特的概率模型的选定要参考前面已经编码的n-1 bit所采用的模型;

第三种和第四种上下文模型仅用于残差数据的编码,有依赖于块的类型。其中第三种模型依赖的是带编码系数在扫描路径中的位置。第四种模型则是根据前面已编码系数幅度中某个特定幅度值出现的总次数,来为当前变换系数中的二进制值确定上下文模型。

下面是第一种上下文模型。

UInt TComDataCU::getCtxAffineFlag( UInt uiAbsPartIdx )//得到Affine flag的上下文模型;

{
  TComDataCU* pcTempCU;
  UInt        uiTempPartIdx;
  UInt        uiCtx = 0;
  //得到左相邻CU的affine 标记;
  pcTempCU = getPULeft( uiTempPartIdx, m_absZIdxInCtu + uiAbsPartIdx );
  uiCtx    = ( pcTempCU ) ? pcTempCU->isAffine( uiTempPartIdx ) : 0;
  //得到上相邻CU的affine 标记;
  pcTempCU = getPUAbove( uiTempPartIdx, m_absZIdxInCtu + uiAbsPartIdx );
  uiCtx   += ( pcTempCU ) ? pcTempCU->isAffine( uiTempPartIdx ) : 0;


  return uiCtx;
}

#if ALF_HM3_REFACTOR
UInt TComDataCU::getCtxAlfCtrlFlag( UInt uiAbsPartIdx )//得到ALF控制 flag的上下文模型
{
  TComDataCU* pcTempCU;
  UInt        uiTempPartIdx;
  UInt        uiCtx = 0;


  // Get BCBP of left PU
  pcTempCU = getPULeft( uiTempPartIdx, getZorderIdxInCtu() + uiAbsPartIdx );
  uiCtx    = ( pcTempCU ) ? pcTempCU->getAlfCtrlFlag( uiTempPartIdx ) : 0;


  // Get BCBP of above PU
  pcTempCU = getPUAbove( uiTempPartIdx, getZorderIdxInCtu() + uiAbsPartIdx );
  uiCtx   += ( pcTempCU ) ? pcTempCU->getAlfCtrlFlag( uiTempPartIdx ) : 0;


  return uiCtx;
}

#if JVET_C0024_QTBT
UInt TComDataCU::getCtxBTSplitFlag( UInt uiAbsPartIdx, UInt uiWidth, UInt uiHeight )//得到二叉树划分的上下文模型
{
  TComDataCU* pcTempCU;
  UInt        uiTempPartIdx;
  UInt        uiCtx;
  UInt        uiTempDepth;

  UInt uiCurrDepth = getDepth(uiAbsPartIdx)*2 + getBTDepth(uiAbsPartIdx, uiWidth, uiHeight);
  // Get left split flag
  pcTempCU = getPULeft( uiTempPartIdx, m_absZIdxInCtu + uiAbsPartIdx );
  uiTempDepth = ( pcTempCU ) ? (pcTempCU->getDepth(uiTempPartIdx)*2 + pcTempCU->getBTDepth(uiTempPartIdx)) : 0;

  uiCtx  = ( pcTempCU ) ? (  uiTempDepth > uiCurrDepth ? 1 : 0 ) : 0;

  // Get above split flag
  pcTempCU = getPUAbove( uiTempPartIdx, m_absZIdxInCtu + uiAbsPartIdx );
  uiTempDepth = ( pcTempCU ) ? (pcTempCU->getDepth(uiTempPartIdx)*2 + pcTempCU->getBTDepth(uiTempPartIdx)) : 0;

  uiCtx  += ( pcTempCU ) ? (  uiTempDepth > uiCurrDepth ? 1 : 0 ) : 0;

  return uiCtx;
}
#endif
UInt TComDataCU::getCtxFRUCME( UInt uiAbsPartIdx )//得到FRUC 运动估计的上下文模型
{
  TComDataCU* pcTempCU;
  UInt        uiTempPartIdx;
  UInt        uiCtx = 0;

  // Get BCBP of left PU
  pcTempCU = getPULeft( uiTempPartIdx, m_absZIdxInCtu + uiAbsPartIdx );
  uiCtx    = ( pcTempCU ) ? pcTempCU->getFRUCMgrMode( uiTempPartIdx ) == FRUC_MERGE_BILATERALMV : 0;

  // Get BCBP of above PU
  pcTempCU = getPUAbove( uiTempPartIdx, m_absZIdxInCtu + uiAbsPartIdx );
  uiCtx   += ( pcTempCU ) ? pcTempCU->getFRUCMgrMode( uiTempPartIdx ) == FRUC_MERGE_BILATERALMV : 0;

  return( uiCtx );
}

#if VCEG_AZ07_FRUC_MERGE
UInt TComDataCU::getCtxFRUCMgrMode( UInt uiAbsPartIdx )//得到 FRUC merge的上下文模型
{
  TComDataCU* pcTempCU;
  UInt        uiTempPartIdx;
  UInt        uiCtx = 0;

  // Get BCBP of left PU
  pcTempCU = getPULeft( uiTempPartIdx, m_absZIdxInCtu+ uiAbsPartIdx );
  uiCtx    = ( pcTempCU ) ? pcTempCU->getFRUCMgrMode( uiTempPartIdx ) > 0 : 0;

  // Get BCBP of above PU
  pcTempCU = getPUAbove( uiTempPartIdx, m_absZIdxInCtu + uiAbsPartIdx );
  uiCtx   += ( pcTempCU ) ? pcTempCU->getFRUCMgrMode( uiTempPartIdx ) > 0 : 0;

  return( uiCtx );
}
#if VCEG_AZ07_IMV
UInt TComDataCU::getCtxiMVFlag( UInt uiAbsPartIdx )//得到运动矢量分辨率 flag的上下文模型
{
  TComDataCU* pcTempCU;
  UInt        uiTempPartIdx;
  UInt        uiCtx = 0;

  // Get BCBP of left PU
  pcTempCU = getPULeft( uiTempPartIdx, m_absZIdxInCtu + uiAbsPartIdx );

#if  JVET_E0076_MULTI_PEL_MVD
  uiCtx    = ( pcTempCU ) ? (pcTempCU->getiMVFlag( uiTempPartIdx ) ? 1 : 0 ) : 0;
#else
  uiCtx    = ( pcTempCU ) ? pcTempCU->getiMVFlag( uiTempPartIdx ) : 0;
#endif

  // Get BCBP of above PU
  pcTempCU = getPUAbove( uiTempPartIdx, m_absZIdxInCtu + uiAbsPartIdx );

#if  JVET_E0076_MULTI_PEL_MVD
  uiCtx   += ( pcTempCU ) ? (pcTempCU->getiMVFlag( uiTempPartIdx ) ? 1 : 0 ) : 0;
#else
  uiCtx   += ( pcTempCU ) ? pcTempCU->getiMVFlag( uiTempPartIdx ) : 0;
#endif

  return uiCtx;
}

UInt TComDataCU::getCtxSkipFlag( UInt uiAbsPartIdx )//得到skip flag的上下文模型
{
  TComDataCU* pcTempCU;
  UInt        uiTempPartIdx;
  UInt        uiCtx = 0;

  // Get BCBP of left PU
  pcTempCU = getPULeft( uiTempPartIdx, m_absZIdxInCtu + uiAbsPartIdx );
  uiCtx    = ( pcTempCU ) ? pcTempCU->isSkipped( uiTempPartIdx ) : 0;

  // Get BCBP of above PU
  pcTempCU = getPUAbove( uiTempPartIdx, m_absZIdxInCtu + uiAbsPartIdx );
  uiCtx   += ( pcTempCU ) ? pcTempCU->isSkipped( uiTempPartIdx ) : 0;

  return uiCtx;
}

UInt TComDataCU::getCtxSplitFlag( UInt uiAbsPartIdx, UInt uiDepth )//得到四叉树划分 flag的上下文模型
{
  TComDataCU* pcTempCU;
  UInt        uiTempPartIdx;
  UInt        uiCtx;
  // Get left split flag
  pcTempCU = getPULeft( uiTempPartIdx, m_absZIdxInCtu + uiAbsPartIdx );
  uiCtx  = ( pcTempCU ) ? ( ( pcTempCU->getDepth( uiTempPartIdx ) > uiDepth ) ? 1 : 0 ) : 0;

  // Get above split flag
  pcTempCU = getPUAbove( uiTempPartIdx, m_absZIdxInCtu + uiAbsPartIdx );
  uiCtx += ( pcTempCU ) ? ( ( pcTempCU->getDepth( uiTempPartIdx ) > uiDepth ) ? 1 : 0 ) : 0;

#if COM16_C806_LARGE_CTU
  UChar ucMinDepth = 0;
#if JVET_C0024_QTBT
  UChar ucMaxDepth = g_aucConvertToBit[getSlice()->getSPS()->getCTUSize()] 
  - g_aucConvertToBit[getSlice()->getSPS()->getMinQTSize(getSlice()->getSliceType(), getTextType())];
#else
  UChar ucMaxDepth = ( UChar )( getSlice()->getSPS()->getLog2DiffMaxMinCodingBlockSize() );
#endif
  getMaxMinCUDepth( ucMinDepth , ucMaxDepth , uiAbsPartIdx + getZorderIdxInCtu() );
  if( uiDepth < ucMinDepth )
  {
    uiCtx = 3;
  }
  else if( uiDepth >= ucMaxDepth + 1 )
  {    
    uiCtx = 4;
  }
#endif

  return uiCtx;
}

还有两种上下文模型暂时还不知道属于哪一种上下文模型:

UInt TComDataCU::getCtxInterDir( UInt uiAbsPartIdx )//帧间模式的上下文模型
{
#if COM16_C806_LARGE_CTU
#if JVET_C0024_QTBT
  return( Clip3( 0 , 3 , 5 - ((g_aucConvertToBit[getWidth( uiAbsPartIdx )]+g_aucConvertToBit[getHeight(uiAbsPartIdx)]+1)>>1) ) ); //和普通的得到上下文模型的函数不一样
#else
  return( Clip3( 0 , 3 , 4 - g_aucConvertToBit[getWidth( uiAbsPartIdx )] ) ); 
#endif
#else
  return getDepth( uiAbsPartIdx );
#endif
}

UInt TComDataCU::getCtxQtCbf( TComTU &rTu, const ChannelType chType )//变换量化 cbf的上下文模型
{
  const UInt transformDepth = rTu.GetTransformDepthRel();

  if (isChroma(chType))
  {
    return transformDepth;
  }
  else
  {
    const UInt uiCtx = ( transformDepth == 0 ? 1 : 0 );
    return uiCtx;
  }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值