📄 umc_h264_task_broker.cpp
字号:
info->m_iDecMBReady += pTask->m_iMBToProcess;
}
pSlice->m_iMaxMB = pTask->m_iMaxMB;
// error handling
if (pTask->m_bError)
{
if (isReadyIncrease)
info->m_iDecMBReady = pSlice->m_iMaxMB;
pSlice->m_iMaxMB = pSlice->m_iCurMBToDec;
pSlice->m_bError = true;
}
if (pSlice->m_iCurMBToDec >= pSlice->m_iMaxMB)
{
pSlice->m_bDecVacant = 0;
if (isReadyIncrease)
{
Ipp32s pos = info->GetPositionByNumber(pSlice->GetSliceNum());
VM_ASSERT(pos >= 0);
H264Slice * pNextSlice = info->GetSlice(pos + 1);
if (pNextSlice)
{
info->m_iDecMBReady = pNextSlice->m_iCurMBToDec;
}
}
}
else
{
pSlice->m_bDecVacant = 1;
}
DEBUG_PRINT((VM_STRING("(%d) (%d) (%d) dec ready %d\n"), pTask->m_iThreadNumber, info->m_pFrame->m_PicOrderCnt[0], (Ipp32s)(pSlice->IsBottomField()), info->m_iDecMBReady));
}
break;
case TASK_REC:
{
VM_ASSERT(pTask->m_iFirstMB == pSlice->m_iCurMBToRec);
pSlice->m_iCurMBToRec += pTask->m_iMBToProcess;
bool isReadyIncrease = (pTask->m_iFirstMB == info->m_iRecMBReady) && pSlice->m_bDeblocked;
if (isReadyIncrease)
{
info->m_iRecMBReady += pTask->m_iMBToProcess;
}
// error handling
/*if (pTask->m_bError)
{
if (isReadyIncrease)
{
info->m_iRecMBReady = pSlice->m_iMaxMB;
}
pSlice->m_iMaxMB = pSlice->m_iCurMBToRec;
pSlice->m_bError = true;
}*/
pSlice->m_CoeffsBuffers.UnLockOutputBuffer();
if (pSlice->m_iMaxMB <= pSlice->m_iCurMBToRec)
{
pSlice->m_bRecVacant = 0;
pSlice->m_bDecoded = true;
if (isReadyIncrease)
{
Ipp32s pos = info->GetPositionByNumber(pSlice->GetSliceNum());
VM_ASSERT(pos >= 0);
H264Slice * pNextSlice = info->GetSlice(pos + 1);
if (pNextSlice)
{
if (pNextSlice->m_bDeblocked)
info->m_iRecMBReady = pNextSlice->m_iCurMBToRec;
else
info->m_iRecMBReady = pNextSlice->m_iCurMBToDeb;
info->RemoveSlice(pos);
}
}
// check condition for frame deblocking
//if (DEBLOCK_FILTER_ON_NO_SLICE_EDGES == pSlice->m_SliceHeader.disable_deblocking_filter_idc)
// m_bDoFrameDeblocking = false; // DEBUG : ADB
}
else
{
pSlice->m_bRecVacant = 1;
}
DEBUG_PRINT((VM_STRING("(%d) (%d) (%d) rec ready %d\n"), pTask->m_iThreadNumber, info->m_pFrame->m_PicOrderCnt[0], (Ipp32s)(pSlice->IsBottomField()), info->m_iRecMBReady));
}
break;
case TASK_DEC_REC:
{
VM_ASSERT(pTask->m_iFirstMB == pSlice->m_iCurMBToDec);
VM_ASSERT(pTask->m_iFirstMB == pSlice->m_iCurMBToRec);
pSlice->m_iCurMBToDec += pTask->m_iMBToProcess;
pSlice->m_iCurMBToRec += pTask->m_iMBToProcess;
bool isReadyIncrease = (pTask->m_iFirstMB == info->m_iDecMBReady
&& pTask->m_iFirstMB == info->m_iRecMBReady);
pSlice->m_iMaxMB = pTask->m_iMaxMB;
if (isReadyIncrease)
{
info->m_iDecMBReady += pTask->m_iMBToProcess;
if (pSlice->m_bDeblocked)
info->m_iRecMBReady += pTask->m_iMBToProcess;
}
// error handling
if (pTask->m_bError)
{
if (isReadyIncrease)
{
info->m_iDecMBReady = pSlice->m_iMaxMB;
if (pSlice->m_bDeblocked)
info->m_iRecMBReady = pSlice->m_iMaxMB;
}
pSlice->m_iMaxMB = pSlice->m_iCurMBToDec;
pSlice->m_bError = true;
}
if (pSlice->m_iCurMBToDec >= pSlice->m_iMaxMB)
{
VM_ASSERT(pSlice->m_iCurMBToRec >= pSlice->m_iMaxMB);
pSlice->m_bDecVacant = 0;
pSlice->m_bRecVacant = 0;
pSlice->m_bDecoded = true;
if (isReadyIncrease)
{
Ipp32s pos = info->GetPositionByNumber(pSlice->GetSliceNum());
VM_ASSERT(pos >= 0);
H264Slice * pNextSlice = info->GetSlice(pos + 1);
if (pNextSlice)
{
info->m_iDecMBReady = pNextSlice->m_iCurMBToDec;
if (pSlice->m_bDeblocked)
{
if (pNextSlice->m_bDeblocked)
info->m_iRecMBReady = pNextSlice->m_iCurMBToRec;
else
info->m_iRecMBReady = pNextSlice->m_iCurMBToDeb;
info->RemoveSlice(pos);
}
}
}
}
else
{
pSlice->m_bDecVacant = 1;
pSlice->m_bRecVacant = 1;
}
DEBUG_PRINT((VM_STRING("(%d) (%d) (%d) (%d) dec_rec ready %d %d\n"), pTask->m_iThreadNumber, (Ipp32s)(info != m_FirstAU), info->m_pFrame->m_PicOrderCnt[0], (Ipp32s)(pSlice->IsBottomField()), info->m_iDecMBReady, info->m_iRecMBReady));
}
break;
case TASK_DEB:
{
VM_ASSERT(pTask->m_iFirstMB == pSlice->m_iCurMBToDeb);
pSlice->m_iCurMBToDeb += pTask->m_iMBToProcess;
bool isReadyIncrease = (pTask->m_iFirstMB == info->m_iRecMBReady);
if (isReadyIncrease)
{
info->m_iRecMBReady += pTask->m_iMBToProcess;
}
if (pSlice->m_iMaxMB <= pSlice->m_iCurMBToDeb)
{
pSlice->m_bDeblocked = true;
pSlice->m_bInProcess = false;
pSlice->m_bDecVacant = 0;
pSlice->m_bRecVacant = 0;
Ipp32s pos = info->GetPositionByNumber(pSlice->GetSliceNum());
if (isReadyIncrease)
{
VM_ASSERT(pos >= 0);
H264Slice * pNextSlice = info->GetSlice(pos + 1);
if (pNextSlice)
{
if (pNextSlice->m_bDeblocked)
info->m_iRecMBReady = pNextSlice->m_iCurMBToRec;
else
info->m_iRecMBReady = pNextSlice->m_iCurMBToDeb;
}
}
info->RemoveSlice(pos);
}
else
{
pSlice->m_bDebVacant = 1;
}
DEBUG_PRINT((VM_STRING("(%d) (%d) (%d) after deb ready %d %d\n"), pTask->m_iThreadNumber, info->m_pFrame->m_PicOrderCnt[0], (Ipp32s)(pSlice->IsBottomField()), info->m_iDecMBReady, info->m_iRecMBReady));
}
break;
#if 0
case TASK_DEB_THREADED:
pSlice->m_DebTools.SetProcessedMB(pTask);
if (pSlice->m_DebTools.IsDeblockingDone())
pSlice->m_bDeblocked = true;
break;
case TASK_DEB_FRAME_THREADED:
m_DebTools.SetProcessedMB(pTask);
if (m_DebTools.IsDeblockingDone())
{
Ipp32s i;
// frame is deblocked
for (i = 0; i < GetNumberOfSlicesFromCurrentFrame(); i += 1)
{
H264Slice *pTemp = GetSliceFromCurrentFrame(i);
pTemp->m_bDeblocked = true;
}
}
break;
#endif
default:
// illegal case
VM_ASSERT(false);
break;
}
}
} // void TaskBroker::AddPerformedTask(H264Task *pTask)
bool TaskBroker::IsEnoughForStartDecoding(H264DecoderFrame *& pFrame, bool force)
{
Lock();
H264DecoderFrame * frame = pFrame;
Ipp32s au_count = 0;
for (; frame; frame = frame->future())
{
H264DecoderFrameInfo *slicesInfo = frame->GetAU(0);
if (slicesInfo->GetAllSliceCount())
{
if (slicesInfo->IsField())
{
Ipp32s field_au = 0;
if (slicesInfo->GetStatus() >= H264DecoderFrameInfo::STATUS_FILLED)
field_au++;
if (frame->GetAU(1)->GetStatus() >= H264DecoderFrameInfo::STATUS_FILLED
|| frame->GetAU(1)->GetStatus() == H264DecoderFrameInfo::STATUS_NONE)
field_au++;
if (field_au == 2 || (force && field_au))
au_count++;
}
else
{
if (slicesInfo->GetStatus() >= H264DecoderFrameInfo::STATUS_FILLED)
au_count++;
}
}
}
Unlock();
if (au_count >= m_iConsumerNumber || (force && au_count))
return true;
return false;
}
TaskBrokerSingleThread::TaskBrokerSingleThread(TaskSupplier * pTaskSupplier)
: TaskBroker(pTaskSupplier)
{
}
// Get next working task
bool TaskBrokerSingleThread::GetNextTaskInternal(H264Task *pTask)
{
if (GetNextSlice(m_FirstAU, pTask))
return true;
else
{
// switch to second field
if (m_FirstAU && m_FirstAU->IsField())
{
SwitchCurrentAU();
if (m_FirstAU && m_FirstAU->m_pFrame != m_pCurrentFrame)
{
m_FirstAU = 0;
return false;
}
return GetNextSlice(m_FirstAU, pTask);
}
}
return false;
}
TaskBrokerTwoThread::TaskBrokerTwoThread(TaskSupplier * pTaskSupplier)
: TaskBrokerSingleThread(pTaskSupplier)
{
}
bool TaskBrokerTwoThread::Init(Ipp32s iConsumerNumber)
{
if (!TaskBroker::Init(iConsumerNumber))
return false;
m_nWaitingThreads = 0;
// initilaize event(s)
for (Ipp32s i = 0; i < m_iConsumerNumber; i += 1)
{
if (NULL == m_eWaiting[i])
{
if (false == m_eWaiting.AllocateOneMore())
return false;
if (UMC_OK != m_eWaiting[i]->Init(0, 0))
return false;
}
}
return true;
}
void TaskBrokerTwoThread::Reset()
{
Lock();
TaskBrokerSingleThread::Reset();
AwakeThreads();
Unlock();
}
void TaskBrokerTwoThread::Release()
{
Lock();
TaskBrokerSingleThread::Release();
AwakeThreads();
Unlock();
/*for (Ipp32s i = 0; i < m_iConsumerNumber; i += 1)
{
Event *pEvent = m_eWaiting[i];
if (pEvent)
pEvent->Reset();
}
m_nWaitingThreads = 0;*/
}
void TaskBrokerTwoThread::CompleteFrame()
{
DEBUG_PRINT((VM_STRING("frame completed - poc - %d\n"), m_pCurrentFrame->m_PicOrderCnt[0]));
m_pCurrentFrame = 0;
SwitchCurrentAU();
}
bool TaskBrokerTwoThread::GetNextTaskInternal(H264Task *pTask)
{
#ifdef TIME
CStarter start(pTask->m_iThreadNumber);
#endif // TIME
bool is_completed = m_FirstAU->IsCompleted();
if (m_FirstAU && m_FirstAU->IsSliceGroups())
{
if (!pTask->m_iThreadNumber)
{
if (is_completed)
{
m_FirstAU->SetStatus(H264DecoderFrameInfo::STATUS_COMPLETED);
m_pCurrentFrame = 0;
return false;
}
else
{
return TaskBrokerSingleThread::GetNextTaskInternal(pTask);
}
}
else
{
return false;
}
}
if (m_FirstAU && is_completed)
{
SwitchCurrentAU();
}
while (false == m_IsShouldQuit)
{
if (IsFrameCompleted())
{
if (!pTask->m_iThreadNumber)
{
CompleteFrame();
AwakeThreads();
return false;
}
if (m_pCurrentFrame)
AwakeThreads();
}
if (!m_FirstAU)
{
AwakeThreads();
}
else
{
for (H264DecoderFrameInfo *pTemp = m_FirstAU; pTemp; pTemp = pTemp->GetNextAU())
{
if (pTemp->IsSliceGroups())
break;
if (GetNextTaskManySlices(pTemp, pTask))
{
return true;
}
}
}
#ifdef TIME
timer.SleepStart(pTask->m_iThreadNumber);
#endif // TIME
/*printf("\n\nstart sleeping for thrad - %d\n", pTask->m_iThreadNumber);
PrintInfoStatus(m_FirstAU);
printf("additional - \n");
PrintInfoStatus(m_AdditionalInfo);
printf("end\n");*/
//__asm int 3;
// it is time to sleep
m_nWaitingThreads |= (1 << (pTask->m_iThreadNumber));
DEBUG_PRINT((VM_STRING("(%d) sleep\n"), pTask->m_iThreadNumber));
#ifndef LIGHT_SYNC
Unlock();
#endif
sleep_count++;
m_eWaiting[pTask->m_iThreadNumber]->Wait();
#ifndef LIGHT_SYNC
Lock();
#endif
pTask->m_WrittenSize = 0;
m_nWaitingThreads ^= (1 << (pTask->m_iThreadNumber));
#ifdef TIME
timer.SleepStop(pTask->m_iThreadNumber);
#endif // TIME
};
return false;
}
bool TaskBrokerTwoThread::WrapDecodingTask(H264DecoderFrameInfo * info, H264Task *pTask, H264Slice *pSlice)
{
VM_ASSERT(pSlice);
#ifdef LIGHT_SYNC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -