ErrVal MbDecoder::calcMv( MbDataAccess& rcMbDataAccess, MbDataAccess* pcMbDataAccessBaseMotion ) { if( rcMbDataAccess.getMbData().getBLSkipFlag() ) { return Err::m_nOK; } if( rcMbDataAccess.getMbData().getMbMode() == INTRA_4X4 ) { //----- intra prediction ----- rcMbDataAccess.getMbMotionData( LIST_0 ).setRefIdx( BLOCK_NOT_PREDICTED ); rcMbDataAccess.getMbMotionData( LIST_0 ).setAllMv ( Mv::ZeroMv() ); rcMbDataAccess.getMbMotionData( LIST_1 ).setRefIdx( BLOCK_NOT_PREDICTED ); rcMbDataAccess.getMbMotionData( LIST_1 ).setAllMv ( Mv::ZeroMv() ); } else { if( rcMbDataAccess.getMbData().getMbMode() == MODE_8x8 || rcMbDataAccess.getMbData().getMbMode() == MODE_8x8ref0 ) { for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ ) { //----- motion compensated prediction ----- RNOK( m_pcMotionCompensation->calcMvSubMb( c8x8Idx, rcMbDataAccess, pcMbDataAccessBaseMotion ) ); } } else { //----- motion compensated prediction ----- RNOK( m_pcMotionCompensation->calcMvMb( rcMbDataAccess, pcMbDataAccessBaseMotion ) ); } } return Err::m_nOK; }
ErrVal MbCoder::xWriteIntraPredModes( MbDataAccess& rcMbDataAccess ) { ROFRS( rcMbDataAccess.getMbData().isIntra(), Err::m_nOK ); if( rcMbDataAccess.getMbData().isIntra4x4() ) { if( rcMbDataAccess.getSH().getPPS().getTransform8x8ModeFlag() ) { RNOK( m_pcMbSymbolWriteIf->transformSize8x8Flag( rcMbDataAccess ) ); } if( rcMbDataAccess.getMbData().isTransformSize8x8() ) { for( B8x8Idx cIdx; cIdx.isLegal(); cIdx++ ) { RNOK( m_pcMbSymbolWriteIf->intraPredModeLuma( rcMbDataAccess, cIdx ) ); } } else { for( S4x4Idx cIdx; cIdx.isLegal(); cIdx++ ) { RNOK( m_pcMbSymbolWriteIf->intraPredModeLuma( rcMbDataAccess, cIdx ) ); } } } if( rcMbDataAccess.getMbData().isIntra4x4() || rcMbDataAccess.getMbData().isIntra16x16() ) { RNOK( m_pcMbSymbolWriteIf->intraPredModeChroma( rcMbDataAccess ) ); } return Err::m_nOK; }
ErrVal MbDecoder::xDecodeMbIntra16x16( MbDataAccess& rcMbDataAccess, IntYuvMbBuffer& cYuvMbBuffer, IntYuvMbBuffer& rcPredBuffer ) { Int iStride = cYuvMbBuffer.getLStride(); RNOK( m_pcIntraPrediction->predictLumaMb( cYuvMbBuffer.getMbLumAddr(), iStride, rcMbDataAccess.getMbData().intraPredMode() ) ); rcPredBuffer.loadLuma( cYuvMbBuffer ); MbTransformCoeffs& rcCoeffs = m_cTCoeffs; Quantizer cQuantizer; cQuantizer.setQp ( rcMbDataAccess, false ); const QpParameter rcLQp = cQuantizer.getLumaQp(); Int iScaleY = g_aaiDequantCoef[rcLQp.rem()][0] << rcLQp.per(); const UChar* pucScaleY = rcMbDataAccess.getSH().getScalingMatrix( 0 ); if( pucScaleY ) { iScaleY *= pucScaleY[0]; iScaleY >>= 4; } RNOK( m_pcTransform->invTransformDcCoeff( rcCoeffs.get( B4x4Idx(0) ), iScaleY ) ); for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ ) { RNOK( m_pcTransform->invTransform4x4Blk( cYuvMbBuffer.getYBlk( cIdx ), iStride, rcCoeffs.get( cIdx ) ) ); } UInt uiChromaCbp = rcMbDataAccess.getMbData().getCbpChroma16x16(); RNOK( xDecodeChroma( rcMbDataAccess, cYuvMbBuffer, rcPredBuffer, uiChromaCbp, true ) ); return Err::m_nOK; }
ErrVal MbDecoder::xDecodeMbIntra4x4( MbDataAccess& rcMbDataAccess, IntYuvMbBuffer& cYuvMbBuffer, IntYuvMbBuffer& rcPredBuffer ) { Int iStride = cYuvMbBuffer.getLStride(); MbTransformCoeffs& rcCoeffs = m_cTCoeffs; for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ ) { rcMbDataAccess.getMbData().intraPredMode( cIdx ) = rcMbDataAccess.decodeIntraPredMode( cIdx ); XPel* puc = cYuvMbBuffer.getYBlk( cIdx ); UInt uiPredMode = rcMbDataAccess.getMbData().intraPredMode( cIdx ); RNOK( m_pcIntraPrediction->predictLumaBlock( puc, iStride, uiPredMode, cIdx ) ); rcPredBuffer.loadLuma( cYuvMbBuffer, cIdx ); if( rcMbDataAccess.getMbData().is4x4BlkCoded( cIdx ) ) { RNOK( m_pcTransform->invTransform4x4Blk( puc, iStride, rcCoeffs.get( cIdx ) ) ); } } UInt uiChromaCbp = rcMbDataAccess.getMbData().getCbpChroma4x4(); RNOK( xDecodeChroma( rcMbDataAccess, cYuvMbBuffer, rcPredBuffer, uiChromaCbp, true ) ); return Err::m_nOK; }
ErrVal MbDecoder::xDecodeChroma( MbDataAccess& rcMbDataAccess, YuvMbBuffer& rcRecYuvBuffer, UInt uiChromaCbp, Bool bPredChroma ) { MbTransformCoeffs& rcCoeffs = m_cTCoeffs; Pel* pucCb = rcRecYuvBuffer.getMbCbAddr(); Pel* pucCr = rcRecYuvBuffer.getMbCrAddr(); Int iStride = rcRecYuvBuffer.getCStride(); if( bPredChroma ) { RNOK( m_pcIntraPrediction->predictChromaBlock( pucCb, pucCr, iStride, rcMbDataAccess.getMbData().getChromaPredMode() ) ); } ROTRS( 0 == uiChromaCbp, Err::m_nOK ); Int iScale; Bool bIntra = rcMbDataAccess.getMbData().isIntra(); UInt uiUScalId = ( bIntra ? 1 : 4 ); UInt uiVScalId = ( bIntra ? 2 : 5 ); const UChar* pucScaleU = rcMbDataAccess.getSH().getScalingMatrix( uiUScalId ); const UChar* pucScaleV = rcMbDataAccess.getSH().getScalingMatrix( uiVScalId ); // scaling has already been performed on DC coefficients iScale = ( pucScaleU ? pucScaleU[0] : 16 ); m_pcTransform->invTransformChromaDc( rcCoeffs.get( CIdx(0) ), iScale ); iScale = ( pucScaleV ? pucScaleV[0] : 16 ); m_pcTransform->invTransformChromaDc( rcCoeffs.get( CIdx(4) ), iScale ); RNOK( m_pcTransform->invTransformChromaBlocks( pucCb, iStride, rcCoeffs.get( CIdx(0) ) ) ); RNOK( m_pcTransform->invTransformChromaBlocks( pucCr, iStride, rcCoeffs.get( CIdx(4) ) ) ); return Err::m_nOK; }
Void IntMbTempData::copyResidualDataTo( MbDataAccess& rcMbDataAccess ) { rcMbDataAccess.getMbData ().setBCBP ( getBCBP () ); rcMbDataAccess.getMbData ().setMbExtCbp ( getMbExtCbp () ); rcMbDataAccess.getMbData ().setQp ( getQp () ); rcMbDataAccess.getMbTCoeffs ().copyFrom ( *this ); rcMbDataAccess.getMbData ().setTransformSize8x8 ( isTransformSize8x8 () ); rcMbDataAccess.getMbData ().setResidualPredFlags ( getResidualPredFlags() ); }
ErrVal SliceEncoder::updateBaseLayerResidual( ControlData& rcControlData, UInt uiMbInRow ) { ROF( m_bInitDone ); SliceHeader& rcSliceHeader = *rcControlData.getSliceHeader (); MbDataCtrl* pcMbDataCtrl = rcControlData.getMbDataCtrl (); MbDataCtrl* pcBaseLayerCtrl = rcControlData.getBaseLayerCtrl (); Frame* pcBaseLayerSbb = rcControlData.getBaseLayerSbb (); UInt uiMbAddress = 0; UInt uiLastMbAddress = rcSliceHeader.getMbInPic() - 1; //====== initialization ====== RNOK( pcMbDataCtrl->initSlice( rcSliceHeader, DECODE_PROCESS, false, NULL ) ); for( ; uiMbAddress <= uiLastMbAddress; ) { UInt uiMbY = uiMbAddress / uiMbInRow; UInt uiMbX = uiMbAddress % uiMbInRow; MbDataAccess* pcMbDataAccess = 0; MbDataAccess* pcMbDataAccessBase = 0; RNOK( pcMbDataCtrl ->initMb ( pcMbDataAccess, uiMbY, uiMbX ) ); if( pcBaseLayerCtrl ) { RNOK( pcBaseLayerCtrl ->initMb ( pcMbDataAccessBase, uiMbY, uiMbX ) ); //pcMbDataAccess->setMbDataAccessBase( pcMbDataAccessBase ); } // Update the state of the baselayer residual data -- it may be reused in subsequent layers - [email protected] if( !pcMbDataAccess->getMbData().getResidualPredFlag() ) { if( pcBaseLayerSbb && ( pcMbDataAccess->getMbData().isIntra() || ! pcMbDataAccess->getMbData().getResidualPredFlag() ) ) { YuvPicBuffer* pcBaseResidual = pcBaseLayerSbb->getFullPelYuvBuffer(); pcBaseResidual->getBufferCtrl().initMb( uiMbY, uiMbX, false); pcBaseResidual->clearCurrMb(); } } uiMbAddress++; } return Err::m_nOK; }
ErrVal MbDecoder::xDecodeMbIntraBL( MbDataAccess& rcMbDataAccess, IntYuvPicBuffer* pcRecYuvBuffer, IntYuvMbBuffer& rcPredBuffer, IntYuvPicBuffer* pcBaseYuvBuffer ) { IntYuvMbBuffer cYuvMbBuffer; MbTransformCoeffs& rcCoeffs = m_cTCoeffs; cYuvMbBuffer.loadBuffer ( pcBaseYuvBuffer ); rcPredBuffer.loadLuma ( cYuvMbBuffer ); rcPredBuffer.loadChroma ( cYuvMbBuffer ); if( rcMbDataAccess.getMbData().isTransformSize8x8() ) { for( B8x8Idx cIdx; cIdx.isLegal(); cIdx++ ) { if( rcMbDataAccess.getMbData().is4x4BlkCoded( cIdx ) ) { RNOK( m_pcTransform->invTransform8x8Blk( cYuvMbBuffer.getYBlk( cIdx ), cYuvMbBuffer.getLStride(), rcCoeffs.get8x8(cIdx) ) ); } } } else { for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ ) { if( rcMbDataAccess.getMbData().is4x4BlkCoded( cIdx ) ) { RNOK( m_pcTransform->invTransform4x4Blk( cYuvMbBuffer.getYBlk( cIdx ), cYuvMbBuffer.getLStride(), rcCoeffs.get(cIdx) ) ); } } } UInt uiChromaCbp = rcMbDataAccess.getMbData().getCbpChroma4x4(); RNOK( xDecodeChroma( rcMbDataAccess, cYuvMbBuffer, rcPredBuffer, uiChromaCbp, false ) ); pcRecYuvBuffer->loadBuffer( &cYuvMbBuffer ); return Err::m_nOK; }
ErrVal MbDecoder::compensatePrediction( MbDataAccess& rcMbDataAccess ) { ROTRS( rcMbDataAccess.getMbData().isIntra(), Err::m_nOK ); IntYuvMbBuffer cIntYuvMbBuffer; YuvMbBuffer cYuvMbBuffer; RNOK( m_pcMotionCompensation->compensateMb( rcMbDataAccess, &cYuvMbBuffer, false, false ) ); cIntYuvMbBuffer.loadBuffer( &cYuvMbBuffer ); RNOK( m_pcFrameMng->getPredictionIntFrame()->getFullPelYuvBuffer()->loadBuffer( &cIntYuvMbBuffer ) ); return Err::m_nOK; }
ErrVal MbCoder::encodeMotion( MbDataAccess& rcMbDataAccess, MbDataAccess* pcMbDataAccessBase ) { ROT( rcMbDataAccess.getMbData().isIntra() ); //===== base mode flag ===== RNOK( m_pcMbSymbolWriteIf->BLSkipFlag( rcMbDataAccess ) ); ROTRS( rcMbDataAccess.getMbData().getBLSkipFlag(), Err::m_nOK ); //===== macroblock mode ===== RNOK( m_pcMbSymbolWriteIf->mbMode( rcMbDataAccess ) ); //===== BLOCK MODES ===== if( rcMbDataAccess.getMbData().isInter8x8() ) { RNOK( m_pcMbSymbolWriteIf->blockModes( rcMbDataAccess ) ); } //===== MOTION INFORMATION ===== MbMode eMbMode = rcMbDataAccess.getMbData().getMbMode(); if( rcMbDataAccess.getSH().isInterB() ) { RNOK( xWriteMotionPredFlags_FGS ( rcMbDataAccess, pcMbDataAccessBase, eMbMode, LIST_0 ) ); RNOK( xWriteMotionPredFlags_FGS ( rcMbDataAccess, pcMbDataAccessBase, eMbMode, LIST_1 ) ); RNOK( xWriteReferenceFrames ( rcMbDataAccess, eMbMode, LIST_0 ) ); RNOK( xWriteReferenceFrames ( rcMbDataAccess, eMbMode, LIST_1 ) ); RNOK( xWriteMotionVectors ( rcMbDataAccess, eMbMode, LIST_0 ) ); RNOK( xWriteMotionVectors ( rcMbDataAccess, eMbMode, LIST_1 ) ); } else { RNOK( xWriteMotionPredFlags_FGS ( rcMbDataAccess, pcMbDataAccessBase, eMbMode, LIST_0 ) ); RNOK( xWriteReferenceFrames ( rcMbDataAccess, eMbMode, LIST_0 ) ); RNOK( xWriteMotionVectors ( rcMbDataAccess, eMbMode, LIST_0 ) ); } //===== residual prediction flag ===== Bool bBaseCoeff = ( pcMbDataAccessBase->getMbData().getMbCbp() != 0 ); RNOK( m_pcMbSymbolWriteIf->resPredFlag_FGS( rcMbDataAccess, bBaseCoeff ) ); return Err::m_nOK; }
Void IntMbTempData::copyTo( MbDataAccess& rcMbDataAccess ) { rcMbDataAccess.getMbData() .copyFrom( *this ); rcMbDataAccess.getMbTCoeffs() .copyFrom( *this ); rcMbDataAccess.getMbMvdData(LIST_0) .copyFrom( m_acMbMvdData[LIST_0] ); rcMbDataAccess.getMbMotionData(LIST_0).copyFrom( m_acMbMotionData[LIST_0] ); if( rcMbDataAccess.getSH().isBSlice() ) { rcMbDataAccess.getMbMvdData(LIST_1) .copyFrom( m_acMbMvdData[LIST_1] ); rcMbDataAccess.getMbMotionData(LIST_1).copyFrom( m_acMbMotionData[LIST_1] ); } }
ErrVal MbParser::xSkipMb( MbDataAccess& rcMbDataAccess ) { if( rcMbDataAccess.getSH().isBSlice() ) { RNOK( rcMbDataAccess.setConvertMbType( 0 ) ); } else { rcMbDataAccess.getMbMotionData( LIST_0 ).setRefIdx( 1 ); RNOK( rcMbDataAccess.setConvertMbType( MSYS_UINT_MAX ) ); } rcMbDataAccess.getMbData().setMbCbp( 0 ); return Err::m_nOK; }
ErrVal MbParser::xGet8x8BlockMv( MbDataAccess& rcMbDataAccess, B8x8Idx c8x8Idx, ListIdx eLstIdx ) { ParIdx8x8 eParIdx = c8x8Idx.b8x8(); switch( rcMbDataAccess.getMbData().getBlkMode( c8x8Idx.b8x8Index() ) ) { case BLK_8x8: { DECRNOK( m_pcMbSymbolReadIf->mvd( rcMbDataAccess, eLstIdx, eParIdx ) ); break; } case BLK_8x4: { DECRNOK( m_pcMbSymbolReadIf->mvd( rcMbDataAccess, eLstIdx, eParIdx, SPART_8x4_0 ) ); DECRNOK( m_pcMbSymbolReadIf->mvd( rcMbDataAccess, eLstIdx, eParIdx, SPART_8x4_1 ) ); break; } case BLK_4x8: { DECRNOK( m_pcMbSymbolReadIf->mvd( rcMbDataAccess, eLstIdx, eParIdx, SPART_4x8_0 ) ); DECRNOK( m_pcMbSymbolReadIf->mvd( rcMbDataAccess, eLstIdx, eParIdx, SPART_4x8_1 ) ); break; } case BLK_4x4: { DECRNOK( m_pcMbSymbolReadIf->mvd( rcMbDataAccess, eLstIdx, eParIdx, SPART_4x4_0 ) ); DECRNOK( m_pcMbSymbolReadIf->mvd( rcMbDataAccess, eLstIdx, eParIdx, SPART_4x4_1 ) ); DECRNOK( m_pcMbSymbolReadIf->mvd( rcMbDataAccess, eLstIdx, eParIdx, SPART_4x4_2 ) ); DECRNOK( m_pcMbSymbolReadIf->mvd( rcMbDataAccess, eLstIdx, eParIdx, SPART_4x4_3 ) ); break; } case BLK_SKIP: { break; } default: { return Err::m_nERR; } } return Err::m_nOK; }
ErrVal MbCoder::xWriteBlockMv( MbDataAccess& rcMbDataAccess, B8x8Idx c8x8Idx, ListIdx eLstIdx ) { BlkMode eBlkMode = rcMbDataAccess.getMbData().getBlkMode( c8x8Idx.b8x8Index() ); ParIdx8x8 eParIdx = c8x8Idx.b8x8(); switch( eBlkMode ) { case BLK_8x8: { RNOK( m_pcMbSymbolWriteIf->mvd( rcMbDataAccess, eLstIdx, eParIdx ) ); break; } case BLK_8x4: { RNOK( m_pcMbSymbolWriteIf->mvd( rcMbDataAccess, eLstIdx, eParIdx, SPART_8x4_0 ) ); RNOK( m_pcMbSymbolWriteIf->mvd( rcMbDataAccess, eLstIdx, eParIdx, SPART_8x4_1 ) ); break; } case BLK_4x8: { RNOK( m_pcMbSymbolWriteIf->mvd( rcMbDataAccess, eLstIdx, eParIdx, SPART_4x8_0 ) ); RNOK( m_pcMbSymbolWriteIf->mvd( rcMbDataAccess, eLstIdx, eParIdx, SPART_4x8_1 ) ); break; } case BLK_4x4: { RNOK( m_pcMbSymbolWriteIf->mvd( rcMbDataAccess, eLstIdx, eParIdx, SPART_4x4_0 ) ); RNOK( m_pcMbSymbolWriteIf->mvd( rcMbDataAccess, eLstIdx, eParIdx, SPART_4x4_1 ) ); RNOK( m_pcMbSymbolWriteIf->mvd( rcMbDataAccess, eLstIdx, eParIdx, SPART_4x4_2 ) ); RNOK( m_pcMbSymbolWriteIf->mvd( rcMbDataAccess, eLstIdx, eParIdx, SPART_4x4_3 ) ); break; } case BLK_SKIP: { break; } default: { AF(); return Err::m_nERR; } } return Err::m_nOK; }
Bool MbParser::xCheckSkipSliceMb( MbDataAccess& rcMbDataAccess, UInt uiNumMbRead, Bool& rbEndOfSlice ) { ROFRS( rcMbDataAccess.getSH().getSliceSkipFlag(), false ); MbData& rcMbData = rcMbDataAccess.getMbData(); rcMbData.setSkipFlag ( false ); rcMbData.setBLSkipFlag ( true ); rcMbData.setResidualPredFlag ( true ); rcMbData.setMbExtCbp ( 0 ); rcMbData.setFwdBwd ( 0 ); rcMbDataAccess.resetQp (); rcMbDataAccess.getMbMotionData( LIST_0 ).clear( BLOCK_NOT_PREDICTED ); rcMbDataAccess.getMbMotionData( LIST_1 ).clear( BLOCK_NOT_PREDICTED ); rcMbDataAccess.getMbMvdData ( LIST_0 ).clear(); rcMbDataAccess.getMbMvdData ( LIST_1 ).clear(); rbEndOfSlice = ( uiNumMbRead >= rcMbDataAccess.getSH().getNumMbsInSliceMinus1() ); return true; }
ErrVal MbParser::xReadIntraPredModes( MbDataAccess& rcMbDataAccess ) { ROFRS( rcMbDataAccess.getMbData().isIntra(), Err::m_nOK ); if( rcMbDataAccess.getMbData().isIntra4x4() ) { if( rcMbDataAccess.getSH().getPPS().getTransform8x8ModeFlag() ) { DECRNOK( m_pcMbSymbolReadIf->transformSize8x8Flag( rcMbDataAccess ) ); } if( rcMbDataAccess.getMbData().isTransformSize8x8() ) { for( B8x8Idx cIdx; cIdx.isLegal(); cIdx++ ) { DECRNOK( m_pcMbSymbolReadIf->intraPredModeLuma8x8( rcMbDataAccess, cIdx ) ); } } else { for( S4x4Idx cIdx; cIdx.isLegal(); cIdx++ ) { DECRNOK( m_pcMbSymbolReadIf->intraPredModeLuma( rcMbDataAccess, cIdx ) ); } } } if( rcMbDataAccess.getMbData().isIntra4x4() || rcMbDataAccess.getMbData().isIntra16x16() ) { if( rcMbDataAccess.getSH().getSPS().getChromaFormatIdc() ) { DECRNOK( m_pcMbSymbolReadIf->intraPredModeChroma( rcMbDataAccess ) ); } else { rcMbDataAccess.getMbData().setChromaPredMode( 0 ); // DC prediction } } return Err::m_nOK; }
ErrVal MbCoder::xWriteReferenceFrames( MbDataAccess& rcMbDataAccess, MbMode eMbMode, ListIdx eLstIdx ) { AOT_DBG( rcMbDataAccess.getMbData().isIntra() ); if( 1 == rcMbDataAccess.getNumActiveRef( eLstIdx ) ) { return Err::m_nOK; } Bool bPred = rcMbDataAccess.getSH().getAdaptivePredictionFlag(); MbMotionData& rcMot = rcMbDataAccess.getMbMotionData( eLstIdx ); switch( eMbMode ) { case MODE_SKIP: { break; } case MODE_16x16: { if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_0, eLstIdx) && ( ! bPred || ! rcMot.getMotPredFlag() ) ) { RNOK( m_pcMbSymbolWriteIf->refFrame( rcMbDataAccess, eLstIdx ) ); } break; } case MODE_16x8: { if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_0, eLstIdx) && ( ! bPred || ! rcMot.getMotPredFlag( PART_16x8_0 ) ) ) { RNOK( m_pcMbSymbolWriteIf->refFrame( rcMbDataAccess, eLstIdx, PART_16x8_0 ) ); } if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_2, eLstIdx) && ( ! bPred || ! rcMot.getMotPredFlag( PART_16x8_1 ) ) ) { RNOK( m_pcMbSymbolWriteIf->refFrame( rcMbDataAccess, eLstIdx, PART_16x8_1 ) ); } break; } case MODE_8x16: { if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_0, eLstIdx) && ( ! bPred || ! rcMot.getMotPredFlag( PART_8x16_0 ) ) ) { RNOK( m_pcMbSymbolWriteIf->refFrame( rcMbDataAccess, eLstIdx, PART_8x16_0 ) ); } if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_1, eLstIdx) && ( ! bPred || ! rcMot.getMotPredFlag( PART_8x16_1 ) ) ) { RNOK( m_pcMbSymbolWriteIf->refFrame( rcMbDataAccess, eLstIdx, PART_8x16_1 ) ); } break; } case MODE_8x8: case MODE_8x8ref0: { for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ ) { if( BLK_SKIP != rcMbDataAccess.getMbData().getBlkMode( c8x8Idx.b8x8Index() ) && rcMbDataAccess.getMbData().isBlockFwdBwd( c8x8Idx.b8x8Index(), eLstIdx ) && ( ! bPred || ! rcMot.getMotPredFlag( c8x8Idx.b8x8() ) ) ) { RNOK( m_pcMbSymbolWriteIf->refFrame( rcMbDataAccess, eLstIdx, c8x8Idx.b8x8() ) ); } } break; } default: { AF(); return Err::m_nERR; } } return Err::m_nOK; }
ErrVal MbCoder::xWriteMotionPredFlags( MbDataAccess& rcMbDataAccess, MbMode eMbMode, ListIdx eLstIdx ) { AOT_DBG( rcMbDataAccess.getMbData().isIntra() ); ROFRS ( rcMbDataAccess.getSH().getAdaptivePredictionFlag (), Err::m_nOK ); switch( eMbMode ) { case MODE_SKIP: { break; } case MODE_16x16: { if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_0, eLstIdx) ) { RNOK( m_pcMbSymbolWriteIf->motionPredFlag( rcMbDataAccess, eLstIdx ) ); } break; } case MODE_16x8: { if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_0, eLstIdx) ) { RNOK( m_pcMbSymbolWriteIf->motionPredFlag( rcMbDataAccess, eLstIdx, PART_16x8_0 ) ); } if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_2, eLstIdx) ) { RNOK( m_pcMbSymbolWriteIf->motionPredFlag( rcMbDataAccess, eLstIdx, PART_16x8_1 ) ); } break; } case MODE_8x16: { if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_0, eLstIdx) ) { RNOK( m_pcMbSymbolWriteIf->motionPredFlag( rcMbDataAccess, eLstIdx, PART_8x16_0 ) ); } if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_1, eLstIdx) ) { RNOK( m_pcMbSymbolWriteIf->motionPredFlag( rcMbDataAccess, eLstIdx, PART_8x16_1 ) ); } break; } case MODE_8x8: case MODE_8x8ref0: { for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ ) { if( BLK_SKIP != rcMbDataAccess.getMbData().getBlkMode ( c8x8Idx.b8x8Index() ) && rcMbDataAccess .getMbData().isBlockFwdBwd( c8x8Idx.b8x8Index(), eLstIdx) ) { RNOK( m_pcMbSymbolWriteIf->motionPredFlag( rcMbDataAccess, eLstIdx, c8x8Idx.b8x8() ) ); } } break; } default: { AF(); return Err::m_nERR; } } return Err::m_nOK; }
ErrVal SliceEncoder::encodeSliceSVC( ControlData& rcControlData, // control data Frame& rcOrgFrame, // original frame Frame& rcFrame, // reconstructed frame Frame* pcResidualFrameLF, // reconstructed residual for loop filter Frame* pcResidualFrameILPred,// reconstructed residual for inter-layer prediction Frame* pcPredFrame, // prediction signal PicType ePicType, // picture type UInt uiNumMaxIter, // maximum number of iteration for bi-predictive search UInt uiIterSearchRange, // search range for iterative search Bool bBiPred8x8Disable, // if bi-prediction for blocks smaller than 8x8 is allowed Bool bMCBlks8x8Disable, // if blocks smaller than 8x8 are disabled UInt uiMaxDeltaQp, // maximum delta QP UInt& ruiBits // size of coded data ) { ROF( m_bInitDone ); SliceHeader& rcSliceHeader = *rcControlData.getSliceHeader ( ePicType ); MbDataCtrl* pcMbDataCtrl = rcControlData.getMbDataCtrl (); MbDataCtrl* pcMbDataCtrl0L1 = rcControlData.getMbDataCtrl0L1 (); Frame* pcBaseIntraRecFrame = rcControlData.getBaseLayerRec (); Frame* pcBaseResidualFrame = rcControlData.getBaseLayerSbb (); MbDataCtrl* pcBaseMbDataCtrl = rcControlData.getBaseLayerCtrl (); Double dLambda = rcControlData.getLambda (); RefListStruct& rcRefListStruct = rcControlData.getRefListStruct (); UInt uiMbAddress = rcSliceHeader.getFirstMbInSlice (); UInt uiLastMbAddress = rcSliceHeader.getLastMbInSlice (); UInt uiMaxMvPerMb = rcSliceHeader.getSPS().getMaxMVsPer2Mb () >> 1; // hard limit (doesn't take into account last macroblock) UInt uiNumMbsCoded = 0; UInt uiDeltaQp = 0; //===== get field buffers if required ===== if( ePicType!=FRAME ) { RNOK( rcOrgFrame.addFieldBuffer( ePicType ) ); RNOK( rcFrame .addFieldBuffer( ePicType ) ); if( pcResidualFrameLF ) RNOK( pcResidualFrameLF ->addFieldBuffer( ePicType ) ); if( pcResidualFrameILPred ) RNOK( pcResidualFrameILPred ->addFieldBuffer( ePicType ) ); if( pcPredFrame ) RNOK( pcPredFrame ->addFieldBuffer( ePicType ) ); if( pcBaseIntraRecFrame ) RNOK( pcBaseIntraRecFrame ->addFieldBuffer( ePicType ) ); if( pcBaseResidualFrame ) RNOK( pcBaseResidualFrame ->addFieldBuffer( ePicType ) ); } Frame& rcOrgPic = *rcOrgFrame.getPic( ePicType ); Frame& rcPic = *rcFrame .getPic( ePicType ); Frame* pcResidualPicLF = ( pcResidualFrameLF ? pcResidualFrameLF ->getPic( ePicType ) : 0 ); Frame* pcResidualPicILPred = ( pcResidualFrameILPred ? pcResidualFrameILPred ->getPic( ePicType ) : 0 ); Frame* pcPredPic = ( pcPredFrame ? pcPredFrame ->getPic( ePicType ) : 0 ); Frame* pcBaseIntraRecPic = ( pcBaseIntraRecFrame ? pcBaseIntraRecFrame ->getPic( ePicType ) : 0 ); Frame* pcBaseResidualPic = ( pcBaseResidualFrame ? pcBaseResidualFrame ->getPic( ePicType ) : 0 ); //====== initialization ====== RNOK( pcMbDataCtrl ->initSlice ( rcSliceHeader, ENCODE_PROCESS, false, pcMbDataCtrl0L1 ) ); if( pcBaseMbDataCtrl ) { RNOK( pcBaseMbDataCtrl->initSlice ( rcSliceHeader, PRE_PROCESS, false, NULL ) ); } RNOK( m_pcControlMng ->initSliceForCoding( rcSliceHeader ) ); UInt uiBitsStart = m_pcMbCoder->getBitCount(); //===== M A I N L O O P O V E R M A C R O B L O C K S ===== for( m_pcMbCoder->bSliceCodedDone = false; uiMbAddress <= uiLastMbAddress; ) //--ICU/ETRI FMO Implementation { //===== rate control initialization ===== if( bRateControlEnable && !pcJSVMParams->m_uiLayerId ) { pcGenericRC->m_pcJSVMParams->number = pcGenericRC->m_pcJSVMParams->current_frame_number; pcJSVMParams->CurrGopLevel = pcGenericRC->getCurrGopLevel( pcGenericRC->m_pcJSVMParams->number ); pcGenericRC->m_pcJSVMParams->nal_reference_idc = ( pcJSVMParams->CurrGopLevel == 0 ? 0 : 1 ); pcGenericRC->m_pcJSVMParams->current_mb_nr = uiMbAddress; if( pcGenericRC->m_pcJSVMParams->basicunit == pcGenericRC->m_pcJSVMParams->FrameSizeInMbs ) { // qp remains unchanged } else if( pcGenericRC->m_pcJSVMParams->type == P_SLICE ) { // basic unit layer rate control (P slice) if( pcGenericRC->m_pcJSVMParams->NumberofCodedMacroBlocks > 0 && (pcGenericRC->m_pcJSVMParams->NumberofCodedMacroBlocks % pcGenericRC->m_pcJSVMParams->BasicUnit) == 0 ) { // frame coding if( pcGenericRC->m_pcJSVMParams->frame_mbs_only_flag ) { pcQuadraticRC->updateRCModel(); pcGenericRC->m_pcJSVMParams->qp = pcQuadraticRC->updateQPRC2( pcGenericRC->m_iTopFieldFlag ); } } } else if ( pcGenericRC->m_pcJSVMParams->RCUpdateMode == RC_MODE_1 ) { // basic unit layer rate control (I slice) if( pcGenericRC->m_pcJSVMParams->NumberofCodedMacroBlocks > 0 && (pcGenericRC->m_pcJSVMParams->NumberofCodedMacroBlocks % pcGenericRC->m_pcJSVMParams->BasicUnit) == 0 ) { // frame coding if( pcGenericRC->m_pcJSVMParams->frame_mbs_only_flag ) { pcQuadraticRC->updateRCModel(); if ( pcJSVMParams->m_uiIntraPeriod != 1 ) pcGenericRC->m_pcJSVMParams->qp = pcQuadraticRC->updateQPRC2(pcGenericRC->m_iTopFieldFlag); else pcGenericRC->m_pcJSVMParams->qp = pcQuadraticRC->updateQPRC1(pcGenericRC->m_iTopFieldFlag); } } } } //===== macroblock initialization ===== MbDataAccess* pcMbDataAccess = NULL; MbDataAccess* pcMbDataAccessBase = NULL; Double dCost = 0; UInt uiMbY, uiMbX; rcSliceHeader.getMbPositionFromAddress ( uiMbY, uiMbX, uiMbAddress ); RNOK( pcMbDataCtrl ->initMb ( pcMbDataAccess, uiMbY, uiMbX ) ); if ( pcBaseMbDataCtrl ) { RNOK( pcBaseMbDataCtrl->initMb ( pcMbDataAccessBase, uiMbY, uiMbX ) ); } RNOK( m_pcControlMng ->initMbForCoding ( *pcMbDataAccess, uiMbY, uiMbX, false, false ) ); pcMbDataAccess ->setMbDataAccessBase ( pcMbDataAccessBase ); if ( ! rcSliceHeader.getNoInterLayerPredFlag () ) { m_pcMbEncoder->setBaseModeAllowedFlag ( m_apabBaseModeFlagAllowedArrays[ ePicType == FRAME ? 0 : 1 ][ uiMbAddress ] ); } if ( bRateControlEnable && !pcJSVMParams->m_uiLayerId ) { pcMbDataAccess->getMbData().setQp ( pcGenericRC->m_pcJSVMParams->qp ); uiDeltaQp = 0; } else { pcMbDataAccess->getMbData().setQp ( rcSliceHeader.getSliceQp() ); uiDeltaQp = ( rcSliceHeader.getTemporalId() == 0 ? 0 : uiMaxDeltaQp ); // old JSVM behaviour } //===== determine macroblock data ===== RNOK( m_pcMbEncoder->encodeMacroblockSVC( *pcMbDataAccess, pcMbDataAccessBase, rcOrgPic, rcPic, pcResidualPicLF, pcResidualPicILPred, pcPredPic, pcBaseIntraRecPic, pcBaseResidualPic, rcRefListStruct, uiMaxMvPerMb, uiNumMaxIter, uiIterSearchRange, bBiPred8x8Disable, bMCBlks8x8Disable, true, uiDeltaQp, dLambda, dCost ) ); //===== check for end of slice and code data into NAL unit ==== uiNumMbsCoded++; if( m_uiSliceMode == 1 ) //fixed slice size in number of MBs { if( uiNumMbsCoded >= m_uiSliceArgument ) // this slice is done { RNOK( m_pcMbCoder->encode( *pcMbDataAccess, pcMbDataAccessBase, true, true ) ); rcControlData.m_uiCurrentFirstMB = rcSliceHeader.getFMO()->getNextMBNr( uiMbAddress ); rcSliceHeader.setNumMbsInSlice( uiNumMbsCoded ); if( rcSliceHeader.getFMO()->getNextMBNr( uiMbAddress ) == -1 ) { rcControlData.m_bSliceGroupAllCoded = true; } break; } else { RNOK( m_pcMbCoder->encode( *pcMbDataAccess, pcMbDataAccessBase, ( uiMbAddress == uiLastMbAddress ), true ) ); } } else if( m_uiSliceMode == 2 ) //fixed slice size in number of bytes { RNOK( m_pcMbCoder->encode( *pcMbDataAccess, pcMbDataAccessBase, ( uiMbAddress == uiLastMbAddress ), true ) ); if( ( rcSliceHeader.getFMO()->getNextMBNr( uiMbAddress ) == -1 ) && ( !m_pcMbCoder->bSliceCodedDone ) ) { rcControlData.m_bSliceGroupAllCoded = true; } if( m_pcMbCoder->bSliceCodedDone ) { rcControlData.m_uiCurrentFirstMB = uiMbAddress; rcSliceHeader.setNumMbsInSlice( uiNumMbsCoded - 1 ); //set SliceId equal to zero because this MBData belong to the next slice UInt uiDummyX = 0, uiDummyY = 0, uiMbIdx = 0; rcSliceHeader.getMbPosAndIndexFromAddress( uiDummyX, uiDummyY, uiMbIdx, rcControlData.m_uiCurrentFirstMB ); pcMbDataCtrl->xGetMbData( uiMbIdx )->setSliceId( 0 ); break; } } else // no slices (one slice per slice group) { RNOK( m_pcMbCoder->encode( *pcMbDataAccess, pcMbDataAccessBase, ( uiMbAddress == uiLastMbAddress ), true ) ); } //===== update rate control ===== if( bRateControlEnable && !pcJSVMParams->m_uiLayerId ) { pcGenericRC->m_iNumberofHeaderBits += pcGenericRC->m_iRCHeaderBits; pcGenericRC->m_iNumberofBasicUnitHeaderBits += pcGenericRC->m_iRCHeaderBits; pcGenericRC->m_iNumberofTextureBits += pcGenericRC->m_iRCTextureBits; pcGenericRC->m_iNumberofBasicUnitTextureBits += pcGenericRC->m_iRCTextureBits; pcGenericRC->m_pcJSVMParams->NumberofCodedMacroBlocks++; } //===== update macroblock address and check for end of slice group uiMbAddress = rcSliceHeader.getFMO()->getNextMBNr( uiMbAddress ); if( uiMbAddress == -1 ) { rcControlData.m_bSliceGroupAllCoded = true; break; } } //===== remove field buffers if required ===== if( ePicType!=FRAME ) { RNOK( rcOrgFrame.removeFieldBuffer( ePicType ) ); RNOK( rcFrame .removeFieldBuffer( ePicType ) ); if( pcResidualFrameLF ) RNOK( pcResidualFrameLF ->removeFieldBuffer( ePicType ) ); if( pcResidualFrameILPred ) RNOK( pcResidualFrameILPred ->removeFieldBuffer( ePicType ) ); if( pcPredFrame ) RNOK( pcPredFrame ->removeFieldBuffer( ePicType ) ); if( pcBaseIntraRecFrame ) RNOK( pcBaseIntraRecFrame ->removeFieldBuffer( ePicType ) ); if( pcBaseResidualFrame ) RNOK( pcBaseResidualFrame ->removeFieldBuffer( ePicType ) ); } //===== update bits ===== ruiBits += m_pcMbCoder->getBitCount() - uiBitsStart; return Err::m_nOK; }
ErrVal SliceEncoder::encodeMbAffSliceSVC( ControlData& rcControlData, // control data Frame& rcOrgFrame, // original frame Frame& rcFrame, // reconstructed frame Frame* pcResidualFrameLF, // reconstructed residual for loop filter Frame* pcResidualFrameILPred,// reconstructed residual for inter-layer prediction Frame* pcPredFrame, // prediction signal UInt uiNumMaxIter, // maximum number of iteration for bi-predictive search UInt uiIterSearchRange, // search range for iterative search Bool bBiPred8x8Disable, // if bi-prediction for blocks smaller than 8x8 is allowed Bool bMCBlks8x8Disable, // if blocks smaller than 8x8 are disabled UInt uiMaxDeltaQp, // maximum delta QP UInt& ruiBits // size of coded data ) { ROF( m_bInitDone ); SliceHeader& rcSliceHeader = *rcControlData.getSliceHeader (); MbDataCtrl* pcMbDataCtrl = rcControlData.getMbDataCtrl (); MbDataCtrl* pcMbDataCtrl0L1 = rcControlData.getMbDataCtrl0L1 (); Frame* pcBaseIntraRecFrame = rcControlData.getBaseLayerRec (); Frame* pcBaseResidualFrame = rcControlData.getBaseLayerSbb (); MbDataCtrl* pcBaseMbDataCtrl = rcControlData.getBaseLayerCtrl (); MbDataCtrl* pcBaseMbDataCtrlField = rcControlData.getBaseLayerCtrlField (); Double dLambda = rcControlData.getLambda (); RefListStruct& rcRefListStruct = rcControlData.getRefListStruct (); UInt uiLastQP = rcSliceHeader.getSliceQp (); UInt uiMbAddress = rcSliceHeader.getFirstMbInSlice (); UInt uiLastMbAddress = rcSliceHeader.getLastMbInSlice (); UInt uiMaxMvPerMb = rcSliceHeader.getSPS().getMaxMVsPer2Mb () >> 1; // hard limit (doesn't take into account last macroblock) Bool bSNR = rcSliceHeader.getSCoeffResidualPredFlag() || rcSliceHeader.getTCoeffLevelPredictionFlag(); UInt uiNumMbsCoded = 0; //===== set frame/field buffers ===== Frame* apcOrgPic [4] = { 0, 0, 0, 0 }; Frame* apcPic [4] = { 0, 0, 0, 0 }; Frame* apcResidualPicLF [4] = { 0, 0, 0, 0 }; Frame* apcResidualPicILPred[4] = { 0, 0, 0, 0 }; Frame* apcPredPic [4] = { 0, 0, 0, 0 }; Frame* apcBaseIntraRecPic [4] = { 0, 0, 0, 0 }; Frame* apcBaseResidualPic [4] = { 0, 0, 0, 0 }; RNOK( gSetFrameFieldArrays( apcOrgPic, &rcOrgFrame ) ); RNOK( gSetFrameFieldArrays( apcPic, &rcFrame ) ); RNOK( gSetFrameFieldArrays( apcResidualPicLF, pcResidualFrameLF ) ); RNOK( gSetFrameFieldArrays( apcResidualPicILPred, pcResidualFrameILPred ) ); RNOK( gSetFrameFieldArrays( apcPredPic, pcPredFrame ) ); RNOK( gSetFrameFieldArrays( apcBaseIntraRecPic, pcBaseIntraRecFrame ) ); RNOK( gSetFrameFieldArrays( apcBaseResidualPic, pcBaseResidualFrame ) ); MbDataBuffer acFldMbData [2]; YuvMbBuffer acFldMbRec [2]; YuvMbBuffer acFldMbResLF [2]; YuvMbBuffer acFldMbResILPred [2]; YuvMbBuffer acFldMbPredSignal[2]; //====== set frame/field reference lists ===== RefListStruct acRefListFieldStruct[2]; RNOK( gSetFrameFieldLists( acRefListFieldStruct[0], acRefListFieldStruct[1], rcRefListStruct ) ); //====== initialization ====== RNOK( pcMbDataCtrl ->initSlice ( rcSliceHeader, ENCODE_PROCESS, false, pcMbDataCtrl0L1 ) ); if( pcBaseMbDataCtrl ) { RNOK( pcBaseMbDataCtrl ->initSlice ( rcSliceHeader, PRE_PROCESS, false, NULL ) ); } if( pcBaseMbDataCtrlField ) { RNOK( pcBaseMbDataCtrlField ->initSlice ( rcSliceHeader, PRE_PROCESS, false, NULL ) ); } RNOK( m_pcControlMng ->initSliceForCoding( rcSliceHeader ) ); UInt uiBitsStart = m_pcMbCoder->getBitCount(); //===== M A I N L O O P O V E R M A C R O B L O C K P A I R S ===== for( m_pcMbCoder->bSliceCodedDone = false; uiMbAddress <= uiLastMbAddress; ) { UInt auiLastQpTest [2] = { uiLastQP, uiLastQP }; Bool abSkipModeAllowed [4] = { true, true, true, true }; Double adMbPairCost [2] = { 0.0, 0.0 }; //===== determine macroblock data ===== for( UInt uiMbTest = 0; uiMbTest < 4; uiMbTest++ ) { //--- set basic parameters --- UInt uiMbAddressMbAff = ( uiMbTest % 2 ) + uiMbAddress; UInt uiFieldMode = ( uiMbTest < 2 ? 1 : 0 ); RefListStruct& rcRefListPicStruct = ( uiFieldMode ? acRefListFieldStruct[ uiMbTest ] : rcRefListStruct ); //--- macroblock initialization --- MbDataAccess* pcMbDataAccess = NULL; MbDataAccess* pcMbDataAccessBase = NULL; Double dCost = 0; UInt uiMbY, uiMbX; rcSliceHeader.getMbPositionFromAddress ( uiMbY, uiMbX, uiMbAddressMbAff ); RNOK( pcMbDataCtrl ->initMb ( pcMbDataAccess, uiMbY, uiMbX ) ); if ( pcBaseMbDataCtrl && ( !uiFieldMode || bSNR ) ) { RNOK( pcBaseMbDataCtrl ->initMb ( pcMbDataAccessBase, uiMbY, uiMbX ) ); } if ( pcBaseMbDataCtrlField && uiFieldMode && !bSNR ) { RNOK( pcBaseMbDataCtrlField ->initMb ( pcMbDataAccessBase, uiMbY, uiMbX ) ); } RNOK( m_pcControlMng ->initMbForCoding ( *pcMbDataAccess, uiMbY, uiMbX, true, uiFieldMode == 1 ) ); pcMbDataAccess ->setMbDataAccessBase ( pcMbDataAccessBase ); pcMbDataAccess ->setLastQp ( auiLastQpTest[ uiFieldMode ] ); if( uiMbTest == 0 ) { abSkipModeAllowed[ 1 ] = pcMbDataAccess->getDefaultFieldFlag(); abSkipModeAllowed[ 3 ] = ! abSkipModeAllowed[ 1 ]; } if( ! rcSliceHeader.getNoInterLayerPredFlag () ) { m_pcMbEncoder->setBaseModeAllowedFlag ( m_apabBaseModeFlagAllowedArrays[ uiFieldMode ][ uiMbAddressMbAff ] ); } //--- determine macroblock data --- pcMbDataAccess->getMbData().setQp( rcSliceHeader.getSliceQp() ); UInt uiDeltaQp = ( rcSliceHeader.getTemporalId() == 0 ? 0 : uiMaxDeltaQp ); // old JSVM behaviour RNOK( m_pcMbEncoder->encodeMacroblockSVC( *pcMbDataAccess, pcMbDataAccessBase, *apcOrgPic[ uiMbTest ], *apcPic[ uiMbTest ], apcResidualPicLF[ uiMbTest ], apcResidualPicILPred[ uiMbTest ], apcPredPic[ uiMbTest ], apcBaseIntraRecPic[ uiMbTest ], apcBaseResidualPic[ uiMbTest ], rcRefListPicStruct, uiMaxMvPerMb, uiNumMaxIter, uiIterSearchRange, bBiPred8x8Disable, bMCBlks8x8Disable, abSkipModeAllowed[ uiMbTest ], uiDeltaQp, dLambda, dCost ) ); auiLastQpTest [ uiFieldMode ] = pcMbDataAccess->getMbData().getQp(); if( adMbPairCost[ uiFieldMode ] != DOUBLE_MAX ) { adMbPairCost [ uiFieldMode ] += dCost; } //--- store field macroblock data --- if( uiFieldMode ) { acFldMbData[uiMbTest].copy( pcMbDataAccess->getMbData() ); if( apcPic [uiMbTest] ) acFldMbRec [uiMbTest].loadBuffer( apcPic [uiMbTest]->getFullPelYuvBuffer() ); if( apcResidualPicLF [uiMbTest] ) acFldMbResLF [uiMbTest].loadBuffer( apcResidualPicLF [uiMbTest]->getFullPelYuvBuffer() ); if( apcResidualPicILPred[uiMbTest] ) acFldMbResILPred [uiMbTest].loadBuffer( apcResidualPicILPred[uiMbTest]->getFullPelYuvBuffer() ); if( apcPredPic [uiMbTest] ) acFldMbPredSignal[uiMbTest].loadBuffer( apcPredPic [uiMbTest]->getFullPelYuvBuffer() ); } } //===== decide frame/field mode ===== #ifdef RANDOM_MBAFF Bool bFieldCodingMode = gBoolRandom(); #else Bool bFieldCodingMode = ( adMbPairCost[1] < adMbPairCost[0] ); #endif //===== code macroblock pair into NAL unit ===== for( UInt uiMbIdx = 0; uiMbIdx < 2; uiMbIdx++ ) { //--- macroblock initialization --- UInt uiMbAddressMbAff = uiMbAddress + uiMbIdx; MbDataAccess* pcMbDataAccess = NULL; MbDataAccess* pcMbDataAccessBase = NULL; UInt uiMbY, uiMbX; rcSliceHeader.getMbPositionFromAddress ( uiMbY, uiMbX, uiMbAddressMbAff ); RNOK( pcMbDataCtrl ->initMb ( pcMbDataAccess, uiMbY, uiMbX ) ); if ( pcBaseMbDataCtrl && ( !bFieldCodingMode || bSNR ) ) { RNOK( pcBaseMbDataCtrl ->initMb ( pcMbDataAccessBase, uiMbY, uiMbX ) ); } if ( pcBaseMbDataCtrlField && bFieldCodingMode && !bSNR ) { RNOK( pcBaseMbDataCtrlField ->initMb ( pcMbDataAccessBase, uiMbY, uiMbX ) ); } RNOK( m_pcControlMng ->initMbForCoding ( *pcMbDataAccess, uiMbY, uiMbX, true, bFieldCodingMode ) ); pcMbDataAccess ->setMbDataAccessBase( pcMbDataAccessBase ); pcMbDataAccess ->setLastQp ( uiLastQP ); //--- restore field data --- if( bFieldCodingMode ) { pcMbDataAccess->getMbData().copy( acFldMbData[uiMbIdx] ); if( apcPic [uiMbIdx] ) apcPic [uiMbIdx]->getFullPelYuvBuffer()->loadBuffer( &acFldMbRec [uiMbIdx] ); if( apcResidualPicLF [uiMbIdx] ) apcResidualPicLF [uiMbIdx]->getFullPelYuvBuffer()->loadBuffer( &acFldMbResLF [uiMbIdx] ); if( apcResidualPicILPred[uiMbIdx] ) apcResidualPicILPred[uiMbIdx]->getFullPelYuvBuffer()->loadBuffer( &acFldMbResILPred [uiMbIdx] ); if( apcPredPic [uiMbIdx] ) apcPredPic [uiMbIdx]->getFullPelYuvBuffer()->loadBuffer( &acFldMbPredSignal[uiMbIdx] ); } //--- write data --- uiNumMbsCoded++; Bool bEndOfSlice = ( uiMbIdx == 1 ) && ( ( uiMbAddressMbAff == uiLastMbAddress ) || ( m_uiSliceMode == 1 && uiNumMbsCoded + 1 >= m_uiSliceArgument ) ); RNOK( m_pcMbCoder->encode( *pcMbDataAccess, pcMbDataAccessBase, bEndOfSlice, ( uiMbIdx == 1 ) ) ); //--- update last QP --- uiLastQP = pcMbDataAccess->getMbData().getQp(); //--- check for end of slice --- if( m_uiSliceMode == 2 && m_pcMbCoder->bSliceCodedDone && uiMbIdx == 0 ) { uiNumMbsCoded++; break; } } //===== check for end of slice ==== if( m_uiSliceMode == 1 && uiNumMbsCoded + 1 >= m_uiSliceArgument ) //fixed slice size in number of MBs { rcControlData.m_uiCurrentFirstMB = rcSliceHeader.getFMO()->getNextMBNr( uiMbAddress + 1 ); rcSliceHeader.setNumMbsInSlice( uiNumMbsCoded ); if( rcSliceHeader.getFMO()->getNextMBNr( uiMbAddress + 1 ) == -1 ) { rcControlData.m_bSliceGroupAllCoded = true; } break; } else if( m_uiSliceMode == 2 ) //fixed slice size in number of bytes { if( ( rcSliceHeader.getFMO()->getNextMBNr( uiMbAddress + 1 ) == -1 ) && ( !m_pcMbCoder->bSliceCodedDone ) ) { rcControlData.m_bSliceGroupAllCoded = true; } if( m_pcMbCoder->bSliceCodedDone ) { rcControlData.m_uiCurrentFirstMB = uiMbAddress; rcSliceHeader.setNumMbsInSlice( uiNumMbsCoded - 2 ); //set SliceId equal to zero because this MBData belong to the next slice UInt uiDummyX = 0, uiDummyY = 0, uiMbTopIdx = 0, uiMbBotIdx = 0; rcSliceHeader.getMbPosAndIndexFromAddress( uiDummyX, uiDummyY, uiMbTopIdx, rcControlData.m_uiCurrentFirstMB ); rcSliceHeader.getMbPosAndIndexFromAddress( uiDummyX, uiDummyY, uiMbBotIdx, rcControlData.m_uiCurrentFirstMB + 1 ); pcMbDataCtrl->xGetMbData( uiMbTopIdx )->setSliceId( 0 ); pcMbDataCtrl->xGetMbData( uiMbBotIdx )->setSliceId( 0 ); break; } } //===== update macroblock address and check for end of slice group uiMbAddress = rcSliceHeader.getFMO()->getNextMBNr( uiMbAddress + 1 ); if( uiMbAddress == -1 ) { rcControlData.m_bSliceGroupAllCoded = true; break; } } //===== remove field buffers ===== RNOK( rcOrgFrame.removeFrameFieldBuffer() ); RNOK( rcFrame .removeFrameFieldBuffer() ); if( pcResidualFrameLF ) RNOK( pcResidualFrameLF ->removeFrameFieldBuffer() ); if( pcResidualFrameILPred ) RNOK( pcResidualFrameILPred ->removeFrameFieldBuffer() ); if( pcPredFrame ) RNOK( pcPredFrame ->removeFrameFieldBuffer() ); if( pcBaseIntraRecFrame ) RNOK( pcBaseIntraRecFrame ->removeFrameFieldBuffer() ); if( pcBaseResidualFrame ) RNOK( pcBaseResidualFrame ->removeFrameFieldBuffer() ); //===== update bits ===== ruiBits += m_pcMbCoder->getBitCount() - uiBitsStart; return Err::m_nOK; }
ErrVal MbCoder::encode( MbDataAccess& rcMbDataAccess, MbDataAccess* pcMbDataAccessBase, Int iSpatialScalabilityType, Bool bTerminateSlice ) { ROF( m_bInitDone ); //===== skip flag ===== Bool bIsCoded = ! rcMbDataAccess.isSkippedMb(); RNOK( m_pcMbSymbolWriteIf->skipFlag( rcMbDataAccess, false ) ); if( bIsCoded ) { //===== base layer mode flag and base layer refinement flag ===== if( rcMbDataAccess.getSH().getBaseLayerId() != MSYS_UINT_MAX ) { if ( pcMbDataAccessBase->getMbData().getInCropWindowFlag() == true )// TMM_ESS { if( rcMbDataAccess.getSH().getAdaptivePredictionFlag() ) { RNOK ( m_pcMbSymbolWriteIf->BLSkipFlag( rcMbDataAccess ) ); } else { ROF( rcMbDataAccess.getMbData().getBLSkipFlag () ); } // TMM_ESS { } else // of if ( rcMbDataAccess.getMbData().getInCropWindowFlag() == true ) { ROT ( rcMbDataAccess.getMbData().getBLSkipFlag () ); } // TMM_ESS } } else { ROT ( rcMbDataAccess.getMbData().getBLSkipFlag () ); } //===== macroblock mode ===== if( ! rcMbDataAccess.getMbData().getBLSkipFlag() ) { MbMode eMbModeOrg = rcMbDataAccess.getMbData().getMbMode(); MbMode eMbModeSet = ( eMbModeOrg == INTRA_BL ? INTRA_4X4 : eMbModeOrg ); rcMbDataAccess.getMbData().setMbMode( eMbModeSet ); RNOK( m_pcMbSymbolWriteIf->mbMode( rcMbDataAccess ) ); rcMbDataAccess.getMbData().setMbMode( eMbModeOrg ); } //--- reset motion pred flags --- if( rcMbDataAccess.getMbData().getBLSkipFlag() || rcMbDataAccess.getMbData().isIntra() || rcMbDataAccess.getMbData().getMbMode() == MODE_SKIP ) { rcMbDataAccess.getMbMotionData( LIST_0 ).setMotPredFlag( false ); rcMbDataAccess.getMbMotionData( LIST_1 ).setMotPredFlag( false ); } else if( rcMbDataAccess.getSH().isInterB() ) { for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ ) { if( BLK_SKIP == rcMbDataAccess.getMbData().getBlkMode ( c8x8Idx.b8x8Index() ) || !rcMbDataAccess .getMbData().isBlockFwdBwd( c8x8Idx.b8x8Index(), LIST_0 ) ) { rcMbDataAccess.getMbMotionData( LIST_0 ).setMotPredFlag( false, c8x8Idx ); } if( BLK_SKIP == rcMbDataAccess.getMbData().getBlkMode ( c8x8Idx.b8x8Index() ) || !rcMbDataAccess .getMbData().isBlockFwdBwd( c8x8Idx.b8x8Index(), LIST_1 ) ) { rcMbDataAccess.getMbMotionData( LIST_1 ).setMotPredFlag( false, c8x8Idx ); } } } //===== prediction info ===== if( ! rcMbDataAccess.getMbData().getBLSkipFlag() ) { //===== BLOCK MODES ===== if( rcMbDataAccess.getMbData().isInter8x8() ) { RNOK( m_pcMbSymbolWriteIf->blockModes( rcMbDataAccess ) ); } if( rcMbDataAccess.getMbData().isPCM() ) { //===== PCM SAMPLES ===== RNOK( m_pcMbSymbolWriteIf->samplesPCM( rcMbDataAccess ) ); } else if( rcMbDataAccess.getMbData().isIntra() ) { //===== INTRA PREDICTION MODES ===== RNOK( xWriteIntraPredModes( rcMbDataAccess ) ); } else { //===== MOTION INFORMATION ===== MbMode eMbMode = rcMbDataAccess.getMbData().getMbMode(); if( rcMbDataAccess.getSH().isInterB() ) { RNOK( xWriteMotionPredFlags( rcMbDataAccess, eMbMode, LIST_0 ) ); RNOK( xWriteMotionPredFlags( rcMbDataAccess, eMbMode, LIST_1 ) ); RNOK( xWriteReferenceFrames( rcMbDataAccess, eMbMode, LIST_0 ) ); RNOK( xWriteReferenceFrames( rcMbDataAccess, eMbMode, LIST_1 ) ); RNOK( xWriteMotionVectors ( rcMbDataAccess, eMbMode, LIST_0 ) ); RNOK( xWriteMotionVectors ( rcMbDataAccess, eMbMode, LIST_1 ) ); } else { RNOK( xWriteMotionPredFlags( rcMbDataAccess, eMbMode, LIST_0 ) ); RNOK( xWriteReferenceFrames( rcMbDataAccess, eMbMode, LIST_0 ) ); RNOK( xWriteMotionVectors ( rcMbDataAccess, eMbMode, LIST_0 ) ); } } } //===== TEXTURE ===== if( ! rcMbDataAccess.getMbData().isPCM() ) { Bool bTrafo8x8Flag = ( rcMbDataAccess.getSH().getPPS().getTransform8x8ModeFlag() && ( rcMbDataAccess.getMbData().getBLSkipFlag() || ( rcMbDataAccess.getMbData().is8x8TrafoFlagPresent() && !rcMbDataAccess.getMbData().isIntra4x4() ) ) ); //-- JVT-R091 RNOK( xWriteTextureInfo( rcMbDataAccess, pcMbDataAccessBase, rcMbDataAccess.getMbTCoeffs(), bTrafo8x8Flag ) ); //-- } } //--- write terminating bit --- RNOK( m_pcMbSymbolWriteIf->terminatingBit ( bTerminateSlice ? 1:0 ) ); if( bTerminateSlice ) { RNOK( m_pcMbSymbolWriteIf->finishSlice() ); } return Err::m_nOK; }
ErrVal MbParser::read( MbDataAccess& rcMbDataAccess, UInt uiNumMbRead, Bool& rbEndOfSlice, UInt& ruiNextSkippedVLC ) { const CommonMainH264* pcMainH264 = CommonMain::getMainH264(); // FIXME: if (pcMainH264->getCurrentPictureId() == 1 && pcMainH264->getCurrentLayerId() == 16 && rcMbDataAccess.getMbData().getMbAddr() == 76) { int a = 0; } ROF( m_bInitDone ); ROTRS( xCheckSkipSliceMb( rcMbDataAccess, uiNumMbRead, rbEndOfSlice ), Err::m_nOK ); Bool bIsCoded = true; if( m_pcMbSymbolReadIf->isMbSkipped( rcMbDataAccess, ruiNextSkippedVLC ) ) { bIsCoded = false; rcMbDataAccess.getMbTCoeffs().clear(); rcMbDataAccess.getMbData().clearIntraPredictionModes( true ); RNOK( xSkipMb( rcMbDataAccess ) ); rcMbDataAccess.getMbData().setBLSkipFlag( false ); rcMbDataAccess.getMbData().setResidualPredFlag( rcMbDataAccess.getMbData().getInCropWindowFlag() ? rcMbDataAccess.getSH().getDefaultResidualPredictionFlag() : false ); if( rcMbDataAccess.getSH().isBSlice() ) { rcMbDataAccess.getMbData().setFwdBwd( 0x3333 ); rcMbDataAccess.getMbMotionData( LIST_0 ).clear( RefIdxValues(1) ); rcMbDataAccess.getMbMvdData ( LIST_0 ).clear(); rcMbDataAccess.getMbMotionData( LIST_1 ).clear( RefIdxValues(1) ); rcMbDataAccess.getMbMvdData ( LIST_1 ).clear(); } else { rcMbDataAccess.getMbData().setFwdBwd( 0x1111 ); rcMbDataAccess.getMbMotionData( LIST_0 ).clear( RefIdxValues(1) ); rcMbDataAccess.getMbMvdData ( LIST_0 ).clear(); } rcMbDataAccess.resetQp(); // set QP to that of the last macroblock } if( bIsCoded ) { if( rcMbDataAccess.getSH().isMbaffFrame() && ( rcMbDataAccess.isTopMb() || m_bPrevIsSkipped ) ) { RNOK( m_pcMbSymbolReadIf->fieldFlag( rcMbDataAccess) ); } Bool bBaseLayerAvailable = ! rcMbDataAccess.getSH().getNoInterLayerPredFlag(); //===== base layer mode flag and base layer refinement flag ===== if( bBaseLayerAvailable ) { if ( rcMbDataAccess.getMbData().getInCropWindowFlag() == true ) { if( rcMbDataAccess.getSH().getAdaptiveBaseModeFlag() ) { m_pcMbSymbolReadIf->isBLSkipped( rcMbDataAccess ); } else { rcMbDataAccess.getMbData().setBLSkipFlag( rcMbDataAccess.getSH().getDefaultBaseModeFlag() ); } } else { rcMbDataAccess.getMbData().setBLSkipFlag( false ); } } else { rcMbDataAccess.getMbData().setBLSkipFlag( false ); } if( rcMbDataAccess.getSH().getStoreRefBasePicFlag() && rcMbDataAccess.getSH().getQualityId() > 0 && rcMbDataAccess.getMbData().getBLSkipFlag() == false ) { printf("Conformance Issue: base_mode_flag = 0 in enhancement layer MGS key picture\n"); } //===== macroblock mode ===== if( ! rcMbDataAccess.getMbData().getBLSkipFlag() ) { DECRNOK( m_pcMbSymbolReadIf->mbMode( rcMbDataAccess ) ); } if( rcMbDataAccess.getMbData().getBLSkipFlag() ) { //===== copy motion data from base layer ====== rcMbDataAccess.getMbMvdData( LIST_0 ).clear(); rcMbDataAccess.getMbMvdData( LIST_1 ).clear(); rcMbDataAccess.getMbData().setBLSkipFlag( true ); } else { //===== BLOCK MODES ===== if( rcMbDataAccess.getMbData().isInter8x8() ) { DECRNOK( m_pcMbSymbolReadIf->blockModes( rcMbDataAccess ) ); //===== set motion data for skip block mode ===== UInt uiFwdBwd = 0; for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ ) { UInt uiBlkFwdBwd = rcMbDataAccess.getMbData().getBlockFwdBwd( c8x8Idx.b8x8Index() ); if( rcMbDataAccess.getMbData().getBlkMode( c8x8Idx.b8x8Index() ) == BLK_SKIP ) { uiBlkFwdBwd = 3; rcMbDataAccess.getMbMotionData( LIST_0 ).setRefIdx( 1, c8x8Idx.b8x8() ); rcMbDataAccess.getMbMotionData( LIST_1 ).setRefIdx( 1, c8x8Idx.b8x8() ); rcMbDataAccess.getMbMvdData ( LIST_0 ).setAllMv ( Mv::ZeroMv(), c8x8Idx.b8x8() ); rcMbDataAccess.getMbMvdData ( LIST_1 ).setAllMv ( Mv::ZeroMv(), c8x8Idx.b8x8() ); } uiFwdBwd |= ( uiBlkFwdBwd << ( c8x8Idx.b8x8Index() * 4 ) ); } rcMbDataAccess.getMbData().setFwdBwd( uiFwdBwd ); } rcMbDataAccess.resetQp(); // set QP to that of the last macroblock //===== MOTION DATA ===== MbMode eMbMode = rcMbDataAccess.getMbData().getMbMode(); if( rcMbDataAccess.getMbData().isIntra() ) { //===== clear mtoion data for intra blocks ===== rcMbDataAccess.getMbMotionData( LIST_0 ).clear( BLOCK_NOT_PREDICTED ); rcMbDataAccess.getMbMvdData ( LIST_0 ).clear(); if( rcMbDataAccess.getSH().isBSlice() ) { rcMbDataAccess.getMbMotionData( LIST_1 ).clear( BLOCK_NOT_PREDICTED ); rcMbDataAccess.getMbMvdData ( LIST_1 ).clear(); } } else if( eMbMode == MODE_SKIP ) { if( rcMbDataAccess.getSH().isBSlice() ) { rcMbDataAccess.getMbData().setFwdBwd( 0x3333 ); rcMbDataAccess.getMbMotionData( LIST_0 ).clear( RefIdxValues(1) ); rcMbDataAccess.getMbMvdData ( LIST_0 ).clear(); rcMbDataAccess.getMbMotionData( LIST_1 ).clear( RefIdxValues(1) ); rcMbDataAccess.getMbMvdData ( LIST_1 ).clear(); } else { rcMbDataAccess.getMbData().setFwdBwd( 0x1111 ); rcMbDataAccess.getMbMotionData( LIST_0 ).clear( RefIdxValues(1) ); rcMbDataAccess.getMbMvdData ( LIST_0 ).clear(); rcMbDataAccess.getMbMotionData( LIST_1 ).clear( BLOCK_NOT_PREDICTED ); rcMbDataAccess.getMbMvdData ( LIST_1 ).clear(); } } else { if( rcMbDataAccess.getSH().isBSlice() ) { DECRNOK( xReadMotionPredFlags ( rcMbDataAccess, eMbMode, LIST_0 ) ); DECRNOK( xReadMotionPredFlags ( rcMbDataAccess, eMbMode, LIST_1 ) ); DECRNOK( xReadReferenceIndices ( rcMbDataAccess, eMbMode, LIST_0 ) ); DECRNOK( xReadReferenceIndices ( rcMbDataAccess, eMbMode, LIST_1 ) ); DECRNOK( xReadMotionVectors ( rcMbDataAccess, eMbMode, LIST_0 ) ); DECRNOK( xReadMotionVectors ( rcMbDataAccess, eMbMode, LIST_1 ) ); } else { DECRNOK( xReadMotionPredFlags ( rcMbDataAccess, eMbMode, LIST_0 ) ); DECRNOK( xReadReferenceIndices ( rcMbDataAccess, eMbMode, LIST_0 ) ); DECRNOK( xReadMotionVectors ( rcMbDataAccess, eMbMode, LIST_0 ) ); } } } //===== TEXTURE INFO ===== if( rcMbDataAccess.getMbData().isPCM() ) { DECRNOK( m_pcMbSymbolReadIf->samplesPCM( rcMbDataAccess ) ); } else { if( ! rcMbDataAccess.getMbData().getBLSkipFlag() ) { DECRNOK( xReadIntraPredModes( rcMbDataAccess ) ); } Bool bTrafo8x8Flag = ( rcMbDataAccess.getSH().getPPS().getTransform8x8ModeFlag() && ( rcMbDataAccess.getMbData().getBLSkipFlag() || ( rcMbDataAccess.getMbData().is8x8TrafoFlagPresent( rcMbDataAccess.getSH().getSPS().getDirect8x8InferenceFlag() ) && !rcMbDataAccess.getMbData().isIntra4x4() ) ) ); bBaseLayerAvailable = ! rcMbDataAccess.getSH().getNoInterLayerPredFlag(); DECRNOK( xReadTextureInfo( rcMbDataAccess, bTrafo8x8Flag, bBaseLayerAvailable, rcMbDataAccess.getSH().getScanIdxStart(), rcMbDataAccess.getSH().getScanIdxStop() ) ); } } m_bPrevIsSkipped = ! bIsCoded; if( rcMbDataAccess.getSH().isMbaffFrame() && ( rcMbDataAccess.isTopMb() ) ) { rbEndOfSlice = false; return Err::m_nOK; } //===== terminating bits ===== rbEndOfSlice = m_pcMbSymbolReadIf->isEndOfSlice(); return Err::m_nOK; }
ErrVal MbParser::xReadTextureInfo( MbDataAccess& rcMbDataAccess, Bool bTrafo8x8Flag, Bool bBaseLayerAvailable, UInt uiStart, UInt uiStop ) { Bool bReadDQp = ( uiStart < uiStop ); if( !rcMbDataAccess.getSH().isIntraSlice() && rcMbDataAccess.getMbData().getInCropWindowFlag() && ( rcMbDataAccess.getMbData().getBLSkipFlag() || !rcMbDataAccess.getMbData().isIntra() ) ) { if( rcMbDataAccess.getSH().getAdaptiveResidualPredictionFlag() ) { DECRNOK( m_pcMbSymbolReadIf->resPredFlag( rcMbDataAccess ) ); } else { rcMbDataAccess.getMbData().setResidualPredFlag( rcMbDataAccess.getSH().getDefaultResidualPredictionFlag() ); } } else { rcMbDataAccess.getMbData().setResidualPredFlag( false ); } if( rcMbDataAccess.getMbData().getBLSkipFlag() || !rcMbDataAccess.getMbData().isIntra16x16() ) { if( uiStart >= uiStop ) { rcMbDataAccess.getMbData().setMbCbp( 0 ); } else { DECRNOK( m_pcMbSymbolReadIf->cbp( rcMbDataAccess, uiStart, uiStop ) ); } bReadDQp = rcMbDataAccess.getMbData().getMbCbp() != 0; } if( bTrafo8x8Flag && ( rcMbDataAccess.getMbData().getMbCbp() & 0x0F ) ) { DECRNOK( m_pcMbSymbolReadIf->transformSize8x8Flag( rcMbDataAccess ) ); } if( bReadDQp ) { DECRNOK( m_pcMbSymbolReadIf->deltaQp( rcMbDataAccess ) ); } else { rcMbDataAccess.resetQp(); } Bool bIntra16x16 = ( !rcMbDataAccess.getMbData().getBLSkipFlag() && rcMbDataAccess.getMbData().isIntra16x16 () ); if( bIntra16x16 ) { UInt uiDummy = 0; if( uiStart == 0 && uiStop != 0 ) { DECRNOK( m_pcMbSymbolReadIf->residualBlock( rcMbDataAccess, B4x4Idx(0), LUMA_I16_DC, uiDummy, uiStart, uiStop ) ); } if( rcMbDataAccess.getMbData().isAcCoded() && uiStop > 1 ) { for( S4x4Idx cIdx; cIdx.isLegal(); cIdx++ ) { DECRNOK( m_pcMbSymbolReadIf->residualBlock( rcMbDataAccess, cIdx, LUMA_I16_AC, uiDummy, uiStart, uiStop ) ); } rcMbDataAccess.getMbData().setMbCbp( 0xf + ( rcMbDataAccess.getMbData().getCbpChroma16x16() << 4) ); } else { rcMbDataAccess.getMbData().setMbCbp( 0x0 + ( rcMbDataAccess.getMbData().getCbpChroma16x16() << 4) ); } DECRNOK( xScanChromaBlocks( rcMbDataAccess, rcMbDataAccess.getMbData().getCbpChroma16x16(), uiStart, uiStop ) ); return Err::m_nOK; } UInt uiMbExtCbp = rcMbDataAccess.getMbData().getMbExtCbp(); if( rcMbDataAccess.getMbData().isTransformSize8x8() ) { for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ ) { if( uiMbExtCbp & ( 1 << c8x8Idx.b4x4() ) ) { DECRNOK( m_pcMbSymbolReadIf->residualBlock8x8( rcMbDataAccess, c8x8Idx, uiStart, uiStop ) ); } } } else { for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ ) { if( uiMbExtCbp & ( 1 << c8x8Idx.b4x4() ) ) { for( S4x4Idx cIdx( c8x8Idx ); cIdx.isLegal( c8x8Idx ); cIdx++ ) { DECRNOK( m_pcMbSymbolReadIf->residualBlock( rcMbDataAccess, cIdx , LUMA_SCAN, uiMbExtCbp, uiStart, uiStop ) ); } } } } rcMbDataAccess.getMbData().setMbExtCbp( uiMbExtCbp ); DECRNOK( xScanChromaBlocks ( rcMbDataAccess, rcMbDataAccess.getMbData().getCbpChroma4x4(), uiStart, uiStop ) ); return Err::m_nOK; }
ErrVal MbParser::xReadMotionPredFlags( MbDataAccess& rcMbDataAccess, MbMode eMbMode, ListIdx eLstIdx ) { ROTRS( rcMbDataAccess.getSH ().getNoInterLayerPredFlag(), Err::m_nOK ); ROFRS( rcMbDataAccess.getMbData ().getInCropWindowFlag(), Err::m_nOK ); MbMotionData& rcMbMotionData = rcMbDataAccess.getMbMotionData( eLstIdx ); rcMbMotionData.setMotPredFlag( rcMbDataAccess.getSH().getDefaultMotionPredictionFlag() ); ROFRS ( rcMbDataAccess.getSH().getAdaptiveMotionPredictionFlag(), Err::m_nOK ); //--- clear --- rcMbMotionData.setMotPredFlag( false ); if( rcMbDataAccess.getMbData().isIntra() ) { return Err::m_nOK; } switch( eMbMode ) { case MODE_SKIP: { break; } case MODE_16x16: { if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_0, eLstIdx ) ) { DECRNOK( m_pcMbSymbolReadIf->motionPredFlag( rcMbDataAccess, eLstIdx ) ); } break; } case MODE_16x8: { if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_0, eLstIdx ) ) { DECRNOK( m_pcMbSymbolReadIf->motionPredFlag( rcMbDataAccess, eLstIdx, PART_16x8_0 ) ); } if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_2, eLstIdx ) ) { DECRNOK( m_pcMbSymbolReadIf->motionPredFlag( rcMbDataAccess, eLstIdx, PART_16x8_1 ) ); } break; } case MODE_8x16: { if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_0, eLstIdx ) ) { DECRNOK( m_pcMbSymbolReadIf->motionPredFlag( rcMbDataAccess, eLstIdx, PART_8x16_0 ) ); } if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_1, eLstIdx ) ) { DECRNOK( m_pcMbSymbolReadIf->motionPredFlag( rcMbDataAccess, eLstIdx, PART_8x16_1 ) ); } break; } case MODE_8x8: case MODE_8x8ref0: { for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ ) { if( BLK_SKIP != rcMbDataAccess.getMbData().getBlkMode ( c8x8Idx.b8x8Index() ) && rcMbDataAccess .getMbData().isBlockFwdBwd( c8x8Idx.b8x8Index(), eLstIdx ) ) { DECRNOK( m_pcMbSymbolReadIf->motionPredFlag( rcMbDataAccess, eLstIdx, c8x8Idx.b8x8() ) ); } } break; } default: { AF(); return Err::m_nERR; } } return Err::m_nOK; }
ErrVal MbParser::xReadReferenceIndices( MbDataAccess& rcMbDataAccess, MbMode eMbMode, ListIdx eLstIdx ) { MbMotionData& rcMbMotionData = rcMbDataAccess.getMbMotionData( eLstIdx ); if( rcMbDataAccess.getMbData().isIntra() ) { rcMbMotionData.setRefIdx( -1 ); return Err::m_nOK; } switch( eMbMode ) { case MODE_SKIP: { break; } case MODE_16x16: { if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_0, eLstIdx ) ) { if( !rcMbMotionData.getMotPredFlag() ) { if( 1 == rcMbDataAccess.getNumActiveRef( eLstIdx ) ) { rcMbMotionData.setRefIdx( 1 ); } else { DECRNOK( m_pcMbSymbolReadIf->refFrame( rcMbDataAccess, eLstIdx ) ); } } } else { rcMbMotionData.setRefIdx( BLOCK_NOT_PREDICTED ); } break; } case MODE_16x8: { if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_0, eLstIdx ) ) { if( !rcMbMotionData.getMotPredFlag(PART_16x8_0) ) { if( 1 == rcMbDataAccess.getNumActiveRef( eLstIdx ) ) { rcMbMotionData.setRefIdx( 1, PART_16x8_0 ); } else { DECRNOK( m_pcMbSymbolReadIf->refFrame( rcMbDataAccess, eLstIdx, PART_16x8_0 ) ); } } } else { rcMbMotionData.setRefIdx( BLOCK_NOT_PREDICTED, PART_16x8_0 ); } if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_2, eLstIdx ) ) { if( !rcMbMotionData.getMotPredFlag(PART_16x8_1) ) { if( 1 == rcMbDataAccess.getNumActiveRef( eLstIdx ) ) { rcMbMotionData.setRefIdx( 1, PART_16x8_1 ); } else { DECRNOK( m_pcMbSymbolReadIf->refFrame( rcMbDataAccess, eLstIdx, PART_16x8_1 ) ); } } } else { rcMbMotionData.setRefIdx( BLOCK_NOT_PREDICTED, PART_16x8_1 ); } break; } case MODE_8x16: { if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_0, eLstIdx ) ) { if( !rcMbMotionData.getMotPredFlag(PART_8x16_0) ) { if( 1 == rcMbDataAccess.getNumActiveRef( eLstIdx ) ) { rcMbMotionData.setRefIdx( 1, PART_8x16_0 ); } else { DECRNOK( m_pcMbSymbolReadIf->refFrame( rcMbDataAccess, eLstIdx, PART_8x16_0 ) ); } } } else { rcMbMotionData.setRefIdx( BLOCK_NOT_PREDICTED, PART_8x16_0 ); } if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_1, eLstIdx ) ) { if( !rcMbMotionData.getMotPredFlag(PART_8x16_1) ) { if( 1 == rcMbDataAccess.getNumActiveRef( eLstIdx ) ) { rcMbMotionData.setRefIdx( 1, PART_8x16_1 ); } else { DECRNOK( m_pcMbSymbolReadIf->refFrame( rcMbDataAccess, eLstIdx, PART_8x16_1 ) ); } } } else { rcMbMotionData.setRefIdx( BLOCK_NOT_PREDICTED, PART_8x16_1 ); } break; } case MODE_8x8: { for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ ) { if( BLK_SKIP != rcMbDataAccess.getMbData().getBlkMode( c8x8Idx.b8x8Index() ) ) { if( rcMbDataAccess.getMbData().isBlockFwdBwd( c8x8Idx.b8x8Index(), eLstIdx ) ) { if( !rcMbMotionData.getMotPredFlag(c8x8Idx.b8x8()) ) { if( 1 == rcMbDataAccess.getNumActiveRef( eLstIdx ) ) { rcMbMotionData.setRefIdx( 1, c8x8Idx.b8x8() ); } else { DECRNOK( m_pcMbSymbolReadIf->refFrame( rcMbDataAccess, eLstIdx, c8x8Idx.b8x8() ) ); } } } else { rcMbMotionData.setRefIdx( BLOCK_NOT_PREDICTED, c8x8Idx.b8x8() ); } } } break; } case MODE_8x8ref0: { rcMbMotionData.setRefIdx( 1 ); break; } default: { AF(); return Err::m_nERR; } } 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; }
ErrVal MbCoder::xWriteMotionVectors( MbDataAccess& rcMbDataAccess, MbMode eMbMode, ListIdx eLstIdx ) { AOT_DBG( rcMbDataAccess.getMbData().isIntra() ); switch( eMbMode ) { case MODE_SKIP: { return Err::m_nOK; } case MODE_16x16: { if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_0, eLstIdx) ) { RNOK( m_pcMbSymbolWriteIf->mvd( rcMbDataAccess, eLstIdx ) ); } return Err::m_nOK; } case MODE_16x8: { if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_0, eLstIdx) ) { RNOK( m_pcMbSymbolWriteIf->mvd( rcMbDataAccess, eLstIdx, PART_16x8_0 ) ); } if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_2, eLstIdx) ) { RNOK( m_pcMbSymbolWriteIf->mvd( rcMbDataAccess, eLstIdx, PART_16x8_1 ) ); } return Err::m_nOK; } case MODE_8x16: { if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_0, eLstIdx) ) { RNOK( m_pcMbSymbolWriteIf->mvd( rcMbDataAccess, eLstIdx, PART_8x16_0 ) ); } if( rcMbDataAccess.getMbData().isBlockFwdBwd( B_8x8_1, eLstIdx) ) { RNOK( m_pcMbSymbolWriteIf->mvd( rcMbDataAccess, eLstIdx, PART_8x16_1 ) ); } return Err::m_nOK; } case MODE_8x8: case MODE_8x8ref0: { for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ ) { if( rcMbDataAccess.getMbData().isBlockFwdBwd( c8x8Idx.b8x8Index(), eLstIdx ) ) { RNOK( xWriteBlockMv( rcMbDataAccess, c8x8Idx, eLstIdx ) ); } } return Err::m_nOK; } default: { AF(); return Err::m_nERR; } } return Err::m_nERR; }
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 MbCoder::xWriteTextureInfo( MbDataAccess& rcMbDataAccess, MbDataAccess* pcMbDataAccessBase, // JVT-R091 const MbTransformCoeffs& rcMbTCoeff, Bool bTrafo8x8Flag ) { Bool bWriteDQp = true; UInt uiCbp = rcMbDataAccess.getMbData().getMbCbp(); if( ! rcMbDataAccess.getMbData().isIntra16x16() ) { RNOK( m_pcMbSymbolWriteIf->cbp( rcMbDataAccess ) ); bWriteDQp = ( 0 != uiCbp ); } if( bTrafo8x8Flag && ( rcMbDataAccess.getMbData().getMbCbp() & 0x0F ) ) { ROT( rcMbDataAccess.getMbData().isIntra16x16() ); ROT( rcMbDataAccess.getMbData().isIntra4x4 () ); RNOK( m_pcMbSymbolWriteIf->transformSize8x8Flag( rcMbDataAccess ) ); } if( bWriteDQp ) { RNOK( m_pcMbSymbolWriteIf->deltaQp( rcMbDataAccess ) ); } if( rcMbDataAccess.getMbData().getBLSkipFlag() || !rcMbDataAccess.getMbData().isIntra() ) { if( rcMbDataAccess.getSH().getAdaptivePredictionFlag() ) { if( ! rcMbDataAccess.getSH().isIntra() ) { RNOK( m_pcMbSymbolWriteIf->resPredFlag( rcMbDataAccess ) ); if ( rcMbDataAccess.getMbData().getResidualPredFlag( PART_16x16 ) && rcMbDataAccess.getMbData().getBLSkipFlag() ) { RNOK( m_pcMbSymbolWriteIf->smoothedRefFlag( rcMbDataAccess ) ); } } } } if( rcMbDataAccess.getMbData().isIntra16x16() ) { RNOK( xScanLumaIntra16x16( rcMbDataAccess, rcMbTCoeff, rcMbDataAccess.getMbData().isAcCoded() ) ); RNOK( xScanChromaBlocks ( rcMbDataAccess, rcMbTCoeff, rcMbDataAccess.getMbData().getCbpChroma16x16() ) ); return Err::m_nOK; } if( rcMbDataAccess.getMbData().isTransformSize8x8() ) { for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ ) { if( (uiCbp >> c8x8Idx.b8x8Index()) & 1 ) { RNOK( m_pcMbSymbolWriteIf->residualBlock8x8( rcMbDataAccess, c8x8Idx, LUMA_SCAN ) ); } } } else { for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ )
ErrVal SliceEncoder::xAddTCoeffs2( MbDataAccess& rcMbDataAccess, MbDataAccess& rcMbDataAccessBase ) { if( rcMbDataAccess.getMbData().isPCM() ) { TCoeff* pSrc = rcMbDataAccessBase.getMbTCoeffs().getTCoeffBuffer(); TCoeff* pDes = rcMbDataAccess .getMbTCoeffs().getTCoeffBuffer(); for( UInt ui = 0; ui < 384; ui++, pSrc++, pDes++ ) { ROT( pDes->getLevel() ); pDes->setLevel( pSrc->getLevel() ); } ROT( rcMbDataAccess.getMbData().getMbExtCbp() ); return Err::m_nOK; } UInt uiBCBP = 0; UInt uiCoded = 0; Bool bCoded = false; Bool bChromaAC = false; Bool bChromaDC = false; // Add the luma coefficients and track the new BCBP if( rcMbDataAccess.getMbData().isTransformSize8x8() ) { for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ ) { bCoded = false; m_pcTransform->addPrediction8x8Blk( rcMbDataAccess.getMbTCoeffs().get8x8( c8x8Idx ), rcMbDataAccessBase.getMbTCoeffs().get8x8( c8x8Idx ), rcMbDataAccess.getMbData().getQp(), rcMbDataAccessBase.getMbData().getQp(), bCoded ); if( rcMbDataAccess.getMbData().isIntra16x16() ) AOT(1); if( bCoded ) uiBCBP |= (0x33 << c8x8Idx.b4x4()); } } else { for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ ) { uiCoded = 0; m_pcTransform->addPrediction4x4Blk( rcMbDataAccess.getMbTCoeffs().get( cIdx ), rcMbDataAccessBase.getMbTCoeffs().get( cIdx ), rcMbDataAccess.getMbData().getQp(), rcMbDataAccessBase.getMbData().getQp(), uiCoded ); if( rcMbDataAccess.getMbData().isIntra16x16() ) { if( *(rcMbDataAccess.getMbTCoeffs().get( cIdx )) ) uiCoded--; } if( uiCoded ) uiBCBP |= 1<<cIdx; } if( rcMbDataAccess.getMbData().isIntra16x16() ) { uiBCBP = uiBCBP?((1<<16)-1):0; } } // Add the chroma coefficients and update the BCBP m_pcTransform->addPredictionChromaBlocks( rcMbDataAccess.getMbTCoeffs().get( CIdx(0) ), rcMbDataAccessBase.getMbTCoeffs().get( CIdx(0) ), rcMbDataAccess.getSH().getCbQp( rcMbDataAccess.getMbData().getQp() ), rcMbDataAccess.getSH().getBaseSliceHeader()->getCbQp( rcMbDataAccessBase.getMbData().getQp() ), bChromaDC, bChromaAC ); m_pcTransform->addPredictionChromaBlocks( rcMbDataAccess.getMbTCoeffs().get( CIdx(4) ), rcMbDataAccessBase.getMbTCoeffs().get( CIdx(4) ), rcMbDataAccess.getSH().getCrQp( rcMbDataAccess.getMbData().getQp() ), rcMbDataAccess.getSH().getBaseSliceHeader()->getCrQp( rcMbDataAccessBase.getMbData().getQp() ), bChromaDC, bChromaAC ); uiBCBP |= (bChromaAC?2:(bChromaDC?1:0))<<16; // Update the CBP rcMbDataAccess.getMbData().setAndConvertMbExtCbp( uiBCBP ); // Update the Intra16x16 mode if( rcMbDataAccess.getMbData().isIntra16x16() ) { UInt uiMbType = INTRA_4X4 + 1; UInt uiPredMode = rcMbDataAccess.getMbData().intraPredMode(); UInt uiChromaCbp = uiBCBP>>16; Bool bACcoded = (uiBCBP && ((1<<16)-1)); uiMbType += uiPredMode; uiMbType += ( bACcoded ) ? 12 : 0; uiMbType += uiChromaCbp << 2; rcMbDataAccess.getMbData().setMbMode( MbMode(uiMbType) ); // Sanity checks if( rcMbDataAccess.getMbData().intraPredMode() != uiPredMode ) AOT(1); if( rcMbDataAccess.getMbData().getCbpChroma16x16() != uiChromaCbp ) AOT(1); if( rcMbDataAccess.getMbData().isAcCoded() != bACcoded ) AOT(1); }