Void TEncEntropy::xEncodeTransform( Bool& bCodeDQP, Bool& codeChromaQpAdj, TComTU &rTu ) { //pcCU, absPartIdxCU, uiAbsPartIdx, uiDepth+1, uiTrIdx+1, quadrant, TComDataCU *pcCU=rTu.getCU(); const UInt uiAbsPartIdx=rTu.GetAbsPartIdxTU(); const UInt numValidComponent = pcCU->getPic()->getNumberValidComponents(); const Bool bChroma = isChromaEnabled(pcCU->getPic()->getChromaFormat()); const UInt uiTrIdx = rTu.GetTransformDepthRel(); const UInt uiDepth = rTu.GetTransformDepthTotal(); #if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST const Bool bDebugRQT=pcCU->getSlice()->getFinalized() && DebugOptionList::DebugRQT.getInt()!=0; if (bDebugRQT) { printf("x..codeTransform: offsetLuma=%d offsetChroma=%d absPartIdx=%d, uiDepth=%d\n width=%d, height=%d, uiTrIdx=%d, uiInnerQuadIdx=%d\n", rTu.getCoefficientOffset(COMPONENT_Y), rTu.getCoefficientOffset(COMPONENT_Cb), uiAbsPartIdx, uiDepth, rTu.getRect(COMPONENT_Y).width, rTu.getRect(COMPONENT_Y).height, rTu.GetTransformDepthRel(), rTu.GetSectionNumber()); } #endif const UInt uiSubdiv = pcCU->getTransformIdx( uiAbsPartIdx ) > uiTrIdx;// + pcCU->getDepth( uiAbsPartIdx ) > uiDepth; const UInt uiLog2TrafoSize = rTu.GetLog2LumaTrSize(); UInt cbf[MAX_NUM_COMPONENT] = {0,0,0}; Bool bHaveACodedBlock = false; Bool bHaveACodedChromaBlock = false; for(UInt ch=0; ch<numValidComponent; ch++) { const ComponentID compID = ComponentID(ch); cbf[compID] = pcCU->getCbf( uiAbsPartIdx, compID , uiTrIdx ); if (cbf[ch] != 0) { bHaveACodedBlock = true; if (isChroma(compID)) { bHaveACodedChromaBlock = true; } } } if( pcCU->isIntra(uiAbsPartIdx) && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_NxN && uiDepth == pcCU->getDepth(uiAbsPartIdx) ) { assert( uiSubdiv ); } else if( pcCU->isInter(uiAbsPartIdx) && (pcCU->getPartitionSize(uiAbsPartIdx) != SIZE_2Nx2N) && uiDepth == pcCU->getDepth(uiAbsPartIdx) && (pcCU->getSlice()->getSPS()->getQuadtreeTUMaxDepthInter() == 1) ) { if ( uiLog2TrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) ) { assert( uiSubdiv ); } else { assert(!uiSubdiv ); } } else if( uiLog2TrafoSize > pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() ) { assert( uiSubdiv ); } else if( uiLog2TrafoSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() ) { assert( !uiSubdiv ); } else if( uiLog2TrafoSize == pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) ) { assert( !uiSubdiv ); } else { assert( uiLog2TrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) ); m_pcEntropyCoderIf->codeTransformSubdivFlag( uiSubdiv, 5 - uiLog2TrafoSize ); } const UInt uiTrDepthCurr = uiDepth - pcCU->getDepth( uiAbsPartIdx ); const Bool bFirstCbfOfCU = uiTrDepthCurr == 0; for(UInt ch=COMPONENT_Cb; ch<numValidComponent; ch++) { const ComponentID compID=ComponentID(ch); if( bFirstCbfOfCU || rTu.ProcessingAllQuadrants(compID) ) { if( bFirstCbfOfCU || pcCU->getCbf( uiAbsPartIdx, compID, uiTrDepthCurr - 1 ) ) { m_pcEntropyCoderIf->codeQtCbf( rTu, compID, (uiSubdiv == 0) ); } } else { assert( pcCU->getCbf( uiAbsPartIdx, compID, uiTrDepthCurr ) == pcCU->getCbf( uiAbsPartIdx, compID, uiTrDepthCurr - 1 ) ); } } if( uiSubdiv ) { TComTURecurse tuRecurseChild(rTu, true); do { xEncodeTransform( bCodeDQP, codeChromaQpAdj, tuRecurseChild ); } while (tuRecurseChild.nextSection(rTu)); } else { { DTRACE_CABAC_VL( g_nSymbolCounter++ ); DTRACE_CABAC_T( "\tTrIdx: abspart=" ); DTRACE_CABAC_V( uiAbsPartIdx ); DTRACE_CABAC_T( "\tdepth=" ); DTRACE_CABAC_V( uiDepth ); DTRACE_CABAC_T( "\ttrdepth=" ); DTRACE_CABAC_V( pcCU->getTransformIdx( uiAbsPartIdx ) ); DTRACE_CABAC_T( "\n" ); } if( !pcCU->isIntra(uiAbsPartIdx) && uiDepth == pcCU->getDepth( uiAbsPartIdx ) && (!bChroma || (!pcCU->getCbf( uiAbsPartIdx, COMPONENT_Cb, 0 ) && !pcCU->getCbf( uiAbsPartIdx, COMPONENT_Cr, 0 ) ) ) ) { assert( pcCU->getCbf( uiAbsPartIdx, COMPONENT_Y, 0 ) ); // printf( "saved one bin! " ); } else { m_pcEntropyCoderIf->codeQtCbf( rTu, COMPONENT_Y, true ); //luma CBF is always at the lowest level } if ( bHaveACodedBlock ) { // dQP: only for CTU once if ( pcCU->getSlice()->getPPS()->getUseDQP() ) { if ( bCodeDQP ) { encodeQP( pcCU, rTu.GetAbsPartIdxCU() ); bCodeDQP = false; } } if ( pcCU->getSlice()->getUseChromaQpAdj() ) { if ( bHaveACodedChromaBlock && codeChromaQpAdj && !pcCU->getCUTransquantBypass(rTu.GetAbsPartIdxCU()) ) { encodeChromaQpAdjustment( pcCU, rTu.GetAbsPartIdxCU() ); codeChromaQpAdj = false; } } const UInt numValidComp=pcCU->getPic()->getNumberValidComponents(); for(UInt ch=COMPONENT_Y; ch<numValidComp; ch++) { const ComponentID compID=ComponentID(ch); if (rTu.ProcessComponentSection(compID)) { #if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST if (bDebugRQT) { printf("Call NxN for chan %d width=%d height=%d cbf=%d\n", compID, rTu.getRect(compID).width, rTu.getRect(compID).height, 1); } #endif if (rTu.getRect(compID).width != rTu.getRect(compID).height) { //code two sub-TUs TComTURecurse subTUIterator(rTu, false, TComTU::VERTICAL_SPLIT, true, compID); do { const UChar subTUCBF = pcCU->getCbf(subTUIterator.GetAbsPartIdxTU(compID), compID, (uiTrIdx + 1)); if (subTUCBF != 0) { #if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST if (bDebugRQT) { printf("Call NxN for chan %d width=%d height=%d cbf=%d\n", compID, subTUIterator.getRect(compID).width, subTUIterator.getRect(compID).height, 1); } #endif m_pcEntropyCoderIf->codeCoeffNxN( subTUIterator, (pcCU->getCoeff(compID) + subTUIterator.getCoefficientOffset(compID)), compID ); } } while (subTUIterator.nextSection(rTu)); } else { if (isChroma(compID) && (cbf[COMPONENT_Y] != 0)) { m_pcEntropyCoderIf->codeCrossComponentPrediction( rTu, compID ); } if (cbf[compID] != 0) { m_pcEntropyCoderIf->codeCoeffNxN( rTu, (pcCU->getCoeff(compID) + rTu.getCoefficientOffset(compID)), compID ); } } } } } } }
UInt PositionCode_Predict(TComYuv *pcResiYuv, TComTU& rTu, const ComponentID compID, TCoeff* pcCoeff /*,Bool bMV,bool bNoResidual*/) { if (!rTu.ProcessComponentSection(compID)) return -1; TComDataCU *pcCU = rTu.getCU(); UInt uiCUAddr = pcCU->getCtuRsAddr(); UInt uiFrameWidthInCU = pcCU->getPic()->getFrameWidthInCtus(); UInt uiCUAboveAddr = uiCUAddr - uiFrameWidthInCU; UInt uiCULeftAddr = uiCUAddr - 1; UInt uiCUAboveLeftAddr = uiCUAddr - 1 - uiFrameWidthInCU; UInt uiCUAboveRightAddr = uiCUAddr + 1 - uiFrameWidthInCU; UInt uiCUArray[4] = { uiCULeftAddr, uiCUAboveAddr, uiCUAboveLeftAddr, uiCUAboveRightAddr }; UInt uiCUHandleAddr; Int curindex, minibits, temp/*,truebits*/; TCoeff pcCoeffTemp[MAX_BUFFER]; TComYuv *pcComYuv = new TComYuv; const TComRectangle &rect = rTu.getRect(compID); UInt uiTempStride, uiSrcStride; uiSrcStride = pcResiYuv->getStride(compID); UInt uiHeight = pcResiYuv->getHeight(compID); UInt uiWidth = pcResiYuv->getWidth(compID); pcComYuv->create(uiWidth, uiHeight, pcCU->getPic()->getChromaFormat()); uiTempStride = pcComYuv->getStride(compID); //memset(pcCoeffTemp,0,sizeof(TCoeff)*MAX_BUFFER); minibits = MAX_INT; for (UInt index = 0; index < 4; index++) { uiCUHandleAddr = uiCUArray[index]; if ((int)uiCUHandleAddr < 0) continue; pcComYuv->clear(); for (UInt y = 0; y < uiHeight; y++) { for (UInt x = 0; x<uiWidth; x++) { *(pcComYuv->getAddr(compID) + y*uiTempStride + x) = *(pcResiYuv->getAddr(compID) + y*uiSrcStride + x); } } //pcResiYuv->copyToPartComponent ( compID, pcComYuv, 0); memset(pcCoeffTemp, 0, sizeof(TCoeff)*MAX_BUFFER); //_CrtMemState s1,s2,s3; //_CrtMemCheckpoint( &s1 ); temp = GolombCode_Predict_SingleNeighbor(pcComYuv, rTu, compID, uiCUHandleAddr, index, pcCoeffTemp); if (temp> -1 && temp < minibits) { curindex = index;//uiCUHandleAddr; minibits = temp; //truebits = minibits / GOLOMB_EXP_BUFFER + ( (minibits % GOLOMB_EXP_BUFFER==0) ? 0:1 ); memcpy(pcCoeff, pcCoeffTemp, sizeof(TCoeff)*rect.height*rect.width/* truebits*/); } //_CrtMemCheckpoint( &s2 ); //if ( _CrtMemDifference( &s3, &s1, &s2) ) //{ // _CrtMemDumpStatistics( &s3 ); // _CrtDumpMemoryLeaks(); //} } pcComYuv->destroy(); delete pcComYuv; pcComYuv = NULL; if (minibits != MAX_INT) { assert(uiCUArray[curindex] >= 0); return minibits; } return MAX_UINT; }