Void TComSlice::decodingRefMarkingForLD( TComList<TComPic*>& rcListPic, Int iMaxNumRefFrames, Int iCurrentPOC ) { assert( iMaxNumRefFrames >= 1 ); while( getActualRefNumber( rcListPic ) > iMaxNumRefFrames ) { sortPicList( rcListPic ); TComList<TComPic*>::iterator it = rcListPic.begin(); while( it != rcListPic.end() ) { if ( (*it)->getSlice(0)->isReferenced() && (*it)->getSlice(0)->getPOC() != iCurrentPOC && (*it)->getSlice(0)->getPOC() % 4 != 0 ) { (*it)->getSlice(0)->setReferenced( false ); // mark POC%4!=0 as unused for reference break; } it++; } if ( it == rcListPic.end() ) // all the reference frames POC%4== 0, mark the first reference frame as unused for reference { it = rcListPic.begin(); while( it != rcListPic.end() ) { if ( (*it)->getSlice(0)->isReferenced() ) { (*it)->getSlice(0)->setReferenced( false ); break; } it++; } } } }
/** 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++; } } }
/** 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; } } }
TComPic* TAppDecTop::xGetPicFromView( Int viewId, Int poc, Bool isDepth ) { assert( ( viewId >= 0 ) ); #if FLEX_CODING_ORDER_M23723 if (getTDecTop(viewId,isDepth)) { TComList<TComPic*>* apcListPic = getTDecTop( viewId, isDepth )->getListPic(); TComPic* pcPic = NULL; for( TComList<TComPic*>::iterator it=apcListPic->begin(); it!=apcListPic->end(); it++ ) { if( (*it)->getPOC() == poc ) { pcPic = *it; break; } } return pcPic; } else return NULL; #else TComList<TComPic*>* apcListPic = getTDecTop( viewId, isDepth )->getListPic(); TComPic* pcPic = NULL; for( TComList<TComPic*>::iterator it=apcListPic->begin(); it!=apcListPic->end(); it++ ) { if( (*it)->getPOC() == poc ) { pcPic = *it; break; } } return pcPic; #endif }
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); } }
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; }
/** 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++; } } }