残差信号编码(residual coding) 和CABAC 中TU-level 的上下文parsing 代码分析

CABAC 是唯一一个应用到HEVC中的熵编码方式,效率明显高于CAVLC编码。

但是CABAC有天然的serial operation dependence,致使硬件实施很困难,尤其是real-time 要求和mobile 设备等。

CABAC 用到的上下文模型中, 残差信号也就是转移系数相关的上下文占了70%左右的bins,对熵编码的性能影响也是显而易见的

再者就是MVD(motion vector difference )占据了差不多20% 的 bins 

对着来那个部分进行优化,以使得CABAC的计算复杂度和数据依赖性的减少都有着重要意义

至于优化,先要了解这部分的parsing 过程

接下来先分析下残差信号的转移系数的parsing过程的code ,希望可以共同学习

在类TEncSbac下定义了所有模块的syntax elements parsing 过程函数, codeCoeffN*N 就是针对转移系数的函数:

Void TEncSbac::codeCoeffNxN( TComDataCU* pcCU, TCoeff* pcCoef, UInt uiAbsPartIdx, UInt uiWidth, UInt uiHeight, UInt uiDepth, TextType eTType )
{
  DTRACE_CABAC_VL( g_nSymbolCounter++ )
  DTRACE_CABAC_T( "\tparseCoeffNxN()\teType=" )
  DTRACE_CABAC_V( eTType )
  DTRACE_CABAC_T( "\twidth=" )
  DTRACE_CABAC_V( uiWidth )
  DTRACE_CABAC_T( "\theight=" )
  DTRACE_CABAC_V( uiHeight )
  DTRACE_CABAC_T( "\tdepth=" )
  DTRACE_CABAC_V( uiDepth )
  DTRACE_CABAC_T( "\tabspartidx=" )
  DTRACE_CABAC_V( uiAbsPartIdx )
  DTRACE_CABAC_T( "\ttoCU-X=" )
  DTRACE_CABAC_V( pcCU->getCUPelX() )
  DTRACE_CABAC_T( "\ttoCU-Y=" )
  DTRACE_CABAC_V( pcCU->getCUPelY() )
  DTRACE_CABAC_T( "\tCU-addr=" )
  DTRACE_CABAC_V(  pcCU->getAddr() )
  DTRACE_CABAC_T( "\tinCU-X=" )
  DTRACE_CABAC_V( g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ] )
  DTRACE_CABAC_T( "\tinCU-Y=" )
  DTRACE_CABAC_V( g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ] )
  DTRACE_CABAC_T( "\tpredmode=" )
  DTRACE_CABAC_V(  pcCU->getPredictionMode( uiAbsPartIdx ) )
  DTRACE_CABAC_T( "\n" )

  if( uiWidth > m_pcSlice->getSPS()->getMaxTrSize() )
  {
    uiWidth  = m_pcSlice->getSPS()->getMaxTrSize();
    uiHeight = m_pcSlice->getSPS()->getMaxTrSize();
  }
  
  UInt uiNumSig = 0;
  
  // compute number of significant coefficients
  uiNumSig = TEncEntropy::countNonZeroCoeffs(pcCoef, uiWidth * uiHeight);                                                //@Note: the nonzero coefficients are calculted in TU level
  
  if ( uiNumSig == 0 )
    return;
  if(pcCU->getSlice()->getPPS()->getUseTransformSkip())
  {
    codeTransformSkipFlags( pcCU,uiAbsPartIdx, uiWidth, uiHeight, eTType );
  }
  eTType = eTType == TEXT_LUMA ? TEXT_LUMA : ( eTType == TEXT_NONE ? TEXT_NONE : TEXT_CHROMA );                          //@Note: fixed the text model: Luma, Chroma, None
       
  //----- encode significance map -----  
  const UInt   uiLog2BlockSize = g_aucConvertToBit[ uiWidth ] + 2;                                                       //@Note: Char  g_aucConvertToBit  [ MAX_CU_SIZE+1 ];    MAX_CU_SIZE = (1<< MAX_CU_DEPTH) = 64

  UInt uiScanIdx = pcCU->getCoefScanIdx(uiAbsPartIdx, uiWidth, eTType==TEXT_LUMA, pcCU->isIntra(uiAbsPartIdx));          //@Note: return the scanIdx, Veri. Hori. Diag.
 
  const UInt *scan = g_auiSigLastScan[ uiScanIdx ][ uiLog2BlockSize - 1 ];                                                //@Note: scan order table [3][6]
  
  Bool beValid;
  if (pcCU->getCUTransquantBypass(uiAbsPartIdx))                                                                        //@Note: if cu_transquant_bypass_flag = 1, the scanning and transform, in-loop filter are bypass
  {
    beValid = false;
  }
  else                                                                                                                   //@Note: if cu_transquant_bypass_flag = 0, check the hide flag for coefficient sign
  {
    beValid = pcCU->getSlice()->getPPS()->getSignHideFlag() > 0;
  }

  // Find position of last coefficient
  Int scanPosLast = -1;                                                                                                  //@Note: do ... while
  Int posLast;  

  const UInt * scanCG;
  {                                                                                                                       //@Note: g_auiSigLastScan[3][6]
    scanCG = g_auiSigLastScan[ uiScanIdx ][ uiLog2BlockSize > 3 ? uiLog2BlockSize-2-1 : 0 ];                              //@Note: TU 16*16: g_auiSigLastScan[uiScanIdx][1]
    if( uiLog2BlockSize == 3 )                                                                                            //@Note: TU 8*8:   g_sigL
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值