mbdataaccess.cpp

来自「SVC最新更新代码」· C++ 代码 · 共 1,098 行 · 第 1/3 页

CPP
1,098
字号
  // inter P
  m_rcMbCurr.setMbMode( MbMode(++uiMbType) );
  m_rcMbCurr.setFwdBwd( (uiMbType < INTRA_4X4) ? 0x1111 : 0 );
  ROT( uiMbType > 25 + 6 );
  return Err::m_nOK;
}

ErrVal
MbDataAccess::setSVCDirectModeMvAndRef( RefFrameList& rcRefList0,
                                        RefFrameList& rcRefList1,
                                        Int           i8x8Blk     /* = -1 for entire macroblock */ )
{
  UInt  uiFirst4x4Index = ( i8x8Blk == 3 ? 10 : i8x8Blk == 2 ? 8 : i8x8Blk == 1 ? 2 : i8x8Blk == 0 ? 0 : 0 );
  UInt  uiLast4x4Index  = ( i8x8Blk == 3 ? 11 : i8x8Blk == 2 ? 9 : i8x8Blk == 1 ? 3 : i8x8Blk == 0 ? 1 : 3 );
  SChar ascRefIdx [2];
  Mv    acMv      [2];
  for(  UInt uiListIdx = 0; uiListIdx < 2; uiListIdx++ )
  {
    ListIdx eListIdx = ( uiListIdx ? LIST_1 : LIST_0 );
    xSetNeighboursMvPredictor( eListIdx, B4x4Idx( uiFirst4x4Index ), B4x4Idx( uiLast4x4Index ) );
    if( ( ascRefIdx[uiListIdx] = m_cMv3D_A.minRefIdx( m_cMv3D_B ).minRefIdx( m_cMv3D_C ).getRef() ) > 0 )
    {
      xGetMvPredictorUseNeighbours( acMv[uiListIdx], ascRefIdx[uiListIdx], MEDIAN );
    }
  }
  if( ascRefIdx[0] < 1 && ascRefIdx[1] < 1 )
  {
    ascRefIdx[0] = 1;
    ascRefIdx[1] = 1;
  }
  ROF( ascRefIdx[0] <= (SChar)rcRefList0.getActive() && ascRefIdx[1] <= (SChar)rcRefList1.getActive() );
  if ( i8x8Blk < 0 || i8x8Blk > 3 ) // 16x16
  {
    getMbMotionData( LIST_0 ).setRefIdx( ascRefIdx[0] );
    getMbMotionData( LIST_1 ).setRefIdx( ascRefIdx[1] );
    getMbMotionData( LIST_0 ).setAllMv ( acMv     [0] );
    getMbMotionData( LIST_1 ).setAllMv ( acMv     [1] );
  }
  else
  {
    ParIdx8x8 eParIdx8x8 = ( i8x8Blk == 0 ? PART_8x8_0 : i8x8Blk == 1 ? PART_8x8_1 : i8x8Blk == 2 ? PART_8x8_2 : PART_8x8_3 );
    getMbMotionData( LIST_0 ).setRefIdx( ascRefIdx[0], eParIdx8x8 );
    getMbMotionData( LIST_1 ).setRefIdx( ascRefIdx[1], eParIdx8x8 );
    getMbMotionData( LIST_0 ).setAllMv ( acMv     [0], eParIdx8x8 );
    getMbMotionData( LIST_1 ).setAllMv ( acMv     [1], eParIdx8x8 );
  }
  return Err::m_nOK;
}

Bool MbDataAccess::getMvPredictorDirect( ParIdx8x8 eParIdx, 
                                         Bool& rbOneMv, 
                                         Bool bFaultTolerant, 
                                         RefFrameList* pcL0RefFrameList, 
                                         RefFrameList* pcL1RefFrameList )
{
  rbOneMv = getSH().getSPS().getDirect8x8InferenceFlag();

  if( getSH().getDirectSpatialMvPredFlag() )
  {
    return xSpatialDirectMode ( eParIdx, rbOneMv, pcL0RefFrameList, pcL1RefFrameList );
  }
  return xTemporalDirectMode( eParIdx, rbOneMv, bFaultTolerant );
}

Bool MbDataAccess::xSpatialDirectMode( ParIdx8x8 eParIdx, Bool b8x8, RefFrameList* pcL0RefFrameList, RefFrameList* pcL1RefFrameList )

{
  UInt          uiLstIdx;
  Bool          bDirectZeroPred   = false;
  Bool          bAllColNonZero    = false;
  Bool          bColZeroFlagBlk0  = false;
  Bool          bColZeroFlagBlk1  = false;
  Bool          bColZeroFlagBlk2  = false;
  Bool          bColZeroFlagBlk3  = false;

  //===== get reference indices and spatially predicted motion vectors =====
  Mv    acMvPred[2];
  SChar ascRefIdx[2];
  xSetNeighboursMvPredictor(LIST_0, B4x4Idx(0), B4x4Idx(3) );
  if( ( ascRefIdx[LIST_0] = m_cMv3D_A.minRefIdx( m_cMv3D_B ).minRefIdx( m_cMv3D_C ).getRef() ) > 0 )
  {
    xGetMvPredictorUseNeighbours( acMvPred[LIST_0], ascRefIdx[LIST_0], MEDIAN );
  }
  xSetNeighboursMvPredictor(LIST_1, B4x4Idx(0), B4x4Idx(3) );
  if( ( ascRefIdx[LIST_1] = m_cMv3D_A.minRefIdx( m_cMv3D_B ).minRefIdx( m_cMv3D_C ).getRef() ) > 0 )
  {
    xGetMvPredictorUseNeighbours( acMvPred[LIST_1], ascRefIdx[LIST_1], MEDIAN );
  }

  //===== check reference indices =====
  if( ascRefIdx[LIST_0] < 1 && ascRefIdx[LIST_1] < 1 )
  {
    ascRefIdx[LIST_0] = 1;
    ascRefIdx[LIST_1] = 1;
    bDirectZeroPred   = true;
    bAllColNonZero    = true;
  }

  //===== check co-located =====
  if( ! bAllColNonZero )
  {
    SChar   scRefIdxCol;
    Mv      acMvCol[4];

    if( ! bAllColNonZero )
    {
      if( NULL != pcL0RefFrameList && NULL != pcL1RefFrameList )
      {
        bAllColNonZero  = (*pcL1RefFrameList)[1]->isLongTerm();
      }
      else
      {
        AOT(1);
      }
    }

    if( ! bAllColNonZero )
    {
      if( b8x8 )
      {
        SParIdx4x4 eSubMbPartIdx = ( eParIdx <= PART_8x8_1 ? ( eParIdx == PART_8x8_0 ? SPART_4x4_0 : SPART_4x4_1 )
                                                           : ( eParIdx == PART_8x8_2 ? SPART_4x4_2 : SPART_4x4_3 ) );

        xGetColocatedMvRefIdx( acMvCol[0], scRefIdxCol, B4x4Idx( eParIdx + eSubMbPartIdx ) );
      }
      else
      {
        //===== THIS SHALL NEVER BE CALLED FOR INTERLACED SEQUENCES =====
        xGetColocatedMvsRefIdxNonInterlaced( acMvCol, scRefIdxCol, eParIdx );
      }

      bAllColNonZero = ( scRefIdxCol != 1 );
    }

    if( ! bAllColNonZero )
    {
      bColZeroFlagBlk0   = ( acMvCol[0].getAbsHor() <= 1 && acMvCol[0].getAbsVer() <= 1 );

      if( ! b8x8 )
      {
        bColZeroFlagBlk1 = ( acMvCol[1].getAbsHor() <= 1 && acMvCol[1].getAbsVer() <= 1 );
        bColZeroFlagBlk2 = ( acMvCol[2].getAbsHor() <= 1 && acMvCol[2].getAbsVer() <= 1 );
        bColZeroFlagBlk3 = ( acMvCol[3].getAbsHor() <= 1 && acMvCol[3].getAbsVer() <= 1 );
      }
    }
  }

  //===== set motion vectors and reference frames =====
  for( uiLstIdx = 0; uiLstIdx < 2; uiLstIdx++ )
  {
    ListIdx       eListIdx          = ListIdx( uiLstIdx );
    MbMotionData& rcMbMotionDataLX  = getMbMotionData( eListIdx );
    SChar         scRefIdx          = ascRefIdx[ eListIdx ];
    Bool          bZeroMv;
		Bool          bMvValid = true;

    //----- set motion vectors -----
    if( b8x8 || bAllColNonZero || scRefIdx < 1 )
    {
      bZeroMv         = ( bDirectZeroPred || scRefIdx < 1 || ( scRefIdx == 1 && bColZeroFlagBlk0 ) );
      const Mv& rcMv  = ( bZeroMv ? Mv::ZeroMv() : acMvPred [ eListIdx ] );
      rcMbMotionDataLX.setAllMv( rcMv, eParIdx );
			bMvValid = xCheckMv( rcMv );
    }
    else
    {
      bZeroMv         = ( scRefIdx == 1 && bColZeroFlagBlk0 );
      const Mv& rcMv0 = ( bZeroMv ? Mv::ZeroMv() : acMvPred [ eListIdx ] );
      rcMbMotionDataLX.setAllMv( rcMv0, eParIdx, SPART_4x4_0 );
			bMvValid &= xCheckMv( rcMv0 );

      bZeroMv         = ( scRefIdx == 1 && bColZeroFlagBlk1 );
      const Mv& rcMv1 = ( bZeroMv ? Mv::ZeroMv() : acMvPred [ eListIdx ] );
      rcMbMotionDataLX.setAllMv( rcMv1, eParIdx, SPART_4x4_1 );
			bMvValid &= xCheckMv( rcMv1 );

      bZeroMv         = ( scRefIdx == 1 && bColZeroFlagBlk2 );
      const Mv& rcMv2 = ( bZeroMv ? Mv::ZeroMv() : acMvPred [ eListIdx ] );
      rcMbMotionDataLX.setAllMv( rcMv2, eParIdx, SPART_4x4_2 );
			bMvValid &= xCheckMv( rcMv2 );

      bZeroMv         = ( scRefIdx == 1 && bColZeroFlagBlk3 );
      const Mv& rcMv3 = ( bZeroMv ? Mv::ZeroMv() : acMvPred [ eListIdx ] );
      rcMbMotionDataLX.setAllMv( rcMv3, eParIdx, SPART_4x4_3 );
			bMvValid &= xCheckMv( rcMv3 );
    }

    //----- set reference indices and reference pictures -----
    rcMbMotionDataLX.setRefIdx ( scRefIdx,  eParIdx );

    if ( !bMvValid )
    {
      return false;
  }
}
	return true;
}


Bool
MbDataAccess::xTemporalDirectModeMvRef( Mv acMv[], SChar ascRefIdx[], LumaIdx cIdx, Bool bFaultTolerant )
{
  SChar             scRefIdxCol;
  Mv                cMvCol;
  const RefPicIdc&  rcRefPicCol = xGetColocatedMvRefPic( cMvCol, scRefIdxCol, cIdx );

  //----- get reference index for list 0 -----
  if( scRefIdxCol > 0 )
  {
    if( rcRefPicCol.isValid() )
    {
      const Frame* pcFrame = rcRefPicCol.getPic();
      AOF( pcFrame ); // something wrong
      if( ( getMbPicType() == FRAME || pcFrame->getPicType() == FRAME ) && ( getMbPicType() != pcFrame->getPicType() ) )
      {
        pcFrame = pcFrame->getFrame()->getPic( getMbPicType() );
        AOF( pcFrame );
      }
      RefFrameList& rcRefList = *m_rcSliceHeader.getRefFrameList( getMbPicType(), LIST_0 );
      SChar         scRefIdx  = BLOCK_NOT_AVAILABLE;
      for( UInt uiIndex = 1; uiIndex <= rcRefList.getSize(); uiIndex++ )
      {
        if( rcRefList[uiIndex] == pcFrame )
        {
          scRefIdx = uiIndex;
          break;
        }
      }
      ascRefIdx[LIST_0] = scRefIdx;
      if( scRefIdx < 1 )
      {
        AOT(1);
        ROFRS( bFaultTolerant, false ); // not allowed
        ascRefIdx[LIST_0] = 1;
      }
    }
    else
    {
      AOT(1);
      ROFRS( bFaultTolerant, false ); // not allowed
    }
  }

  Int iScale = m_rcSliceHeader.getDistScaleFactor( getMbPicType(), ascRefIdx[LIST_0], ascRefIdx[LIST_1] );
  if( iScale == 1024 )
  {
    acMv[LIST_0]  = cMvCol;
    acMv[LIST_1]  = Mv::ZeroMv();
  }
  else
  {
    acMv[LIST_0]  = cMvCol.scaleMv( iScale );
    acMv[LIST_1]  = acMv[LIST_0] - cMvCol;
  }
  Bool   bMvValid = xCheckMv( acMv[LIST_0]);
  return bMvValid;
}


Bool
MbDataAccess::xTemporalDirectModeMvsRefNonInterlaced( Mv aacMv[][4], SChar ascRefIdx[], ParIdx8x8 eParIdx, Bool bFaultTolerant )
{
  SChar             scRefIdxCol;
  Mv                acMvCol[4];
  const RefPicIdc&  rcRefPicCol = xGetColocatedMvsRefPicNonInterlaced( acMvCol, scRefIdxCol, eParIdx );

  //----- get reference index for list 0 -----
  if( scRefIdxCol > 0 )
  {
    if( rcRefPicCol.isValid() ) 
    {
      const Frame* pcFrame = rcRefPicCol.getPic();
      AOF( pcFrame );                         // something wrong
      AOF( pcFrame->getPicType() == FRAME );  // something wrong
      RefFrameList& rcRefList = *m_rcSliceHeader.getRefFrameList( getMbPicType(), LIST_0 );
      SChar         scRefIdx  = BLOCK_NOT_AVAILABLE;
      for( UInt uiIndex = 1; uiIndex <= rcRefList.getSize(); uiIndex++ )
      {
        if( rcRefList[uiIndex] == pcFrame )
        {
          scRefIdx = uiIndex;
          break;
        }
      }
      ascRefIdx[LIST_0] = scRefIdx;
      if( scRefIdx < 1 )
      {
        AOT(1);
        ROFRS( bFaultTolerant, false ); // not allowed
        ascRefIdx[LIST_0] = 1;
      }
    }
    else
    {
      AOT(1);
      ROFRS( bFaultTolerant, false ); // not allowed
    }
  }
  Bool bMvValid = true;
  Int iScale = m_rcSliceHeader.getDistScaleFactor     ( getMbPicType(), ascRefIdx[LIST_0], ascRefIdx[LIST_1] );
  if( iScale == 1024 )
  {
    for( UInt uiIndex = 0; uiIndex < 4; uiIndex++ )
    {
      aacMv[LIST_0][uiIndex] = acMvCol[uiIndex];
      aacMv[LIST_1][uiIndex] = Mv::ZeroMv();
    }
  }
  else
  {
    for( UInt uiIndex = 0; uiIndex < 4; uiIndex++ )
    {
      aacMv[LIST_0][uiIndex] = acMvCol[uiIndex].scaleMv( iScale );
      aacMv[LIST_1][uiIndex] = aacMv[LIST_0][uiIndex] - acMvCol[uiIndex];
      bMvValid &= xCheckMv( aacMv[LIST_0][uiIndex] );
    }
  }
  return bMvValid;
}


Bool MbDataAccess::xTemporalDirectMode( ParIdx8x8 eParIdx, Bool b8x8, Bool bFaultTolerant )
{
  Bool  bModeAllowed;
  SChar ascRefIdx[2]  = { 1, 1 };

  if( b8x8 )
  {
    Mv          acMv[2];
    SParIdx4x4  eSubMbPartIdx = ( eParIdx <= PART_8x8_1 ? ( eParIdx == PART_8x8_0 ? SPART_4x4_0 : SPART_4x4_1 )
                                                        : ( eParIdx == PART_8x8_2 ? SPART_4x4_2 : SPART_4x4_3 ) );
    B4x4Idx     cIdx          = B4x4Idx( eParIdx + eSubMbPartIdx );

    bModeAllowed = xTemporalDirectModeMvRef( acMv, ascRefIdx, cIdx, bFaultTolerant );
    ROFRS( bModeAllowed, bModeAllowed );
    for( UInt uiLstIdx = 0; uiLstIdx < 2; uiLstIdx++ )
    {
      ListIdx       eListIdx          = ListIdx( uiLstIdx );
      MbMotionData& rcMbMotionDataLX  = getMbMotionData( eListIdx );
      rcMbMotionDataLX.setAllMv    ( acMv     [eListIdx], eParIdx );
      rcMbMotionDataLX.setRefIdx   ( ascRefIdx[eListIdx], eParIdx );
    }
  }
  else // do not do this for interlaced stuff
  {
    Mv      aacMv[2][4];
    bModeAllowed = xTemporalDirectModeMvsRefNonInterlaced( aacMv, ascRefIdx, eParIdx, bFaultTolerant );
    ROFRS( bModeAllowed, bModeAllowed );
    for( UInt uiLstIdx = 0; uiLstIdx < 2; uiLstIdx++ )
    {
      ListIdx       eListIdx          = ListIdx( uiLstIdx );
      MbMotionData& rcMbMotionDataLX  = getMbMotionData( eListIdx );
      rcMbMotionDataLX.setAllMv     ( aacMv[eListIdx][0],  eParIdx, SPART_4x4_0 );
      rcMbMotionDataLX.setAllMv     ( aacMv[eListIdx][1],  eParIdx, SPART_4x4_1 );
      rcMbMotionDataLX.setAllMv     ( aacMv[eListIdx][2],  eParIdx, SPART_4x4_2 );
      rcMbMotionDataLX.setAllMv     ( aacMv[eListIdx][3],  eParIdx, SPART_4x4_3 );
      rcMbMotionDataLX.setRefIdx    ( ascRefIdx[eListIdx], eParIdx );
    }
  }

  return bModeAllowed;
}

H264AVC_NAMESPACE_END

⌨️ 快捷键说明

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