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

📄 umc_h264_task_broker.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*
//
//              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 <cstdarg>
#include "umc_h264_task_broker.h"
#include "umc_h264_segment_decoder_mt.h"
#include "umc_h264_heap.h"
#include "umc_h264_task_supplier.h"
#include "umc_h264_frame_list.h"

//#define ECHO
//#define ECHO_DEB
//#define VM_DEBUG
//#define _TASK_MESSAGE

//#define TIME

//#define LIGHT_SYNC

static Ipp32s lock_failed = 0;
static Ipp32s sleep_count = 0;

/*__declspec(naked)
int TryRealGet(void *)
{
    __asm
    {
        mov eax, 01h
        xor edx, edx
        mov ecx, dword ptr [esp + 04h]
        lock cmpxchg dword ptr [ecx], edx
        setz al
        movzx eax, al
        ret
    }
}

Ipp32s TryToGet(void *p)
{
    Ipp32s res = TryRealGet(p);
    if (!res)
        lock_failed++;
    return res;
}*/

template<class T>
static void swap(T & t1, T & t2)
{
    T & temp = t1;
    t1 = t2;
    t2 = temp;
}

#if 0
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);
    va_end(arglist);
    fflush(stdout);
}

#if defined ECHO || defined TIME
#define DEBUG_PRINT(x) Trace x
#else
#define DEBUG_PRINT(x)
#endif

#if 0
#define DEBUG_PRINT1(x) Trace x
#else
#define DEBUG_PRINT1(x)
#endif


#else
#define DEBUG_PRINT(x)
#define DEBUG_PRINT1(x)
#endif

namespace UMC
{

void PrintInfoStatus(H264DecoderFrameInfo * info)
{
    if (!info)
        return;

    printf("needtoCheck - %d. status - %d\n", info->GetRefAU() != 0, info->GetStatus());
    /*for (Ipp32s i = 0; i < info->GetSliceCount(); i++)
    {
        printf("slice - %d\n", i);
        H264Slice * pSlice = info->GetSlice(i);
        printf("POC - (%d, %d), \n", info->m_pFrame->m_PicOrderCnt[0], info->m_pFrame->m_PicOrderCnt[1]);
        printf("cur to dec - %d\n", pSlice->m_iCurMBToDec);
        printf("cur to rec - %d\n", pSlice->m_iCurMBToRec);
        printf("cur to deb - %d\n", pSlice->m_iCurMBToDeb);
        printf("dec, rec, deb vacant - %d, %d, %d\n", pSlice->m_bDecVacant, pSlice->m_bRecVacant, pSlice->m_bDebVacant);
        printf("in/out buffers available - %d, %d\n", pSlice->m_CoeffsBuffers.IsInputAvailable(), pSlice->m_CoeffsBuffers.IsOutputAvailable());
        fflush(stdout);
    }*/
}

void PrintAllInfos(H264DecoderFrame * frame)
{
    printf("all info\n");
    for (; frame; frame = frame->future())
    {
        H264DecoderFrameInfo *slicesInfo = frame->GetAU(0);

        if (slicesInfo->GetAllSliceCount())
        {
            printf("poc - %d\n", slicesInfo->m_pFrame->m_PicOrderCnt[0]);
            if (slicesInfo->IsField())
            {
                PrintInfoStatus(slicesInfo);
                PrintInfoStatus(frame->GetAU(1));
            }
            else
            {
                PrintInfoStatus(slicesInfo);
            }
        }
    }

    printf("all info end\n");
}

Ipp32s GetDecodingOffset(H264DecoderFrameInfo * curInfo, Ipp32s &readyCount)
{
    Ipp32s offset = 0;

    H264DecoderFrameInfo * refInfo = curInfo->GetRefAU();
    VM_ASSERT(refInfo);

    if (curInfo->m_pFrame != refInfo->m_pFrame)
    {
        switch(curInfo->m_pFrame->m_PictureStructureForDec)
        {
        case FRM_STRUCTURE:
            if (refInfo->m_pFrame->m_PictureStructureForDec == FLD_STRUCTURE)
            {
                readyCount *= 2;
                offset++;
            }
            else
            {
            }
            break;
        case AFRM_STRUCTURE:
            if (refInfo->m_pFrame->m_PictureStructureForDec == FLD_STRUCTURE)
            {
                readyCount *= 2;
                offset++;
            }
            else
            {
            }
            break;
        case FLD_STRUCTURE:
            switch(refInfo->m_pFrame->m_PictureStructureForDec)
            {
            case FLD_STRUCTURE:
                break;
            case AFRM_STRUCTURE:
            case FRM_STRUCTURE:
                readyCount /= 2;
                offset++;
                break;
            }
            break;
        }
    }

    return offset;
}


#ifdef TIME

static
class CTimer
{
public:

