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 ); } } } } } } }
//index== 0 above 1 left 2 above and left 3 above and right Int GolombCode_Predict_SingleNeighbor(TComYuv *pcResiYuv, TComTU& rTu, const ComponentID compID, UInt uiCUHandleAddr, UInt uiAIndex, TCoeff* pcCoeff) { const Bool bIsLuma = isLuma(compID); const TComRectangle &rect = rTu.getRect(compID); TComDataCU *pcCU = rTu.getCU(); UInt uiCUAddr = pcCU->getCtuRsAddr(); //if ((int)uiCUHandleAddr < 0) return -1; TComPicYuv *pcPicYuvResi = pcCU->getPic()->getPicYuvResi(); if (pcPicYuvResi == NULL) return -1; const UInt uiAbsPartIdx = rTu.GetAbsPartIdxTU(); // const UInt uiZOrder = pcCU->getZorderIdxInCU() +uiAbsPartIdx; const UInt uiTrDepth = rTu.GetTransformDepthRelAdj(compID); const UInt uiFullDepth = rTu.GetTransformDepthTotal(); const UInt uiLog2TrSize = rTu.GetLog2LumaTrSize(); const ChromaFormat chFmt = pcCU->getPic()->getChromaFormat(); const UInt uiWidth = rect.width; const UInt uiHeight = rect.height; const UInt uiStride = pcResiYuv->getStride(compID); UInt uiAddr = pcCU->getCtuRsAddr(); TComYuv *pcTemp; pcTemp = new TComYuv; UInt uiSrc1Stride = pcPicYuvResi->getStride(compID); UInt CUPelX, CUPelY; CUPelX = (uiCUHandleAddr % pcCU->getPic()->getFrameWidthInCtus()) * g_uiMaxCUWidth; CUPelY = (uiCUHandleAddr / pcCU->getPic()->getFrameWidthInCtus()) * g_uiMaxCUHeight; CUPelX = CUPelX + g_auiRasterToPelX[g_auiZscanToRaster[uiAbsPartIdx]]; CUPelY = CUPelY + g_auiRasterToPelY[g_auiZscanToRaster[uiAbsPartIdx]]; //for(int m=0;m<256;m++) cout<<g_auiZscanToRaster[m] <<" ";cout<<endl; //for(int m=0;m<256;m++) cout<<g_auiRasterToPelX[m] <<" ";cout<<endl; //for(int m=0;m<256;m++) cout<<g_auiRasterToPelY[m] <<" ";cout<<endl; //Pel *pSrc1 = pcPicYuvResi->getAddr(compID) +CUPelY * uiSrc1Stride + CUPelX; Pel *pSrc1 = pcPicYuvResi->getAddr(compID, uiCUHandleAddr, uiAbsPartIdx + pcCU->getZorderIdxInCtu()); /* if( compID != COMPONENT_Y) { pSrc1 = pcPicYuvResi->getAddr(COMPONENT_Y, uiCUHandleAddr, uiAbsPartIdx + pcCU->getZorderIdxInCU()); }*/ pcTemp->create(uiWidth, uiHeight, chFmt); // pcTemp->copyFromPicComponent(compID,pcPicYuvResi,uiCUHandleAddr, pcCU->getZorderIdxInCU()+uiAbsPartIdx); UInt uiTempStride = pcTemp->getStride(compID); Pel *pTemp = pcTemp->getAddr(compID); for (Int y = 0; y < uiHeight; y++) { for (Int x = 0; x < uiWidth; x++) { pTemp[x] = pSrc1[x]; } pTemp += uiTempStride; pSrc1 += uiSrc1Stride; } int srclx = 0; int srcly = 0; int srclv = 0; int srchasleft = 1; Pel srcpel; int srclist[3][64 * 64]; int srcindex = 0; memset(srclist, -1, 3 * 64 * 64 * sizeof(int)); int cursrclistindex = 0; Pel* piSrc = pcTemp->getAddr(compID); //Pel* piSrc = pcTemp->getAddr(compID, uiAbsPartIdx); Pel* pSrc = piSrc; //found the source list while (srchasleft) { int ndis = 1000; int nx = -1; int ny = -1; pSrc = piSrc; for (UInt y = 0; y < uiHeight; y++) { for (UInt x = 0; x<uiWidth; x++) { assert(pSrc[x] >-256 && pSrc[x] < 256); if (pSrc[x] != 0) { int dis = 0; dis += getG0Bits((x - srclx)); dis += getG0Bits((y - srcly)); if (dis < ndis) { nx = x; ny = y; ndis = dis; } } } pSrc += uiTempStride; } if (nx != -1 && ny != -1) { srcpel = *(piSrc + ny*uiTempStride + nx); srclx = nx; srcly = ny; srclv = srcpel; srclist[0][srcindex] = srclx; srclist[1][srcindex] = srcly; srclist[2][srcindex] = srcpel; srcindex++; *(piSrc + ny*uiTempStride + nx) = 0; } else { srchasleft = 0; } } if (srcindex == 0) { pcTemp->destroy(); delete pcTemp; pcTemp = NULL; return -1; } //// TComPicYuv *pcPicOrg = pcCU->getPic()->getPicYuvOrg(); Pel* piOrg = pcPicOrg->getAddr(compID, pcCU->getCtuRsAddr(), pcCU->getZorderIdxInCtu() + uiAbsPartIdx); const UInt uiOrgStride = pcPicOrg->getStride(compID); //// Pel* piResi = pcResiYuv->getAddr(compID, uiAbsPartIdx); Pel* pResi = piResi; int dstindex = 0; int indexlist[64 * 64][5]; memset(indexlist, 0, 5 * 64 * 64 * sizeof(int)); int contz = 0; int contnz = 0; int cs = 0; int bits = 0; // int temp; int lx = 0; int ly = 0; int lv = 0; int hasleft = 1; Pel pel; while (hasleft) { //found the least distance point int ndis = 1000; int nx = -1; int ny = -1; pResi = piResi; for (UInt y = 0; y < uiHeight; y++) { for (UInt x = 0; x < uiWidth; x++) { if (pResi[x] != 0) { int dis = 0; dis += getG0Bits((x - lx)); dis += getG0Bits((y - ly)); if (dis < ndis) { nx = x; ny = y; ndis = dis; } } } pResi += uiStride; } if (nx != -1 && ny != -1) { pel = *(piResi + ny*uiStride + nx); int srcdis = 1024 * 4; int srccur = -1; for (UInt s = 0; s < srcindex; s++) { int curdis = 0; curdis += getG0Bits((nx - srclist[0][s])); curdis += getG0Bits((ny - srclist[1][s])); // curdis += getG0Bits( (pel-srclist[2][s]));// getG0Bits can handle -512 && 512 if (curdis < srcdis) { srccur = s; srcdis = curdis; } } if (srccur != -1) { indexlist[dstindex][0] = nx - srclist[0][srccur]; indexlist[dstindex][1] = ny - srclist[1][srccur]; assert(pel != 0); indexlist[dstindex][4] = srccur; dstindex++; cursrclistindex = srccur; } else { assert(true); } lx = nx; ly = ny; lv = pel; *(piResi + ny*uiStride + nx) = 0; } else { hasleft = 0; } } pcTemp->destroy(); delete pcTemp; pcTemp = NULL; if (dstindex == 0) { assert(bits == 0); return bits; } qsort(indexlist, dstindex, sizeof(int)* 5, compare5); for (UInt x = dstindex - 1; x > 0; x--) { indexlist[x][4] -= indexlist[x - 1][4]; } //bits += getG0Bits( (indexlist[0][0])); //bits += getG0Bits( (indexlist[0][1])); int maxlength = 0; UInt truebits = 0; bool vlcf[3] = { false, false, false };// dx & dy residual srcindex int z01 = 0; for (UInt x = 1; x < dstindex; x++) { if (indexlist[x][0] == indexlist[x - 1][0] && indexlist[x][1] == indexlist[x - 1][1]) { maxlength++; } else { bits += getG0Bits((maxlength)); bits += getG0Bits((indexlist[x - 1][0])); bits += getG0Bits((indexlist[x - 1][1])); maxlength = 0; } if (indexlist[x][0] == 0 && indexlist[x][1] == 0) z01++; } bits += getG0Bits((maxlength)); bits += getG0Bits((indexlist[dstindex - 1][0])); bits += getG0Bits((indexlist[dstindex - 1][1])); UInt sbits = 0; for (UInt x = 0; x < dstindex; x++) { sbits += getG0Bits((indexlist[x][0])); sbits += getG0Bits((indexlist[x][1])); } // printf("gain %6d position before %6d after %6d\n",sbits-bits,sbits,bits); if (sbits < bits) { vlcf[0] = true; bits = sbits; } sbits = bits + 1; //bits += getG0Bits( PTable(compID,indexlist[0][2])); { maxlength = 0; for (UInt x = 1; x < dstindex; x++) { if (indexlist[x][2] == indexlist[x - 1][2] && indexlist[x][3] == indexlist[x - 1][3]) { maxlength++; } else { bits += getG0Bits((maxlength)); bits += getG0Bits(indexlist[x - 1][3]); bits += getG0Bits(indexlist[x - 1][2]); maxlength = 0; } } bits += getG0Bits((maxlength)); bits += getG0Bits(indexlist[dstindex - 1][3]); bits += getG0Bits((indexlist[dstindex - 1][2])); } UInt vbits = 0; sbits = bits - sbits; for (UInt x = 0; x < dstindex; x++) { { vbits += getG0Bits(indexlist[x][2]); vbits += getG0Bits(indexlist[x][3]); } } // printf("gain %6d delta resi before %6d after %6d\n",vbits-sbits,vbits,sbits); if (vbits < sbits) { vlcf[1] = true; bits = bits - sbits + vbits; } sbits = bits + 1; //bits += getG0Bits( (indexlist[0][3])); Int srcPosIndex; srcPosIndex = 4; maxlength = 0; for (UInt x = 1; x < dstindex; x++) { if (indexlist[x][srcPosIndex] == indexlist[x - 1][srcPosIndex]) { maxlength++; } else { bits += getG0Bits((maxlength)); bits += getG0Bits((indexlist[x - 1][srcPosIndex])); maxlength = 0; } } bits += getG0Bits((maxlength)); bits += getG0Bits((indexlist[dstindex - 1][srcPosIndex])); sbits = bits - sbits; vbits = 0; for (UInt x = 0; x < dstindex; x++) { vbits += getG0Bits((indexlist[x][srcPosIndex])); } // printf("gain %6d delta index before %6d after %6d\n",vbits-sbits,vbits,sbits); if (vbits < sbits) { vlcf[2] = true; bits = bits - sbits + vbits; } //#if INTRA_PR_DEBUG // if( pcCU->getAddr()==INTRA_PR_CUNUM ) // printf("position distance zero %6d of %6d total bits %6d\n",z01,dstindex,bits+1); //#endif truebits = 0; ExpGolombEncode(uiAIndex, pcCoeff, truebits); //--------------encode srcindex if (vlcf[2]) { ExpGolombEncode(0, pcCoeff, truebits); for (UInt x = 0; x < dstindex; x++) { //cout<<" "<<indexlist[x][3] ; ExpGolombEncode((indexlist[x][srcPosIndex]), pcCoeff, truebits); } } else{ ExpGolombEncode(1, pcCoeff, truebits); maxlength = 0; for (UInt x = 1; x<dstindex; x++) { if (indexlist[x][srcPosIndex] == indexlist[x - 1][srcPosIndex]) { maxlength++; } else { ExpGolombEncode((maxlength), pcCoeff, truebits); ExpGolombEncode((indexlist[x - 1][srcPosIndex]), pcCoeff, truebits); maxlength = 0; } } assert(maxlength>-1); ExpGolombEncode((maxlength), pcCoeff, truebits); ExpGolombEncode((indexlist[dstindex - 1][srcPosIndex]), pcCoeff, truebits); } ExpGolombEncode(-1, pcCoeff, truebits); //---------------encode residual if (vlcf[1]) { ExpGolombEncode(0, pcCoeff, truebits); for (UInt x = 0; x < dstindex; x++) { { ExpGolombEncode(indexlist[x][2], pcCoeff, truebits); // if( !bNoResidual) // ExpGolombEncode( indexlist[x][3],pcCoeff,truebits); } } } else{ ExpGolombEncode(1, pcCoeff, truebits); //ExpGolombEncode( (indexlist[0][2]),pcCoeff,truebits); maxlength = 0; { for (UInt x = 1; x < dstindex; x++) { if (indexlist[x][2] == indexlist[x - 1][2] && indexlist[x][3] == indexlist[x - 1][3]) { maxlength++; } else { ExpGolombEncode((maxlength), pcCoeff, truebits); //assert( (maxlength)>=0); ExpGolombEncode(indexlist[x - 1][2], pcCoeff, truebits); // if( !bNoResidual) // ExpGolombEncode( indexlist[x-1][3],pcCoeff,truebits); maxlength = 0; } } ExpGolombEncode((maxlength), pcCoeff, truebits); ExpGolombEncode(indexlist[dstindex - 1][2], pcCoeff, truebits); //if( !bNoResidual) // ExpGolombEncode( indexlist[dstindex-1][3] , pcCoeff, truebits); } } //--------------encode dx and dy ----------- if (vlcf[0]) { ExpGolombEncode(0, pcCoeff, truebits); for (UInt x = 0; x < dstindex; x++) { ExpGolombEncode((indexlist[x][0]), pcCoeff, truebits); ExpGolombEncode((indexlist[x][1]), pcCoeff, truebits); } } else{ ExpGolombEncode(1, pcCoeff, truebits); //ExpGolombEncode( (indexlist[0][0]),pcCoeff,truebits); //ExpGolombEncode( (indexlist[0][1]),pcCoeff,truebits); maxlength = 0; for (UInt x = 1; x < dstindex; x++) { if (indexlist[x][0] == indexlist[x - 1][0] && indexlist[x][1] == indexlist[x - 1][1]) { maxlength++; } else { ExpGolombEncode((maxlength), pcCoeff, truebits); ExpGolombEncode((indexlist[x - 1][0]), pcCoeff, truebits); ExpGolombEncode((indexlist[x - 1][1]), pcCoeff, truebits); maxlength = 0; } } ExpGolombEncode((maxlength), pcCoeff, truebits); ExpGolombEncode((indexlist[dstindex - 1][0]), pcCoeff, truebits); ExpGolombEncode((indexlist[dstindex - 1][1]), pcCoeff, truebits); } return truebits;/* bits +1*/; }