📄 umc_avs_dec_fussion_core.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_avs_dec_pic.h"
#include "umc_avs_dec_processing_unit_cc.h"
#include "umc_avs_dec_processing_unit_dec.h"
#include "umc_avs_dec_processing_unit_rec.h"
#include "umc_avs_dec_processing_unit_decrec.h"
#include "umc_avs_dec_processing_unit_deb.h"
#include "umc_avs_dec_processing_unit_sleep.h"
#include "umc_video_decoder.h"
#include "umc_automatic_mutex.h"
namespace UMC
{
AVSFussionCore::AVSFussionCore(void)
{
m_pPerformers = NULL;
m_iNumberOfThreads = 0;
memset(&m_seqHeader, 0, sizeof(m_seqHeader));
memset(&m_picHeader, 0, sizeof(m_picHeader));
m_iPrevSliceStartCode = 0;
m_iNumFrames = 0;
} // AVSFussionCore::AVSFussionCore(void)
AVSFussionCore::~AVSFussionCore(void)
{
Close();
} // AVSFussionCore::~AVSFussionCore(void)
template <class T> static
void DeallocateList(T &list)
{
while (list.GetHead())
{
delete list.ExtractHead();
}
} // void DeallocateList(T list)
Status AVSFussionCore::Close(void)
{
// peel slices off the frames
Reset();
// delete allocated frames
DeallocateList(m_FreeFrames);
// delete allocated slices
DeallocateList(m_FreeSlices);
// delete allocated slices
DeallocateList(m_FreeMemory);
// deinitialize list of performers
if (m_pPerformers)
{
Ipp32s i;
for (i = 0; i < m_iNumberOfThreads; i += 1)
{
DeallocateList(m_pPerformers[i]);
}
delete [] m_pPerformers;
}
m_pPerformers = NULL;
m_iNumberOfThreads = 0;
memset(&m_seqHeader, 0, sizeof(m_seqHeader));
memset(&m_picHeader, 0, sizeof(m_picHeader));
m_iPrevSliceStartCode = 0;
m_iNumFrames = 0;
return UMC_OK;
} // Status AVSFussionCore::Close(void)
#define AVS_ALLOCATE_PROCESSING_UNIT(name) \
{ \
AVSListElement<AVSProcessingUnit> *pTemp; \
pTemp = new name(); \
if (NULL == pTemp) \
return UMC_ERR_ALLOC; \
m_pPerformers[i].AddToTail(*pTemp); \
umcRes = pTemp->Init(&m_guard); \
if (UMC_OK != umcRes) \
return UMC_ERR_FAILED; \
}
Status AVSFussionCore::Init(Ipp32s iNumThreads, VideoDecoderParams *pParams)
{
AVSListElement<AVSProcessingUnit> *pPerf;
Status umcRes;
Ipp32s i;
// check error(s)
if (0 >= iNumThreads)
return UMC_ERR_INVALID_PARAMS;
// release the object before initialization
Close();
// initialize the synchronization tool
if (false == m_guard.IsInited())
{
umcRes = m_guard.Init();
if (UMC_OK != umcRes)
return umcRes;
}
// do initialization
m_iNumberOfThreads = iNumThreads;
// allocate the performers array
m_pPerformers = new AVSList<AVSProcessingUnit> [m_iNumberOfThreads];
if (NULL == m_pPerformers)
return UMC_ERR_ALLOC;
// allocates the specific performers
pPerf = new AVSColorProcessingUnit();
if (NULL == pPerf)
return UMC_ERR_ALLOC;
m_pPerformers[0].AddToTail(*pPerf);
umcRes = ((AVSColorProcessingUnit *) pPerf)->Init(&m_guard, pParams->pPostProcessing);
if (UMC_OK != umcRes)
return UMC_ERR_FAILED;
for (i = 0; i < m_iNumberOfThreads; i += 1)
{
// allocate the deblocker
AVS_ALLOCATE_PROCESSING_UNIT(AVSDebProcessingUnit);
// allocate the decoder(s)
if (1 == m_iNumberOfThreads)
{
AVS_ALLOCATE_PROCESSING_UNIT(AVSDecRecProcessingUnit);
}
else
{
AVS_ALLOCATE_PROCESSING_UNIT(AVSRecProcessingUnit);
AVS_ALLOCATE_PROCESSING_UNIT(AVSDecProcessingUnit);
}
// allocate the sleeper
AVS_ALLOCATE_PROCESSING_UNIT(AVSSleepProcessingUnit);
}
return UMC_OK;
} // Status AVSFussionCore::Init(Ipp32s iNumThreads, VideoDecoderParams *pParams)
Status AVSFussionCore::Reset(void)
{
AutomaticMutex guard(m_guard.ExtractHandle());
AVSListElement<AVSFrame> *pFrame;
// just merge being processed frames into the free queue.
m_FreeFrames.AddToTail(m_Frames);
// reset being processed frames
pFrame = m_FreeFrames.GetHead();
while (pFrame)
{
// move slices and memory pieces into the corresponding lists
PurgeFrame(pFrame);
// get the next frame
pFrame = pFrame->GetNext();
}
return UMC_OK;
} // Status AVSFussionCore::Reset(void)
Status AVSFussionCore::SetDestination(VideoData *pDst)
{
AVSListElement<AVSFrame> *pFrame, *pPrevRef = NULL, *pToShow = NULL;
// we can touch frame queue without the synchronization,
// because we not intend to modify it.
pFrame = m_Frames.GetHead();
while (pFrame)
{
if (false == pFrame->IsShown())
{
if (pFrame->IsReference())
{
// first reference frame should be shown first
if (NULL == pPrevRef)
{
pToShow = pFrame;
break;
}
else if (false == pPrevRef->IsShown())
{
pToShow = pPrevRef;
break;
}
}
else
{
// any non-reference frame can be shown
pToShow = pFrame;
break;
}
}
// save the previous reference frame
if (pFrame->IsReference())
pPrevRef = pFrame;
// get the next frame
pFrame = pFrame->GetNext();
}
// show the last reference
if ((NULL == pFrame) &&
(pPrevRef) &&
(false == pPrevRef->IsShown()))
{
pToShow = pPrevRef;
}
if (NULL == pToShow)
return UMC_ERR_NOT_ENOUGH_DATA;
// save the conversion parameters
pToShow->m_cnvCtx.m_pPicDst = pDst;
return UMC_OK;
} // Status AVSFussionCore::SetDestination(VideoData *pDst)
AVSProcessingUnit *AVSFussionCore::GetTask(Ipp32s iThreadNum)
{
AutomaticMutex guard(m_guard.ExtractHandle());
AVSListElement<AVSProcessingUnit> *pPerf = m_pPerformers[iThreadNum].GetHead();
Status umcRes = UMC_OK;
do
{
// try one by one all performers from a queue
if (pPerf->LoadJob(m_Frames.GetHead()))
return pPerf;
pPerf = pPerf->GetNext();
} while (UMC_OK == umcRes);
// it is an impossible case,
// we always must get a performer
return NULL;
} // AVSProcessingUnit *AVSFussionCore::GetTask(Ipp32s iThreadNum)
} // namespace UMC
#endif // #if defined(UMC_ENABLE_AVS_VIDEO_DECODER)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -