Beispiel #1
0
ErrVal
SliceEncoder::updatePictureResTransform( ControlData&     rcControlData,
                                         UInt          uiMbInRow )
{
  ROF( m_bInitDone );

  SliceHeader&  rcSliceHeader         = *rcControlData.getSliceHeader           ();
  MbDataCtrl*   pcMbDataCtrl          =  rcControlData.getMbDataCtrl            ();
  MbDataCtrl*   pcBaseLayerCtrl       =  rcControlData.getBaseLayerCtrl         ();
  UInt          uiMbAddress           =  0;
  UInt          uiLastMbAddress       =  rcSliceHeader.getMbInPic() - 1;

  //====== initialization ======
  RNOK( pcMbDataCtrl->initSlice( rcSliceHeader, DECODE_PROCESS, false, NULL ) );

  // Update the macroblock state
  // Must be done after the bit-stream has been constructed
  for( ; uiMbAddress <= uiLastMbAddress; )
  {
    UInt          uiMbY               = 0;
    UInt          uiMbX               = 0;
    MbDataAccess* pcMbDataAccess      = 0;
    MbDataAccess* pcMbDataAccessBase  = 0;

    rcSliceHeader.getMbPositionFromAddress( uiMbY, uiMbX, uiMbAddress );
    RNOK( pcMbDataCtrl      ->initMb          ( pcMbDataAccess,     uiMbY, uiMbX ) );
    if( pcBaseLayerCtrl )
    {
      RNOK( pcBaseLayerCtrl ->initMb          ( pcMbDataAccessBase, uiMbY, uiMbX ) );
      pcMbDataAccess->setMbDataAccessBase( pcMbDataAccessBase );
    }

    // modify QP values (as specified in G.8.1.5.1.2)
    if( pcMbDataAccess->getMbData().getMbCbp() == 0 && ( pcMbDataAccess->getMbData().getMbMode() == INTRA_BL || pcMbDataAccess->getMbData().getResidualPredFlag() ) )
    {
      pcMbDataAccess->getMbData().setQp   ( pcMbDataAccessBase->getMbData().getQp() );
      pcMbDataAccess->getMbData().setQp4LF( pcMbDataAccessBase->getMbData().getQp() );
    }

    // if cbp==0, tranform size is not transmitted, in this case inherit the transform size from base layer
    if( ( pcMbDataAccess->getMbData().getResidualPredFlag() && ! pcMbDataAccess->getMbData().isIntra() && ! pcMbDataAccessBase->getMbData().isIntra() ) || ( pcMbDataAccess->getMbData().getMbMode() == INTRA_BL ) )
    {
      if( ( pcMbDataAccess->getMbData().getMbCbp() & 0x0F ) == 0 )
      {
        pcMbDataAccess->getMbData().setTransformSize8x8( pcMbDataAccessBase->getMbData().isTransformSize8x8() );
      }
    }

    // set I_PCM mode (for deblocking) when CBP is 0, mbMode is I_BL, and base layer mbMode is I_PCM
    if( pcMbDataAccess->getMbData().getMbCbp() == 0 && pcMbDataAccess->getMbData().isIntraBL() && pcMbDataAccessBase->getMbData().isPCM() )
    {
      pcMbDataAccess->getMbData().setMbMode( MODE_PCM );
    }

    uiMbAddress++;
  }

  return Err::m_nOK;
}
Beispiel #2
0
ErrVal
SliceEncoder::encodeSlice( SliceHeader&  rcSliceHeader,
                           Frame*        pcFrame,
                           MbDataCtrl*   pcMbDataCtrl,
                           RefListStruct& rcRefListStruct,
                           Bool          bMCBlks8x8Disable,
                           UInt          uiMbInRow,
                           Double        dlambda )
{
  ROF( pcFrame );
  ROF( pcMbDataCtrl );
  UInt uiMaxMvPerMb = rcSliceHeader.getSPS().getMaxMVsPer2Mb () >> 1; // hard limit (don't take into account last macroblock)

  //===== get co-located picture =====
  MbDataCtrl*   pcMbDataCtrlL1 = NULL;
  RefFrameList& rcList1        = rcRefListStruct.acRefFrameListME[1];
  if( rcList1.getActive() && rcList1.getEntry( 0 )->getRecPicBufUnit() )
  {
    pcMbDataCtrlL1 = rcList1.getEntry( 0 )->getRecPicBufUnit()->getMbDataCtrl();
  }
  ROT( rcSliceHeader.isBSlice() && ! pcMbDataCtrlL1 );

  //===== initialization =====
  RNOK( pcMbDataCtrl  ->initSlice         ( rcSliceHeader, ENCODE_PROCESS, false, pcMbDataCtrlL1 ) );
  RNOK( m_pcControlMng->initSliceForCoding( rcSliceHeader ) );



  //===== loop over macroblocks =====
  for( UInt uiMbAddress = rcSliceHeader.getFirstMbInSlice(); uiMbAddress <= rcSliceHeader.getLastMbInSlice(); uiMbAddress = rcSliceHeader.getFMO()->getNextMBNr( uiMbAddress ) )
  {
    UInt          uiMbY           = uiMbAddress / uiMbInRow;
    UInt          uiMbX           = uiMbAddress % uiMbInRow;
    MbDataAccess* pcMbDataAccess  = 0;

    RNOK( pcMbDataCtrl  ->initMb          (  pcMbDataAccess, uiMbY, uiMbX ) );
    RNOK( m_pcControlMng->initMbForCoding ( *pcMbDataAccess, uiMbY, uiMbX, false, false  ) );
    pcMbDataAccess->setMbDataAccessBase   ( NULL );

    RNOK( m_pcMbEncoder ->encodeMacroblock( *pcMbDataAccess,
                                             pcFrame,
                                             rcRefListStruct,
                                             uiMaxMvPerMb,
                                             bMCBlks8x8Disable,
                                             m_pcCodingParameter->getBiPred8x8Disable() > 0,
                                             m_pcCodingParameter->getMotionVectorSearchParams().getNumMaxIter(),
                                             m_pcCodingParameter->getMotionVectorSearchParams().getIterSearchRange(),
                                             dlambda ) );
    RNOK( m_pcMbCoder   ->encode          ( *pcMbDataAccess,
                                              NULL,
                                             ( uiMbAddress == rcSliceHeader.getLastMbInSlice() )
                                             ,true ) );
  }

  return Err::m_nOK;
}
Beispiel #3
0
// JVT-V035
ErrVal
SliceEncoder::updatePictureAVCRewrite( ControlData& rcControlData, UInt uiMbInRow )
{
  ROF( m_bInitDone );

  SliceHeader&  rcSliceHeader   = *rcControlData.getSliceHeader();
  FMO&          rcFMO           = *rcSliceHeader.getFMO();
  MbDataCtrl*   pcMbDataCtrl    = rcControlData.getMbDataCtrl();
  MbDataCtrl*   pcBaseLayerCtrl = rcControlData.getBaseLayerCtrl();

  //====== initialization ======
  RNOK( pcMbDataCtrl->initSlice( rcSliceHeader, DECODE_PROCESS, false, NULL ) );

  if( rcSliceHeader.getTCoeffLevelPredictionFlag() == true )
  {
	  // Update the macroblock state
	  // Must be done after the bit-stream has been constructed
    for( Int iSliceGroupId = rcFMO.getFirstSliceGroupId(); ! rcFMO.SliceGroupCompletelyCoded( iSliceGroupId ); iSliceGroupId = rcFMO.getNextSliceGroupId( iSliceGroupId ) )
    {
      UInt  uiFirstMbInSliceGroup = rcFMO.getFirstMBOfSliceGroup( iSliceGroupId );
      UInt  uiLastMbInSliceGroup  = rcFMO.getLastMBInSliceGroup ( iSliceGroupId );

      for( UInt uiMbAddress = uiFirstMbInSliceGroup; uiMbAddress <= uiLastMbInSliceGroup; uiMbAddress = rcFMO.getNextMBNr( uiMbAddress ) )
	    {
		    UInt          uiMbY               = 0;
		    UInt          uiMbX               = 0;
		    MbDataAccess* pcMbDataAccess      = 0;
		    MbDataAccess* pcMbDataAccessBase  = 0;

        rcSliceHeader.getMbPositionFromAddress( uiMbY, uiMbX, uiMbAddress );
		    RNOK( pcMbDataCtrl->initMb( pcMbDataAccess, uiMbY, uiMbX ) );

		    if( pcBaseLayerCtrl )
		    {
			    RNOK( pcBaseLayerCtrl ->initMb( pcMbDataAccessBase, uiMbY, uiMbX ) );
			    pcMbDataAccess->setMbDataAccessBase( pcMbDataAccessBase );
		    }

        // modify QP values (as specified in G.8.1.5.1.2)
        if( pcMbDataAccess->getMbData().getMbCbp() == 0 && ( pcMbDataAccess->getMbData().getMbMode() == INTRA_BL || pcMbDataAccess->getMbData().getResidualPredFlag() ) )
        {
          pcMbDataAccess->getMbData().setQp( pcMbDataAccessBase->getMbData().getQp() );
        }

		    if( pcMbDataAccess->isTCoeffPred() )
		    {
			    if( pcMbDataAccess->getMbData().getMbMode() == INTRA_BL )
			    {
				    // We're going to use the BL skip flag to correctly decode the intra prediction mode
				    AOT( pcMbDataAccess->getMbData().getBLSkipFlag() == false );

				    // Inherit the mode of the base block
				    pcMbDataAccess->getMbData().setMbMode( pcMbDataAccessBase->getMbData().getMbMode() );

				    // Inherit intra prediction modes
				    for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
					    pcMbDataAccess->getMbData().intraPredMode(cIdx) = pcMbDataAccessBase->getMbData().intraPredMode(cIdx);

				    pcMbDataAccess->getMbData().setChromaPredMode( pcMbDataAccessBase->getMbData().getChromaPredMode() );
			    }

  		    // The 8x8 transform flag is present in the bit-stream unless transform coefficients
			    // are not transmitted at the enhancement layer.  In this case, inherit the base layer
			    // transform type.  This makes intra predition work correctly, etc.
          if( ( pcMbDataAccess->getMbData().getMbCbp() & 0x0F ) == 0 )
          {
            pcMbDataAccess->getMbData().setTransformSize8x8( pcMbDataAccessBase->getMbData().isTransformSize8x8() );
          }

			    xAddTCoeffs2( *pcMbDataAccess, *pcMbDataAccessBase );
		    }

        if( pcMbDataAccess->getMbAddress() != uiFirstMbInSliceGroup &&
            pcMbDataAccess->getSH().getTCoeffLevelPredictionFlag() &&
           !pcMbDataAccess->getSH().getNoInterLayerPredFlag() &&
           !pcMbDataAccess->getMbData().isIntra16x16() &&
            pcMbDataAccess->getMbData().getMbExtCbp() == 0 )
        {
          pcMbDataAccess->getMbData().setQp4LF( pcMbDataAccess->getLastQp4LF() );
        }
        else
        {
          pcMbDataAccess->getMbData().setQp4LF( pcMbDataAccess->getMbData().getQp() );
        }
	    }
    }
  }

  return Err::m_nOK;
}