📄 umc_h264_enc_cpb.cpp
字号:
{ H264EncoderFrame *pFutureFrame = m_pCurrent->future(); pFrame->setFuture(pFutureFrame); if (pFutureFrame) { pFutureFrame->setPrevious(pFrame); } else { // Must be at the tail m_pTail = pFrame; } pFrame->setPrevious(m_pCurrent); m_pCurrent->setFuture(pFrame); } else { // Must be the first frame append(pFrame); }}H264EncoderFrame *H264EncoderFrameList::findNextDisposable(void){ H264EncoderFrame *pTmp; if (!m_pCurrent) { // There are no frames in the list, return return NULL; } // Loop through starting with the next frame after the current one for (pTmp = m_pCurrent->future(); pTmp; pTmp = pTmp->future()) { if (pTmp->isDisposable()) { // We got one // Update the current m_pCurrent = pTmp; return pTmp; } } // We got all the way to the tail without finding a free frame // Start from the head and go until the current for (pTmp = m_pHead; pTmp && pTmp->previous() != m_pCurrent; pTmp = pTmp->future()) { if (pTmp->isDisposable()) { // We got one // Update the current m_pCurrent = pTmp; return pTmp; } } // We never found one return NULL;}///////////////////////////////////////////////////////////////////////////////// findOldestDisplayable// Search through the list for the oldest displayable frame. It must be// not disposable, not outputted, and have smallest PicOrderCnt.///////////////////////////////////////////////////////////////////////////////H264EncoderFrame *H264EncoderFrameList::findOldestToEncode(H264EncoderFrameList *dpb,Ipp32u min_L1_refs){ H264EncoderFrame *pCurr = m_pHead; H264EncoderFrame *pOldest = NULL; Ipp32s SmallestPicOrderCnt = 0x7fffffff; // very large positive Ipp32s LargestRefPicListResetCount = 0; bool exclude_cur=false; while (pCurr) { if (!pCurr->wasEncoded()) { if (pCurr->m_PicCodType==BPREDPIC) { Ipp32u active_L1_refs; dpb->countL1Refs(active_L1_refs,pCurr->PicOrderCnt(0)); exclude_cur=active_L1_refs<min_L1_refs; } if (!exclude_cur) { // corresponding frame if (pCurr->RefPicListResetCount(0,3) > LargestRefPicListResetCount ) { pOldest = pCurr; SmallestPicOrderCnt = pCurr->PicOrderCnt(0,3); LargestRefPicListResetCount = pCurr->RefPicListResetCount(0,3); } else if ((pCurr->PicOrderCnt(0,3) < SmallestPicOrderCnt ) && (pCurr->RefPicListResetCount(0,3) == LargestRefPicListResetCount )) { pOldest = pCurr; SmallestPicOrderCnt = pCurr->PicOrderCnt(0,3); } } } pCurr = pCurr->future(); exclude_cur=false; } // may be OK if NULL return pOldest;} // findOldestDisplayable///////////////////////////////////////////////////////////////////////////////// findNewestToEncode// Search through the list for the newest displayable frame. It must be// not disposable, not outputted, and have smallest PicOrderCnt.///////////////////////////////////////////////////////////////////////////////H264EncoderFrame *H264EncoderFrameList::findNewestToEncode(H264EncoderFrameList *dpb){ H264EncoderFrame *pCurr = m_pHead; H264EncoderFrame *pNewest = NULL; Ipp32s LargestPicOrderCnt = -1; Ipp32s LargestRefPicListResetCount = 0; while (pCurr) { if (!pCurr->wasEncoded()) { // corresponding frame if (pCurr->RefPicListResetCount(0,3) > LargestRefPicListResetCount) { pNewest = pCurr; LargestPicOrderCnt = pCurr->PicOrderCnt(0,3); LargestRefPicListResetCount = pCurr->RefPicListResetCount(0,3); } else if ((pCurr->PicOrderCnt(0,3) > LargestPicOrderCnt) && (pCurr->RefPicListResetCount(0,3) == LargestRefPicListResetCount)) { pNewest = pCurr; LargestPicOrderCnt = pCurr->PicOrderCnt(0,3); } } pCurr = pCurr->future(); } // may be OK if NULL return pNewest;} // findNewestToEncode///////////////////////////////////////////////////////////////////////////////// countNumDisplayable// Return number of displayable frames.///////////////////////////////////////////////////////////////////////////////Ipp32s H264EncoderFrameList::countNumToEncode(){ H264EncoderFrame *pCurr = m_pHead; Ipp32u NumToEncode= 0; while (pCurr) { if (pCurr->wasEncoded()) NumToEncode++; pCurr = pCurr->future(); } return NumToEncode;} // countNumDisplayable///////////////////////////////////////////////////////////////////////////////// countActiveRefs// Return number of active short and long term reference frames.///////////////////////////////////////////////////////////////////////////////void H264EncoderFrameList::countActiveRefs(Ipp32u &NumShortTerm, Ipp32u &NumLongTerm){ H264EncoderFrame *pCurr = m_pHead; NumShortTerm = 0; NumLongTerm = 0; while (pCurr) { if (pCurr->isShortTermRef()) NumShortTerm++; else if (pCurr->isLongTermRef()) NumLongTerm++; pCurr = pCurr->future(); }} // countActiveRefsvoid H264EncoderFrameList::countL1Refs(Ipp32u &NumRefs, Ipp32s curPOC){ H264EncoderFrame *pCurr = m_pHead; NumRefs = 0; while (pCurr) { if (pCurr->isShortTermRef() && pCurr->PicOrderCnt(0,3)>curPOC) NumRefs++; pCurr = pCurr->future(); }} // countActiveRefs///////////////////////////////////////////////////////////////////////////////// removeAllRef// Marks all frames as not used as reference frames.///////////////////////////////////////////////////////////////////////////////void H264EncoderFrameList::removeAllRef(){ H264EncoderFrame *pCurr = m_pHead; while (pCurr) { pCurr->unSetisLongTermRef(0); pCurr->unSetisLongTermRef(1); pCurr->unSetisShortTermRef(0); pCurr->unSetisShortTermRef(1); pCurr = pCurr->future(); }} // removeAllRefvoid H264EncoderFrameList::IncreaseRefPicListResetCount(H264EncoderFrame *ExcludeFrame){ H264EncoderFrame *pCurr = m_pHead; while (pCurr) { if (pCurr!=ExcludeFrame) { pCurr->IncreaseRefPicListResetCount(0); pCurr->IncreaseRefPicListResetCount(1); } pCurr = pCurr->future(); }} // IncreaseRefPicListResetCount//////////////////////////////////////////////////////////////////////////////// freeOldestShortTermRef// Marks the oldest (having smallest FrameNumWrap) short-term reference frame// as not used as reference frame.///////////////////////////////////////////////////////////////////////////////void H264EncoderFrameList::freeOldestShortTermRef(){ H264EncoderFrame *pCurr = m_pHead; H264EncoderFrame *pOldest = NULL; Ipp32s SmallestFrameNumWrap = 0x0fffffff; // very large positive while (pCurr) { if (pCurr->isShortTermRef() && (pCurr->FrameNumWrap() < SmallestFrameNumWrap)) { pOldest = pCurr; SmallestFrameNumWrap = pCurr->FrameNumWrap(); } pCurr = pCurr->future(); } VM_ASSERT(pOldest != NULL); // Should not have been called if no short-term refs if (pOldest) { pOldest->unSetisShortTermRef(0); pOldest->unSetisShortTermRef(1); }} // freeOldestShortTermRef///////////////////////////////////////////////////////////////////////////////// freeShortTermRef// Mark the short-term reference frame with specified PicNum as not used///////////////////////////////////////////////////////////////////////////////void H264EncoderFrameList::freeShortTermRef(Ipp32s PicNum){ H264EncoderFrame *pCurr = m_pHead; bool found = false; while (pCurr) { if (pCurr->m_PictureStructureForRef>=FRM_STRUCTURE) { if (pCurr->isShortTermRef() && (pCurr->PicNum(0) == PicNum)) { pCurr->unSetisShortTermRef(0); break; } } else { if (pCurr->isShortTermRef(0) && (pCurr->PicNum(0) == PicNum)) { pCurr->unSetisShortTermRef(0); found = true; } if (pCurr->isShortTermRef(1) && (pCurr->PicNum(1) == PicNum)) { pCurr->unSetisShortTermRef(1); found = true; } if (found) break; } pCurr = pCurr->future(); } VM_ASSERT(pCurr != NULL); // No match found, should not happen.} // freeShortTermRef///////////////////////////////////////////////////////////////////////////////// freeLongTermRef// Mark the long-term reference frame with specified LongTermPicNum as not used///////////////////////////////////////////////////////////////////////////////void H264EncoderFrameList::freeLongTermRef(Ipp32s LongTermPicNum){ H264EncoderFrame *pCurr = m_pHead; bool found = false; while (pCurr) { if (pCurr->m_PictureStructureForRef>=FRM_STRUCTURE) { if (pCurr->isLongTermRef() && (pCurr->LongTermPicNum(0) == LongTermPicNum)) { pCurr->unSetisLongTermRef(0); break; } } else { if (pCurr->isLongTermRef(0) && (pCurr->LongTermPicNum(0) == LongTermPicNum)) { pCurr->unSetisLongTermRef(0); found = true; } if (pCurr->isLongTermRef(1) && (pCurr->LongTermPicNum(1) == LongTermPicNum)) { pCurr->unSetisLongTermRef(1); found = true; } if (found) break; } pCurr = pCurr->future(); } VM_ASSERT(pCurr != NULL); // No match found, should not happen.} // freeLongTermRef///////////////////////////////////////////////////////////////////////////////// freeLongTermRef// Mark the long-term reference frame with specified LongTermFrameIdx// as not used///////////////////////////////////////////////////////////////////////////////void H264EncoderFrameList::freeLongTermRefIdx(Ipp32s LongTermFrameIdx){ H264EncoderFrame *pCurr = m_pHead; bool found = false; while (pCurr) { if (pCurr->m_PictureStructureForRef>=FRM_STRUCTURE) { if (pCurr->isLongTermRef() && (pCurr->LongTermFrameIdx() == LongTermFrameIdx )) { pCurr->unSetisLongTermRef(0); break; } } else { if (pCurr->isLongTermRef(0) && (pCurr->LongTermFrameIdx() == LongTermFrameIdx )) { pCurr->unSetisLongTermRef(0); found = true; } if (pCurr->isLongTermRef(1) && (pCurr->LongTermFrameIdx() == LongTermFrameIdx )) { pCurr->unSetisLongTermRef(1); found = true; } if (found) break; } pCurr = pCurr->future(); } // OK if none found} // freeLongTermRefIdx///////////////////////////////////////////////////////////////////////////////// freeOldLongTermRef// Mark any long-term reference frame with LongTermFrameIdx greater// than MaxLongTermFrameIdx as not used. When MaxLongTermFrameIdx is -1, this// indicates no long-term frame indices and all long-term reference// frames should be freed.///////////////////////////////////////////////////////////////////////////////void H264EncoderFrameList::freeOldLongTermRef(Ipp32s MaxLongTermFrameIdx){ H264EncoderFrame *pCurr = m_pHead; while (pCurr) { if (pCurr->isLongTermRef(0) && (pCurr->LongTermFrameIdx() > MaxLongTermFrameIdx)) { pCurr->unSetisLongTermRef(0); pCurr->unSetisLongTermRef(1); } pCurr = pCurr->future(); }} // freeOldLongTermRef///////////////////////////////////////////////////////////////////////////////// changeSTtoLTRef// Mark the short-term reference frame with specified PicNum as long-term// with specified long term idx.///////////////////////////////////////////////////////////////////////////////void H264EncoderFrameList::changeSTtoLTRef(Ipp32s PicNum, Ipp32s LongTermFrameIdx){ H264EncoderFrame *pCurr = m_pHead; bool found=false; while (pCurr) { if (pCurr->m_PictureStructureForRef>=FRM_STRUCTURE) { if (pCurr->isShortTermRef() && (pCurr->PicNum(0) == PicNum)) { pCurr->unSetisShortTermRef(0); pCurr->setLongTermFrameIdx(LongTermFrameIdx); pCurr->SetisLongTermRef(0); pCurr->UpdateLongTermPicNum(2); break; } } else { if (pCurr->isShortTermRef(0) && (pCurr->PicNum(0) == PicNum)) { pCurr->unSetisShortTermRef(0); pCurr->setLongTermFrameIdx(LongTermFrameIdx); pCurr->SetisLongTermRef(0); pCurr->UpdateLongTermPicNum(pCurr->m_bottom_field_flag[0]); found = true; } if (pCurr->isShortTermRef(1) && (pCurr->PicNum(1) == PicNum)) { pCurr->unSetisShortTermRef(1); pCurr->setLongTermFrameIdx(LongTermFrameIdx); pCurr->SetisLongTermRef(1); pCurr->UpdateLongTermPicNum(pCurr->m_bottom_field_flag[1]); found = true; } if (found) break; } pCurr = pCurr->future(); } VM_ASSERT(pCurr != NULL); // No match found, should not happen.} // changeSTtoLTRefH264EncoderFrame *H264EncoderFrameList::InsertFrame(const H264_Image& rFrame,EnumPicCodType ePictureType,Ipp32s num_slices){ Status ps=UMC_OK; H264EncoderFrame *pFrm = findNextDisposable(); if (!pFrm) { pFrm = new H264EncoderFrame; pFrm->allocate(rFrame.format.dimensions,num_slices); if (ps != UMC_OK) { return NULL; } insertAtCurrent(pFrm); } pFrm->ColorCnvtFrame( rFrame); pFrm->m_PicCodType = ePictureType; pFrm->unsetWasEncoded(); return pFrm;}} //namespace UMC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -