📄 umc_h264_enc_cpb.cpp
字号:
m_pYPlane = (PixType*)GetPlanePointer(alpha_plane);
m_mbinfo = m_mbinfo_alpha;
m_isAuxiliary = true;
}
template <class PixType>
inline void H264EncoderFrame<PixType>::usePrimary()
{
m_pYPlane = (PixType*)GetPlanePointer(0);
m_mbinfo = m_mbinfo_prim;
m_isAuxiliary = false;
}
#endif
template <class PixType> H264EncoderFrameList<PixType>::~H264EncoderFrameList()
{
H264EncoderFrame<PixType> *pCurr = m_pHead;
while (pCurr)
{
H264EncoderFrame<PixType> *pNext = pCurr->future();
delete pCurr;
pCurr = pNext;
}
m_pHead = m_pTail = 0;
}
template <class PixType>
H264EncoderFrame<PixType>* H264EncoderFrameList<PixType>::detachHead()
{
H264EncoderFrame<PixType> *pHead = m_pHead;
if (pHead)
{
m_pHead = m_pHead->future();
if (m_pHead)
m_pHead->setPrevious(0);
else
{
m_pTail = 0;
}
}
m_pCurrent = m_pHead;
return pHead;
}
template <class PixType>
void H264EncoderFrameList<PixType>::RemoveFrame(H264EncoderFrame<PixType> *pFrm)
{
H264EncoderFrame<PixType> *pPrev = pFrm->previous();
H264EncoderFrame<PixType> *pFut = pFrm->future();
if (pFrm==m_pHead) //must be equal to pPrev==NULL
{
VM_ASSERT(pPrev==NULL);
detachHead();
}
else
{
if (pFut==NULL)
{
m_pTail = pPrev;
pPrev->setFuture(0);
}
else
{
pPrev->setFuture(pFut);
pFut->setPrevious(pPrev);
}
}
m_pCurrent = m_pHead;
}
//////////////////////////////////////////////////////////////////////////////
// append
// Appends a new decoded frame buffer to the "end" of the linked list
//////////////////////////////////////////////////////////////////////////////
template <class PixType>
void H264EncoderFrameList<PixType>::append(H264EncoderFrame<PixType> *pFrame)
{
// Error check
if (!pFrame)
{
// Sent in a NULL frame
return;
}
// Has a list been constructed - is their a head?
if (!m_pHead)
{
// Must be the first frame appended
// Set the head to the current
m_pHead = pFrame;
m_pHead->setPrevious(0);
m_pCurrent = m_pHead;
}
if (m_pTail)
{
// Set the old tail as the previous for the current
pFrame->setPrevious(m_pTail);
// Set the old tail's future to the current
m_pTail->setFuture(pFrame);
}
else
{
// Must be the first frame appended
// Set the tail to the current
m_pTail = pFrame;
}
// The current is now the new tail
m_pTail = pFrame;
m_pTail->setFuture(0);
//
}
template <class PixType>
void H264EncoderFrameList<PixType>::insertAtCurrent(H264EncoderFrame<PixType> *pFrame)
{
if (m_pCurrent)
{
H264EncoderFrame<PixType> *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);
}
}
template <class PixType>
H264EncoderFrame<PixType> *H264EncoderFrameList<PixType>::findNextDisposable(void)
{
H264EncoderFrame<PixType> *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;
}
template <class PixType>
H264EncoderFrame<PixType> *H264EncoderFrameList<PixType>::findOldestDisposable()
{
if (!m_pCurrent)
{
// There are no frames in the list, return
return NULL;
}
m_pCurrent = 0;
Ipp32s SmallestPicOrderCnt = 0x7fffffff;
Ipp32s LargestRefPicListResetCount = 0;
// We got all the way to the tail without finding a free frame
// Start from the head and go until the current
for (H264EncoderFrame<PixType> *pTmp = m_pHead; pTmp; pTmp = pTmp->future())
{
if (pTmp->isDisposable())
{
if (pTmp->RefPicListResetCount(0,3) > LargestRefPicListResetCount )
{
m_pCurrent = pTmp;
SmallestPicOrderCnt = pTmp->PicOrderCnt(0,3);
LargestRefPicListResetCount = pTmp->RefPicListResetCount(0,3);
}
else if ((pTmp->PicOrderCnt(0,3) < SmallestPicOrderCnt ) && (pTmp->RefPicListResetCount(0,3) == LargestRefPicListResetCount ))
{
// Update the current
m_pCurrent = pTmp;
SmallestPicOrderCnt = pTmp->PicOrderCnt(0,3);
}
}
}
// We never found one
return m_pCurrent;
}
///////////////////////////////////////////////////////////////////////////////
// findOldestDisplayable
// Search through the list for the oldest displayable frame. It must be
// not disposable, not outputted, and have smallest PicOrderCnt.
///////////////////////////////////////////////////////////////////////////////
template <class PixType>
H264EncoderFrame<PixType> *H264EncoderFrameList<PixType>::findOldestToEncode(H264EncoderFrameList<PixType> *dpb,Ipp32u min_L1_refs, Ipp32s use_b_as_refs)
{
H264EncoderFrame<PixType> *pCurr = m_pHead;
H264EncoderFrame<PixType> *pOldest = NULL;
H264EncoderFrame<PixType> *pLastBref = NULL;
H264EncoderFrame<PixType> *pFirstBref = NULL;
Ipp32s SmallestPicOrderCnt = 0x7fffffff; // very large positive
Ipp32s MaxBrefPOC = -1;
Ipp32s MinBrefPOC = 0x7fffffff; // very large positive
Ipp32s LargestRefPicListResetCount = 0;
bool exclude_cur=false;
static unsigned int test = 0;
static Ipp32s curPpoc = 0;
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;
//Get B with maximum POC and active_L1_refs<min_L1_refs when B used as refs
if( use_b_as_refs && pCurr->m_RefPic && pCurr->PicOrderCnt(0,3) < curPpoc && (pCurr->RefPicListResetCount(0,3) == LargestRefPicListResetCount ) ){
if(pCurr->PicOrderCnt(0,3) > MaxBrefPOC){
pLastBref = pCurr;
MaxBrefPOC = pCurr->PicOrderCnt(0,3);
}
if(pCurr->PicOrderCnt(0,3) < MinBrefPOC){
pFirstBref = pCurr;
MinBrefPOC = pCurr->PicOrderCnt(0,3);
}
}
}
if (!exclude_cur)
{
// corresponding frame
if (pCurr->RefPicListResetCount(0,3) > LargestRefPicListResetCount )
{
pOldest = pCurr;
SmallestPicOrderCnt = pCurr->PicOrderCnt(0,3);
LargestRefPicListResetCount = pCurr->RefPicListResetCount(0,3);
pLastBref = pCurr;
pFirstBref = pCurr;
MaxBrefPOC = pCurr->PicOrderCnt(0,3);
MaxBrefPOC = pCurr->PicOrderCnt(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
if( use_b_as_refs && pOldest ){
if (pOldest->m_PicCodType==PREDPIC){
test = 0;
curPpoc = pOldest->PicOrderCnt(0,3);
}else if(pOldest->m_PicCodType==BPREDPIC && pLastBref != NULL){
if( test & 1 )
pOldest = pLastBref;
else
pOldest = pFirstBref;
test = !test; // for next B
}
}
return pOldest;
} // findOldestDisplayable
///////////////////////////////////////////////////////////////////////////////
// findNewestToEncode
// Search through the list for the newest displayable frame. It must be
// not disposable, not outputted, and have smallest PicOrderCnt.
///////////////////////////////////////////////////////////////////////////////
template <class PixType>
H264EncoderFrame<PixType> *H264EncoderFrameList<PixType>::findNewestToEncode()
{
H264EncoderFrame<PixType> *pCurr = m_pHead;
H264EncoderFrame<PixType> *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.
///////////////////////////////////////////////////////////////////////////////
template <class PixType>
Ipp32s H264EncoderFrameList<PixType>::countNumToEncode()
{
H264EncoderFrame<PixType> *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.
///////////////////////////////////////////////////////////////////////////////
template <class PixType>
void H264EncoderFrameList<PixType>::countActiveRefs(Ipp32u &NumShortTerm, Ipp32u &NumLongTerm)
{
H264EncoderFrame<PixType> *pCurr = m_pHead;
NumShortTerm = 0;
NumLongTerm = 0;
while (pCurr)
{
if (pCurr->isShortTermRef())
NumShortTerm++;
else if (pCurr->isLongTermRef())
NumLongTerm++;
pCurr = pCurr->future();
}
} // countActiveRefs
template <class PixType>
void H264EncoderFrameList<PixType>::countL1Refs(Ipp32u &NumRefs, Ipp32s curPOC)
{
H264EncoderFrame<PixType> *pCurr = m_pHead;
NumRefs = 0;
while (pCurr)
{
if (pCurr->isShortTermRef() && pCurr->PicOrderCnt(0,3)>curPOC)
NumRefs++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -