⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mbdatactrl.cpp

📁 JVT-Z203_jsvm.rar
💻 CPP
📖 第 1 页 / 共 5 页
字号:
{
  Int iBase8x8MbPartIdx     = 0;  // index of top-left 8x8 block that is covered by the macroblock partition
  Int iBase4x4SubMbPartIdx  = 0;  // index of top-left 4x4 block that is covered by the sub-macroblock partition (inside 8x8 block)
  Int iBaseMbIdx            = MSYS_INT_MAX;
  Int iXInsideBaseMb        = MSYS_INT_MAX;
  Int iYInsideBaseMb        = MSYS_INT_MAX;
  RNOK( xGetRefLayerMb( iXInsideCurrMb, iYInsideCurrMb, iBaseMbIdx, iXInsideBaseMb, iYInsideBaseMb ) );

  //===== check whether available =====
  if( iBaseMbIdx == MSYS_INT_MAX )
  {
    riPartIdc = -2; // not available
    return Err::m_nOK;
  }
  
  //===== check whether intra =====
  MbData& rcMbDataBase = m_rcMbDataCtrlBase.getMbDataByIndex( (UInt)iBaseMbIdx );
  if( rcMbDataBase.isIntra() )
  {
    riPartIdc = -1; // intra
    return Err::m_nOK;
  }

  Int     iB8x8IdxBase    = ( (   iYInsideBaseMb       >> 3 ) << 1 ) + (   iXInsideBaseMb       >> 3 );
  Int     iB4x4IdxBase    = ( ( ( iYInsideBaseMb & 7 ) >> 2 ) << 1 ) + ( ( iXInsideBaseMb & 7 ) >> 2 );
  MbMode  eMbModeBase     = rcMbDataBase.getMbMode ();
  BlkMode eBlkModeBase    = rcMbDataBase.getBlkMode( Par8x8( iB8x8IdxBase ) );
  Bool    bBSkipOrDirect  = ( eMbModeBase == MODE_SKIP && rcMbDataBase.getSliceType() == B_SLICE );
  ROT( rcMbDataBase.getSliceType() == NOT_SPECIFIED_SLICE ); // check whether slice type is set

  if( bBSkipOrDirect )
  {
    //===== determine macroblock and sub-macroblock partition index for B_Skip and B_Direct_16x16 =====
    if( m_iRefLayerDQId == 0 )
    {
      iBase8x8MbPartIdx     = iB8x8IdxBase;
      iBase4x4SubMbPartIdx  = iB4x4IdxBase;
    }
  }
  else
  {
    const UInt aauiNxNPartIdx[6][4] =
    {
      { 0, 0, 0, 0 }, // MODE_SKIP (P Slice)
      { 0, 0, 0, 0 }, // MODE_16x16     or    BLK_8x8
      { 0, 0, 2, 2 }, // MODE_16x8      or    BLK_8x4
      { 0, 1, 0, 1 }, // MODE_8x16      or    BLK_4x8
      { 0, 1, 2, 3 }, // MODE_8x8       or    BLK_4x4
      { 0, 1, 2, 3 }  // MODE_8x8ref0
    };

    //===== determine macroblock partition index =====
    iBase8x8MbPartIdx = aauiNxNPartIdx[ eMbModeBase ][ iB8x8IdxBase ];
  
    //===== determine sub-macroblock partition index =====
    if( eMbModeBase == MODE_8x8 || eMbModeBase == MODE_8x8ref0 )
    {
      if( eBlkModeBase == BLK_SKIP )
      {
        if( m_iRefLayerDQId == 0 )
        {
          iBase4x4SubMbPartIdx = iB4x4IdxBase;
        }
      }
      else
      {
        iBase4x4SubMbPartIdx = aauiNxNPartIdx[ eBlkModeBase - BLK_8x8 + 1 ][ iB4x4IdxBase ];
      }
    }
  }

  //===== set partition indication =====
  Int iBase4x4BlkX    = ( ( iBase8x8MbPartIdx  & 1 ) << 1 ) + ( iBase4x4SubMbPartIdx  & 1 );
  Int iBase4x4BlkY    = ( ( iBase8x8MbPartIdx >> 1 ) << 1 ) + ( iBase4x4SubMbPartIdx >> 1 );
  Int iBase4x4BlkIdx  = ( iBase4x4BlkY << 2 ) + iBase4x4BlkX;
  riPartIdc           = ( iBaseMbIdx   << 4 ) + iBase4x4BlkIdx;
  return Err::m_nOK;
}


//===== this function implements subclause G.8.6.1.1 =====
ErrVal
MotionUpsampling::xSetPartIdcArray()
{
  ROFRS( m_bInCropWindow, Err::m_nOK );

  //===== determine all 16 initial partition indexes =====
  {
    m_bIntraBL  = true;
    for( Int iY = 0; iY < 4; iY++ )
    for( Int iX = 0; iX < 4; iX++ )
    {
      RNOK( xGetRefLayerPartIdc( ( iX << 2 ) + 1, ( iY << 2 ) + 1, m_aaiPartIdc[iX][iY] ) );
      m_bIntraBL  = ( m_bIntraBL  && ( m_aaiPartIdc[iX][iY] == -1 ) );
    }
    if( m_bIntraBL )
    {
      m_eMbMode  = INTRA_BL;
    }
  }
  ROTRS( m_bIntraBL,                  Err::m_nOK );
  ROTRS( m_cPosCalc.m_bRSChangeFlag,  Err::m_nOK );

  //===== replace values of "-1" on a 4x4 block basis =====
  {
    for( Int iYP = 0; iYP < 2; iYP++ )
    for( Int iXP = 0; iXP < 2; iXP++ )
    {
      Bool aabProcI4x4Blk[2][2] = { { false, false }, { false, false } };

      for( Int iYS = 0; iYS < 2; iYS++ )
      for( Int iXS = 0; iXS < 2; iXS++ )
      {
        Int iYC = ( iYP << 1 ) + iYS;
        Int iXC = ( iXP << 1 ) + iXS;

        if( m_aaiPartIdc[iXC][iYC] == -1 )
        {
          Int iYSInv  = 1 - iYS;
          Int iXSInv  = 1 - iXS;
          Int iYCInv  = ( iYP << 1 ) + iYSInv;
          Int iXCInv  = ( iXP << 1 ) + iXSInv;
          aabProcI4x4Blk[iXS][iYS] = true;
          
          if( ! aabProcI4x4Blk[iXSInv][iYS] && m_aaiPartIdc[iXCInv][iYC] != -1 )
          {
            m_aaiPartIdc[iXC][iYC] = m_aaiPartIdc[iXCInv][iYC];
          }
          else if( ! aabProcI4x4Blk[iXS][iYSInv] && m_aaiPartIdc[iXC][iYCInv] != -1 )
          {
            m_aaiPartIdc[iXC][iYC] = m_aaiPartIdc[iXC][iYCInv];
          }
          else if( ! aabProcI4x4Blk[iXSInv][iYSInv] && m_aaiPartIdc[iXCInv][iYCInv] != -1 )
          {
            m_aaiPartIdc[iXC][iYC] = m_aaiPartIdc[iXCInv][iYCInv];
          }
        }
      }
    }
  }

  //===== replace values of "-1" on an 8x8 block basis =====
  {
    Bool aabProcI8x8Blk[2][2] = { { false, false }, { false, false } };

    for( Int iYP = 0; iYP < 2; iYP++ )
    for( Int iXP = 0; iXP < 2; iXP++ )
    {
      Int iYPInv  = 1 - iYP;
      Int iXPInv  = 1 - iXP;
      Int iYO     = ( iYP << 1 );
      Int iXO     = ( iXP << 1 );
      Int iYOInv  = ( 2 - iYP );
      Int iXOInv  = ( 2 - iXP );

      if( m_aaiPartIdc[iXO][iYO] == -1 )
      {
        aabProcI8x8Blk[iXP][iYP] = true;

        if( ! aabProcI8x8Blk[iXPInv][iYP] && m_aaiPartIdc[iXOInv][iYO] != -1 )
        {
          m_aaiPartIdc[iXO  ][iYO  ] = m_aaiPartIdc[iXOInv][iYO  ];
          m_aaiPartIdc[iXO+1][iYO  ] = m_aaiPartIdc[iXOInv][iYO  ];
          m_aaiPartIdc[iXO  ][iYO+1] = m_aaiPartIdc[iXOInv][iYO+1];
          m_aaiPartIdc[iXO+1][iYO+1] = m_aaiPartIdc[iXOInv][iYO+1];
        }
        else if( ! aabProcI8x8Blk[iXP][iYPInv] && m_aaiPartIdc[iXO][iYOInv] != -1 )
        {
          m_aaiPartIdc[iXO  ][iYO  ] = m_aaiPartIdc[iXO  ][iYOInv];
          m_aaiPartIdc[iXO+1][iYO  ] = m_aaiPartIdc[iXO+1][iYOInv];
          m_aaiPartIdc[iXO  ][iYO+1] = m_aaiPartIdc[iXO  ][iYOInv];
          m_aaiPartIdc[iXO+1][iYO+1] = m_aaiPartIdc[iXO+1][iYOInv];
        }
        else if( ! aabProcI8x8Blk[iXPInv][iYPInv] && m_aaiPartIdc[iXOInv][iYOInv] != -1 )
        {
          m_aaiPartIdc[iXO  ][iYO  ] = m_aaiPartIdc[iXOInv][iYOInv];
          m_aaiPartIdc[iXO+1][iYO  ] = m_aaiPartIdc[iXOInv][iYOInv];
          m_aaiPartIdc[iXO  ][iYO+1] = m_aaiPartIdc[iXOInv][iYOInv];
          m_aaiPartIdc[iXO+1][iYO+1] = m_aaiPartIdc[iXOInv][iYOInv];
        }
      }      
    }
  }

  return Err::m_nOK;
}


//===== this function implements the reference index and motion vector scaling of subclause G.8.6.1.2 =====
ErrVal
MotionUpsampling::xGetInitialBaseRefIdxAndMv( Int     i4x4BlkX,
                                              Int     i4x4BlkY,
                                              ListIdx eListIdx,
                                              Int     iPartIdc,
                                              Int&    riRefIdx,
                                              Mv&     rcMv )
{
  Int           iMbIdxBase        = iPartIdc >> 4;
  B4x4Idx       c4x4IdxBase       = iPartIdc & 15;
  MbData&       rcMbDataBase      = m_rcMbDataCtrlBase.getMbDataByIndex ( (UInt)iMbIdxBase );
  Int           iCurrFieldMb      = ( m_bCurrFieldMb                ? 1 : 0 );
  Int           iBaseFieldMb      = ( rcMbDataBase  .getFieldFlag() ? 1 : 0 );
  MbMotionData& rcMotionDataBase  = rcMbDataBase    .getMbMotionData  ( eListIdx    );
  Int           iRefIdxBase       = rcMotionDataBase.getRefIdx        ( c4x4IdxBase );
  const Mv&     rcMvBase          = rcMotionDataBase.getMv            ( c4x4IdxBase );

  if( iRefIdxBase < 1 )
  {
    riRefIdx  = BLOCK_NOT_PREDICTED;
    rcMv      = Mv::ZeroMv();
    return Err::m_nOK;
  }

  //===== set reference index and convert motion vector to frame motion vector =====
  riRefIdx  = ( ( ( iRefIdxBase - 1 ) << ( iCurrFieldMb - m_cMvScale.m_iCurrField ) ) >> ( iBaseFieldMb - m_cMvScale.m_iBaseField ) ) + 1;
  Int iMvX  = rcMvBase.getHor();
  Int iMvY  = rcMvBase.getVer() * ( 1 + iBaseFieldMb );

  //===== get motion vector scaling factors =====
  Bool  bCropChange = ( m_cMvScale.m_bCropChangeFlag && riRefIdx <= m_cMvScale.m_aiNumActive[eListIdx] );
  Int   idOX        = 0;
  Int   idOY        = 0;
  Int   idSW        = 0;
  Int   idSH        = 0;
  Int   iScaleX     = m_cMvScale.m_iScaleX;
  Int   iScaleY     = m_cMvScale.m_iScaleY;
  if( bCropChange )
  {
    idOX    = m_cMvScale.m_aaidOX[eListIdx][riRefIdx-1];
    idOY    = m_cMvScale.m_aaidOY[eListIdx][riRefIdx-1];
    idSW    = m_cMvScale.m_aaidSW[eListIdx][riRefIdx-1];
    idSH    = m_cMvScale.m_aaidSH[eListIdx][riRefIdx-1];
    iScaleX = ( ( ( m_cMvScale.m_iScaledW + idSW ) << 16 ) + ( m_cMvScale.m_iRefW >> 1 ) ) / m_cMvScale.m_iRefW;
    iScaleY = ( ( ( m_cMvScale.m_iScaledH + idSH ) << 16 ) + ( m_cMvScale.m_iRefH >> 1 ) ) / m_cMvScale.m_iRefH;
  }

  //===== get scaled motion vector components =====
  iMvX  = ( iMvX * iScaleX + 32768 ) >> 16;
  iMvY  = ( iMvY * iScaleY + 32768 ) >> 16;

  //===== add correction vector =====
  if( bCropChange )
  {
    Int iFldInFrame = ( m_cMvScale.m_iCurrMbAff && m_bCurrFieldMb ? 1 : 0 );
    Int iMbPosX     = (   m_iMbXCurr << 4 );
    Int iMbPosY     = ( ( m_iMbYCurr >> iFldInFrame ) << ( 4 + iFldInFrame ) ) + ( m_iMbYCurr & iFldInFrame );
    Int iXFrm       =   iMbPosX +   ( ( i4x4BlkX << 2 ) + 1 );
    Int iYFrm       = ( iMbPosY + ( ( ( i4x4BlkX << 2 ) + 1 ) << ( iCurrFieldMb - m_cMvScale.m_iCurrField ) ) ) << m_cMvScale.m_iCurrField;
    Int iX          = iXFrm - m_cMvScale.m_iOffsetX;
    Int iY          = iYFrm - m_cMvScale.m_iOffsetY;
    iScaleX         = ( ( ( 4 * idSW ) << 16 ) + ( m_cMvScale.m_iScaledW >> 1 ) ) / m_cMvScale.m_iScaledW;
    iScaleY         = ( ( ( 4 * idSH ) << 16 ) + ( m_cMvScale.m_iScaledH >> 1 ) ) / m_cMvScale.m_iScaledH;
    iMvX           += ( ( iX * iScaleX + 32768 ) >> 16 ) - 4 * idOX;
    iMvY           += ( ( iY * iScaleY + 32768 ) >> 16 ) - 4 * idOY;
  }

  //===== set mv predictor (scale to field vector when required) =====
  rcMv.set( (Short)iMvX, (Short)( iMvY / ( 1 + iCurrFieldMb ) ) );

  return Err::m_nOK;
}


//===== this function implements the function MinPositive() specified in subclause G.8.6.1.2 =====
Int
MotionUpsampling::xGetMinRefIdx( Int iRefIdxA, Int iRefIdxB )
{
  ROTRS( iRefIdxA < 1,  iRefIdxB );
  ROTRS( iRefIdxB < 1,  iRefIdxA );
  return min( iRefIdxA, iRefIdxB );
}


//===== this function implements the first part of subclause G.8.6.1.2 =====
ErrVal
MotionUpsampling::xGetRefIdxAndInitialMvPred( ListIdx eListIdx )
{
  //===== get initial predictors for reference indices and motion vectors =====
  {
    for( Int i4x4BlkY = 0; i4x4BlkY < 4; i4x4BlkY++ )
    for( Int i4x4BlkX = 0; i4x4BlkX < 4; i4x4BlkX++ )
    {
      RNOK( xGetInitialBaseRefIdxAndMv( i4x4BlkX, i4x4BlkY, eListIdx, m_aaiPartIdc[i4x4BlkX][i4x4BlkY], 
                                        m_aaiRefIdxTemp[i4x4BlkX][i4x4BlkY], m_aaacMv[eListIdx][i4x4BlkX][i4x4BlkY] ) );
    }
  }
      
  //===== set reference indices =====
  m_aaaiRefIdx[eListIdx][0][0] = m_aaiRefIdxTemp[0][0];
  m_aaaiRefIdx[eListIdx][0][1] = m_aaiRefIdxTemp[0][2];
  m_aaaiRefIdx[eListIdx][1][0] = m_aaiRefIdxTemp[2][0];
  m_aaaiRefIdx[eListIdx][1][1] = m_aaiRefIdxTemp[2][2];
  ROTRS( m_cMvScale.m_bRSChangeFlag, Err::m_nOK );

  //===== merge reference indices and modify motion vectors accordingly =====
  for( Int i8x8BlkY = 0; i8x8BlkY < 2; i8x8BlkY++ )
  for( Int i8x8BlkX = 0; i8x8BlkX < 2; i8x8BlkX++ )
  {
    //----- determine reference indices -----
    for( Int i4x4BlkY = 0; i4x4BlkY < 2; i4x4BlkY++ )
    for( Int i4x4BlkX = 0; i4x4BlkX < 2; i4x4BlkX++ )
    {
      Int iY  = ( i8x8BlkY << 1 ) + i4x4BlkY;
      Int iX  = ( i8x8BlkX << 1 ) + i4x4BlkX;
      m_aaaiRefIdx[eListIdx][i8x8BlkX][i8x8BlkY] = xGetMinRefIdx( m_aaaiRefIdx[eListIdx][i8x8BlkX][i8x8BlkY], m_aaiRefIdxTemp[iX][iY] );
    }

    //----- update motion vectors -----
    for( Int iYS = 0; iYS < 2; iYS++ )
    for( Int iXS = 0; iXS < 2; iXS++ )
    {
      Int iY = ( i8x8BlkY << 1 ) + iYS;
      Int iX = ( i8x8BlkX << 1 ) + iXS;
      
      if( m_aaaiRefIdx[eListIdx][i8x8BlkX][i8x8BlkY] != m_aaiRefIdxTemp[iX][iY] )
      {
        Int iYInv = ( i8x8BlkY << 1 ) + 1 - iYS;
        Int iXInv = ( i8x8BlkX << 1 ) + 1 - iXS;

        if( m_aaaiRefIdx[eListIdx][i8x8BlkX][i8x8BlkY] == m_aaiRefIdxTemp[iXInv][iY] )
        {
          m_aaacMv[eListIdx][iX][iY] = m_aaacMv[eListIdx][iXInv][iY];
        }
        else if( m_aaaiRefIdx[eListIdx][i8x8BlkX][i8x8BlkY] == m_aaiRefIdxTemp[iX][iYInv] )
        {
          m_aaacMv[eListIdx][iX][iY] = m_aaacMv[eListIdx][iX][iYInv];
        }
        else
        {
          ROF( m_aaaiRefIdx[eListIdx][i8x8BlkX][i8x8BlkY] == m_aaiRefIdxTemp[iXInv][iYInv] );
          m_aaacMv[eListIdx][iX][iY] = m_aaacMv[eListIdx][iXInv][iYInv];
        }
      }
    }    
  }

  return Err::m_nOK;
}


//===== this function implements the function mvDiff specified in subclause G.8.6.1.2 =====
Int
MotionUpsampling::xMvDiff( const Mv& rcMvA, const Mv& rcMbB )
{
  return rcMvA.getAbsHorDiff( rcMbB ) + rcMvA.getAbsVerDiff( rcMbB );
}


//===== this function implements subclause G.8.6.1.2 =====
ErrVal
MotionUpsampling::xDeriveBlockModeAndUpdateMv( Int i8x8BlkIdx )
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -