⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umc_h264_slice_decoding.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
//
//              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 + -