📄 umc_avs_dec_fussion_core_alloc.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) 2007 Intel Corporation. All Rights Reserved.
//
//
*/
#include "umc_defs.h"
#if defined(UMC_ENABLE_AVS_VIDEO_DECODER)
#include "umc_avs_dec_fussion_core.h"
#include "umc_automatic_mutex.h"
namespace UMC
{
enum
{
NUMBER_OF_COEFF_ROWS = 5
};
AVSListElement<AVSFrame> *AVSFussionCore::AllocateFrame(void)
{
AVSListElement<AVSFrame> *pToReturn = NULL;
do
{
pToReturn = m_FreeFrames.GetHead();
// we must have at least 2 frames in free queue
if ((pToReturn) &&
(pToReturn->GetNext()))
return pToReturn;
// run through the frame list and try to get old frame
if (m_iNumFrames >= AVS_DEF_NUMBER_OF_FRAMES + m_iNumberOfThreads)
{
AutomaticMutex guard(m_guard.ExtractHandle());
AVSListElement<AVSFrame> *pHead, *pNext, *pNext2;
pToReturn = NULL;
// analyze 3 frames to decide,
// which one is the oldest frame
pHead = m_Frames.GetHead();
pNext = pHead->GetNext();
pNext2 = pNext->GetNext();
if (false == pNext2->IsReference())
{
// we can use the frame only
// if it was shown
if (pNext2->IsShown())
{
pNext->SetNext(pNext2->GetNext());
pToReturn = pNext2;
}
}
else
{
// it is quite a complex case
// we can use the frame only
// if it was shown,
// and the following reference frames are ready
if ((pHead->IsShown()) &&
(pNext->IsReady()) &&
(pNext2->IsReady()))
{
pToReturn = m_Frames.ExtractHead();
}
}
// remove all useless stuff from the frame
if (pToReturn)
{
pToReturn->SetNext(NULL);
PurgeFrame(pToReturn);
}
else
return NULL;
}
// there is an unsufficient amount of frames,
// so allocate one more
else
{
pToReturn = new AVSListElement<AVSFrame>();
if (NULL == pToReturn)
return NULL;
// we do not need to initialize the frame,
// because we don't have a picture header with parameters
m_iNumFrames += 1;
}
// add the frame to the free list
m_FreeFrames.AddToTail(*pToReturn);
// set return value to NULL
// just to run through the cycle again
pToReturn = NULL;
} while (NULL == pToReturn);
return pToReturn;
} // AVSListElement<AVSFrame> *AVSFussionCore::AllocateFrame(void)
AVSListElement<AVSMemory> *AVSFussionCore::AllocateMemoryPiece(size_t nRequiredSize)
{
AVSListElement<AVSMemory> *pTemp, *pPrev;
// try to find an existing piece, which fits requirements
pPrev = NULL;
pTemp = m_FreeMemory.GetHead();
while (pTemp)
{
if (pTemp->GetSize() >= nRequiredSize)
break;
// touch the next element
pPrev = pTemp;
pTemp = pTemp->GetNext();
}
// we find a fitting element, exclude it from the list
if (pTemp)
{
// it is from somewhere in the middle of the list,
// exclude it, relink the list
if (pPrev)
{
pPrev->SetNext(pTemp->GetNext());
pTemp->SetNext(NULL);
}
// it was the single element in the list
else
m_FreeMemory.ExtractHead();
}
// the list is empty or all elements are too small
else
{
// we need to allocate one more pieces
if (NULL == pPrev)
{
pTemp = new AVSListElement<AVSMemory> ();
}
// take the first element to re-initialize
else
{
pTemp = m_FreeMemory.ExtractHead();
}
// initialize the memory piece
if (UMC_OK != pTemp->Init(nRequiredSize))
{
m_FreeMemory.AddToHead(*pTemp);
return NULL;
}
}
return pTemp;
} // AVSListElement<AVSMemory> *AVSFussionCore::AllocateMemoryPiece(size_t nRequiredSize)
AVSListElement<AVSSlice> *AVSFussionCore::AllocateSlice(void)
{
AVSListElement<AVSSlice> *pTemp, *pPrev;
size_t iRequiredBuffer;
Ipp32s iRequiredRows;
// calculate the size of the buffer for coefficients
iRequiredRows = 1;
switch (m_seqHeader.chroma_format)
{
case AVS_CHROMA_422_FORMAT:
iRequiredBuffer = 64 * 8;
break;
default:
iRequiredBuffer = 64 * 6;
break;
}
if (1 < m_iNumberOfThreads)
{
Ipp32s widthMB = (m_seqHeader.horizontal_size + 15) / 16;
iRequiredRows = NUMBER_OF_COEFF_ROWS;
iRequiredBuffer *= widthMB;
}
// try to find an existing piece, which fits requirements
pPrev = NULL;
pTemp = m_FreeSlices.GetHead();
while (pTemp)
{
if (pTemp->GetCoeffsBufferSize() >= iRequiredBuffer)
break;
// touch the next element
pPrev = pTemp;
pTemp = pTemp->GetNext();
}
// we found a suitable element, exclude it from the list
if (pTemp)
{
// it is from somewhere in the middle of the list,
// exclude it, relink the list
if (pPrev)
{
pPrev->SetNext(pTemp->GetNext());
pTemp->SetNext(NULL);
}
// it was the single element in the list
else
m_FreeSlices.ExtractHead();
}
// the list is empty or all elements are too small
else
{
// we need to allocate one more pieces
if (NULL == pPrev)
{
pTemp = new AVSListElement<AVSSlice> ();
}
// take the first element to re-initialize
else
{
pTemp = m_FreeSlices.ExtractHead();
}
// initialize the memory piece
if (UMC_OK != pTemp->InitCoeffsBuffer(iRequiredBuffer, iRequiredRows))
{
m_FreeSlices.AddToHead(*pTemp);
return NULL;
}
}
return pTemp;
} // AVSListElement<AVSSlice> *AVSFussionCore::AllocateSlice(void)
} // namespace UMC
#endif // #if defined(UMC_ENABLE_AVS_VIDEO_DECODER)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -