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

📄 umc_h264_task_supplier.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*
//
//              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_task_supplier.h"
#include "umc_h264_frame_list.h"
#include "umc_automatic_mutex.h"
#include "umc_h264_nal_spl.h"
#include "umc_h264_bitstream.h"

#include "umc_h264_dec_defs_dec.h"
#include "vm_sys_info.h"
#include "umc_h264_segment_decoder_mt.h"


#include "umc_h264_task_broker.h"
#include "umc_video_processing.h"
#include "umc_structures.h"

#if 0
#include <cstdarg>
inline
void Trace(vm_char * format, ...)
{
    va_list(arglist);
    va_start(arglist, format);

    vm_char cStr[256];
    vsprintf(cStr, format, arglist);

    //OutputDebugString(cStr);
    printf("%s", cStr);
    //fflush(stdout);
}

#if defined _DEBUG
#define DEBUG_PRINT(x) Trace x
Ipp32s frame_count = 0;
#else
#define DEBUG_PRINT(x)
#endif

#else
#define DEBUG_PRINT(x)
#endif

namespace UMC
{

inline ColorFormat GetColorFormat(Ipp32s color_format)
{
    ColorFormat format;
    switch(color_format)
    {
    case 0:
        format = GRAY;
        break;
    case 2:
        format = YUV422;
        break;
    case 3:
        format = YUV444;
        break;
    case 1:
    default:
        format = YUV420;
        break;
    }

    return format;
}

void OnSlideWindow(H264DecoderFrame *pRefFrame, H264DecoderFrame *pCurrentFrame, NotifiersChain * defaultChain, bool force)
{
    if (!pRefFrame)
        return;

    if (!pRefFrame->IsFrameExist())
    {
        pRefFrame->setWasOutputted();
        return;
    }

    if (force || (!pRefFrame->isShortTermRef() && !pRefFrame->isLongTermRef()))
    {
        NotifiersChain *notif = defaultChain;

        if (pCurrentFrame && pCurrentFrame->GetBusyState() >= 2)
        {
            VM_ASSERT(pCurrentFrame);
            notif = pCurrentFrame->GetNotifiersChain();
        }

        if (notif)
        {
            pRefFrame->IncrementBusyState();
            notif->AddNotifier(new notifier0<H264DecoderFrame>
                (pRefFrame, &H264DecoderFrame::DecrementBusyState));
        }
    }
}

bool CutPlanes(H264DecoderFrame * , H264SeqParamSet * );
#if 0
void CheckRef(H264DecoderFrame ** refs, H264DecoderFrame *pFrame)
{
    for (Ipp32s i = 0; refs[i]; i++)
    {
        if (refs[i] == pFrame)
        {
            __asm int 3;
        }
    }
}

void CheckReferences(UMC::H264DecoderFrame * pFrame, UMC::H264DecoderFrame * start)
{
    if (pFrame)
    {
        H264DecoderFrame * pTemp = start;
        while (pTemp)
        {
            if (pTemp == pFrame)
            {
                pTemp = pTemp->future();
                continue;
            }

            H264DecoderFrameInfo * auInfo = pTemp->GetAU(0);

            if (auInfo->GetStatus() != H264DecoderFrameInfo::STATUS_COMPLETED)
            {
                for (Ipp32s i = 0; i < auInfo->m_SliceCount; i++)
                {
                    H264Slice * slice = auInfo->m_pSliceQueue[i];

                    H264DecoderFrame ** refs = pTemp->GetRefPicList(slice->GetSliceNum(), 0)->m_RefPicList;
                    CheckRef(refs, pFrame);
                    refs = pTemp->GetRefPicList(slice->GetSliceNum(), 1)->m_RefPicList;
                    CheckRef(refs, pFrame);
                }

                for (Ipp32s i = 0; i < auInfo->m_SliceCountNonActual; i++)
                {
                    H264Slice * slice = auInfo->m_pSliceQueueNonActual[i];

                    H264DecoderFrame ** refs = pTemp->GetRefPicList(slice->GetSliceNum(), 0)->m_RefPicList;
                    CheckRef(refs, pFrame);
                    refs = pTemp->GetRefPicList(slice->GetSliceNum(), 1)->m_RefPicList;
                    CheckRef(refs, pFrame);
                }
            }


            auInfo = pTemp->GetAU(1);

            if (auInfo->GetStatus() != H264DecoderFrameInfo::STATUS_COMPLETED)
            {
                for (Ipp32s i = 0; i < auInfo->m_SliceCount; i++)
                {
                    H264Slice * slice = auInfo->m_pSliceQueue[i];

                    H264DecoderFrame ** refs = pTemp->GetRefPicList(slice->GetSliceNum(), 0)->m_RefPicList;
                    CheckRef(refs, pFrame);
                    refs = pTemp->GetRefPicList(slice->GetSliceNum(), 1)->m_RefPicList;
                    CheckRef(refs, pFrame);
                }

                for (Ipp32s i = 0; i < auInfo->m_SliceCountNonActual; i++)
                {
                    H264Slice * slice = auInfo->m_pSliceQueueNonActual[i];

                    H264DecoderFrame ** refs = pTemp->GetRefPicList(slice->GetSliceNum(), 0)->m_RefPicList;
                    CheckRef(refs, pFrame);
                    refs = pTemp->GetRefPicList(slice->GetSliceNum(), 1)->m_RefPicList;
                    CheckRef(refs, pFrame);
                }
            }

            pTemp = pTemp->future();
        }
    }
}
#endif

/****************************************************************************************************/
// Skipping class routine
/****************************************************************************************************/
Skipping::Skipping()
    : m_VideoDecodingSpeed(0)
    , m_SkipCycle(1)
    , m_ModSkipCycle(1)
    , m_SkipFlag(0)
    , m_PermanentTurnOffDeblocking(0)
    , m_NumberOfSkippedFrames(0)
{
}

void Skipping::Reset()
{
    m_VideoDecodingSpeed = 0;
    m_SkipCycle = 0;
    m_ModSkipCycle = 0;
    m_PermanentTurnOffDeblocking = 0;
    m_NumberOfSkippedFrames = 0;
}

bool Skipping::IsShouldSkipDeblocking(H264DecoderFrame * pFrame, Ipp32s field)
{
    return (IS_SKIP_DEBLOCKING_MODE_PERMANENT ||
        (IS_SKIP_DEBLOCKING_MODE_NON_REF && !pFrame->GetAU(field)->IsReference()));
}

bool Skipping::IsShouldSkipFrame(H264DecoderFrame * pFrame, Ipp32s /*field*/)
{
    bool isShouldSkip = false;

    //bool isReference = pFrame->GetAU(field)->IsReference();

    bool isReference0 = pFrame->GetAU(0)->IsReference();
    bool isReference1 = pFrame->GetAU(1)->IsReference();

    bool isReference = isReference0 || isReference1;

    if ((m_VideoDecodingSpeed > 0) && !isReference)
    {
        if ((m_SkipFlag % m_ModSkipCycle) == 0)
        {
            isShouldSkip = true;
        }

        m_SkipFlag++;

        if (m_SkipFlag >= m_SkipCycle)
            m_SkipFlag = 0;
    }

    if (isShouldSkip)
        m_NumberOfSkippedFrames++;

    return isShouldSkip;
}

void Skipping::ChangeVideoDecodingSpeed(Ipp32s & num)
{
    m_VideoDecodingSpeed += num;

    if (m_VideoDecodingSpeed < 0)
        m_VideoDecodingSpeed = 0;
    if (m_VideoDecodingSpeed > 7)
        m_VideoDecodingSpeed = 7;

    num = m_VideoDecodingSpeed;

    if (m_VideoDecodingSpeed > 6)
    {
        m_SkipCycle = 1;
        m_ModSkipCycle = 1;
        m_PermanentTurnOffDeblocking = 2;
    }
    else if (m_VideoDecodingSpeed > 5)
    {
        m_SkipCycle = 1;
        m_ModSkipCycle = 1;
        m_PermanentTurnOffDeblocking = 0;
    }
    else if (m_VideoDecodingSpeed > 4)
    {
        m_SkipCycle = 3;
        m_ModSkipCycle = 2;
        m_PermanentTurnOffDeblocking = 1;
    }
    else if (m_VideoDecodingSpeed > 3)
    {
        m_SkipCycle = 3;
        m_ModSkipCycle = 2;
        m_PermanentTurnOffDeblocking = 0;
    }
    else if (m_VideoDecodingSpeed > 2)
    {
        m_SkipCycle = 2;
        m_ModSkipCycle = 2;
        m_PermanentTurnOffDeblocking = 0;
    }
    else if (m_VideoDecodingSpeed > 1)
    {
        m_SkipCycle = 3;
        m_ModSkipCycle = 3;
        m_PermanentTurnOffDeblocking = 0;
    }
    else if (m_VideoDecodingSpeed == 1)
    {
        m_SkipCycle = 4;
        m_ModSkipCycle = 4;
        m_PermanentTurnOffDeblocking = 0;
    }
    else
    {
        m_PermanentTurnOffDeblocking = 0;
    }
}

H264VideoDecoder::SkipInfo Skipping::GetSkipInfo() const
{
    H264VideoDecoder::SkipInfo info;
    info.isDeblockingTurnedOff = (m_VideoDecodingSpeed == 5) || (m_VideoDecodingSpeed == 7);
    info.numberOfSkippedFrames = m_NumberOfSkippedFrames;
    return info;
}

struct H264IntraTypesProp
{
    Ipp32s m_nSize;                                             // (Ipp32s) size of allocated intra type array
    MemID m_mid;                                                // (MemID) mem id of allocated buffer for intra types

