📄 umc_h264_frame_list.cpp
字号:
/*
//
// INTEL CORPORATION PROPRIETARY INFORMATION
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Intel Corporation and may not be copied
// or disclosed except in accordance with the terms of that agreement.
// Copyright (c) 2003-2007 Intel Corporation. All Rights Reserved.
//
//
*/
#include "umc_defs.h"
#if defined (UMC_ENABLE_H264_VIDEO_DECODER)
#include "umc_h264_frame_list.h"
namespace UMC
{
H264DecoderFrameList::H264DecoderFrameList(void)
{
m_pHead = NULL;
m_pTail = NULL;
} // H264DecoderFrameList::H264DecoderFrameList(void)
H264DecoderFrameList::~H264DecoderFrameList(void)
{
Release();
} // H264DecoderFrameList::~H264DecoderFrameList(void)
void H264DecoderFrameList::Release(void)
{
// destroy frame list
while (m_pHead)
{
H264DecoderFrame *pNext = m_pHead->future();
delete m_pHead;
m_pHead = pNext;
}
m_pHead = NULL;
m_pTail = NULL;
} // void H264DecoderFrameList::Release(void)
H264DecoderFrame* H264DecoderFrameList::detachHead()
{
H264DecoderFrame *pHead = m_pHead;
if (pHead)
{
m_pHead = m_pHead->future();
if (m_pHead)
m_pHead->setPrevious(0);
else
m_pTail = 0;
}
return pHead;
}
void H264DecoderFrameList::moveToHead(H264DecoderFrame *pFrame)
{
if (pFrame == m_pHead)
return;
if (pFrame == m_pTail)
{
m_pTail = pFrame->previous();
m_pTail->setFuture(0);
}
else
{
pFrame->previous()->setFuture(pFrame->future());
pFrame->future()->setPrevious(pFrame->previous());
}
pFrame->setPrevious(0);
pFrame->setFuture(m_pHead);
m_pHead->setPrevious(pFrame);
m_pHead = pFrame;
}
//////////////////////////////////////////////////////////////////////////////
// append
// Appends a new decoded frame buffer to the "end" of the linked list
//////////////////////////////////////////////////////////////////////////////
void H264DecoderFrameList::append(H264DecoderFrame *pFrame)
{
// Error check
if (!pFrame)
{
// Sent in a NULL frame
return;
}
pFrame->m_index = GetFreeIndex();
// 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);
}
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);
//
}
void H264DecoderFrameList::insertList(H264DecoderFrameList &src)
{
if (!src.isEmpty())
{
src.tail()->setFuture(m_pHead);
if (m_pHead)
m_pHead->setPrevious(src.tail());
m_pHead = src.head();
if (!m_pTail)
m_pTail = src.tail();
src.m_pHead = src.m_pTail = 0;
}
}
H264DBPList::H264DBPList()
{
}
void H264DBPList::MoveAllSkippedToTail(void)
{
}
H264DecoderFrame * H264DBPList::GetFirstBusy(void)
{
for (H264DecoderFrame * pTmp = m_pHead; pTmp; pTmp = pTmp->future())
{
if (pTmp->GetBusyState() > 1)
{
return pTmp;
}
}
return 0;
}
H264DecoderFrame * H264DBPList::GetOldestDisposable(void)
{
H264DecoderFrame *pOldest = NULL;
Ipp32s SmallestPicOrderCnt = 0x7fffffff; // very large positive
Ipp32s LargestRefPicListResetCount = 0;
for (H264DecoderFrame * pTmp = m_pHead; pTmp; pTmp = pTmp->future())
{
if (pTmp->isDisposable())
{
if (pTmp->RefPicListResetCount(0,3) > LargestRefPicListResetCount)
{
pOldest = pTmp;
SmallestPicOrderCnt = pTmp->PicOrderCnt(0,3);
LargestRefPicListResetCount = pTmp->RefPicListResetCount(0,3);
}
else if ((pTmp->PicOrderCnt(0,3) < SmallestPicOrderCnt) &&
(pTmp->RefPicListResetCount(0,3) == LargestRefPicListResetCount))
{
pOldest = pTmp;
SmallestPicOrderCnt = pTmp->PicOrderCnt(0,3);
}
}
}
return pOldest;
} // H264DecoderFrame *H264DBPList::GetDisposable(void)
void H264DBPList::MoveToTail(H264DecoderFrame * pFrame)
{
if (m_pHead == m_pTail || pFrame == m_pTail)
{
return;
}
// move to tail
if (pFrame == m_pHead)
{
m_pHead = pFrame->m_pFutureFrame;
m_pHead->m_pPreviousFrame = 0;
}
else
{
pFrame->m_pPreviousFrame->m_pFutureFrame = pFrame->m_pFutureFrame;
pFrame->m_pFutureFrame->m_pPreviousFrame = pFrame->m_pPreviousFrame;
}
m_pTail->m_pFutureFrame = pFrame;
pFrame->m_pPreviousFrame = m_pTail;
m_pTail = pFrame;
pFrame->m_pFutureFrame = 0;
}
bool H264DBPList::IsDisposableExist()
{
for (H264DecoderFrame * pTmp = m_pHead; pTmp; pTmp = pTmp->future())
{
if (pTmp->isDisposable())
{
return true;
}
}
return false;
}
H264DecoderFrame * H264DBPList::GetDisposable(void)
{
for (H264DecoderFrame * pTmp = m_pHead; pTmp; pTmp = pTmp->future())
{
if (pTmp->isDisposable())
{
if (m_pHead == m_pTail || pTmp == m_pTail)
{
return pTmp;
}
// move to tail
if (pTmp == m_pHead)
{
m_pHead = pTmp->m_pFutureFrame;
m_pHead->m_pPreviousFrame = 0;
}
else
{
pTmp->m_pPreviousFrame->m_pFutureFrame = pTmp->m_pFutureFrame;
pTmp->m_pFutureFrame->m_pPreviousFrame = pTmp->m_pPreviousFrame;
}
m_pTail->m_pFutureFrame = pTmp;
pTmp->m_pPreviousFrame = m_pTail;
m_pTail = pTmp;
pTmp->m_pFutureFrame = 0;
return pTmp;
}
}
// We never found one
return NULL;
} // H264DecoderFrame *H264DBPList::GetDisposable(void)
///////////////////////////////////////////////////////////////////////////////
// findOldestDisplayable
// Search through the list for the oldest displayable frame. It must be
// not disposable, not outputted, and have smallest PicOrderCnt.
///////////////////////////////////////////////////////////////////////////////
H264DecoderFrame * H264DBPList::findOldestDisplayable(Ipp32s dbpSize)
{
H264DecoderFrame *pCurr = m_pHead;
H264DecoderFrame *pOldest = NULL;
Ipp32s SmallestPicOrderCnt = 0x7fffffff; // very large positive
Ipp32s LargestRefPicListResetCount = 0;
Ipp32s count = 0;
while (pCurr)
{
if ((pCurr->isDisplayable() || pCurr->GetBusyState() >= 2) && !pCurr->wasOutputted())
{
// 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);
}
if (!pOldest->IsFrameExist() && pCurr->IsFrameExist())
{
if (pCurr->PicOrderCnt(0,3) == SmallestPicOrderCnt &&
pCurr->RefPicListResetCount(0,3) == LargestRefPicListResetCount)
pOldest = pCurr;
}
if (count == dbpSize + 1)
break;
count++;
}
pCurr = pCurr->future();
}
// may be OK if NULL
return pOldest;
} // findOldestDisplayable
Ipp32s H264DBPList::countAllFrames()
{
H264DecoderFrame *pCurr = head();
Ipp32u count = 0;
while (pCurr)
{
count++;
pCurr = pCurr->future();
}
return count;
}
///////////////////////////////////////////////////////////////////////////////
// countNumDisplayable
// Return number of displayable frames.
///////////////////////////////////////////////////////////////////////////////
Ipp32s H264DBPList::countNumDisplayable()
{
H264DecoderFrame *pCurr = head();
Ipp32u NumDisplayable = 0;
while (pCurr)
{
if (pCurr->isCouldDisplay() || (pCurr->GetBusyState() >= 2))
NumDisplayable++;
pCurr = pCurr->future();
}
return NumDisplayable;
} // countNumDisplayable
///////////////////////////////////////////////////////////////////////////////
// countActiveRefs
// Return number of active Ipp16s and long term reference frames.
///////////////////////////////////////////////////////////////////////////////
void H264DBPList::countActiveRefs(Ipp32u &NumShortTerm, Ipp32u &NumLongTerm)
{
H264DecoderFrame *pCurr = m_pHead;
NumShortTerm = 0;
NumLongTerm = 0;
while (pCurr)
{
if (pCurr->isShortTermRef())
NumShortTerm++;
else if (pCurr->isLongTermRef())
NumLongTerm++;
pCurr = pCurr->future();
}
} // countActiveRefs
///////////////////////////////////////////////////////////////////////////////
// removeAllRef
// Marks all frames as not used as reference frames.
///////////////////////////////////////////////////////////////////////////////
void OnSlideWindow(H264DecoderFrame *pRefFrame, H264DecoderFrame *pCurrentFrame, NotifiersChain * defaultChain, bool force);
void H264DBPList::removeAllRef(H264DecoderFrame * pFrame)
{
H264DecoderFrame *pCurr = m_pHead;
while (pCurr)
{
if (pCurr->isShortTermRef() || pCurr->isLongTermRef())
{
OnSlideWindow(pCurr, pFrame, 0, true);
}
pCurr->unSetisLongTermRef(0);
pCurr->unSetisLongTermRef(1);
pCurr->unSetisShortTermRef(0);
pCurr->unSetisShortTermRef(1);
pCurr = pCurr->future();
}
} // removeAllRef
void H264DBPList::IncreaseRefPicListResetCount(H264DecoderFrame *ExcludeFrame)
{
H264DecoderFrame *pCurr = m_pHead;
while (pCurr)
{
if (pCurr!=ExcludeFrame)
{
pCurr->IncreaseRefPicListResetCount(0);
pCurr->IncreaseRefPicListResetCount(1);
}
pCurr = pCurr->future();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -