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; }
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; }
// 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; }