    void Reset(void)
    {
        m_nSize = 0;
        m_mid = 0;
    }
};

/****************************************************************************************************/
// TaskSupplier
/****************************************************************************************************/
TaskSupplier::TaskSupplier(VideoData &lastDecodedFrame, BaseCodec *&postProcessing)
    : m_pDecodedFramesList(0)
    , m_MaxLongTermFrameIdx(0)
    , m_pNALSplitter(0)
    , m_pFirstUncompletedFrame(0)
    , m_pTaskBroker(0)

    , m_midParsedData(0)
    , m_pParsedData(0)
    , m_parsedDataLength(0)
    , m_PostProcessing(postProcessing)
    , m_LastDecodedFrame(lastDecodedFrame)
    , m_iThreadNum(0)
    , m_maxDecFrameBuffering(1)
    , m_dpbSize(1)
    , m_DPBSizeEx(0)
    , m_TrickModeSpeed(1)
    , m_UIDFrameCounter(0)
    , m_pSegmentDecoder(0)
    , m_ppMBIntraTypes(0)
    , m_piMBIntraProp(0)
    , m_pMBInfo(0)
    , m_pLastDisplayed(0)
{
}

TaskSupplier::~TaskSupplier()
{
    Close();
}

Status TaskSupplier::Init(BaseCodecParams *pInit)
{
    VideoDecoderParams *init = DynamicCast<VideoDecoderParams> (pInit);

    if (NULL == init)
        return UMC_ERR_NULL_PTR;

    Close();

    m_dpbSize = 0;
    m_DPBSizeEx = 0;
    m_pCurrentFrame = 0;
    m_iCurrentResource = 0;

    if (ABSOWN(init->dPlaybackRate - 1) > 0.0001)
    {
        m_TrickModeSpeed = 2;
    }
    else
    {
        m_TrickModeSpeed = 1;
    }

    Ipp32s nAllowedThreadNumber = init->numThreads;
    if(nAllowedThreadNumber < 0) nAllowedThreadNumber = 0;
    if(nAllowedThreadNumber > 8) nAllowedThreadNumber = 8;
#ifdef _DEBUG
    if (!nAllowedThreadNumber)
        nAllowedThreadNumber = 1;
#endif // _DEBUG

    // calculate number of slice decoders.
    // It should be equal to CPU number
    m_iThreadNum = (0 == nAllowedThreadNumber) ? (vm_sys_info_get_cpu_num()) : (nAllowedThreadNumber);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -