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

📄 umc_avs_dec_fussion_core.cpp

📁 audio-video-codecs.rar语音编解码器
💻 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 + -