📄 umc_h264_task_broker.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 <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 + -