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; }
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; }
ErrVal MbTransformCoeffs::copyPredictionFrom( YuvMbBuffer &rcPred ) { TCoeff *pcDst = get( B4x4Idx(0) ); XPel *pSrc = rcPred.getMbLumAddr(); Int iSrcStride = rcPred.getLStride(); UInt uiY, uiX; for( uiY = 0; uiY < 16; uiY++ ) { for( uiX = 0; uiX < 16; uiX++ ) { (pcDst++)->setSPred( pSrc[uiX] ); } pSrc += iSrcStride; } iSrcStride = rcPred.getCStride(); pSrc = rcPred.getMbCbAddr(); for( uiY = 0; uiY < 8; uiY++ ) { for( uiX = 0; uiX < 8; uiX++ ) { (pcDst++)->setSPred( pSrc[uiX] ); } pSrc += iSrcStride; } pSrc = rcPred.getMbCrAddr(); for( uiY = 0; uiY < 8; uiY++ ) { for( uiX = 0; uiX < 8; uiX++ ) { (pcDst++)->setSPred( pSrc[uiX] ); } pSrc += iSrcStride; } return Err::m_nOK; }
ErrVal MbDecoder::xDecodeMbInter( MbDataAccess& rcMbDataAccess, YuvMbBuffer& rcRecYuvBuffer, IntYuvMbBuffer& rcPredIntYuvMbBuffer, IntYuvMbBuffer& rcResIntYuvMbBuffer, Bool bReconstruct ) { rcResIntYuvMbBuffer.setAllSamplesToZero(); if( ! bReconstruct ) { RNOK( m_pcMotionCompensation->calculateMb ( rcMbDataAccess, true ) ); rcRecYuvBuffer.setZero(); } else { RNOK( m_pcMotionCompensation->compensateMb( rcMbDataAccess, &rcRecYuvBuffer, true ) ); } rcPredIntYuvMbBuffer.loadBuffer( &rcRecYuvBuffer ); MbTransformCoeffs& rcCoeffs = m_cTCoeffs; m_pcTransform->setClipMode( false ); if( rcMbDataAccess.getMbData().isTransformSize8x8() ) { for( B8x8Idx cIdx8x8; cIdx8x8.isLegal(); cIdx8x8++ ) { if( rcMbDataAccess.getMbData().is4x4BlkCoded( cIdx8x8 ) ) { RNOK( m_pcTransform->invTransform8x8Blk( rcResIntYuvMbBuffer.getYBlk( cIdx8x8 ), rcResIntYuvMbBuffer.getLStride(), rcCoeffs.get8x8(cIdx8x8) ) ); } } } else { for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ ) { if( rcMbDataAccess.getMbData().is4x4BlkCoded( cIdx ) ) { RNOK( m_pcTransform->invTransform4x4Blk( rcResIntYuvMbBuffer.getYBlk( cIdx ), rcResIntYuvMbBuffer.getLStride(), rcCoeffs.get(cIdx) ) ); } } } UInt uiChromaCbp = rcMbDataAccess.getMbData().getCbpChroma4x4(); IntYuvMbBuffer cPredBuffer; RNOK( xDecodeChroma( rcMbDataAccess, rcResIntYuvMbBuffer, cPredBuffer, uiChromaCbp, false ) ); m_pcTransform->setClipMode( true ); IntYuvMbBuffer cIntYuvMbBuffer; cIntYuvMbBuffer. loadLuma ( rcPredIntYuvMbBuffer ); cIntYuvMbBuffer. loadChroma ( rcPredIntYuvMbBuffer ); cIntYuvMbBuffer. add ( rcResIntYuvMbBuffer ); rcRecYuvBuffer. loadBufferClip( &cIntYuvMbBuffer ); return Err::m_nOK; }
ErrVal MbDecoder::process( MbDataAccess& rcMbDataAccess, Bool bReconstructAll ) { ROF( m_bInitDone ); RNOK( xScaleTCoeffs( rcMbDataAccess ) ); YuvPicBuffer *pcRecYuvBuffer; RNOK( m_pcFrameMng->getRecYuvBuffer( pcRecYuvBuffer ) ); IntYuvMbBuffer cPredIntYuvMbBuffer; IntYuvMbBuffer cResIntYuvMbBuffer; YuvMbBuffer cYuvMbBuffer; if( rcMbDataAccess.getMbData().isPCM() ) { RNOK( xDecodeMbPCM( rcMbDataAccess, cYuvMbBuffer ) ); cResIntYuvMbBuffer .setAllSamplesToZero(); cPredIntYuvMbBuffer.loadBuffer( &cYuvMbBuffer ); } else { if( rcMbDataAccess.getMbData().isIntra() ) { m_pcIntraPrediction->setAvailableMaskMb( rcMbDataAccess.getAvailableMask() ); cResIntYuvMbBuffer.loadIntraPredictors( pcRecYuvBuffer ); if( rcMbDataAccess.getMbData().isIntra4x4() ) { if( rcMbDataAccess.getMbData().isTransformSize8x8() ) { RNOK( xDecodeMbIntra8x8( rcMbDataAccess, cResIntYuvMbBuffer, cPredIntYuvMbBuffer ) ); } else { RNOK( xDecodeMbIntra4x4( rcMbDataAccess, cResIntYuvMbBuffer, cPredIntYuvMbBuffer ) ); } } else { RNOK( xDecodeMbIntra16x16( rcMbDataAccess, cResIntYuvMbBuffer, cPredIntYuvMbBuffer ) ); } cYuvMbBuffer.loadBuffer( &cResIntYuvMbBuffer ); } else { RNOK( xDecodeMbInter( rcMbDataAccess, cYuvMbBuffer, cPredIntYuvMbBuffer, cResIntYuvMbBuffer, bReconstructAll ) ); } } pcRecYuvBuffer->loadBuffer( &cYuvMbBuffer ); { B4x4Idx cdx; XPel* puc = cResIntYuvMbBuffer.getYBlk(cdx); for (int i = 0; i < 16; ++i) { for (int j = 0; j < 16; ++j) { printf("%4d", puc[i*24+j]); } printf("\n"); } printf("\n"); } return Err::m_nOK; }