[정수리] HEVC 학습(25) - 변환 계수의 인코딩 중 하나

본고는 먼저 계수 스캐닝 모델의 초기화를 소개한다.
코드와 해당 설명을 직접 제공합니다.
 
// scanning order table
UInt* g_auiSigLastScan[ 3 ][ MAX_CU_DEPTH ]; //!< [pattern][depth]

const UInt g_sigLastScan8x8[ 3 ][ 4 ] =
{
  {0, 2, 1, 3}, //!< right-up diagonal
  {0, 1, 2, 3}, //!< horizontal
  {0, 2, 1, 3}  //!< vertical
};
UInt g_sigLastScanCG32x32[ 64 ];

 
Void initSigLastScan(UInt* pBuffD, UInt* pBuffH, UInt* pBuffV, Int iWidth, Int iHeight, Int iDepth)
{
  const UInt  uiNumScanPos  = UInt( iWidth * iWidth );
  UInt        uiNextScanPos = 0;

  /*
  **            ,                  。
  **   ,     ,   2x2,4x4,8x8,16x16,32x32,64x64,128x128 7   ,  ,      
  **     4x4,8x8,16x16,32x32 4 ,          draft      ,      4   。
  **   ,          JCTVC-G644     ,                     ,  
  **       。
  */

  if( iWidth < 16 )
  {
  UInt* pBuffTemp = pBuffD;
  if( iWidth == 8 )
  {
    pBuffTemp = g_sigLastScanCG32x32; //!<   TU 32x32      ,CG Coefficient Group   
  }
  for( UInt uiScanLine = 0; uiNextScanPos < uiNumScanPos; uiScanLine++ )
  {
    Int    iPrimDim  = Int( uiScanLine );	//!< uiScanLine            
    Int    iScndDim  = 0;						//!<            
    while( iPrimDim >= iWidth )				//!<                        
    {													//!<                  ,     1,      1
      iScndDim++;
      iPrimDim--;
    }
    while( iPrimDim >= 0 && iScndDim < iWidth ) //!<              (     )       
    {//!< pBuffTemp     :iPrimDim             ,iiScndDim              
      pBuffTemp[ uiNextScanPos ] = iPrimDim * iWidth + iScndDim ;
      uiNextScanPos++;
      iScndDim++;
      iPrimDim--;
    }
  }
  }
  if( iWidth > 4 )
  {
    UInt uiNumBlkSide = iWidth >> 2;						//!<  4x4       
    UInt uiNumBlks    = uiNumBlkSide * uiNumBlkSide; //!<    
    UInt log2Blk      = g_aucConvertToBit[ uiNumBlkSide ] + 1;

    for( UInt uiBlk = 0; uiBlk < uiNumBlks; uiBlk++ )
    {
      uiNextScanPos   = 0;
      UInt initBlkPos = g_auiSigLastScan[ SCAN_DIAG ][ log2Blk ][ uiBlk ]; //!<  4x4       (  )	
      if( iWidth == 32 )
      {
        initBlkPos = g_sigLastScanCG32x32[ uiBlk ]; //!< TU 32x32 ,    16 4x4    up-right diamond  ,       32x32  4x4        
      }
      UInt offsetY    = initBlkPos / uiNumBlkSide;					//!<   4x4         
      UInt offsetX    = initBlkPos - offsetY * uiNumBlkSide;	//!<   4x4         
      UInt offsetD    = 4 * ( offsetX + offsetY * iWidth );		//!<   4x4        
      UInt offsetScan = 16 * uiBlk;	//!<    4x4    16   (   ),      4x4          1 4x4          
      for( UInt uiScanLine = 0; uiNextScanPos < 16; uiScanLine++ ) //!<    4x4          	
      {
        Int    iPrimDim  = Int( uiScanLine );
        Int    iScndDim  = 0;
        while( iPrimDim >= 4 ) //!<                  ,     1,      1
        {
          iScndDim++;
          iPrimDim--;
        }
        while( iPrimDim >= 0 && iScndDim < 4 ) //!<              (     )       
        {
          pBuffD[ uiNextScanPos + offsetScan ] = iPrimDim * iWidth + iScndDim + offsetD;
          uiNextScanPos++;
          iScndDim++;
          iPrimDim--;
        }
      }
    }
  }
  
  UInt uiCnt = 0;
  if( iWidth > 2 )
  {//!<       
    UInt numBlkSide = iWidth >> 2;  
    for(Int blkY=0; blkY < numBlkSide; blkY++) //!<  4x4    ,   
    {
      for(Int blkX=0; blkX < numBlkSide; blkX++)
      {
        UInt offset    = blkY * 4 * iWidth + blkX * 4; //!<     4x4         
        for(Int y=0; y < 4; y++) //!<    4x4   16       ,   
        {
          for(Int x=0; x < 4; x++)
          {
            pBuffH[uiCnt] = y*iWidth + x + offset;
            uiCnt ++;
          }
        }
      }
    }
    //!<       
    uiCnt = 0;
    for(Int blkX=0; blkX < numBlkSide; blkX++) //!<  4x4    ,   
    {
      for(Int blkY=0; blkY < numBlkSide; blkY++)
      {
        UInt offset    = blkY * 4 * iWidth + blkX * 4;
        for(Int x=0; x < 4; x++) //!< //!<    4x4   16       ,   
        {
          for(Int y=0; y < 4; y++)
          {
            pBuffV[uiCnt] = y*iWidth + x + offset;
            uiCnt ++;
          }
        }
      } //!< for(Int blkY=0; blkY < numBlkSide; blkY++)       
    } //!< for(Int blkX=0; blkX < numBlkSide; blkX++)     
  } //!< if( iWidth > 2 )   
  else  //!< if( iWidth <= 2 )
  { //!< Horizontal scan pattern
  for(Int iY=0; iY < iHeight; iY++)
  {
    for(Int iX=0; iX < iWidth; iX++)
    {
      pBuffH[uiCnt] = iY*iWidth + iX;
      uiCnt ++;
    }
  }

  //!< Vertical scan pattern
  uiCnt = 0;
  for(Int iX=0; iX < iWidth; iX++)
  {
    for(Int iY=0; iY < iHeight; iY++)
    {
      pBuffV[uiCnt] = iY*iWidth + iX;
      uiCnt ++;
    }
  }    
  } //!< else //!< if( iWidth <= 2 )
}

좋은 웹페이지 즐겨찾기