Exemple #1
0
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;
}