    enum
    {
        NUMBER_OF_THREADS = 4
    };

    CTimer(void)
    {
        memset(m_iDecTime, 0, sizeof(m_iDecTime));
        memset(m_iRecTime, 0, sizeof(m_iRecTime));
        memset(m_iDebTime, 0, sizeof(m_iDebTime));
        memset(m_iDebTimeT, 0, sizeof(m_iDebTimeT));
        memset(m_iSleepTime, 0, sizeof(m_iSleepTime));
        memset(m_iDebSleepTime, 0, sizeof(m_iDebSleepTime));
    }

    ~CTimer(void)
    {
        Ipp32s i;

        for (i = 0; i < NUMBER_OF_THREADS; i += 1)
        {
            DEBUG_PRINT((VM_STRING("%d: dec - % 8d, rec - % 8d, deb - % 8d, deb th - % 8d (sleep - % 8d, in deb - % 8d)\n"),
                    i,
                    (Ipp32s) (m_iDecTime[i] / 1000000),
                    (Ipp32s) (m_iRecTime[i] / 1000000),
                    (Ipp32s) (m_iDebTime[i] / 1000000),
                    (Ipp32s) (m_iDebTimeT[i] / 1000000),
                    (Ipp32s) (m_iSleepTime[i] / 1000000),
                    (Ipp32s) (m_iDebSleepTime[i] / 1000000)));
        }

        Ipp64s iAll = 0;

        for (i = 0; i < NUMBER_OF_THREADS; i += 1)
        {
            iAll += m_iDecTime[i]+
                           m_iRecTime[i]+
                           m_iDebTime[i]+
                           m_iDebTimeT[i]+
                           m_iSleepTime[i];
        }

        for (i = 0; i < NUMBER_OF_THREADS; i += 1)
        {
            DEBUG_PRINT((VM_STRING("%d: dec - % 8d%%, rec - % 8d%%, deb - % 8d%%, deb th - % 8d%%\n"),
                    i,
                    (Ipp32s) (100 * m_iDecTime[i] / iAll),
                    (Ipp32s) (100 * m_iRecTime[i] / iAll),
                    (Ipp32s) (100 * m_iDebTime[i] / iAll),
                    (Ipp32s) (100 * m_iDebTimeT[i] / iAll)));
        }
    }

    void ThreadStarted(Ipp32s iThread)
    {
        QueryPerformanceCounter((LARGE_INTEGER *) m_iStartTime + iThread);
    }

    void ThreadFinished(Ipp32s iThread, Ipp32s iTask)
    {
        Ipp64s iEnd;

        QueryPerformanceCounter((LARGE_INTEGER *) &iEnd);

        switch (iTask)
        {
        case TASK_DEC_NEXT:
        case TASK_DEC:
            m_iDecTime[iThread] += iEnd - m_iStartTime[iThread];
            break;

        case TASK_REC_NEXT:
        case TASK_REC:
            m_iRecTime[iThread] += iEnd - m_iStartTime[iThread];
            break;

        case TASK_DEB:
            m_iDebTime[iThread] += iEnd - m_iStartTime[iThread];
            break;

        case TASK_DEB_THREADED:
        case TASK_DEB_FRAME_THREADED:
            m_iDebTimeT[iThread] += iEnd - m_iStartTime[iThread];
            break;

        default:
            break;
        };
    }

    void DebSleepStart(Ipp32s iThread)
    {
        QueryPerformanceCounter((LARGE_INTEGER *) m_iStartTime + iThread);
    }

    void DebSleepStop(Ipp32s iThread)
    {
        Ipp64s iEnd;

        QueryPerformanceCounter((LARGE_INTEGER *) &iEnd);

        m_iDebSleepTime[iThread] += iEnd - m_iStartTime[iThread];
    }

    void SleepStart(Ipp32s iThread)
    {
        QueryPerformanceCounter((LARGE_INTEGER *) m_iStartTime + iThread);
    }

    void SleepStop(Ipp32s iThread)
    {
        Ipp64s iEnd;

        QueryPerformanceCounter((LARGE_INTEGER *) &iEnd);

        m_iSleepTime[iThread] += iEnd - m_iStartTime[iThread];
    }

protected:
    Ipp64s m_iDecTime[NUMBER_OF_THREADS];
    Ipp64s m_iRecTime[NUMBER_OF_THREADS];
    Ipp64s m_iDebTime[NUMBER_OF_THREADS];
    Ipp64s m_iDebTimeT[NUMBER_OF_THREADS];
    Ipp64s m_iDebSleepTime[NUMBER_OF_THREADS];
    Ipp64s m_iSleepTime[NUMBER_OF_THREADS];
    Ipp64s m_iStartTime[NUMBER_OF_THREADS];

} timer;

class CStarter
{
public:
    CStarter(Ipp32s iThread)
    {
        m_iThread = iThread;
    }
    ~CStarter(void)
    {
        timer.ThreadStarted(m_iThread);
    }

protected:
    Ipp32s m_iThread;
};

#endif // TIME


enum
{
    CURRENT_SLICE,
    OTHER_SLICES
};


TaskBroker::TaskBroker(TaskSupplier * pTaskSupplier)
    : m_iConsumerNumber(0)
    , m_pTaskSupplier(pTaskSupplier)
{
    Release();
}

TaskBroker::~TaskBroker()
{
    Release();
}

bool TaskBroker::Init(Ipp32s iConsumerNumber)
{
    Release();

    m_Completed.Init(0, 0);

    // we keep this variable due some optimizations purposes
    m_iConsumerNumber = iConsumerNumber;
    m_IsShouldQuit = false;
    return true;
}

void TaskBroker::Reset()
{
    m_pCurrentFrame = 0;
    m_FirstAU = 0;
    is_completed = 0;
    m_IsShouldQuit = true;
}

void TaskBroker::Release()
{
    Reset();
}

void TaskBroker::Lock()
{
    m_mGuard.Lock();
    /*if ((m_mGuard.TryLock() != UMC_OK))
    {
        lock_failed++;
        m_mGuard.Lock();
    }*/
}

void TaskBroker::Unlock()
{
    m_mGuard.Unlock();
}

void TaskBroker::SwitchCurrentAU()
{
    if (!m_FirstAU || !m_FirstAU->IsCompleted())
        return;

    DEBUG_PRINT((VM_STRING("Switch current AU - is_completed %d\n"), m_FirstAU->IsCompleted()));
    //m_FirstAU->SetStatus(H264DecoderFrameInfo::STATUS_COMPLETED);  //quuu

    while (m_FirstAU)
    {
        m_FirstAU = m_FirstAU->GetNextAU();

        if (m_FirstAU)
        {
            m_FirstAU->SetRefAU(0);

            if (m_FirstAU->IsCompleted())
            {
                //m_FirstAU->SetStatus(H264DecoderFrameInfo::STATUS_COMPLETED); // quuu
            }
            else
            {
                break;
            }
        }
    }

    if (!m_FirstAU)
    {
        m_FirstAU = FindAU(m_pTaskSupplier->m_pFirstUncompletedFrame);
        if (m_FirstAU)
        {
            m_FirstAU->SetStatus(H264DecoderFrameInfo::STATUS_STARTED);
            m_FirstAU->SetRefAU(0);
            DEBUG_PRINT1(("SwitchCurrentAU additional poc - %d, first - poc %d\n", m_FirstAU->m_pFrame->m_PicOrderCnt[0], m_pTaskSupplier->m_pFirstUncompletedFrame->m_PicOrderCnt[0]));
        }
    }

    if (m_FirstAU && m_FirstAU->IsSliceGroups())
        m_FirstAU = 0;
}

void TaskBroker::Start()
{
    Lock();
    m_pCurrentFrame = m_pTaskSupplier->m_pFirstUncompletedFrame;
    DEBUG_PRINT1(("start - Cuurentframe poc - %d\n", m_pCurrentFrame->m_PicOrderCnt[0]));

    H264DecoderFrame * frame = m_pCurrentFrame;
    for (; frame; frame = frame->future())
    {
        H264DecoderFrameInfo *slicesInfo = frame->GetAU(0);
        if (slicesInfo->GetStatus() == H264DecoderFrameInfo::STATUS_STARTED)
            slicesInfo->SetStatus(H264DecoderFrameInfo::STATUS_FILLED);

        slicesInfo = frame->GetAU(1);
        if (slicesInfo->GetStatus() == H264DecoderFrameInfo::STATUS_STARTED)
            slicesInfo->SetStatus(H264DecoderFrameInfo::STATUS_FILLED);
    }

    InitAUs(m_pTaskSupplier->m_pFirstUncompletedFrame);
    Unlock();
}

H264DecoderFrameInfo * TaskBroker::FindAU(H264DecoderFrame * frame)
{
    H264DecoderFrame * temp = frame;

    frame = temp;
    for (; frame; frame = frame->future())
    {
        H264DecoderFrameInfo *slicesInfo = frame->GetAU(0);

        if (slicesInfo->GetAllSliceCount())

⌨️ 快捷键说明

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