示例#1
0
Void TDecTop::deletePicBuffer ( )
{
  TComList<TComPic*>::iterator  iterPic   = m_cListPic.begin();
  Int iSize = Int( m_cListPic.size() );
  
  for (Int i = 0; i < iSize; i++ )
  {
    TComPic* pcPic = *(iterPic++);
    pcPic->destroy();
    
    delete pcPic;
    pcPic = NULL;
  }
  
  // destroy ALF temporary buffers
  m_cAdaptiveLoopFilter.destroy();

#if MTK_SAO
  m_cSAO.destroy();
#endif
  
  m_cLoopFilter.        destroy();
  
  // destroy ROM
  destroyROM();
}
示例#2
0
void DPB::computeRPS(int curPoc, bool isRAP, TComReferencePictureSet * rps, unsigned int maxDecPicBuffer)
{
    unsigned int poci = 0, numNeg = 0, numPos = 0;

    TComPic* iterPic = m_picList.first();

    while (iterPic && (poci < maxDecPicBuffer - 1))
    {
        if ((iterPic->getPOC() != curPoc) && (iterPic->getSlice()->isReferenced()))
        {
            rps->m_POC[poci] = iterPic->getPOC();
            rps->m_deltaPOC[poci] = rps->m_POC[poci] - curPoc;
            (rps->m_deltaPOC[poci] < 0) ? numNeg++ : numPos++;
            rps->m_used[poci] = !isRAP;
            poci++;
        }
        iterPic = iterPic->m_next;
    }

    rps->m_numberOfPictures = poci;
    rps->m_numberOfPositivePictures = numPos;
    rps->m_numberOfNegativePictures = numNeg;
    rps->m_numberOfLongtermPictures = 0;
    rps->m_interRPSPrediction = false;          // To be changed later when needed

    rps->sortDeltaPOC();
}
示例#3
0
DPB::~DPB()
{
    while (!m_picList.empty())
    {
        TComPic* pic = m_picList.popFront();
        pic->destroy();
        delete pic;
    }
}
示例#4
0
文件: dpb.cpp 项目: roman5566/x265
DPB::~DPB()
{
    while (!m_picList.empty())
    {
        TComPic* pic = m_picList.popFront();
        pic->destroy(m_cfg->param.bframes);
        delete pic;
    }
}
示例#5
0
Void TEncTop::deletePicBuffer()
{
  TComList<TComPic*>::iterator iterPic = m_cListPic.begin();
  Int iSize = Int( m_cListPic.size() );

  for ( Int i = 0; i < iSize; i++ )
  {
    TComPic* pcPic = *(iterPic++);

    pcPic->destroy();
    delete pcPic;
    pcPic = NULL;
  }
}
示例#6
0
Void updatePixel(TComDataCU* pCtu, Pixel** ppPixel)
{
	UInt uiMaxCUWidth = pCtu->getSlice()->getSPS()->getMaxCUWidth();		// max cu width
	UInt uiMaxCUHeight = pCtu->getSlice()->getSPS()->getMaxCUHeight();		// max cu height

	// pic
	TComPic *pcPic = pCtu->getPic();
	//TComPicYuv* pcPredYuv = pcPic->getPicYuvPred();
	//TComPicYuv* pcResiYuv = pcPic->getPicYuvResi();
	TComPicYuv* pcRecoYuv = pcPic->getPicYuvRec();
	UInt uiNumValidCopmonent = pcPic->getNumberValidComponents();

	for (UInt ch = 0; ch < uiNumValidCopmonent; ch++)
	{
		ComponentID cId = ComponentID(ch);
		// picture description
		UInt uiStride = pcRecoYuv->getStride(cId);									// stride for a certain component
		UInt uiPicWidth = pcRecoYuv->getWidth(cId);									// picture width for a certain component
		UInt uiPicHeight = pcRecoYuv->getHeight(cId);								// picture height for a certain component

		UInt uiCUPelX = pCtu->getCUPelX() >> (pcRecoYuv->getComponentScaleX(cId));			// x of upper left corner of the cu
		UInt uiCUPelY = pCtu->getCUPelY() >> (pcRecoYuv->getComponentScaleY(cId));;			// y of upper left corner of the
		UInt uiCBWidth = uiMaxCUWidth >> (pcRecoYuv->getComponentScaleX(cId));		// code block width for a certain component
		UInt uiCBHeight = uiMaxCUHeight >> (pcRecoYuv->getComponentScaleY(cId));	// code block height for a certain component

		// rectangle of the code block
		UInt uiTopX = Clip3((UInt)0, uiPicWidth, uiCUPelX);
		UInt uiTopY = Clip3((UInt)0, uiPicHeight, uiCUPelY);
		UInt uiBottomX = Clip3((UInt)0, uiPicWidth, uiCUPelX + uiCBWidth);
		UInt uiBottomY = Clip3((UInt)0, uiPicHeight, uiCUPelY + uiCBHeight);

		Pel* pBuffer = pcRecoYuv->getAddr(cId);
		for (UInt uiY = uiTopY; uiY < uiBottomY; uiY++)
		{
			for (UInt uiX = uiTopX; uiX < uiBottomX; uiX++)
			{
				UInt uiOrgX, uiOrgY;
				uiOrgX = g_auiRsmpldToOrg[cId][0][uiX];
				uiOrgY = g_auiRsmpldToOrg[cId][1][uiY];
				Pixel* pPixel = ppPixel[cId] + getSerialIndex(uiOrgX, uiOrgY, uiPicWidth);

				pPixel->m_bIsRec = true;
				pPixel->m_uiReco = pBuffer[uiY*uiStride + uiX];
			}
		}
	}
}
示例#7
0
Int TComSlice::getActualRefNumber( TComList<TComPic*>& rcListPic )
{
  Int iActualNumOfReference = 0;

  TComList<TComPic*>::iterator iterPic = rcListPic.begin();
  while ( iterPic != rcListPic.end() )
  {
    TComPic* rpcPic = *(iterPic);
    if ( rpcPic->getSlice( 0 )->isReferenced() && rpcPic->getReconMark() ) 
    {
      iActualNumOfReference++;
    }
    iterPic++;
  }

  return iActualNumOfReference;
}
示例#8
0
TComPic* TComSlice::xGetRefPic(PicList& picList, int poc)
{
    TComPic *iterPic = picList.first();
    TComPic* pic = NULL;

    while (iterPic)
    {
        pic = iterPic;
        if (pic->getPOC() == poc)
        {
            break;
        }
        iterPic = iterPic->m_next;
    }

    return pic;
}
示例#9
0
/** Function for marking reference pictures with higher temporal layer IDs as not used if the current picture is a temporal layer switching point.
 * \param rcListPic List of picture buffers
 * Both the encoder and decoder call this function to mark reference pictures with temporal layer ID higher than current picture's temporal layer ID as not used.
 */
Void TComSlice::decodingTLayerSwitchingMarking( TComList<TComPic*>& rcListPic )
{
  TComPic* rpcPic;
  if ( m_bTLayerSwitchingFlag ) 
  {
    // mark all pictures of temporal layer > m_uiTLyr as not used for reference
    TComList<TComPic*>::iterator iterPic = rcListPic.begin();
    while ( iterPic != rcListPic.end() )
    {
      rpcPic = *(iterPic);
      if ( rpcPic->getTLayer() > m_uiTLayer ) 
      {
        rpcPic->getSlice( 0 )->setReferenced( false );
      }
      iterPic++;
    }
  }
}
示例#10
0
Void TDecTop::checkNoOutputPriorPics (TComList<TComPic*>* pcListPic)
{
    if (!pcListPic || !m_isNoOutputPriorPics)
    {
        return;
    }

    TComList<TComPic*>::iterator  iterPic   = pcListPic->begin();

    while (iterPic != pcListPic->end())
    {
        TComPic* pcPicTmp = *(iterPic++);
        if (m_lastPOCNoOutputPriorPics != pcPicTmp->getPOC())
        {
            pcPicTmp->setOutputMark(false);
        }
    }
}
示例#11
0
TComPic* TComSlice::xGetLongTermRefPic(PicList& picList, int poc, bool pocHasMsb)
{
    TComPic* iterPic = picList.first();
    TComPic* pic = iterPic;
    TComPic* stPic = pic;

    int pocCycle = 1 << getSPS()->getBitsForPOC();

    if (!pocHasMsb)
    {
        poc = poc % pocCycle;
    }

    while (iterPic)
    {
        pic = iterPic;
        if (pic && pic->getPOC() != this->getPOC() && pic->getSlice()->isReferenced())
        {
            int picPoc = pic->getPOC();
            if (!pocHasMsb)
            {
                picPoc = picPoc % pocCycle;
            }

            if (poc == picPoc)
            {
                if (pic->getIsLongTerm())
                {
                    return pic;
                }
                else
                {
                    stPic = pic;
                }
                break;
            }
        }

        iterPic = iterPic->m_next;
    }

    return stPic;
}
示例#12
0
/**
 - Application has picture buffer list with size of GOP + 1
 - Picture buffer list acts like as ring buffer
 - End of the list has the latest picture
 .
 \param   flush               cause encoder to encode a partial GOP
 \param   pcPicYuvOrg         original YUV picture
 \param   pcPicYuvTrueOrg     
 \param   snrCSC
 \retval  rcListPicYuvRecOut  list of reconstruction YUV pictures
 \retval  accessUnitsOut      list of output access units
 \retval  iNumEncoded         number of encoded pictures
 */
Void TEncTop::encode( Bool flush, TComPicYuv* pcPicYuvOrg, TComPicYuv* pcPicYuvTrueOrg, const InputColourSpaceConversion snrCSC, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsOut, Int& iNumEncoded )
{
  if (pcPicYuvOrg != NULL)
  {
    // get original YUV
    TComPic* pcPicCurr = NULL;

    xGetNewPicBuffer( pcPicCurr );
    pcPicYuvOrg->copyToPic( pcPicCurr->getPicYuvOrg() );
    pcPicYuvTrueOrg->copyToPic( pcPicCurr->getPicYuvTrueOrg() );

    // compute image characteristics
    if ( getUseAdaptiveQP() )
    {
      m_cPreanalyzer.xPreanalyze( dynamic_cast<TEncPic*>( pcPicCurr ) );
    }
  }

  if ((m_iNumPicRcvd == 0) || (!flush && (m_iPOCLast != 0) && (m_iNumPicRcvd != m_iGOPSize) && (m_iGOPSize != 0)))
  {
    iNumEncoded = 0;
    return;
  }

  if ( m_RCEnableRateControl )
  {
    m_cRateCtrl.initRCGOP( m_iNumPicRcvd );
  }

  
  // compress GOP
  m_cGOPEncoder.compressGOP(m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, accessUnitsOut, false, false, snrCSC, m_printFrameMSE,&m_cSearch);

  if ( m_RCEnableRateControl )
  {
    m_cRateCtrl.destroyRCGOP();
  }

  iNumEncoded         = m_iNumPicRcvd;
  m_iNumPicRcvd       = 0;
  m_uiNumAllPicCoded += iNumEncoded;
}
示例#13
0
文件: dpb.cpp 项目: roman5566/x265
// move unreferenced pictures from picList to freeList for recycle
void DPB::recycleUnreferenced(PicList& freeList)
{
    TComPic *iterPic = m_picList.first();

    while (iterPic)
    {
        TComPic *pic = iterPic;
        iterPic = iterPic->m_next;
        if (pic->getSlice()->isReferenced() == false && pic->m_countRefEncoders == 0)
        {
            pic->m_reconRowCount = 0;

            // iterator is invalidated by remove, restart scan
            m_picList.remove(*pic);
            iterPic = m_picList.first();

            freeList.pushBack(*pic);
        }
    }
}
示例#14
0
Void TDecTop::deletePicBuffer ( )
{
    TComList<TComPic*>::iterator  iterPic   = m_cListPic.begin();
    Int iSize = Int( m_cListPic.size() );

    for (Int i = 0; i < iSize; i++ )
    {
        TComPic* pcPic = *(iterPic++);
        pcPic->destroy();

        delete pcPic;
        pcPic = NULL;
    }

    m_cSAO.destroy();

    m_cLoopFilter.        destroy();

    // destroy ROM
    destroyROM();
}
示例#15
0
Void TDecTop::executeLoopFilters(Int& poc, TComList<TComPic*>*& rpcListPic)
{
    if (!m_pcPic)
    {
        /* nothing to deblock */
        return;
    }

    TComPic*   pcPic         = m_pcPic;

    // Execute Deblock + Cleanup

    m_cGopDecoder.filterPicture(pcPic);

    TComSlice::sortPicList( m_cListPic ); // sorting for application output
    poc                 = pcPic->getSlice(m_uiSliceIdx-1)->getPOC();
    rpcListPic          = &m_cListPic;
    m_cCuDecoder.destroy();
    m_bFirstSliceInPicture  = true;

    return;
}
示例#16
0
/** Function for mimicking decoder's reference picture buffer management.
 * \param rcListPic List of picture buffers
 * \param iGOPSIze Current GOP size
 * \param iMaxRefPicNum Maximum number of reference pictures allowed
 * The encoder calls this function to mimic the picture buffer management of the decoder in the function xGetNewPicBuffer.
 * This will ensure in the encoder that the pictures that does not exist in the decoder will not be used as reference.
 * TODO: This assumes that the new pics are added at the end of the list.
 *       This needs to be changed for the general case including for the long-term ref pics.
 *       In the future, we should create a single common function for both the encoder and decoder.
 */
Void TComSlice::decodingMarking( TComList<TComPic*>& rcListPic, Int iGOPSIze, Int& iMaxRefPicNum )
{
  Int iActualNumOfReference = 0;

  TComList<TComPic*>::iterator iterPic = rcListPic.begin();
  while ( iterPic != rcListPic.end() )
  {
    TComPic* rpcPic = *(iterPic);
    if ( rpcPic->getSlice( 0 )->isReferenced() ) 
    {
      if ( rpcPic != getPic() )
      {
        iActualNumOfReference++;
      }
    }
    iterPic++;
  }

  // TODO: This assumes that the new pics are added at the end of the list
  // This needs to be changed for the general case including for the long-term ref pics
  iMaxRefPicNum = max(iMaxRefPicNum, max(max(2, getNumRefIdx(REF_PIC_LIST_0)+1), iGOPSIze/2 + 2 + getNumRefIdx(REF_PIC_LIST_0)));
  if ( iActualNumOfReference >= iMaxRefPicNum )
  {
    Int iNumToBeReset = iActualNumOfReference - iMaxRefPicNum + 1;

    iterPic = rcListPic.begin();
    while ( iterPic != rcListPic.end() && iNumToBeReset > 0 )
    {
      TComPic* rpcPic = *(iterPic);
      if ( rpcPic->getSlice( 0 )->isReferenced() ) 
      {
        rpcPic->getSlice( 0 )->setReferenced( false );
        iNumToBeReset--;
      }
      iterPic++;
    }
  }
}
示例#17
0
/** Function for marking the reference pictures when an IDR/CRA/CRANT/BLA/BLANT is encountered.
 * \param pocCRA POC of the CRA/CRANT/BLA/BLANT picture
 * \param bRefreshPending flag indicating if a deferred decoding refresh is pending
 * \param picList reference to the reference picture list
 * This function marks the reference pictures as "unused for reference" in the following conditions.
 * If the nal_unit_type is IDR/BLA/BLANT, all pictures in the reference picture list
 * are marked as "unused for reference"
 *    If the nal_unit_type is BLA/BLANT, set the pocCRA to the temporal reference of the current picture.
 * Otherwise
 *    If the bRefreshPending flag is true (a deferred decoding refresh is pending) and the current
 *    temporal reference is greater than the temporal reference of the latest CRA/CRANT/BLA/BLANT picture (pocCRA),
 *    mark all reference pictures except the latest CRA/CRANT/BLA/BLANT picture as "unused for reference" and set
 *    the bRefreshPending flag to false.
 *    If the nal_unit_type is CRA/CRANT, set the bRefreshPending flag to true and pocCRA to the temporal
 *    reference of the current picture.
 * Note that the current picture is already placed in the reference list and its marking is not changed.
 * If the current picture has a nal_ref_idc that is not 0, it will remain marked as "used for reference".
 */
void DPB::decodingRefreshMarking(int pocCurr, NalUnitType nalUnitType)
{
    if (nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_LP
        || nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_RADL
        || nalUnitType == NAL_UNIT_CODED_SLICE_BLA_N_LP
        || nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL
        || nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP) // IDR or BLA picture
    {
        // mark all pictures as not used for reference
        TComPic* iterPic = m_picList.first();
        while (iterPic)
        {
            if (iterPic->getPOC() != pocCurr)
                iterPic->getSlice()->setReferenced(false);
            iterPic = iterPic->m_next;
        }

        if (nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_LP
            || nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_RADL
            || nalUnitType == NAL_UNIT_CODED_SLICE_BLA_N_LP)
        {
            m_pocCRA = pocCurr;
        }
    }
    else // CRA or No DR
    {
        if (m_bRefreshPending == true && pocCurr > m_pocCRA) // CRA reference marking pending
        {
            TComPic* iterPic = m_picList.first();
            while (iterPic)
            {
                if (iterPic->getPOC() != pocCurr && iterPic->getPOC() != m_pocCRA)
                    iterPic->getSlice()->setReferenced(false);
                iterPic = iterPic->m_next;
            }

            m_bRefreshPending = false;
        }
        if (nalUnitType == NAL_UNIT_CODED_SLICE_CRA) // CRA picture found
        {
            m_bRefreshPending = true;
            m_pocCRA = pocCurr;
        }
    }
}
示例#18
0
/** Function for marking the reference pictures when an IDR and CDR is encountered.
 * \param uiPOCCDR POC of the CDR picture
 * \param bRefreshPending flag indicating if a deferred decoding refresh is pending
 * \param rcListPic reference to the reference picture list
 * This function marks the reference pictures as "unused for reference" in the following conditions.
 * If the nal_unit_type is IDR all pictures in the reference picture list  
 * is marked as "unused for reference" 
 * Otherwise do for the CDR case (non CDR case has no effect since both if conditions below will not be true)
 *    If the bRefreshPending flag is true (a deferred decoding refresh is pending) and the current 
 *    temporal reference is greater than the temporal reference of the latest CDR picture (uiPOCCDR), 
 *    mark all reference pictures except the latest CDR picture as "unused for reference" and set 
 *    the bRefreshPending flag to false.
 *    If the nal_unit_type is CDR, set the bRefreshPending flag to true and iPOCCDR to the temporal 
 *    reference of the current picture.
 * Note that the current picture is already placed in the reference list and its marking is not changed.
 * If the current picture has a nal_ref_idc that is not 0, it will remain marked as "used for reference".
 */
Void TComSlice::decodingRefreshMarking(UInt& uiPOCCDR, Bool& bRefreshPending, TComList<TComPic*>& rcListPic)
{
  TComPic*                 rpcPic;
  UInt uiPOCCurr = getPOC(); 

  if (getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR)  // IDR
  {
    // mark all pictures as not used for reference
    TComList<TComPic*>::iterator        iterPic       = rcListPic.begin();
    while (iterPic != rcListPic.end())
    {
      rpcPic = *(iterPic);
      rpcPic->setCurrSliceIdx(0);
      if (rpcPic->getPOC() != uiPOCCurr) rpcPic->getSlice(0)->setReferenced(false);
      iterPic++;
    }
  }
  else // CDR or No DR
  {
    if (bRefreshPending==true && uiPOCCurr > uiPOCCDR) // CDR reference marking pending 
    {
      TComList<TComPic*>::iterator        iterPic       = rcListPic.begin();
      while (iterPic != rcListPic.end())
      {
        rpcPic = *(iterPic);
        if (rpcPic->getPOC() != uiPOCCurr && rpcPic->getPOC() != uiPOCCDR) rpcPic->getSlice(0)->setReferenced(false);
        iterPic++;
      }
      bRefreshPending = false; 
    }
    if (getNalUnitType() == NAL_UNIT_CODED_SLICE_CDR) // CDR picture found
    {
      bRefreshPending = true; 
      uiPOCCDR = uiPOCCurr;
    }
  }
}
示例#19
0
Void  TComSlice::sortPicList        (TComList<TComPic*>& rcListPic)
{
  TComPic*    pcPicExtract;
  TComPic*    pcPicInsert;
  
  TComList<TComPic*>::iterator    iterPicExtract;
  TComList<TComPic*>::iterator    iterPicExtract_1;
  TComList<TComPic*>::iterator    iterPicInsert;
  
  for (Int i = 1; i < (Int)(rcListPic.size()); i++)
  {
    iterPicExtract = rcListPic.begin();
    for (Int j = 0; j < i; j++) iterPicExtract++;
    pcPicExtract = *(iterPicExtract);
    pcPicExtract->setCurrSliceIdx(0);
    
    iterPicInsert = rcListPic.begin();
    while (iterPicInsert != iterPicExtract)
    {
      pcPicInsert = *(iterPicInsert);
      pcPicInsert->setCurrSliceIdx(0);
      if (pcPicInsert->getPOC() >= pcPicExtract->getPOC())
      {
        break;
      }
      
      iterPicInsert++;
    }
    
    iterPicExtract_1 = iterPicExtract;    iterPicExtract_1++;
    
    //  swap iterPicExtract and iterPicInsert, iterPicExtract = curr. / iterPicInsert = insertion position
    rcListPic.insert (iterPicInsert, iterPicExtract, iterPicExtract_1);
    rcListPic.erase  (iterPicExtract);
  }
}
示例#20
0
Void derivePGRPLT(TComDataCU* pcCtu)
{
	TComPic* pcPic = pcCtu->getPic();
	TComPicYuv* pcOrgYuv = pcPic->getPicYuvOrg();
	UInt uiNumValidComponents = pcOrgYuv->getNumberValidComponents();

	UInt uiMaxCUWidth = pcCtu->getSlice()->getSPS()->getMaxCUWidth();
	UInt uiMaxCUHeight = pcCtu->getSlice()->getSPS()->getMaxCUWidth();

	for (UInt ch = 0; ch < uiNumValidComponents; ch++)
	{
		ComponentID cId = ComponentID(ch);

		UInt uiPicWidth = pcOrgYuv->getWidth(cId);
		UInt uiPicHeight = pcOrgYuv->getHeight(cId);
		UInt uiStride = pcOrgYuv->getStride(cId);

		UInt uiCUPelX = pcCtu->getCUPelX() >> (pcOrgYuv->getComponentScaleX(cId));			// x of upper left corner of the cu
		UInt uiCUPelY = pcCtu->getCUPelY() >> (pcOrgYuv->getComponentScaleY(cId));;			// y of upper left corner of the

		UInt uiCBWidth = uiMaxCUWidth >> (pcOrgYuv->getComponentScaleX(cId));
		UInt uiCBHeight = uiMaxCUHeight >> (pcOrgYuv->getComponentScaleY(cId));

		uiCBWidth = Clip3((UInt)0, uiPicWidth - uiCUPelX, uiCBWidth);
		uiCBHeight = Clip3((UInt)0, uiPicHeight - uiCUPelY, uiCBHeight);

		// statistics

		PelCount* pPixelCount[256];
		for (int i = 0; i < 256; i++)
			pPixelCount[i] = new PelCount(i);

		Pel* pOrg = pcOrgYuv->getAddr(cId, pcCtu->getCtuRsAddr());
		for (UInt uiY = 0; uiY < uiCBHeight; uiY++)
		{
			for (UInt uiX = 0; uiX < uiCBWidth; uiX++)
			{
				pPixelCount[pOrg[uiX]]->m_uiCount++;
			}

			pOrg += uiStride;
		}

		// sort
		sort(pPixelCount, pPixelCount + 256, cmpPelCount);

		g_ppCTUPalette[cId].m_uiSize = 0;
		// insert entry
		for (int i = 0, k = 0; k < 4; i++)
		{
			bool bDuplicate = false;
			for (int j = 0; j < 4; j++)
			{
				// duplicate
				if (g_ppCTUPalette[cId].m_pEntry[i] == g_ppPalette[cId].m_pEntry[j])
				{
					bDuplicate = true;
					break;
				}
			}
			if (!bDuplicate)
			{
				g_ppCTUPalette[cId].m_pEntry[k++] = pPixelCount[i]->m_uiVal;
				g_ppCTUPalette[cId].m_uiSize++;
			}
		}
		for (int i = 0; i < 256; i++)
			delete pPixelCount[i];
	}
}
/** \param pcListPic list of pictures to be written to file
    \todo            DYN_REF_FREE should be revised
 */
Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic, Int viewDepthId )
{
  if(!pcListPic)
  {
    return;
  } 
  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();

  iterPic   = pcListPic->begin();
  
  while (iterPic != pcListPic->end())
  {
    TComPic* pcPic = *(iterPic);
    TComSPS *sps = pcPic->getSlice(0)->getSPS();

    if ( pcPic->getOutputMark() )
    {
      // write to file
      if ( m_pchReconFile )
      {
        m_tVideoIOYuvReconFile[viewDepthId]->write( pcPic->getPicYuvRec(), sps->getPicCropLeftOffset(), sps->getPicCropRightOffset(), sps->getPicCropTopOffset(), sps->getPicCropBottomOffset() );
      }
      
      // update POC of display order
      m_pocLastDisplay[viewDepthId] = pcPic->getPOC();
      
      // erase non-referenced picture in the reference picture list after display
      if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
      {
#if !DYN_REF_FREE
        pcPic->setReconMark(false);
        
        // mark it should be extended later
        pcPic->getPicYuvRec()->setBorderExtension( false );
        
#else
        pcPic->destroy();
        pcListPic->erase( iterPic );
        iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
        continue;
#endif
      }
      pcPic->setOutputMark(false);
    }
    
    iterPic++;
  }
  pcListPic->clear();
  m_pocLastDisplay[viewDepthId] = -MAX_INT;
}
示例#22
0
Void matchTemplate(TComDataCU*& rpcTempCU, Pixel** ppPixel)
{
	// template matching
	UInt uiCUPelX = rpcTempCU->getCUPelX();			// x of upper left corner of the cu
	UInt uiCUPelY = rpcTempCU->getCUPelY();			// y of upper left corner of the cu

	UInt uiMaxCUWidth = rpcTempCU->getSlice()->getSPS()->getMaxCUWidth();		// max cu width
	UInt uiMaxCUHeight = rpcTempCU->getSlice()->getSPS()->getMaxCUHeight();		// max cu height

	// pic
	TComPic* pcPic = rpcTempCU->getPic();
	TComPicYuv* pcPredYuv = pcPic->getPicYuvPred();
	TComPicYuv* pcResiYuv = pcPic->getPicYuvResi();

	UInt uiNumValidCopmonent = pcPic->getNumberValidComponents();

	vector<PixelTemplate> vInsertList;

	for (UInt ch = 0; ch < uiNumValidCopmonent; ch++)
	{
		int all = 0;
		int average = 0;
		int afind = 0;
		int maxfind = 0, minfind = INT_MAX;
		int ax = 0, ay = 0;
		int adiff = 0;

		ComponentID cId = ComponentID(ch);
		// picture description
		UInt uiStride = pcPredYuv->getStride(cId);									// stride for a certain component
		UInt uiPicWidth = pcPredYuv->getWidth(cId);									// picture width for a certain component
		UInt uiPicHeight = pcPredYuv->getHeight(cId);								// picture height for a certain component

		UInt uiCBWidth = uiMaxCUWidth >> (pcPredYuv->getComponentScaleX(cId));		// code block width for a certain component
		UInt uiCBHeight = uiMaxCUHeight >> (pcPredYuv->getComponentScaleY(cId));	// code block height for a certain component

		// rectangle of the code block
		UInt uiTopX = Clip3((UInt)0, uiPicWidth, uiCUPelX);
		UInt uiTopY = Clip3((UInt)0, uiPicHeight, uiCUPelY);
		UInt uiBottomX = Clip3((UInt)0, uiPicWidth, uiCUPelX + uiCBWidth);
		UInt uiBottomY = Clip3((UInt)0, uiPicHeight, uiCUPelY + uiCBHeight);


		for (UInt uiY = uiTopY; uiY < uiBottomY; uiY++)
		{
			for (UInt uiX = uiTopX; uiX < uiBottomX; uiX++)
			{
				UInt uiOrgX, uiOrgY;
				uiOrgX = g_auiRsmpldToOrg[cId][0][uiX];
				uiOrgY = g_auiRsmpldToOrg[cId][1][uiY];


				// template match
				UInt uiHashValue1, uiHashValue2;

				// get hash values
				getHashValue(uiOrgX, uiOrgY, uiPicWidth, ppPixel[cId],uiHashValue1,uiHashValue2);

				Pixel* pCurPixel = ppPixel[cId] + getSerialIndex(uiOrgX, uiOrgY, uiPicWidth);
				//pCurPixel->m_uiHashValue = uiHashValue1;

				assert(uiHashValue1 >= 0 && uiHashValue1 < MAX_PT_NUM);
				
				// lookup table
				PixelTemplate* pLookupTable = g_pLookupTable[cId][uiHashValue1];
				// number of available template pixels
				UInt uiNumTemplate = getNumTemplate(uiOrgX, uiOrgY, uiPicWidth, ppPixel[cId]);

				// if uiNumTemplate < 1, predict target with default value and do not insert template
				if (uiNumTemplate < 1)
				{
					UInt uiIdx = uiY * uiStride + uiX;
					pcPredYuv->getAddr(cId)[uiIdx] = pCurPixel->m_uiPred;
					pcResiYuv->getAddr(cId)[uiIdx] = pCurPixel->m_iResi = pCurPixel->m_uiOrg - pCurPixel->m_uiPred;
					continue;
				}

				// if lookuptable is empty, predict target with default value and insert template
				if (pLookupTable == NULL)
				{
					//
					vInsertList.push_back(PixelTemplate(uiOrgX, uiOrgY, uiHashValue1,uiHashValue2,uiNumTemplate,NEW));
					UInt uiIdx = uiY*uiStride + uiX;
					pcPredYuv->getAddr(cId)[uiIdx] = pCurPixel->m_uiPred;
					pcResiYuv->getAddr(cId)[uiIdx] = pCurPixel->m_iResi = pCurPixel->m_uiOrg - pCurPixel->m_uiPred;
					continue;
				}

				MatchMetric mmBestMetric;
				UInt uiListLength = 0;
				PixelTemplate* pBestMatch = NULL;
				PixelTemplate* pPixelTemplate = pLookupTable;
#if PGR_DEBUG
				int length = 0;
				int a = 0;
				int find = 0;
				int fx = 0, fy = 0;
				int diff = 0;
#endif
				UInt uiRemoved = 0;
				// find best matched template
				while (pPixelTemplate != NULL)
				{
					UInt uiCX = pPixelTemplate->m_PX;
					UInt uiCY = pPixelTemplate->m_PY;
					MatchMetric mmTmp;
#if PGR_DEBUG
					length++;
#endif
					
					tryMatch(uiOrgX, uiOrgY, uiCX, uiCY, mmTmp, uiPicWidth, ppPixel[cId]);
					// set best matched template
					if (mmTmp.m_uiAbsDiff < mmBestMetric.m_uiAbsDiff || 
						(mmTmp.m_uiAbsDiff == mmBestMetric.m_uiAbsDiff)&&(mmTmp.m_uiNumValidPoints > mmBestMetric.m_uiNumValidPoints))
					{
						mmBestMetric = mmTmp;
						pBestMatch = pPixelTemplate;
						find = length; 
						fx = abs(int(uiOrgX - uiCX)) / 64;
						fy = abs(int(uiOrgY - uiCY)) / 64;
						diff = mmTmp.m_uiAbsDiff;

					}

					// replace useless template
					if (mmTmp.m_uiAbsDiff < INSERT_LIMIT && (uiNumTemplate > pPixelTemplate->m_uiNumTemplate || uiNumTemplate == 21) && pPixelTemplate->m_uiState != TO_BE_REMOVED)
					{
						pPixelTemplate->m_uiState = TO_BE_REMOVED;
						uiRemoved++;
					}

					pPixelTemplate = pPixelTemplate->m_pptNext;
				}

				// predict target with best matched candidate
				if (pBestMatch != NULL)
				{
					UInt uiCX = pBestMatch->m_PX;
					UInt uiCY = pBestMatch->m_PY;
					if ((ppPixel[cId] + getSerialIndex(uiCX, uiCY, uiPicWidth))->m_bIsRec)
					{
						pCurPixel->m_mmMatch = mmBestMetric;
						pBestMatch->m_uiNumUsed++;
						Pixel* pRefPixel = ppPixel[cId] + getSerialIndex(mmBestMetric.m_uiX, mmBestMetric.m_uiY, uiPicWidth);
						pCurPixel->m_uiPred = pRefPixel->m_uiReco;								// prediction
						pCurPixel->m_iResi = pCurPixel->m_uiOrg - pCurPixel->m_uiPred;			// residue
					}
				}
				
				// insert new template
				if (mmBestMetric.m_uiAbsDiff > INSERT_LIMIT)
					vInsertList.push_back(PixelTemplate(uiOrgX, uiOrgY, uiHashValue1,uiHashValue2,uiNumTemplate,NEW));
				// replace old template 
				if(uiNumTemplate < 21 && uiRemoved>0 
					|| uiNumTemplate == 21 && uiRemoved > 1)
					vInsertList.push_back(PixelTemplate(uiOrgX, uiOrgY, uiHashValue1, uiHashValue2, uiNumTemplate, DISPLACE));

				UInt uiIdx = uiY*uiStride + uiX;
				pcPredYuv->getAddr(cId)[uiIdx] = pCurPixel->m_uiPred;
				pcResiYuv->getAddr(cId)[uiIdx] = pCurPixel->m_iResi = pCurPixel->m_uiOrg - pCurPixel->m_uiPred;

#if PGR_DEBUG
				all += length;
				afind += find;
				ax += fx;
				ay += fy;
				adiff += diff;
				minfind = min(minfind, find);
				maxfind = max(maxfind, find);
#endif
			}// end for x
		}// end for y
		//fc.close();
#if PGR_DEBUG
		cout <<"search:" <<all / 4096 << endl;
		cout << "find:" << afind / 4096 << endl;
		cout << "max:" << maxfind << "\t" << "min:" << minfind << endl;
		cout << "x:" << ax/4096 << "\t" << "y:" << ay/4096 << endl;
		cout << "diff:" << adiff / 4096 << endl;
#endif


		// insert template
		for (vector<PixelTemplate>::iterator it = vInsertList.begin(); it != vInsertList.end(); it++)
		{
			UInt uiHashValue = it->m_uiHashValue1;
			if (it->m_uiState == DISPLACE)
			{
				PixelTemplate* p = g_pLookupTable[cId][uiHashValue];
				PixelTemplate* pre = NULL;
				while (p != NULL)
				{
					if (p->m_uiState == TO_BE_REMOVED)
					{
						PixelTemplate* q = p;
						if (pre == NULL)
						{
							g_pLookupTable[cId][uiHashValue] = p = p->m_pptNext;
						}
						else
						{
							pre->m_pptNext = p = p->m_pptNext;
						}
						delete q;
						q = NULL;
					}
					else
					{
						pre = p;
						p = p->m_pptNext;
					}
				}
			}

			it->m_uiState = NEW;
			PixelTemplate* pNewTemplate = new PixelTemplate(*it);
			pNewTemplate->m_pptNext = g_pLookupTable[cId][uiHashValue];
			g_pLookupTable[cId][uiHashValue] = pNewTemplate;
		}

		vInsertList.clear();
	}// end for ch
}
示例#23
0
文件: dpb.cpp 项目: roman5566/x265
/** Function for applying picture marking based on the Reference Picture Set in pReferencePictureSet */
void DPB::applyReferencePictureSet(TComReferencePictureSet *rps, int curPoc)
{
    TComPic* outPic;
    int i, isReference;

    // loop through all pictures in the reference picture buffer
    TComPic* iterPic = m_picList.first();

    while (iterPic)
    {
        outPic = iterPic;
        iterPic = iterPic->m_next;

        if (!outPic->getSlice()->isReferenced())
        {
            continue;
        }

        isReference = 0;
        // loop through all pictures in the Reference Picture Set
        // to see if the picture should be kept as reference picture
        for (i = 0; i < rps->getNumberOfPositivePictures() + rps->getNumberOfNegativePictures(); i++)
        {
            if (!outPic->getIsLongTerm() && outPic->getPicSym()->getSlice()->getPOC() == curPoc + rps->getDeltaPOC(i))
            {
                isReference = 1;
                outPic->setUsedByCurr(rps->getUsed(i) == 1);
                outPic->setIsLongTerm(0);
            }
        }

        for (; i < rps->getNumberOfPictures(); i++)
        {
            if (rps->getCheckLTMSBPresent(i) == true)
            {
                if (outPic->getIsLongTerm() && (outPic->getPicSym()->getSlice()->getPOC()) == rps->getPOC(i))
                {
                    isReference = 1;
                    outPic->setUsedByCurr(rps->getUsed(i) == 1);
                }
            }
            else
            {
                if (outPic->getIsLongTerm() && (outPic->getPicSym()->getSlice()->getPOC() %
                                                (1 << outPic->getPicSym()->getSlice()->getSPS()->getBitsForPOC())) == rps->getPOC(i) %
                    (1 << outPic->getPicSym()->getSlice()->getSPS()->getBitsForPOC()))
                {
                    isReference = 1;
                    outPic->setUsedByCurr(rps->getUsed(i) == 1);
                }
            }
        }

        // mark the picture as "unused for reference" if it is not in
        // the Reference Picture Set
        if (outPic->getPicSym()->getSlice()->getPOC() != curPoc && isReference == 0)
        {
            outPic->getSlice()->setReferenced(false);
            outPic->setUsedByCurr(0);
            outPic->setIsLongTerm(0);
        }
        // TODO: Do we require this check here
        // check that pictures of higher or equal temporal layer are not in the RPS if the current picture is a TSA picture

        /*if (this->getNalUnitType() == NAL_UNIT_CODED_SLICE_TLA_R || this->getNalUnitType() == NAL_UNIT_CODED_SLICE_TSA_N)
        {
            assert(outPic->getSlice()->isReferenced() == 0);
        }*/
    }
}
示例#24
0
/** \param pcListPic list of pictures to be written to file
    \todo            DYN_REF_FREE should be revised
 */
Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic )
{
  if(!pcListPic || pcListPic->empty())
  {
    return;
  }
  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();

  iterPic   = pcListPic->begin();
  TComPic* pcPic = *(iterPic);

  if (pcPic->isField()) //Field Decoding
  {
    TComList<TComPic*>::iterator endPic   = pcListPic->end();
    endPic--;
    TComPic *pcPicTop, *pcPicBottom = NULL;
    while (iterPic != endPic)
    {
      pcPicTop = *(iterPic);
      iterPic++;
      pcPicBottom = *(iterPic);

      if ( pcPicTop->getOutputMark() && pcPicBottom->getOutputMark() && !(pcPicTop->getPOC()%2) && (pcPicBottom->getPOC() == pcPicTop->getPOC()+1) )
      {
        // write to file
        if ( m_pchReconFile )
        {
          const Window &conf = pcPicTop->getConformanceWindow();
          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
          const Bool isTff = pcPicTop->isTopField();
          m_cTVideoIOYuvReconFile.write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
                                         m_outputColourSpaceConvert,
                                         conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
                                         conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
                                         conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
                                         conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), NUM_CHROMA_FORMAT, isTff );
        }

        // update POC of display order
        m_iPOCLastDisplay = pcPicBottom->getPOC();

        // erase non-referenced picture in the reference picture list after display
        if ( !pcPicTop->getSlice(0)->isReferenced() && pcPicTop->getReconMark() == true )
        {
#if !DYN_REF_FREE
          pcPicTop->setReconMark(false);

          // mark it should be extended later
          pcPicTop->getPicYuvRec()->setBorderExtension( false );

#else
          pcPicTop->destroy();
          pcListPic->erase( iterPic );
          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
          continue;
#endif
        }
        if ( !pcPicBottom->getSlice(0)->isReferenced() && pcPicBottom->getReconMark() == true )
        {
#if !DYN_REF_FREE
          pcPicBottom->setReconMark(false);

          // mark it should be extended later
          pcPicBottom->getPicYuvRec()->setBorderExtension( false );

#else
          pcPicBottom->destroy();
          pcListPic->erase( iterPic );
          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
          continue;
#endif
        }
        pcPicTop->setOutputMark(false);
        pcPicBottom->setOutputMark(false);

#if !DYN_REF_FREE
        if(pcPicTop)
        {
          pcPicTop->destroy();
          delete pcPicTop;
          pcPicTop = NULL;
        }
#endif
      }
    }
    if(pcPicBottom)
    {
      pcPicBottom->destroy();
      delete pcPicBottom;
      pcPicBottom = NULL;
    }
  }
  else //Frame decoding
  {
    while (iterPic != pcListPic->end())
    {
      pcPic = *(iterPic);

      if ( pcPic->getOutputMark() )
      {
        // write to file
        if ( m_pchReconFile )
        {
          const Window &conf    = pcPic->getConformanceWindow();
          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();

          m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
                                         m_outputColourSpaceConvert,
                                         conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
                                         conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
                                         conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
                                         conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
        }

        // update POC of display order
        m_iPOCLastDisplay = pcPic->getPOC();

        // erase non-referenced picture in the reference picture list after display
        if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
        {
  #if !DYN_REF_FREE
          pcPic->setReconMark(false);

          // mark it should be extended later
          pcPic->getPicYuvRec()->setBorderExtension( false );

  #else
          pcPic->destroy();
          pcListPic->erase( iterPic );
          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
          continue;
  #endif
        }
        pcPic->setOutputMark(false);
      }
  #if !DYN_REF_FREE
      if(pcPic != NULL)
      {
        pcPic->destroy();
        delete pcPic;
        pcPic = NULL;
      }
  #endif
      iterPic++;
    }
  }
  pcListPic->clear();
  m_iPOCLastDisplay = -MAX_INT;
}
示例#25
0
/** \param pcListPic list of pictures to be written to file
    \todo            DYN_REF_FREE should be revised
 */
Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, UInt tId )
{
  if (pcListPic->empty())
  {
    return;
  }

  TComList<TComPic*>::iterator iterPic   = pcListPic->begin();
  Int numPicsNotYetDisplayed = 0;
  Int dpbFullness = 0;
  TComSPS* activeSPS = m_cTDecTop.getActiveSPS();
  UInt numReorderPicsHighestTid;
  UInt maxDecPicBufferingHighestTid;
  UInt maxNrSublayers = activeSPS->getMaxTLayers();

  if(m_iMaxTemporalLayer == -1 || m_iMaxTemporalLayer >= maxNrSublayers)
  {
    numReorderPicsHighestTid = activeSPS->getNumReorderPics(maxNrSublayers-1);
    maxDecPicBufferingHighestTid =  activeSPS->getMaxDecPicBuffering(maxNrSublayers-1); 
  }
  else
  {
    numReorderPicsHighestTid = activeSPS->getNumReorderPics(m_iMaxTemporalLayer);
    maxDecPicBufferingHighestTid = activeSPS->getMaxDecPicBuffering(m_iMaxTemporalLayer); 
  }

  while (iterPic != pcListPic->end())
  {
    TComPic* pcPic = *(iterPic);
    if(pcPic->getOutputMark() && pcPic->getPOC() > m_iPOCLastDisplay)
    {
       numPicsNotYetDisplayed++;
      dpbFullness++;
    }
    else if(pcPic->getSlice( 0 )->isReferenced())
    {
      dpbFullness++;
    }
    iterPic++;
  }

  iterPic = pcListPic->begin();

  if (numPicsNotYetDisplayed>2)
  {
    iterPic++;
  }

  TComPic* pcPic = *(iterPic);
  if (numPicsNotYetDisplayed>2 && pcPic->isField()) //Field Decoding
  {
    TComList<TComPic*>::iterator endPic   = pcListPic->end();
    endPic--;
    iterPic   = pcListPic->begin();
    while (iterPic != endPic)
    {
      TComPic* pcPicTop = *(iterPic);
      iterPic++;
      TComPic* pcPicBottom = *(iterPic);

      if ( pcPicTop->getOutputMark() && pcPicBottom->getOutputMark() &&
          (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid) &&
          (!(pcPicTop->getPOC()%2) && pcPicBottom->getPOC() == pcPicTop->getPOC()+1) &&
          (pcPicTop->getPOC() == m_iPOCLastDisplay+1 || m_iPOCLastDisplay < 0))
      {
        // write to file
        numPicsNotYetDisplayed = numPicsNotYetDisplayed-2;
        if ( m_pchReconFile )
        {
          const Window &conf = pcPicTop->getConformanceWindow();
          const Window &defDisp = m_respectDefDispWindow ? pcPicTop->getDefDisplayWindow() : Window();
          const Bool isTff = pcPicTop->isTopField();

          Bool display = true;
          if( m_decodedNoDisplaySEIEnabled )
          {
            SEIMessages noDisplay = getSeisByType(pcPic->getSEIs(), SEI::NO_DISPLAY );
            const SEINoDisplay *nd = ( noDisplay.size() > 0 ) ? (SEINoDisplay*) *(noDisplay.begin()) : NULL;
            if( (nd != NULL) && nd->m_noDisplay )
            {
              display = false;
            }
          }

          if (display)
          {
            m_cTVideoIOYuvReconFile.write( pcPicTop->getPicYuvRec(), pcPicBottom->getPicYuvRec(),
                                           m_outputColourSpaceConvert,
                                           conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
                                           conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
                                           conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
                                           conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), NUM_CHROMA_FORMAT, isTff );
          }
        }

        // update POC of display order
        m_iPOCLastDisplay = pcPicBottom->getPOC();

        // erase non-referenced picture in the reference picture list after display
        if ( !pcPicTop->getSlice(0)->isReferenced() && pcPicTop->getReconMark() == true )
        {
#if !DYN_REF_FREE
          pcPicTop->setReconMark(false);

          // mark it should be extended later
          pcPicTop->getPicYuvRec()->setBorderExtension( false );

#else
          pcPicTop->destroy();
          pcListPic->erase( iterPic );
          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
          continue;
#endif
        }
        if ( !pcPicBottom->getSlice(0)->isReferenced() && pcPicBottom->getReconMark() == true )
        {
#if !DYN_REF_FREE
          pcPicBottom->setReconMark(false);

          // mark it should be extended later
          pcPicBottom->getPicYuvRec()->setBorderExtension( false );

#else
          pcPicBottom->destroy();
          pcListPic->erase( iterPic );
          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
          continue;
#endif
        }
        pcPicTop->setOutputMark(false);
        pcPicBottom->setOutputMark(false);
      }
    }
  }
  else if (!pcPic->isField()) //Frame Decoding
  {
    iterPic = pcListPic->begin();

    while (iterPic != pcListPic->end())
    {
      pcPic = *(iterPic);

      if(pcPic->getOutputMark() && pcPic->getPOC() > m_iPOCLastDisplay &&
        (numPicsNotYetDisplayed >  numReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid))
      {
        // write to file
         numPicsNotYetDisplayed--;
        if(pcPic->getSlice(0)->isReferenced() == false)
        {
          dpbFullness--;
        }

        if ( m_pchReconFile )
        {
          const Window &conf    = pcPic->getConformanceWindow();
          const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();

          m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
                                         m_outputColourSpaceConvert,
                                         conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
                                         conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
                                         conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
                                         conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
        }

        // update POC of display order
        m_iPOCLastDisplay = pcPic->getPOC();

        // erase non-referenced picture in the reference picture list after display
        if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
        {
#if !DYN_REF_FREE
          pcPic->setReconMark(false);

          // mark it should be extended later
          pcPic->getPicYuvRec()->setBorderExtension( false );

#else
          pcPic->destroy();
          pcListPic->erase( iterPic );
          iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
          continue;
#endif
        }
        pcPic->setOutputMark(false);
      }

      iterPic++;
    }
  }
}
示例#26
0
Void TEncTop::encode(Bool flush, TComPicYuv* pcPicYuvOrg, TComPicYuv* pcPicYuvTrueOrg, const InputColourSpaceConversion snrCSC, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsOut, Int& iNumEncoded, Bool isTff)
{
  iNumEncoded = 0;

  for (Int fieldNum=0; fieldNum<2; fieldNum++)
  {
    if (pcPicYuvOrg)
    {

      /* -- field initialization -- */
      const Bool isTopField=isTff==(fieldNum==0);

      TComPic *pcField;
      xGetNewPicBuffer( pcField );
      pcField->setReconMark (false);                     // where is this normally?

      if (fieldNum==1)                                   // where is this normally?
      {
        TComPicYuv* rpcPicYuvRec;

        // org. buffer
        if ( rcListPicYuvRecOut.size() >= (UInt)m_iGOPSize+1 ) // need to maintain field 0 in list of RecOuts while processing field 1. Hence +1 on m_iGOPSize.
        {
          rpcPicYuvRec = rcListPicYuvRecOut.popFront();
        }
        else
        {
          rpcPicYuvRec = new TComPicYuv;
          rpcPicYuvRec->create( m_iSourceWidth, m_iSourceHeight, m_chromaFormatIDC, m_maxCUWidth, m_maxCUHeight, m_maxTotalCUDepth, true);
        }
        rcListPicYuvRecOut.pushBack( rpcPicYuvRec );
      }

      pcField->getSlice(0)->setPOC( m_iPOCLast );        // superfluous?
      pcField->getPicYuvRec()->setBorderExtension(false);// where is this normally?

      pcField->setTopField(isTopField);                  // interlaced requirement

      for (UInt componentIndex = 0; componentIndex < pcPicYuvOrg->getNumberValidComponents(); componentIndex++)
      {
        const ComponentID component = ComponentID(componentIndex);
        const UInt stride = pcPicYuvOrg->getStride(component);

        separateFields((pcPicYuvOrg->getBuf(component) + pcPicYuvOrg->getMarginX(component) + (pcPicYuvOrg->getMarginY(component) * stride)),
                       pcField->getPicYuvOrg()->getAddr(component),
                       pcPicYuvOrg->getStride(component),
                       pcPicYuvOrg->getWidth(component),
                       pcPicYuvOrg->getHeight(component),
                       isTopField);

        separateFields((pcPicYuvTrueOrg->getBuf(component) + pcPicYuvTrueOrg->getMarginX(component) + (pcPicYuvTrueOrg->getMarginY(component) * stride)),
                       pcField->getPicYuvTrueOrg()->getAddr(component),
                       pcPicYuvTrueOrg->getStride(component),
                       pcPicYuvTrueOrg->getWidth(component),
                       pcPicYuvTrueOrg->getHeight(component),
                       isTopField);
      }

      // compute image characteristics
      if ( getUseAdaptiveQP() )
      {
        m_cPreanalyzer.xPreanalyze( dynamic_cast<TEncPic*>( pcField ) );
      }
    }

    if ( m_iNumPicRcvd && ((flush&&fieldNum==1) || (m_iPOCLast/2)==0 || m_iNumPicRcvd==m_iGOPSize ) )
    {
      // compress GOP
      m_cGOPEncoder.compressGOP(m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, accessUnitsOut, true, isTff, snrCSC, m_printFrameMSE,&m_cSearch);

      iNumEncoded += m_iNumPicRcvd;
      m_uiNumAllPicCoded += m_iNumPicRcvd;
      m_iNumPicRcvd = 0;
    }
  }
}
示例#27
0
/** Function for applying picture marking based on the Reference Picture Set in pReferencePictureSet */
void DPB::applyReferencePictureSet(TComReferencePictureSet *rps, int curPoc)
{
    TComPic* outPic;
    int i, isReference;

    // loop through all pictures in the reference picture buffer
    TComPic* iterPic = m_picList.first();

    while (iterPic)
    {
        outPic = iterPic;
        iterPic = iterPic->m_next;

        if (!outPic->getSlice()->isReferenced())
        {
            continue;
        }

        isReference = 0;
        // loop through all pictures in the Reference Picture Set
        // to see if the picture should be kept as reference picture
        for (i = 0; i < rps->getNumberOfPositivePictures() + rps->getNumberOfNegativePictures(); i++)
        {
            if (!outPic->getIsLongTerm() && outPic->getPicSym()->getSlice()->getPOC() == curPoc + rps->getDeltaPOC(i))
            {
                isReference = 1;
                outPic->setUsedByCurr(rps->getUsed(i) == 1);
                outPic->setIsLongTerm(0);
            }
        }

        for (; i < rps->getNumberOfPictures(); i++)
        {
            if (rps->getCheckLTMSBPresent(i) == true)
            {
                if (outPic->getIsLongTerm() && (outPic->getPicSym()->getSlice()->getPOC()) == rps->getPOC(i))
                {
                    isReference = 1;
                    outPic->setUsedByCurr(rps->getUsed(i) == 1);
                }
            }
            else
            {
                if (outPic->getIsLongTerm() && (outPic->getPicSym()->getSlice()->getPOC() %
                                                (1 << outPic->getPicSym()->getSlice()->getSPS()->getBitsForPOC())) == rps->getPOC(i) %
                    (1 << outPic->getPicSym()->getSlice()->getSPS()->getBitsForPOC()))
                {
                    isReference = 1;
                    outPic->setUsedByCurr(rps->getUsed(i) == 1);
                }
            }
        }

        // mark the picture as "unused for reference" if it is not in
        // the Reference Picture Set
        if (outPic->getPicSym()->getSlice()->getPOC() != curPoc && isReference == 0)
        {
            outPic->getSlice()->setReferenced(false);
            outPic->setUsedByCurr(0);
            outPic->setIsLongTerm(0);
        }
    }
}
示例#28
0
TComPic* TComSlice::xGetRefPic (TComList<TComPic*>& rcListPic,
                                Bool                bDRBFlag,
                                ERBIndex            eERBIndex,
                                UInt                uiPOCCurr,
                                RefPicList          eRefPicList,
                                UInt                uiNthRefPic,
                                UInt                uiTLayer)
{
  //  find current position
  TComList<TComPic*>::iterator  iterPic = rcListPic.begin();
  TComPic*                      pcRefPic   = NULL;
  
  TComPic*                      pcPic = *(iterPic);
  while ( (pcPic->getPOC() != (Int)uiPOCCurr) && (iterPic != rcListPic.end()) )
  {
    iterPic++;
    pcPic = *(iterPic);
  }
  assert (pcPic->getPOC() == (Int)uiPOCCurr);
  
  //  find n-th reference picture with bDRBFlag and eERBIndex
  UInt  uiCount = 0;
  
  if( eRefPicList == REF_PIC_LIST_0 )
  {
    while(1)
    {
      if (iterPic == rcListPic.begin())
        break;
      
      iterPic--;
      pcPic = *(iterPic);
      if( ( !pcPic->getReconMark()                        ) ||
          ( bDRBFlag  != pcPic->getSlice(0)->getDRBFlag()  ) ||
          ( eERBIndex != pcPic->getSlice(0)->getERBIndex() ) )
        continue;
      
      if( !pcPic->getSlice(0)->isReferenced() )
        continue;
      
      if ( pcPic->getTLayer() > uiTLayer )
        continue;
      
      uiCount++;
      if (uiCount == uiNthRefPic)
      {
        pcRefPic = pcPic;
        return  pcRefPic;
      }
    }
    
    if ( !m_pcSPS->getUseLDC() )
    {
      
      iterPic = rcListPic.begin();
      pcPic = *(iterPic);
      while ( (pcPic->getPOC() != (Int)uiPOCCurr) && (iterPic != rcListPic.end()) )
      {
        iterPic++;
        pcPic = *(iterPic);
      }
      assert (pcPic->getPOC() == (Int)uiPOCCurr);
      
      while(1)
      {
        iterPic++;
        if (iterPic == rcListPic.end())
          break;
        
        pcPic = *(iterPic);
        if( ( !pcPic->getReconMark()                        ) ||
          ( bDRBFlag  != pcPic->getSlice(0)->getDRBFlag()  ) ||
          ( eERBIndex != pcPic->getSlice(0)->getERBIndex() ) )
          continue;
        
      if( !pcPic->getSlice(0)->isReferenced() )
          continue;
      
        if ( pcPic->getTLayer() > uiTLayer )
          continue;

        uiCount++;
        if (uiCount == uiNthRefPic)
        {
          pcRefPic = pcPic;
          return  pcRefPic;
        }
      }
    }
  }
  else
  {
    while(1)
    {
      iterPic++;
      if (iterPic == rcListPic.end())
        break;
      
      pcPic = *(iterPic);
      if( ( !pcPic->getReconMark()                        ) ||
          ( bDRBFlag  != pcPic->getSlice(0)->getDRBFlag()  ) ||
          ( eERBIndex != pcPic->getSlice(0)->getERBIndex() ) )
        continue;
      
      if( !pcPic->getSlice(0)->isReferenced() )
        continue;
      
      if ( pcPic->getTLayer() > uiTLayer )
        continue;

      uiCount++;
      if (uiCount == uiNthRefPic)
      {
        pcRefPic = pcPic;
        return  pcRefPic;
      }
    }
    
    iterPic = rcListPic.begin();
    pcPic = *(iterPic);
    while ( (pcPic->getPOC() != (Int)uiPOCCurr) && (iterPic != rcListPic.end()) )
    {
      iterPic++;
      pcPic = *(iterPic);
    }
    assert (pcPic->getPOC() == (Int)uiPOCCurr);
    
    while(1)
    {
      if (iterPic == rcListPic.begin())
        break;
      
      iterPic--;
      pcPic = *(iterPic);
      if( ( !pcPic->getReconMark()                        ) ||
          ( bDRBFlag  != pcPic->getSlice(0)->getDRBFlag()  ) ||
          ( eERBIndex != pcPic->getSlice(0)->getERBIndex() ) )
        continue;
      
      if( !pcPic->getSlice(0)->isReferenced() )
        continue;
      
      if ( pcPic->getTLayer() > uiTLayer )
        continue;

      uiCount++;
      if (uiCount == uiNthRefPic)
      {
        pcRefPic = pcPic;
        return  pcRefPic;
      }
    }
  }
  
  return  pcRefPic;
}
示例#29
0
// Function will arrange the long-term pictures in the decreasing order of poc_lsb_lt,
// and among the pictures with the same lsb, it arranges them in increasing delta_poc_msb_cycle_lt value
void DPB::arrangeLongtermPicturesInRPS(TComSlice *slice)
{
    TComReferencePictureSet *rps = slice->getRPS();

    if (!rps->getNumberOfLongtermPictures())
    {
        return;
    }

    // Arrange long-term reference pictures in the correct order of LSB and MSB,
    // and assign values for pocLSBLT and MSB present flag
    int longtermPicsPoc[MAX_NUM_REF_PICS], longtermPicsLSB[MAX_NUM_REF_PICS], indices[MAX_NUM_REF_PICS];
    int longtermPicsMSB[MAX_NUM_REF_PICS];
    bool mSBPresentFlag[MAX_NUM_REF_PICS];
    ::memset(longtermPicsPoc, 0, sizeof(longtermPicsPoc));  // Store POC values of LTRP
    ::memset(longtermPicsLSB, 0, sizeof(longtermPicsLSB));  // Store POC LSB values of LTRP
    ::memset(longtermPicsMSB, 0, sizeof(longtermPicsMSB));  // Store POC LSB values of LTRP
    ::memset(indices, 0, sizeof(indices));                  // Indices to aid in tracking sorted LTRPs
    ::memset(mSBPresentFlag, 0, sizeof(mSBPresentFlag));    // Indicate if MSB needs to be present

    // Get the long-term reference pictures
    int offset = rps->getNumberOfNegativePictures() + rps->getNumberOfPositivePictures();
    int i, ctr = 0;
    int maxPicOrderCntLSB = 1 << slice->getSPS()->getBitsForPOC();
    for (i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++)
    {
        longtermPicsPoc[ctr] = rps->getPOC(i);                                  // LTRP POC
        longtermPicsLSB[ctr] = getLSB(longtermPicsPoc[ctr], maxPicOrderCntLSB); // LTRP POC LSB
        indices[ctr] = i;
        longtermPicsMSB[ctr] = longtermPicsPoc[ctr] - longtermPicsLSB[ctr];
    }

    int numLongPics = rps->getNumberOfLongtermPictures();
    assert(ctr == numLongPics);

    // Arrange pictures in decreasing order of MSB;
    for (i = 0; i < numLongPics; i++)
    {
        for (int j = 0; j < numLongPics - 1; j++)
        {
            if (longtermPicsMSB[j] < longtermPicsMSB[j + 1])
            {
                std::swap(longtermPicsPoc[j], longtermPicsPoc[j + 1]);
                std::swap(longtermPicsLSB[j], longtermPicsLSB[j + 1]);
                std::swap(longtermPicsMSB[j], longtermPicsMSB[j + 1]);
                std::swap(indices[j], indices[j + 1]);
            }
        }
    }

    for (i = 0; i < numLongPics; i++)
    {
        // Check if MSB present flag should be enabled.
        // Check if the buffer contains any pictures that have the same LSB.
        TComPic* iterPic = m_picList.first();
        while (iterPic)
        {
            if ((getLSB(iterPic->getPOC(), maxPicOrderCntLSB) == longtermPicsLSB[i])   && // Same LSB
                (iterPic->getSlice()->isReferenced()) &&                                  // Reference picture
                (iterPic->getPOC() != longtermPicsPoc[i]))                                // Not the LTRP itself
            {
                mSBPresentFlag[i] = true;
                break;
            }
            iterPic = iterPic->m_next;
        }
    }

    // tempArray for usedByCurr flag
    bool tempArray[MAX_NUM_REF_PICS];
    ::memset(tempArray, 0, sizeof(tempArray));
    for (i = 0; i < numLongPics; i++)
    {
        tempArray[i] = rps->getUsed(indices[i]) ? true : false;
    }

    // Now write the final values;
    ctr = 0;
    int currMSB = 0, currLSB = 0;
    // currPicPoc = currMSB + currLSB
    currLSB = getLSB(slice->getPOC(), maxPicOrderCntLSB);
    currMSB = slice->getPOC() - currLSB;

    for (i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++)
    {
        rps->setPOC(i, longtermPicsPoc[ctr]);
        rps->setDeltaPOC(i, -slice->getPOC() + longtermPicsPoc[ctr]);
        rps->setUsed(i, tempArray[ctr]);
        rps->setPocLSBLT(i, longtermPicsLSB[ctr]);
        rps->setDeltaPocMSBCycleLT(i, (currMSB - (longtermPicsPoc[ctr] - longtermPicsLSB[ctr])) / maxPicOrderCntLSB);
        rps->setDeltaPocMSBPresentFlag(i, mSBPresentFlag[ctr]);

        assert(rps->getDeltaPocMSBCycleLT(i) >= 0); // Non-negative value
    }

    for (i = rps->getNumberOfPictures() - 1, ctr = 1; i >= offset; i--, ctr++)
    {
        for (int j = rps->getNumberOfPictures() - 1 - ctr; j >= offset; j--)
        {
            // Here at the encoder we know that we have set the full POC value for the LTRPs, hence we
            // don't have to check the MSB present flag values for this constraint.
            assert(rps->getPOC(i) != rps->getPOC(j)); // If assert fails, LTRP entry repeated in RPS!!!
        }
    }
}
示例#30
0
Void TComSlice::setRefPicList       ( TComList<TComPic*>& rcListPic )
{
  if (m_eSliceType == I_SLICE)
  {
    ::memset( m_apcRefPicList, 0, sizeof (m_apcRefPicList));
    ::memset( m_aiNumRefIdx,   0, sizeof ( m_aiNumRefIdx ));
    
    return;
  }
  
  m_aiNumRefIdx[0] = min ( m_aiNumRefIdx[0], (Int)(rcListPic.size())-1 );
  m_aiNumRefIdx[1] = min ( m_aiNumRefIdx[1], (Int)(rcListPic.size())-1 );
  
  sortPicList(rcListPic);
  
  TComPic*  pcRefPic;
  for (Int n = 0; n < 2; n++)
  {
    RefPicList  eRefPicList = (RefPicList)n;
    
    UInt  uiOrderDRB  = 1;
    UInt  uiOrderERB  = 1;
    Int   iRefIdx     = 0;
    UInt  uiActualListSize = 0;
    
    if ( m_eSliceType == P_SLICE && eRefPicList == REF_PIC_LIST_1 )
    {
      m_aiNumRefIdx[eRefPicList] = 0;
      ::memset( m_apcRefPicList[eRefPicList], 0, sizeof(m_apcRefPicList[eRefPicList]));
      break;
    }
    
    //  First DRB
    pcRefPic = xGetRefPic(rcListPic, true, ERB_NONE, m_iPOC, eRefPicList, uiOrderDRB, m_uiTLayer);
    if (pcRefPic != NULL)
    {
      m_apcRefPicList[eRefPicList][iRefIdx] = pcRefPic;
      
      pcRefPic->getPicYuvRec()->extendPicBorder();
      
      iRefIdx++;
      uiOrderDRB++;
      uiActualListSize++;
    }
    
    if ( (Int)uiActualListSize >= m_aiNumRefIdx[eRefPicList] )
    {
      m_aiNumRefIdx[eRefPicList] = uiActualListSize;
      continue;
    }
    
    // Long term reference
    // Should be enabled to support long term refernce
    //*
    //  First ERB
    pcRefPic = xGetRefPic(rcListPic, false, ERB_LTR, m_iPOC, eRefPicList, uiOrderERB, m_uiTLayer);
    if (pcRefPic != NULL)
    {
      Bool  bChangeDrbErb = false;
      if      (iRefIdx > 0 && eRefPicList == REF_PIC_LIST_0 && pcRefPic->getPOC() > m_apcRefPicList[eRefPicList][iRefIdx-1]->getPOC())
      {
        bChangeDrbErb = true;
      }
      else if (iRefIdx > 0 && eRefPicList == REF_PIC_LIST_1 && pcRefPic->getPOC() < m_apcRefPicList[eRefPicList][iRefIdx-1]->getPOC())
      {
        bChangeDrbErb = true;
      }
      
      if ( bChangeDrbErb)
      {
        m_apcRefPicList[eRefPicList][iRefIdx]   = m_apcRefPicList[eRefPicList][iRefIdx-1];
        m_apcRefPicList[eRefPicList][iRefIdx-1] = pcRefPic;
      }
      else
      {
        m_apcRefPicList[eRefPicList][iRefIdx] = pcRefPic;
      }
      
      pcRefPic->getPicYuvRec()->extendPicBorder();
      
      iRefIdx++;
      uiOrderERB++;
      uiActualListSize++;
    }
    //*/
    
    // Short term reference
    //  Residue DRB
    UInt  uiBreakCount = 17 - iRefIdx;
    while (1)
    {
      uiBreakCount--;
      if ( (Int)uiActualListSize >= m_aiNumRefIdx[eRefPicList] || uiBreakCount == 0 )
      {
        break;
      }
      
      pcRefPic = xGetRefPic(rcListPic, true, ERB_NONE, m_iPOC, eRefPicList, uiOrderDRB, m_uiTLayer);
      if (pcRefPic != NULL)
      {
        uiOrderDRB++;
      }
      
      if (pcRefPic != NULL)
      {
        m_apcRefPicList[eRefPicList][iRefIdx] = pcRefPic;
        
        pcRefPic->getPicYuvRec()->extendPicBorder();
        
        iRefIdx++;
        uiActualListSize++;
      }
    }
    
    m_aiNumRefIdx[eRefPicList] = uiActualListSize;
  }
}