📄 umc_h264_slice_decoding.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_slice_decoding.h"
#include "umc_h264_segment_decoder_mt.h"
#include "umc_h264_heap.h"
namespace UMC
{
H264ThreadedDeblockingTools::H264ThreadedDeblockingTools(void)
{
} // H264ThreadedDeblockingTools::H264ThreadedDeblockingTools(void)
H264ThreadedDeblockingTools::~H264ThreadedDeblockingTools(void)
{
Release();
} // H264ThreadedDeblockingTools::~H264ThreadedDeblockingTools(void)
void H264ThreadedDeblockingTools::Release(void)
{
// there is nothing to do
} // void H264ThreadedDeblockingTools::Release(void)
bool H264ThreadedDeblockingTools::Init(Ipp32s iConsumerNumber)
{
// release object before initialization
Release();
// save variables
m_iConsumerNumber = IPP_MIN(NUMBER_OF_DEBLOCKERS, iConsumerNumber) * 2;
// allocate working flags
if (false == m_bThreadWorking.Init(m_iConsumerNumber))
return false;
// allocate array for current macroblock number
if (false == m_iCurMBToDeb.Init(m_iConsumerNumber))
return false;
return true;
} // bool H264ThreadedDeblockingTools::Init(Ipp32s iConsumerNumber)
static
void GetDeblockingRange(Ipp32s &iLeft,
Ipp32s &iRight,
Ipp32s iMBWidth,
Ipp32s iThreadNumber,
Ipp32s iConsumerNumber,
Ipp32s iDebUnit)
{
// calculate left value
if (0 == iThreadNumber)
iLeft = 0;
else
iLeft = align_value<Ipp32s> (iMBWidth * iThreadNumber / iConsumerNumber,
iDebUnit);
// calculate right value
if (iConsumerNumber - 1 == iThreadNumber)
iRight = iMBWidth - 1;
else
// calculate right as left_for_next_thread - deb_unit
iRight = align_value<Ipp32s> ((iMBWidth * (iThreadNumber + 1)) / iConsumerNumber,
iDebUnit) - 1;
} // void GetDeblockingRange(Ipp32s &iLeft,
void H264ThreadedDeblockingTools::Reset(Ipp32s iFirstMB, Ipp32s iMaxMB, Ipp32s iDebUnit, Ipp32s iMBWidth)
{
Ipp32s i;
Ipp32s iCurrMB = iFirstMB;
Ipp32s iCurrMBInRow = iCurrMB % iMBWidth;
// save variables
m_iMaxMB = iMaxMB;
m_iDebUnit = iDebUnit;
m_iMBWidth = iMBWidth;
// reset event(s) & current position(s)
for (i = 0; i < m_iConsumerNumber; i += 1)
{
Ipp32s iLeft, iRight;
// get working range for this thread
GetDeblockingRange(iLeft, iRight, iMBWidth, i, m_iConsumerNumber, iDebUnit);
// reset current MB to deblock
if (iCurrMBInRow < iLeft)
m_iCurMBToDeb[i] = iCurrMB - iCurrMBInRow + iLeft;
else if (iCurrMBInRow > iRight)
m_iCurMBToDeb[i] = iCurrMB - iCurrMBInRow + iMBWidth + iLeft;
else
m_iCurMBToDeb[i] = iCurrMB;
// set current thread working status
m_bThreadWorking[i] = false;
}
} // void H264ThreadedDeblockingTools::Reset(Ipp32s iFirstMB, Ipp32s iMaxMB, Ipp32s iDebUnit, Ipp32s iMBWidth)
bool H264ThreadedDeblockingTools::GetMBToProcess(H264Task *pTask)
{
Ipp32s iThreadNumber;
Ipp32s iFirstMB, iMBToProcess;
for (iThreadNumber = 0; iThreadNumber < m_iConsumerNumber; iThreadNumber += 1)
{
if (GetMB(iThreadNumber, iFirstMB, iMBToProcess))
{
// prepare task
pTask->m_bDone = false;
pTask->m_bError = false;
pTask->m_iFirstMB = iFirstMB;
pTask->m_iMaxMB = m_iMaxMB;
pTask->m_iMBToProcess = iMBToProcess;
pTask->m_iTaskID = TASK_DEB_THREADED;
pTask->m_pSlice = NULL;
pTask->pFunction = &H264SegmentDecoderMultiThreaded::DeblockSegmentTask;
#ifdef ECHO_DEB
DEBUG_PRINT(VM_STRING("(%d) dbt - % 4d to % 4d\n"), pTask->m_iThreadNumber,
pTask->m_iFirstMB, pTask->m_iFirstMB + pTask->m_iMBToProcess));
#endif // ECHO_DEB
return true;
}
}
return false;
} // bool H264ThreadedDeblockingTools::GetMBToProcess(H264Task *pTask)
bool H264ThreadedDeblockingTools::GetMB(Ipp32s iThreadNumber,
Ipp32s &iFirstMB,
Ipp32s &iMBToProcess)
{
Ipp32s iCur;
Ipp32s iNumber = iThreadNumber;
Ipp32s iLeft, iRight;
// do we have anything to do ?
iCur = m_iCurMBToDeb[iNumber];
if ((iCur >= m_iMaxMB) ||
(m_bThreadWorking[iThreadNumber]))
return false;
// get working range for this thread
GetDeblockingRange(iLeft, iRight, m_iMBWidth, iNumber, m_iConsumerNumber, m_iDebUnit);
// the left column
if (0 == iNumber)
{
if (m_iCurMBToDeb[iNumber + 1] <= iCur - (iCur % m_iMBWidth) - m_iMBWidth + iRight + m_iDebUnit)
return false;
iFirstMB = m_iCurMBToDeb[iNumber];
iMBToProcess = iRight - IPP_MAX(iLeft, iCur % m_iMBWidth) + 1;
m_bThreadWorking[iThreadNumber] = true;
return true;
}
// a middle column
if (m_iConsumerNumber - 1 != iNumber)
{
if ((m_iCurMBToDeb[iNumber - 1] < iCur) ||
(m_iCurMBToDeb[iNumber + 1] <= iCur - (iCur % m_iMBWidth) - m_iMBWidth + iRight + m_iDebUnit))
return false;
iFirstMB = m_iCurMBToDeb[iNumber];
iMBToProcess = iRight - IPP_MAX(iLeft, iCur % m_iMBWidth) + 1;
m_bThreadWorking[iThreadNumber] = true;
return true;
}
// the right column
if (m_iConsumerNumber - 1 == iNumber)
{
if (m_iCurMBToDeb[iNumber - 1] < iCur)
return false;
iFirstMB = m_iCurMBToDeb[iNumber];
iMBToProcess = iRight - IPP_MAX(iLeft, iCur % m_iMBWidth) + 1;
m_bThreadWorking[iThreadNumber] = true;
return true;
}
return false;
} // bool H264ThreadedDeblockingTools::GetMB(Ipp32s iThreadNumber,
void H264ThreadedDeblockingTools::SetProcessedMB(H264Task *pTask)
{
Ipp32s iThreadNumber;
for (iThreadNumber = 0; iThreadNumber < m_iConsumerNumber; iThreadNumber += 1)
{
if (m_iCurMBToDeb[iThreadNumber] == pTask->m_iFirstMB)
{
SetMB(iThreadNumber, m_iCurMBToDeb[iThreadNumber], pTask->m_iMBToProcess);
break;
}
}
} // void H264ThreadedDeblockingTools::SetProcessedMB(H264Task *pTask)
void H264ThreadedDeblockingTools::SetMB(Ipp32s iThreadNumber,
Ipp32s iFirstMB,
Ipp32s iMBToProcess)
{
Ipp32s iLeft, iRight, iCur;
Ipp32s iNumber;
// fill variables
iNumber = iThreadNumber;
iCur = iFirstMB;
// get working range for this thread
GetDeblockingRange(iLeft, iRight, m_iMBWidth, iNumber, m_iConsumerNumber, m_iDebUnit);
VM_ASSERT(iCur == m_iCurMBToDeb[iNumber]);
// increment current working MB index
iCur += iMBToProcess;
// correct current macroblock index to working range
{
Ipp32s iRest = iCur % m_iMBWidth;
iRest = (iRest) ? (iRest) : (m_iMBWidth);
if (iRest > iRight)
iCur = iCur - iRest + m_iMBWidth + iLeft;
// save current working MB index
m_iCurMBToDeb[iNumber] = iCur;
}
m_bThreadWorking[iNumber] = false;
} // void H264ThreadedDeblockingTools::SetMB(Ipp32s iThreadNumber,
bool H264ThreadedDeblockingTools::IsDeblockingDone(void)
{
bool bDeblocked = false;
Ipp32s i;
// test whole slice deblocking condition
for (i = 0; i < m_iConsumerNumber; i += 1)
{
if (m_iCurMBToDeb[i] < m_iMaxMB)
break;
}
if (m_iConsumerNumber == i)
bDeblocked = true;
return bDeblocked;
} // bool H264ThreadedDeblockingTools::IsDeblockingDone(void)
H264Slice::H264Slice()
{
// DEBUG tools: set following variable to turn of deblocking
m_bPermanentTurnOffDeblocking = false;
// end of DEBUG tools
m_pPicParamSet = 0;
m_pSeqParamSet = 0;
m_pSeqParamSetEx = 0;
m_iMBWidth = -1;
m_iMBHeight = -1;
m_CurrentPicParamSet = -1;
m_CurrentSeqParamSet = -1;
m_iAllocatedMB = 0;
m_pNext = NULL;
m_pCurrentFrame = 0;
m_pMemoryAllocator = 0;//pMemoryAllocator; // DEBUG : !!!
m_DistScaleFactorAFF = 0;
m_DistScaleFactorMVAFF = 0;
}
H264Slice::H264Slice(MemoryAllocator *pMemoryAllocator)
{
// DEBUG tools: set following variable to turn of deblocking
m_bPermanentTurnOffDeblocking = false;
// end of DEBUG tools
m_pPicParamSet = 0;
m_pSeqParamSet = 0;
m_pSeqParamSetEx = 0;
m_iMBWidth = -1;
m_iMBHeight = -1;
m_CurrentPicParamSet = -1;
m_CurrentSeqParamSet = -1;
m_iAllocatedMB = 0;
m_pNext = NULL;
m_pCurrentFrame = 0;
m_pMemoryAllocator = pMemoryAllocator;
m_DistScaleFactorAFF = 0;
m_DistScaleFactorMVAFF = 0;
} // H264Slice::H264Slice(void)
H264Slice::~H264Slice(void)
{
Release();
m_iAllocatedMB = 0;
} // H264Slice::~H264Slice(void)
void H264Slice::Release(void)
{
m_pPicParamSet = 0;
m_pSeqParamSet = 0;
m_pSeqParamSetEx = 0;
m_iMBWidth = -1;
m_iMBHeight = -1;
m_CurrentPicParamSet = -1;
m_CurrentSeqParamSet = -1;
m_CoeffsBuffers.Reset();
m_pNext = NULL;
delete m_DistScaleFactorAFF;
delete m_DistScaleFactorMVAFF;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -