ErrVal MbDecoder::xDecodeMbPCM( MbDataAccess& rcMbDataAccess, YuvMbBuffer& rcRecYuvBuffer ) { Pel* pucSrc = rcMbDataAccess.getMbTCoeffs().getPelBuffer(); Pel* pucDest = rcRecYuvBuffer.getMbLumAddr(); Int iStride = rcRecYuvBuffer.getLStride(); Int n; for( n = 0; n < 16; n++ ) { ::memcpy( pucDest, pucSrc, 16 ); pucSrc += 16; pucDest += iStride; } pucDest = rcRecYuvBuffer.getMbCbAddr(); iStride = rcRecYuvBuffer.getCStride(); for( n = 0; n < 8; n++ ) { ::memcpy( pucDest, pucSrc, 8 ); pucSrc += 8; pucDest += iStride; } pucDest = rcRecYuvBuffer.getMbCrAddr(); for( n = 0; n < 8; n++ ) { ::memcpy( pucDest, pucSrc, 8 ); pucSrc += 8; pucDest += iStride; } 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() ); }
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 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 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); }
ErrVal MbDecoder::xDecodeMbPCM( MbDataAccess& rcMbDataAccess, IntYuvPicBuffer *pcRecYuvBuffer ) { Pel* pucSrc = rcMbDataAccess.getMbTCoeffs().getPelBuffer(); XPel* pucDest = pcRecYuvBuffer->getMbLumAddr(); Int iStride = pcRecYuvBuffer->getLStride(); UInt uiDelta = 1; Int n, m, n1, m1, dest; for( n = 0; n < 16; n+=uiDelta ) { for( m = 0; m < 16; m+=uiDelta ) { dest = *pucSrc++; for( n1=0; n1< +(Int)uiDelta; n1++ ) for( m1=m; m1<m+(Int)uiDelta; m1++ ) { pucDest[m1+n1*iStride] = dest; } } pucDest += uiDelta*iStride; } pucDest = pcRecYuvBuffer->getMbCbAddr(); iStride = pcRecYuvBuffer->getCStride(); for( n = 0; n < 8; n+=uiDelta ) { for( m = 0; m < 8; m+=uiDelta ) { dest = *pucSrc++; for( n1=0; n1< +(Int)uiDelta; n1++ ) for( m1=m; m1<m+(Int)uiDelta; m1++ ) { pucDest[m1+n1*iStride] = dest; } } pucDest += uiDelta*iStride; } pucDest = pcRecYuvBuffer->getMbCrAddr(); for( n = 0; n < 8; n+=uiDelta ) { for( m = 0; m < 8; m+=uiDelta ) { dest = *pucSrc++; for( n1=0; n1< +(Int)uiDelta; n1++ ) for( m1=m; m1<m+(Int)uiDelta; m1++ ) { pucDest[m1+n1*iStride] = dest; } } pucDest += uiDelta*iStride; } return Err::m_nOK; }