예제 #1
0
파일: TComPic.cpp 프로젝트: Kosyl/HEVC
/** destroy non-deblocked filter information for LCU
 */
Void TComPic::destroyNonDBFilterInfo()
{
  if(m_pbValidSlice != NULL)
  {
    delete[] m_pbValidSlice;
    m_pbValidSlice = NULL;
  }

  if(m_pSliceSUMap != NULL)
  {
    delete[] m_pSliceSUMap;
    m_pSliceSUMap = NULL;
  }
  for( UInt CUAddr = 0; CUAddr < getNumCUsInFrame() ; CUAddr++ )
  {
    TComDataCU* pcCU = getCU( CUAddr );
    pcCU->getNDBFilterBlocks()->clear();
  }

  if( m_bIndependentSliceBoundaryForNDBFilter || m_bIndependentTileBoundaryForNDBFilter)
  {
    m_pNDBFilterYuvTmp->destroy();
    delete m_pNDBFilterYuvTmp;
    m_pNDBFilterYuvTmp = NULL;
  }

}
예제 #2
0
파일: TComPic.cpp 프로젝트: Kosyl/HEVC
Void TComPic::compressMotion()
{
  TComPicSym* pPicSym = getPicSym(); 
  for ( UInt uiCUAddr = 0; uiCUAddr < pPicSym->getFrameHeightInCU()*pPicSym->getFrameWidthInCU(); uiCUAddr++ )
  {
    TComDataCU* pcCU = pPicSym->getCU(uiCUAddr);
    pcCU->compressMV(); 
  } 
}
예제 #3
0
Void TComPic::compressMotion()
{
  TComPicSym* pPicSym = getPicSym();
  for ( UInt uiCUAddr = 0; uiCUAddr < pPicSym->getNumberOfCtusInFrame(); uiCUAddr++ )
  {
    TComDataCU* pCtu = pPicSym->getCtu(uiCUAddr);
    pCtu->compressMV();
  }
}
예제 #4
0
Void TDecSlice::decompressSlice(TComBitstream* pcBitstream, TComPic*& rpcPic)
{
  TComDataCU* pcCU;
  UInt        uiIsLast = 0;
#if QC_MDDT//ADAPTIVE_SCAN
    InitScanOrderForSlice(); 
#endif
  // decoder don't need prediction & residual frame buffer
  rpcPic->setPicYuvPred( 0 );
  rpcPic->setPicYuvResi( 0 );

#if HHI_RQT
#if ENC_DEC_TRACE
  g_bJustDoIt = g_bEncDecTraceEnable;
#endif
  DTRACE_CABAC_V( g_nSymbolCounter++ );
  DTRACE_CABAC_T( "\tPOC: " );
  DTRACE_CABAC_V( rpcPic->getPOC() );
  DTRACE_CABAC_T( "\n" );
#if ENC_DEC_TRACE
  g_bJustDoIt = g_bEncDecTraceDisable;
#endif
#endif
  // for all CUs
  for( Int iCUAddr = 0; !uiIsLast; iCUAddr++ )
  {
    pcCU = rpcPic->getCU( iCUAddr );
    pcCU->initCU( rpcPic, iCUAddr );

#if HHI_RQT
#if ENC_DEC_TRACE
    g_bJustDoIt = g_bEncDecTraceEnable;
#endif
#endif
    m_pcCuDecoder->decodeCU     ( pcCU, uiIsLast );
    m_pcCuDecoder->decompressCU ( pcCU );

#if QC_MDDT//ADAPTIVE_SCAN
    updateScanOrder(0);
    normalizeScanStats();
#endif
#if HHI_RQT
#if ENC_DEC_TRACE
    g_bJustDoIt = g_bEncDecTraceDisable;
#endif
#endif
  }
}
예제 #5
0
Void TDecSlice::decompressSlice(TComInputBitstream* pcBitstream, TComPic*& rpcPic)
{
  TComDataCU* pcCU;
  UInt        uiIsLast = 0;
#if FINE_GRANULARITY_SLICES
  Int   iStartCUAddr = max(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU(), rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getEntropySliceCurStartCUAddr()/rpcPic->getNumPartInCU());
#else
  Int   iStartCUAddr = max(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr(), rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getEntropySliceCurStartCUAddr());
#endif

  // decoder don't need prediction & residual frame buffer
  rpcPic->setPicYuvPred( 0 );
  rpcPic->setPicYuvResi( 0 );
  
#if ENC_DEC_TRACE
  g_bJustDoIt = g_bEncDecTraceEnable;
#endif
  DTRACE_CABAC_VL( g_nSymbolCounter++ );
  DTRACE_CABAC_T( "\tPOC: " );
  DTRACE_CABAC_V( rpcPic->getPOC() );
  DTRACE_CABAC_T( "\n" );

#if ENC_DEC_TRACE
  g_bJustDoIt = g_bEncDecTraceDisable;
#endif

  // for all CUs in slice
  UInt  uiLastCUAddr = iStartCUAddr;
  for( Int iCUAddr = iStartCUAddr; !uiIsLast && iCUAddr < rpcPic->getNumCUsInFrame(); iCUAddr++, uiLastCUAddr++ )
  {
    pcCU = rpcPic->getCU( iCUAddr );
    pcCU->initCU( rpcPic, iCUAddr );

#if ENC_DEC_TRACE
    g_bJustDoIt = g_bEncDecTraceEnable;
#endif
    m_pcCuDecoder->decodeCU     ( pcCU, uiIsLast );
    m_pcCuDecoder->decompressCU ( pcCU );
    
#if ENC_DEC_TRACE
    g_bJustDoIt = g_bEncDecTraceDisable;
#endif
  }

}
예제 #6
0
파일: TComPic.cpp 프로젝트: Kosyl/HEVC
/** Create non-deblocked filter information
 * \param pSliceStartAddress array for storing slice start addresses
 * \param numSlices number of slices in picture
 * \param sliceGranularityDepth slice granularity 
 * \param bNDBFilterCrossSliceBoundary cross-slice-boundary in-loop filtering; true for "cross".
 * \param numTiles number of tiles in picture
 * \param bNDBFilterCrossTileBoundary cross-tile-boundary in-loop filtering; true for "cross".
 */
Void TComPic::createNonDBFilterInfo(std::vector<Int> sliceStartAddress, Int sliceGranularityDepth
                                    ,std::vector<Bool>* LFCrossSliceBoundary
                                    ,Int numTiles
                                    ,Bool bNDBFilterCrossTileBoundary)
{
  UInt maxNumSUInLCU = getNumPartInCU();
  UInt numLCUInPic   = getNumCUsInFrame();
  UInt picWidth      = getSlice(0)->getSPS()->getPicWidthInLumaSamples();
  UInt picHeight     = getSlice(0)->getSPS()->getPicHeightInLumaSamples();
  Int  numLCUsInPicWidth = getFrameWidthInCU();
  Int  numLCUsInPicHeight= getFrameHeightInCU();
  UInt maxNumSUInLCUWidth = getNumPartInWidth();
  UInt maxNumSUInLCUHeight= getNumPartInHeight();
  Int  numSlices = (Int) sliceStartAddress.size() - 1;
  m_bIndependentSliceBoundaryForNDBFilter = false;
  if(numSlices > 1)
  {
    for(Int s=0; s< numSlices; s++)
    {
      if((*LFCrossSliceBoundary)[s] == false)
      {
        m_bIndependentSliceBoundaryForNDBFilter = true;
      }
    }
  }
  m_sliceGranularityForNDBFilter = sliceGranularityDepth;
  m_bIndependentTileBoundaryForNDBFilter  = (bNDBFilterCrossTileBoundary)?(false) :((numTiles > 1)?(true):(false));

  m_pbValidSlice = new Bool[numSlices];
  for(Int s=0; s< numSlices; s++)
  {
    m_pbValidSlice[s] = true;
  }
  m_pSliceSUMap = new Int[maxNumSUInLCU * numLCUInPic];

  //initialization
  for(UInt i=0; i< (maxNumSUInLCU * numLCUInPic); i++ )
  {
    m_pSliceSUMap[i] = -1;
  }
  for( UInt CUAddr = 0; CUAddr < numLCUInPic ; CUAddr++ )
  {
    TComDataCU* pcCU = getCU( CUAddr );
    pcCU->setSliceSUMap(m_pSliceSUMap + (CUAddr* maxNumSUInLCU)); 
    pcCU->getNDBFilterBlocks()->clear();
  }
  m_vSliceCUDataLink.clear();

  m_vSliceCUDataLink.resize(numSlices);

  UInt startAddr, endAddr, firstCUInStartLCU, startLCU, endLCU, lastCUInEndLCU, uiAddr;
  UInt LPelX, TPelY, LCUX, LCUY;
  UInt currSU;
  UInt startSU, endSU;

  for(Int s=0; s< numSlices; s++)
  {
    //1st step: decide the real start address
    startAddr = sliceStartAddress[s];
    endAddr   = sliceStartAddress[s+1] -1;

    startLCU            = startAddr / maxNumSUInLCU;
    firstCUInStartLCU   = startAddr % maxNumSUInLCU;

    endLCU              = endAddr   / maxNumSUInLCU;
    lastCUInEndLCU      = endAddr   % maxNumSUInLCU;   

    uiAddr = m_apcPicSym->getCUOrderMap(startLCU);

    LCUX      = getCU(uiAddr)->getCUPelX();
    LCUY      = getCU(uiAddr)->getCUPelY();
    LPelX     = LCUX + g_auiRasterToPelX[ g_auiZscanToRaster[firstCUInStartLCU] ];
    TPelY     = LCUY + g_auiRasterToPelY[ g_auiZscanToRaster[firstCUInStartLCU] ];
    currSU    = firstCUInStartLCU;

    Bool bMoveToNextLCU = false;
    Bool bSliceInOneLCU = (startLCU == endLCU);

    while(!( LPelX < picWidth ) || !( TPelY < picHeight ))
    {
      currSU ++;

      if(bSliceInOneLCU)
      {
        if(currSU > lastCUInEndLCU)
        {
          m_pbValidSlice[s] = false;
          break;
        }
      }

      if(currSU >= maxNumSUInLCU )
      {
        bMoveToNextLCU = true;
        break;
      }

      LPelX = LCUX + g_auiRasterToPelX[ g_auiZscanToRaster[currSU] ];
      TPelY = LCUY + g_auiRasterToPelY[ g_auiZscanToRaster[currSU] ];

    }


    if(!m_pbValidSlice[s])
    {
      continue;
    }

    if(currSU != firstCUInStartLCU)
    {
      if(!bMoveToNextLCU)
      {
        firstCUInStartLCU = currSU;
      }
      else
      {
        startLCU++;
        firstCUInStartLCU = 0;
        assert( startLCU < getNumCUsInFrame());
      }
      assert(startLCU*maxNumSUInLCU + firstCUInStartLCU < endAddr);
    }


    //2nd step: assign NonDBFilterInfo to each processing block
    for(UInt i= startLCU; i <= endLCU; i++)
    {
      startSU = (i == startLCU)?(firstCUInStartLCU):(0);
      endSU   = (i == endLCU  )?(lastCUInEndLCU   ):(maxNumSUInLCU -1);

      uiAddr = m_apcPicSym->getCUOrderMap(i);
      Int iTileID= m_apcPicSym->getTileIdxMap(uiAddr);

      TComDataCU* pcCU = getCU(uiAddr);
      m_vSliceCUDataLink[s].push_back(pcCU);

      createNonDBFilterInfoLCU(iTileID, s, pcCU, startSU, endSU, m_sliceGranularityForNDBFilter, picWidth, picHeight);
    }
  }

  //step 3: border availability
  for(Int s=0; s< numSlices; s++)
  {
    if(!m_pbValidSlice[s])
    {
      continue;
    }

    for(Int i=0; i< m_vSliceCUDataLink[s].size(); i++)
    {
      TComDataCU* pcCU = m_vSliceCUDataLink[s][i];
      uiAddr = pcCU->getAddr();

      if(pcCU->getPic()==0)
      {
        continue;
      }
      Int iTileID= m_apcPicSym->getTileIdxMap(uiAddr);
      Bool bTopTileBoundary = false, bDownTileBoundary= false, bLeftTileBoundary= false, bRightTileBoundary= false;

      if(m_bIndependentTileBoundaryForNDBFilter)
      {
        //left
        if( uiAddr % numLCUsInPicWidth != 0)
        {
          bLeftTileBoundary = ( m_apcPicSym->getTileIdxMap(uiAddr -1) != iTileID )?true:false;
        }
        //right
        if( (uiAddr % numLCUsInPicWidth) != (numLCUsInPicWidth -1) )
        {
          bRightTileBoundary = ( m_apcPicSym->getTileIdxMap(uiAddr +1) != iTileID)?true:false;
        }
        //top
        if( uiAddr >= numLCUsInPicWidth)
        {
          bTopTileBoundary = (m_apcPicSym->getTileIdxMap(uiAddr - numLCUsInPicWidth) !=  iTileID )?true:false;
        }
        //down
        if( uiAddr + numLCUsInPicWidth < numLCUInPic )
        {
          bDownTileBoundary = (m_apcPicSym->getTileIdxMap(uiAddr + numLCUsInPicWidth) != iTileID)?true:false;
        }

      }

      pcCU->setNDBFilterBlockBorderAvailability(numLCUsInPicWidth, numLCUsInPicHeight, maxNumSUInLCUWidth, maxNumSUInLCUHeight,picWidth, picHeight
        , *LFCrossSliceBoundary
        ,bTopTileBoundary, bDownTileBoundary, bLeftTileBoundary, bRightTileBoundary
        ,m_bIndependentTileBoundaryForNDBFilter);

    }

  }

  if( m_bIndependentSliceBoundaryForNDBFilter || m_bIndependentTileBoundaryForNDBFilter)
  {
    m_pNDBFilterYuvTmp = new TComPicYuv();
    m_pNDBFilterYuvTmp->create(picWidth, picHeight, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth);
  }

}
예제 #7
0
//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*/;
}
예제 #8
0
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;
}
Void TDecSlice::decompressSlice(TComInputBitstream** ppcSubstreams, TComPic* pcPic, TDecSbac* pcSbacDecoder)
{
  TComSlice* pcSlice                 = pcPic->getSlice(pcPic->getCurrSliceIdx());

  const Int  startCtuTsAddr          = pcSlice->getSliceSegmentCurStartCtuTsAddr();
  const Int  startCtuRsAddr          = pcPic->getPicSym()->getCtuTsToRsAddrMap(startCtuTsAddr);
  const UInt numCtusInFrame          = pcPic->getNumberOfCtusInFrame();

  const UInt frameWidthInCtus        = pcPic->getPicSym()->getFrameWidthInCtus();
  const Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
  const Bool wavefrontsEnabled       = pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag();

  m_pcEntropyDecoder->setEntropyDecoder ( pcSbacDecoder  );
  m_pcEntropyDecoder->setBitstream      ( ppcSubstreams[0] );
  m_pcEntropyDecoder->resetEntropy      (pcSlice);

  // decoder doesn't need prediction & residual frame buffer
  pcPic->setPicYuvPred( 0 );
  pcPic->setPicYuvResi( 0 );

#if ENC_DEC_TRACE
  g_bJustDoIt = g_bEncDecTraceEnable;
#endif
  DTRACE_CABAC_VL( g_nSymbolCounter++ );
  DTRACE_CABAC_T( "\tPOC: " );
  DTRACE_CABAC_V( pcPic->getPOC() );
  DTRACE_CABAC_T( "\n" );

#if ENC_DEC_TRACE
  g_bJustDoIt = g_bEncDecTraceDisable;
#endif

  // The first CTU of the slice is the first coded substream, but the global substream number, as calculated by getSubstreamForCtuAddr may be higher.
  // This calculates the common offset for all substreams in this slice.
  const UInt subStreamOffset=pcPic->getSubstreamForCtuAddr(startCtuRsAddr, true, pcSlice);


  if (depSliceSegmentsEnabled)
  {
    // modify initial contexts with previous slice segment if this is a dependent slice.
    const UInt startTileIdx=pcPic->getPicSym()->getTileIdxMap(startCtuRsAddr);
    const TComTile *pCurrentTile=pcPic->getPicSym()->getTComTile(startTileIdx);
    const UInt firstCtuRsAddrOfTile = pCurrentTile->getFirstCtuRsAddr();

    if( pcSlice->getDependentSliceSegmentFlag() && startCtuRsAddr != firstCtuRsAddrOfTile)
    {
      if ( pCurrentTile->getTileWidthInCtus() >= 2 || !wavefrontsEnabled)
      {
        pcSbacDecoder->loadContexts(&m_lastSliceSegmentEndContextState);
      }
    }
  }

  // for every CTU in the slice segment...

  Bool isLastCtuOfSliceSegment = false;
  for( UInt ctuTsAddr = startCtuTsAddr; !isLastCtuOfSliceSegment && ctuTsAddr < numCtusInFrame; ctuTsAddr++)
  {
    const UInt ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(ctuTsAddr);
    const TComTile &currentTile = *(pcPic->getPicSym()->getTComTile(pcPic->getPicSym()->getTileIdxMap(ctuRsAddr)));
    const UInt firstCtuRsAddrOfTile = currentTile.getFirstCtuRsAddr();
    const UInt tileXPosInCtus = firstCtuRsAddrOfTile % frameWidthInCtus;
    const UInt tileYPosInCtus = firstCtuRsAddrOfTile / frameWidthInCtus;
    const UInt ctuXPosInCtus  = ctuRsAddr % frameWidthInCtus;
    const UInt ctuYPosInCtus  = ctuRsAddr / frameWidthInCtus;
    const UInt uiSubStrm=pcPic->getSubstreamForCtuAddr(ctuRsAddr, true, pcSlice)-subStreamOffset;
    TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );
    pCtu->initCtu( pcPic, ctuRsAddr );

    m_pcEntropyDecoder->setBitstream( ppcSubstreams[uiSubStrm] );

    // set up CABAC contexts' state for this CTU
    if (ctuRsAddr == firstCtuRsAddrOfTile)
    {
      if (ctuTsAddr != startCtuTsAddr) // if it is the first CTU, then the entropy coder has already been reset
      {
        m_pcEntropyDecoder->resetEntropy(pcSlice);
      }
    }
    else if (ctuXPosInCtus == tileXPosInCtus && wavefrontsEnabled)
    {
      // Synchronize cabac probabilities with upper-right CTU if it's available and at the start of a line.
      if (ctuTsAddr != startCtuTsAddr) // if it is the first CTU, then the entropy coder has already been reset
      {
        m_pcEntropyDecoder->resetEntropy(pcSlice);
      }
      TComDataCU *pCtuUp = pCtu->getCtuAbove();
      if ( pCtuUp && ((ctuRsAddr%frameWidthInCtus+1) < frameWidthInCtus)  )
      {
        TComDataCU *pCtuTR = pcPic->getCtu( ctuRsAddr - frameWidthInCtus + 1 );
        if ( pCtu->CUIsFromSameSliceAndTile(pCtuTR) )
        {
          // Top-right is available, so use it.
          pcSbacDecoder->loadContexts( &m_entropyCodingSyncContextState );
        }
      }
    }

#if ENC_DEC_TRACE
    g_bJustDoIt = g_bEncDecTraceEnable;
#endif

    if ( pcSlice->getSPS()->getUseSAO() )
    {
      SAOBlkParam& saoblkParam = (pcPic->getPicSym()->getSAOBlkParam())[ctuRsAddr];
      Bool bIsSAOSliceEnabled = false;
      Bool sliceEnabled[MAX_NUM_COMPONENT];
      for(Int comp=0; comp < MAX_NUM_COMPONENT; comp++)
      {
        ComponentID compId=ComponentID(comp);
        sliceEnabled[compId] = pcSlice->getSaoEnabledFlag(toChannelType(compId)) && (comp < pcPic->getNumberValidComponents());
        if (sliceEnabled[compId]) bIsSAOSliceEnabled=true;
        saoblkParam[compId].modeIdc = SAO_MODE_OFF;
      }
      if (bIsSAOSliceEnabled)
      {
        Bool leftMergeAvail = false;
        Bool aboveMergeAvail= false;

        //merge left condition
        Int rx = (ctuRsAddr % frameWidthInCtus);
        if(rx > 0)
        {
          leftMergeAvail = pcPic->getSAOMergeAvailability(ctuRsAddr, ctuRsAddr-1);
        }
        //merge up condition
        Int ry = (ctuRsAddr / frameWidthInCtus);
        if(ry > 0)
        {
          aboveMergeAvail = pcPic->getSAOMergeAvailability(ctuRsAddr, ctuRsAddr-frameWidthInCtus);
        }
#if SVC_EXTENSION
        pcSbacDecoder->parseSAOBlkParam( saoblkParam, m_saoMaxOffsetQVal, sliceEnabled, leftMergeAvail, aboveMergeAvail);
#else
        pcSbacDecoder->parseSAOBlkParam( saoblkParam, sliceEnabled, leftMergeAvail, aboveMergeAvail);
#endif      
      }
    }

    m_pcCuDecoder->decodeCtu     ( pCtu, isLastCtuOfSliceSegment );
    m_pcCuDecoder->decompressCtu ( pCtu );

#if ENC_DEC_TRACE
    g_bJustDoIt = g_bEncDecTraceDisable;
#endif

    //Store probabilities of second CTU in line into buffer
    if ( ctuXPosInCtus == tileXPosInCtus+1 && wavefrontsEnabled)
    {
      m_entropyCodingSyncContextState.loadContexts( pcSbacDecoder );
    }

    // Should the sub-stream/stream be terminated after this CTU?
    // (end of slice-segment, end of tile, end of wavefront-CTU-row)
    if (isLastCtuOfSliceSegment ||
         (  ctuXPosInCtus + 1 == tileXPosInCtus + currentTile.getTileWidthInCtus() &&
          ( ctuYPosInCtus + 1 == tileYPosInCtus + currentTile.getTileHeightInCtus() || wavefrontsEnabled)
         )
       )
    {
      UInt binVal;
      pcSbacDecoder->parseTerminatingBit( binVal );
      assert( binVal );
#if DECODER_CHECK_SUBSTREAM_AND_SLICE_TRAILING_BYTES
      pcSbacDecoder->parseRemainingBytes(!isLastCtuOfSliceSegment);
#endif

      if (isLastCtuOfSliceSegment)
      {
        if(!pcSlice->getDependentSliceSegmentFlag())
        {
          pcSlice->setSliceCurEndCtuTsAddr( ctuTsAddr+1 );
        }
        pcSlice->setSliceSegmentCurEndCtuTsAddr( ctuTsAddr+1 );
        break;
      }
    }
  }

  assert(isLastCtuOfSliceSegment == true);


  if( depSliceSegmentsEnabled )
  {
    m_lastSliceSegmentEndContextState.loadContexts( pcSbacDecoder );//ctx end of dep.slice
  }

}
예제 #10
0
Void TComPic::createNonDBFilterInfo(UInt* puiSliceStartAddress, Int iNumSlices, Int iSliceGranularityDepth
                                    ,Bool bNDBFilterCrossSliceBoundary
                                    ,Int iNumTiles
                                    ,Bool bNDBFilterCrossTileBoundary)
{
  UInt uiMaxNumSUInLCU = getNumPartInCU();
  UInt uiNumLCUInPic   = getNumCUsInFrame();
  UInt uiPicWidth      = getCU(0)->getSlice()->getSPS()->getWidth();
  UInt uiPicHeight     = getCU(0)->getSlice()->getSPS()->getHeight();
  Int  iNumLCUsInPicWidth = getFrameWidthInCU();
  Int  iNumLCUsInPicHeight= getFrameHeightInCU();
  UInt uiMaxNumSUInLCUWidth = getNumPartInWidth();
  UInt uiMAxNumSUInLCUHeight= getNumPartInHeight();

  m_bIndependentSliceBoundaryForNDBFilter = (bNDBFilterCrossSliceBoundary)?(false):((iNumSlices > 1)?(true):(false)) ;
  m_iSliceGranularityForNDBFilter = iSliceGranularityDepth;
  m_bIndependentTileBoundaryForNDBFilter  = (bNDBFilterCrossTileBoundary)?(false) :((iNumTiles > 1)?(true):(false));

  m_pbValidSlice = new Bool[iNumSlices];
  for(Int s=0; s< iNumSlices; s++)
  {
    m_pbValidSlice[s] = true;
  }

  if( puiSliceStartAddress == NULL || (iNumSlices == 1 && iNumTiles == 1) )
  {
    return;
  }
  m_piSliceSUMap = new Int[uiMaxNumSUInLCU * uiNumLCUInPic];

  //initialization
  for(UInt i=0; i< (uiMaxNumSUInLCU * uiNumLCUInPic); i++ )
  {
    m_piSliceSUMap[i] = -1;
  }
  for( UInt uiCUAddr = 0; uiCUAddr < uiNumLCUInPic ; uiCUAddr++ )
  {
    TComDataCU* pcCU = getCU( uiCUAddr );
    pcCU->setSliceSUMap(m_piSliceSUMap + (uiCUAddr* uiMaxNumSUInLCU)); 
    pcCU->getNDBFilterBlocks()->clear();
  }
  m_vSliceCUDataLink.clear();

  m_vSliceCUDataLink.resize(iNumSlices);

  UInt uiStartAddr, uiEndAddr, uiFirstCUInStartLCU, uiStartLCU, uiEndLCU, uiLastCUInEndLCU, uiAddr;
  UInt uiLPelX, uiTPelY, uiLCUX, uiLCUY;
  UInt uiCurrSU;
  UInt uiStartSU, uiEndSU;

  for(Int s=0; s< iNumSlices; s++)
  {
    //1st step: decide the real start address
#if FINE_GRANULARITY_SLICES
    uiStartAddr = puiSliceStartAddress[s];
    uiEndAddr   = puiSliceStartAddress[s+1] -1;
#else
    uiStartAddr = (puiSliceStartAddress[s]*uiMaxNumSUInLCU);
    uiEndAddr   = (puiSliceStartAddress[s+1]*uiMaxNumSUInLCU) -1;
#endif

    uiStartLCU            = uiStartAddr / uiMaxNumSUInLCU;
    uiFirstCUInStartLCU   = uiStartAddr % uiMaxNumSUInLCU;

    uiEndLCU              = uiEndAddr   / uiMaxNumSUInLCU;
    uiLastCUInEndLCU      = uiEndAddr   % uiMaxNumSUInLCU;   

#if TILES
    uiAddr = m_apcPicSym->getCUOrderMap(uiStartLCU);
#else
    uiAddr = uiStartLCU;
#endif

    uiLCUX      = getCU(uiAddr)->getCUPelX();
    uiLCUY      = getCU(uiAddr)->getCUPelY();
    uiLPelX     = uiLCUX + g_auiRasterToPelX[ g_auiZscanToRaster[uiFirstCUInStartLCU] ];
    uiTPelY     = uiLCUY + g_auiRasterToPelY[ g_auiZscanToRaster[uiFirstCUInStartLCU] ];
    uiCurrSU    = uiFirstCUInStartLCU;

    Bool bMoveToNextLCU = false;
    Bool bSliceInOneLCU = (uiStartLCU == uiEndLCU);

    while(!( uiLPelX < uiPicWidth ) || !( uiTPelY < uiPicHeight ))
    {
      uiCurrSU ++;

      if(bSliceInOneLCU)
      {
        if(uiCurrSU > uiLastCUInEndLCU)
        {
          m_pbValidSlice[s] = false;
          break;
        }
      }

      if(uiCurrSU >= uiMaxNumSUInLCU )
      {
        bMoveToNextLCU = true;
        break;
      }

      uiLPelX = uiLCUX + g_auiRasterToPelX[ g_auiZscanToRaster[uiCurrSU] ];
      uiTPelY = uiLCUY + g_auiRasterToPelY[ g_auiZscanToRaster[uiCurrSU] ];

    }


    if(!m_pbValidSlice[s])
    {
      continue;
    }

    if(uiCurrSU != uiFirstCUInStartLCU)
    {
      if(!bMoveToNextLCU)
      {
        uiFirstCUInStartLCU = uiCurrSU;
      }
      else
      {
        uiStartLCU++;
        uiFirstCUInStartLCU = 0;
        assert( uiStartLCU < getNumCUsInFrame());
      }
      assert(uiStartLCU*uiMaxNumSUInLCU + uiFirstCUInStartLCU < uiEndAddr);
    }


    //2nd step: assign NonDBFilterInfo to each processing block
    for(UInt i= uiStartLCU; i <= uiEndLCU; i++)
    {
      uiStartSU = (i == uiStartLCU)?(uiFirstCUInStartLCU):(0);
      uiEndSU   = (i == uiEndLCU  )?(uiLastCUInEndLCU   ):(uiMaxNumSUInLCU -1);

#if TILES
      uiAddr = m_apcPicSym->getCUOrderMap(i);
      Int iTileID= m_apcPicSym->getTileIdxMap(uiAddr);
#else
      uiAddr = i;
#endif

      TComDataCU* pcCU = getCU(uiAddr);
      m_vSliceCUDataLink[s].push_back(pcCU);

#if TILES
      createNonDBFilterInfoLCU(iTileID, s, pcCU, uiStartSU, uiEndSU, m_iSliceGranularityForNDBFilter, uiPicWidth, uiPicHeight);
#else
      createNonDBFilterInfoLCU(s, pcCU, uiStartSU, uiEndSU, m_iSliceGranularityForNDBFilter, uiPicWidth, uiPicHeight);
#endif
    }
  }

  //step 3: border availability
  for(Int s=0; s< iNumSlices; s++)
  {
    if(!m_pbValidSlice[s])
    {
      continue;
    }

    for(Int i=0; i< m_vSliceCUDataLink[s].size(); i++)
    {
      TComDataCU* pcCU = m_vSliceCUDataLink[s][i];
      uiAddr = pcCU->getAddr();

      Int iTileID= m_apcPicSym->getTileIdxMap(uiAddr);
      Bool bTopTileBoundary = false, bDownTileBoundary= false, bLeftTileBoundary= false, bRightTileBoundary= false;

      if(m_bIndependentTileBoundaryForNDBFilter)
      {
        //left
        if( uiAddr % iNumLCUsInPicWidth != 0)
        {
          bLeftTileBoundary = ( m_apcPicSym->getTileIdxMap(uiAddr -1) != iTileID )?true:false;
        }
        //right
        if( (uiAddr % iNumLCUsInPicWidth) != (iNumLCUsInPicWidth -1) )
        {
          bRightTileBoundary = ( m_apcPicSym->getTileIdxMap(uiAddr +1) != iTileID)?true:false;
        }
        //top
        if( uiAddr >= iNumLCUsInPicWidth)
        {
          bTopTileBoundary = (m_apcPicSym->getTileIdxMap(uiAddr - iNumLCUsInPicWidth) !=  iTileID )?true:false;
        }
        //down
        if( uiAddr + iNumLCUsInPicWidth < uiNumLCUInPic )
        {
          bDownTileBoundary = (m_apcPicSym->getTileIdxMap(uiAddr + iNumLCUsInPicWidth) != iTileID)?true:false;
        }

      }

      pcCU->setNDBFilterBlockBorderAvailability(iNumLCUsInPicWidth, iNumLCUsInPicHeight, uiMaxNumSUInLCUWidth, uiMAxNumSUInLCUHeight,uiPicWidth, uiPicHeight
        ,m_bIndependentSliceBoundaryForNDBFilter
        ,bTopTileBoundary, bDownTileBoundary, bLeftTileBoundary, bRightTileBoundary
        ,m_bIndependentTileBoundaryForNDBFilter);

    }

  }

  if( m_bIndependentSliceBoundaryForNDBFilter || m_bIndependentTileBoundaryForNDBFilter)
  {
    m_pcNDBFilterYuvTmp = new TComPicYuv();
    m_pcNDBFilterYuvTmp->create(uiPicWidth, uiPicHeight, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth);
  }

}
예제 #11
0
Void TDecSlice::decompressSlice(TComInputBitstream** ppcSubstreams, TComPic*& rpcPic, TDecSbac* pcSbacDecoder, TDecSbac* pcSbacDecoders)
{
  TComDataCU* pcCU;
  UInt        uiIsLast = 0;
  Int   iStartCUEncOrder = max(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU(), rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU());
  Int   iStartCUAddr = rpcPic->getPicSym()->getCUOrderMap(iStartCUEncOrder);


  // decoder don't need prediction & residual frame buffer
#if ENABLE_ANAYSIS_OUTPUT

#else
  rpcPic->setPicYuvPred( 0 );
  rpcPic->setPicYuvResi( 0 );
#endif

#if ENC_DEC_TRACE
  g_bJustDoIt = g_bEncDecTraceEnable;
#endif
  DTRACE_CABAC_VL( g_nSymbolCounter++ );
  DTRACE_CABAC_T( "\tPOC: " );
  DTRACE_CABAC_V( rpcPic->getPOC() );
  DTRACE_CABAC_T( "\n" );

#if ENC_DEC_TRACE
  g_bJustDoIt = g_bEncDecTraceDisable;
#endif

  UInt uiTilesAcross   = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
  TComSlice*  pcSlice = rpcPic->getSlice(rpcPic->getCurrSliceIdx());
  Int  iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();

  // delete decoders if already allocated in previous slice
  if (m_pcBufferSbacDecoders)
  {
    delete [] m_pcBufferSbacDecoders;
  }
  if (m_pcBufferBinCABACs) 
  {
    delete [] m_pcBufferBinCABACs;
  }
  // allocate new decoders based on tile numbaer
  m_pcBufferSbacDecoders = new TDecSbac    [uiTilesAcross];  
  m_pcBufferBinCABACs    = new TDecBinCABAC[uiTilesAcross];
  for (UInt ui = 0; ui < uiTilesAcross; ui++)
  {
    m_pcBufferSbacDecoders[ui].init(&m_pcBufferBinCABACs[ui]);
  }
  //save init. state
  for (UInt ui = 0; ui < uiTilesAcross; ui++)
  {
    m_pcBufferSbacDecoders[ui].load(pcSbacDecoder);
  }

  // free memory if already allocated in previous call
  if (m_pcBufferLowLatSbacDecoders)
  {
    delete [] m_pcBufferLowLatSbacDecoders;
  }
  if (m_pcBufferLowLatBinCABACs)
  {
    delete [] m_pcBufferLowLatBinCABACs;
  }
  m_pcBufferLowLatSbacDecoders = new TDecSbac    [uiTilesAcross];  
  m_pcBufferLowLatBinCABACs    = new TDecBinCABAC[uiTilesAcross];
  for (UInt ui = 0; ui < uiTilesAcross; ui++)
  {
    m_pcBufferLowLatSbacDecoders[ui].init(&m_pcBufferLowLatBinCABACs[ui]);
  }
  //save init. state
  for (UInt ui = 0; ui < uiTilesAcross; ui++)
  {
    m_pcBufferLowLatSbacDecoders[ui].load(pcSbacDecoder);
  }

  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
  UInt uiCol=0, uiLin=0, uiSubStrm=0;

  UInt uiTileCol;
  UInt uiTileStartLCU;
  UInt uiTileLCUX;
  Int iNumSubstreamsPerTile = 1; // if independent.
  Bool depSliceSegmentsEnabled = rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getPPS()->getDependentSliceSegmentsEnabledFlag();
  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iStartCUAddr))->getFirstCUAddr();
  if( depSliceSegmentsEnabled )
  {
    if( (!rpcPic->getSlice(rpcPic->getCurrSliceIdx())->isNextSlice()) &&
       iStartCUAddr != rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iStartCUAddr))->getFirstCUAddr())
    {
      if(pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag())
      {
        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(iStartCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
        m_pcBufferSbacDecoders[uiTileCol].loadContexts( CTXMem[1]  );//2.LCU
        if ( (iStartCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
        {
          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
          uiCol     = iStartCUAddr % uiWidthInLCUs;
          if(uiCol==uiTileLCUX)
          {
            CTXMem[0]->loadContexts(pcSbacDecoder);
          }
        }
      }
      pcSbacDecoder->loadContexts(CTXMem[0] ); //end of depSlice-1
      pcSbacDecoders[uiSubStrm].loadContexts(pcSbacDecoder);
    }
    else
    {
      if(pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag())
      {
        CTXMem[1]->loadContexts(pcSbacDecoder);
      }
      CTXMem[0]->loadContexts(pcSbacDecoder);
    }
  }
  for( Int iCUAddr = iStartCUAddr; !uiIsLast && iCUAddr < rpcPic->getNumCUsInFrame(); iCUAddr = rpcPic->getPicSym()->xCalculateNxtCUAddr(iCUAddr) )
  {
    pcCU = rpcPic->getCU( iCUAddr );
    pcCU->initCU( rpcPic, iCUAddr );
    uiTileCol = rpcPic->getPicSym()->getTileIdxMap(iCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
    uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getFirstCUAddr();
    uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
    uiCol     = iCUAddr % uiWidthInLCUs;
    // The 'line' is now relative to the 1st line in the slice, not the 1st line in the picture.
    uiLin     = (iCUAddr/uiWidthInLCUs)-(iStartCUAddr/uiWidthInLCUs);
    // inherit from TR if necessary, select substream to use.
    if( (pcSlice->getPPS()->getNumSubstreams() > 1) || ( depSliceSegmentsEnabled  && (uiCol == uiTileLCUX)&&(pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag()) ))
    {
      // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
      iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
      uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(iCUAddr)*iNumSubstreamsPerTile
                  + uiLin%iNumSubstreamsPerTile;
      m_pcEntropyDecoder->setBitstream( ppcSubstreams[uiSubStrm] );
      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
      if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled ) && (uiCol == uiTileLCUX)&&(pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag()))
      {
        // We'll sync if the TR is available.
        TComDataCU *pcCUUp = pcCU->getCUAbove();
        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
        TComDataCU *pcCUTR = NULL;
        if ( pcCUUp && ((iCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
        {
          pcCUTR = rpcPic->getCU( iCUAddr - uiWidthInCU + 1 );
        }
        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);

        if ( (true/*bEnforceSliceRestriction*/ &&
             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
             ((pcCUTR->getSCUAddr()+uiMaxParts-1) < pcSlice->getSliceCurStartCUAddr()) ||
             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr)))
             ))
           )
        {
          // TR not available.
        }
        else
        {
          // TR is available, we use it.
          pcSbacDecoders[uiSubStrm].loadContexts( &m_pcBufferSbacDecoders[uiTileCol] );
        }
      }
      pcSbacDecoder->load(&pcSbacDecoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to pcSbacDecoders)
    }
    else if ( pcSlice->getPPS()->getNumSubstreams() <= 1 )
    {
      // Set variables to appropriate values to avoid later code change.
      iNumSubstreamsPerTile = 1;
    }

    if ( (iCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getFirstCUAddr()) && // 1st in tile.
         (iCUAddr!=0) && (iCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())
         && (iCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU())
         ) // !1st in frame && !1st in slice
    {
      if (pcSlice->getPPS()->getNumSubstreams() > 1)
      {
        // We're crossing into another tile, tiles are independent.
        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
        // have to perform it here.
        // For TILES_DECODER, there can be a header at the start of the 1st substream in a tile.  These are read when the substreams
        // are extracted, not here.
      }
      else
      {
        SliceType sliceType  = pcSlice->getSliceType();
        if (pcSlice->getCabacInitFlag())
        {
          switch (sliceType)
          {
          case P_SLICE:           // change initialization table to B_SLICE intialization
            sliceType = B_SLICE; 
            break;
          case B_SLICE:           // change initialization table to P_SLICE intialization
            sliceType = P_SLICE; 
            break;
          default     :           // should not occur
            assert(0);
          }
        }
        m_pcEntropyDecoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
      }
      
    }

#if ENC_DEC_TRACE
    g_bJustDoIt = g_bEncDecTraceEnable;
#endif
    if ( pcSlice->getSPS()->getUseSAO() && (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma()) )
    {
      SAOParam *saoParam = rpcPic->getPicSym()->getSaoParam();
      saoParam->bSaoFlag[0] = pcSlice->getSaoEnabledFlag();
      if (iCUAddr == iStartCUAddr)
      {
        saoParam->bSaoFlag[1] = pcSlice->getSaoEnabledFlagChroma();
      }
      Int numCuInWidth     = saoParam->numCuInWidth;
      Int cuAddrInSlice = iCUAddr - rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU());
      Int cuAddrUpInSlice  = cuAddrInSlice - numCuInWidth;
      Int rx = iCUAddr % numCuInWidth;
      Int ry = iCUAddr / numCuInWidth;
      Int allowMergeLeft = 1;
      Int allowMergeUp   = 1;
      if (rx!=0)
      {
        if (rpcPic->getPicSym()->getTileIdxMap(iCUAddr-1) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr))
        {
          allowMergeLeft = 0;
        }
      }
      if (ry!=0)
      {
        if (rpcPic->getPicSym()->getTileIdxMap(iCUAddr-numCuInWidth) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr))
        {
          allowMergeUp = 0;
        }
      }
      pcSbacDecoder->parseSaoOneLcuInterleaving(rx, ry, saoParam,pcCU, cuAddrInSlice, cuAddrUpInSlice, allowMergeLeft, allowMergeUp);
    }
    else if ( pcSlice->getSPS()->getUseSAO() )
    {
      Int addr = pcCU->getAddr();
      SAOParam *saoParam = rpcPic->getPicSym()->getSaoParam();
      for (Int cIdx=0; cIdx<3; cIdx++)
      {
        SaoLcuParam *saoLcuParam = &(saoParam->saoLcuParam[cIdx][addr]);
        if ( ((cIdx == 0) && !pcSlice->getSaoEnabledFlag()) || ((cIdx == 1 || cIdx == 2) && !pcSlice->getSaoEnabledFlagChroma()))
        {
          saoLcuParam->mergeUpFlag   = 0;
          saoLcuParam->mergeLeftFlag = 0;
          saoLcuParam->subTypeIdx    = 0;
          saoLcuParam->typeIdx       = -1;
          saoLcuParam->offset[0]     = 0;
          saoLcuParam->offset[1]     = 0;
          saoLcuParam->offset[2]     = 0;
          saoLcuParam->offset[3]     = 0;
        }
      }
    }
#if ENABLE_ANAYSIS_OUTPUT
    UInt uiBefore = ppcSubstreams[uiSubStrm]->getByteLocation();
#endif
    m_pcCuDecoder->decodeCU     ( pcCU, uiIsLast );
#if ENABLE_ANAYSIS_OUTPUT
    pcCU->getTotalBits() = ppcSubstreams[uiSubStrm]->getByteLocation() - uiBefore;
#endif
    m_pcCuDecoder->decompressCU ( pcCU );
    
#if ENC_DEC_TRACE
    g_bJustDoIt = g_bEncDecTraceDisable;
#endif
    pcSbacDecoders[uiSubStrm].load(pcSbacDecoder);

    //Store probabilities of second LCU in line into buffer
    if ( (uiCol == uiTileLCUX+1)&& (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag()) )
    {
      m_pcBufferSbacDecoders[uiTileCol].loadContexts( &pcSbacDecoders[uiSubStrm] );
    }
    if( uiIsLast && depSliceSegmentsEnabled )
    {
      if (pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag())
       {
         CTXMem[1]->loadContexts( &m_pcBufferSbacDecoders[uiTileCol] );//ctx 2.LCU
       }
      CTXMem[0]->loadContexts( pcSbacDecoder );//ctx end of dep.slice
      return;
    }
  }
}
Void TDecSlice::decompressSlice(TComInputBitstream* pcBitstream, TComInputBitstream** ppcSubstreams, TComPic*& rpcPic, TDecSbac* pcSbacDecoder, TDecSbac* pcSbacDecoders)
{
  TComDataCU* pcCU;
  UInt        uiIsLast = 0;
  Int   iStartCUEncOrder = max(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU(), rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getEntropySliceCurStartCUAddr()/rpcPic->getNumPartInCU());
  Int   iStartCUAddr = rpcPic->getPicSym()->getCUOrderMap(iStartCUEncOrder);

  // decoder don't need prediction & residual frame buffer
  rpcPic->setPicYuvPred( 0 );
  rpcPic->setPicYuvResi( 0 );
  
#if ENC_DEC_TRACE
  g_bJustDoIt = g_bEncDecTraceEnable;
#endif
  DTRACE_CABAC_VL( g_nSymbolCounter++ );
  DTRACE_CABAC_T( "\tPOC: " );
  DTRACE_CABAC_V( rpcPic->getPOC() );
  DTRACE_CABAC_T( "\n" );

#if ENC_DEC_TRACE
  g_bJustDoIt = g_bEncDecTraceDisable;
#endif

  UInt uiTilesAcross   = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
  TComSlice*  pcSlice = rpcPic->getSlice(rpcPic->getCurrSliceIdx());
  UInt iSymbolMode    = pcSlice->getPPS()->getEntropyCodingMode();
  Int  iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();

  if( iSymbolMode )
  {
    m_pcBufferSbacDecoders = new TDecSbac    [uiTilesAcross];  
    m_pcBufferBinCABACs    = new TDecBinCABAC[uiTilesAcross];
    for (UInt ui = 0; ui < uiTilesAcross; ui++)
    {
      m_pcBufferSbacDecoders[ui].init(&m_pcBufferBinCABACs[ui]);
    }
    //save init. state
    for (UInt ui = 0; ui < uiTilesAcross; ui++)
    {
      m_pcBufferSbacDecoders[ui].load(pcSbacDecoder);
    }
  }  
  if( iSymbolMode )
  {
    m_pcBufferLowLatSbacDecoders = new TDecSbac    [uiTilesAcross];  
    m_pcBufferLowLatBinCABACs    = new TDecBinCABAC[uiTilesAcross];
    for (UInt ui = 0; ui < uiTilesAcross; ui++)
      m_pcBufferLowLatSbacDecoders[ui].init(&m_pcBufferLowLatBinCABACs[ui]);
    //save init. state
    for (UInt ui = 0; ui < uiTilesAcross; ui++)
      m_pcBufferLowLatSbacDecoders[ui].load(pcSbacDecoder);
  }

  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
  UInt uiCol=0, uiLin=0, uiSubStrm=0;

  UInt uiTileCol;
  UInt uiTileStartLCU;
  UInt uiTileLCUX;
  UInt uiTileLCUY;
  UInt uiTileWidth;
  UInt uiTileHeight;
  Int iNumSubstreamsPerTile = 1; // if independent.

  for( Int iCUAddr = iStartCUAddr; !uiIsLast && iCUAddr < rpcPic->getNumCUsInFrame(); iCUAddr = rpcPic->getPicSym()->xCalculateNxtCUAddr(iCUAddr) )
  {
    pcCU = rpcPic->getCU( iCUAddr );
    pcCU->initCU( rpcPic, iCUAddr );
    uiTileCol = rpcPic->getPicSym()->getTileIdxMap(iCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
    uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getFirstCUAddr();
    uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
    uiTileLCUY = uiTileStartLCU / uiWidthInLCUs;
    uiTileWidth = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getTileWidth();
    uiTileHeight = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getTileHeight();
    uiCol     = iCUAddr % uiWidthInLCUs;
    uiLin     = iCUAddr / uiWidthInLCUs;
    // inherit from TR if necessary, select substream to use.
    if( iSymbolMode && pcSlice->getPPS()->getNumSubstreams() > 1 )
    {
      if (pcSlice->getPPS()->getNumSubstreams() > 1)
      {
        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
        iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(iCUAddr)*iNumSubstreamsPerTile
                      + uiLin%iNumSubstreamsPerTile;
      }
      else
      {
        // dependent tiles => substreams are "per frame".
        uiSubStrm = uiLin % iNumSubstreams;
      }
      m_pcEntropyDecoder->setBitstream( ppcSubstreams[uiSubStrm] );
      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
      if (pcSlice->getPPS()->getNumSubstreams() > 1 && uiCol == uiTileLCUX)
      {
        // We'll sync if the TR is available.
        TComDataCU *pcCUUp = pcCU->getCUAbove();
        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
        TComDataCU *pcCUTR = NULL;
        if ( pcCUUp && ((iCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
        {
          pcCUTR = rpcPic->getCU( iCUAddr - uiWidthInCU + 1 );
        }
        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);

        if ( (true/*bEnforceSliceRestriction*/ &&
             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
             ((pcCUTR->getSCUAddr()+uiMaxParts-1) < pcSlice->getSliceCurStartCUAddr()) ||
             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr)))
             ))||
             (true/*bEnforceEntropySliceRestriction*/ &&
             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
             ((pcCUTR->getSCUAddr()+uiMaxParts-1) < pcSlice->getEntropySliceCurStartCUAddr()) ||
             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr)))
             ))
           )
        {
          // TR not available.
        }
        else
        {
          // TR is available, we use it.
            pcSbacDecoders[uiSubStrm].loadContexts( &m_pcBufferSbacDecoders[uiTileCol] );
        }
      }
      pcSbacDecoder->load(&pcSbacDecoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to pcSbacDecoders)
    }
    else if ( iSymbolMode && pcSlice->getPPS()->getNumSubstreams() <= 1 )
    {
      // Set variables to appropriate values to avoid later code change.
      iNumSubstreamsPerTile = 1;
    }

    if ( (iCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getFirstCUAddr()) && // 1st in tile.
         (iCUAddr!=0) && (iCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())) // !1st in frame && !1st in slice
    {
      if (pcSlice->getPPS()->getNumSubstreams() > 1)
      {
        // We're crossing into another tile, tiles are independent.
        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
        // have to perform it here.
        // For TILES_DECODER, there can be a header at the start of the 1st substream in a tile.  These are read when the substreams
        // are extracted, not here.
      }
      else
      {
#if CABAC_INIT_FLAG
        SliceType sliceType  = pcSlice->getSliceType();
        if (pcSlice->getCabacInitFlag())
        {
          switch (sliceType)
          {
          case P_SLICE:           // change initialization table to B_SLICE intialization
            sliceType = B_SLICE; 
            break;
          case B_SLICE:           // change initialization table to P_SLICE intialization
            sliceType = P_SLICE; 
            break;
          default     :           // should not occur
            assert(0);
          }
        }
        m_pcEntropyDecoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
#else
        m_pcEntropyDecoder->updateContextTables( pcSlice->getSliceType(), pcSlice->getSliceQp() );
#endif
      }
      
      Bool bTileMarkerFoundFlag = false;
      TComInputBitstream *pcTmpPtr;
      pcTmpPtr = ppcSubstreams[uiSubStrm]; // for CABAC

      for (UInt uiIdx=0; uiIdx<pcTmpPtr->getTileMarkerLocationCount(); uiIdx++)
      {
        if ( pcTmpPtr->getByteLocation() == (pcTmpPtr->getTileMarkerLocation( uiIdx )+2) )
        {
          bTileMarkerFoundFlag = true;
          break;
        }
      }

      if (bTileMarkerFoundFlag)
      {
        UInt uiTileIdx;
        // Read tile index
        m_pcEntropyDecoder->readTileMarker( uiTileIdx, rpcPic->getPicSym()->getBitsUsedByTileIdx() );
      }
    }



#if ENC_DEC_TRACE
    g_bJustDoIt = g_bEncDecTraceEnable;
#endif
    if ( pcSlice->getSPS()->getUseSAO() && pcSlice->getSaoInterleavingFlag() && pcSlice->getSaoEnabledFlag() )
    {
      pcSlice->getAPS()->getSaoParam()->bSaoFlag[0] = pcSlice->getSaoEnabledFlag();
      if (iCUAddr == iStartCUAddr)
      {
        pcSlice->getAPS()->getSaoParam()->bSaoFlag[1] = pcSlice->getSaoEnabledFlagCb();
        pcSlice->getAPS()->getSaoParam()->bSaoFlag[2] = pcSlice->getSaoEnabledFlagCr();
      }
      Int numCuInWidth     = pcSlice->getAPS()->getSaoParam()->numCuInWidth;
      Int cuAddrInSlice = iCUAddr - pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU();
      Int cuAddrUpInSlice  = cuAddrInSlice - numCuInWidth;
      Int rx = iCUAddr % numCuInWidth;
      Int ry = iCUAddr / numCuInWidth;
      pcSbacDecoder->parseSaoOneLcuInterleaving(rx, ry, pcSlice->getAPS()->getSaoParam(),pcCU, cuAddrInSlice, cuAddrUpInSlice, pcSlice->getSPS()->getLFCrossSliceBoundaryFlag() );
    }

    m_pcCuDecoder->decodeCU     ( pcCU, uiIsLast );
    m_pcCuDecoder->decompressCU ( pcCU );
    
#if ENC_DEC_TRACE
    g_bJustDoIt = g_bEncDecTraceDisable;
#endif
    if( iSymbolMode )
    {
      /*If at the end of a LCU line but not at the end of a substream, perform CABAC flush*/
      if (!uiIsLast && pcSlice->getPPS()->getNumSubstreams() > 1)
      {
        if ((uiCol == uiTileLCUX+uiTileWidth-1) && (uiLin+iNumSubstreamsPerTile < uiTileLCUY+uiTileHeight))
        {
          m_pcEntropyDecoder->decodeFlush();
        }
      }
      pcSbacDecoders[uiSubStrm].load(pcSbacDecoder);

      //Store probabilities of second LCU in line into buffer
      if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX+1))
      {
        m_pcBufferSbacDecoders[uiTileCol].loadContexts( &pcSbacDecoders[uiSubStrm] );
      }

    }
  }

}