📄 umc_h264_task_broker.cpp
字号:
{
if (slicesInfo->IsField())
{
if (slicesInfo->GetStatus() == H264DecoderFrameInfo::STATUS_FILLED)
return slicesInfo;
if (frame->GetAU(1)->GetStatus() == H264DecoderFrameInfo::STATUS_FILLED)
return frame->GetAU(1);
}
else
{
if (slicesInfo->GetStatus() == H264DecoderFrameInfo::STATUS_FILLED)
return slicesInfo;
}
}
}
return 0;
}
void TaskBroker::InitAUs(H264DecoderFrame * pFrame)
{
m_FirstAU = FindAU(pFrame);
if (!m_FirstAU)
return;
m_pCurrentFrame = pFrame;
m_FirstAU->SetStatus(H264DecoderFrameInfo::STATUS_STARTED);
H264DecoderFrameInfo * pPrev = m_FirstAU;
m_FirstAU->SetPrevAU(0);
m_FirstAU->SetNextAU(0);
H264DecoderFrameInfo * refAU = 0;
m_FirstAU->SetRefAU(0);
if (m_FirstAU->IsReference())
refAU = m_FirstAU;
H264DecoderFrameInfo * pTemp = FindAU(m_pCurrentFrame);
for (; pTemp; pTemp = FindAU(m_pCurrentFrame))
{
pTemp->SetStatus(H264DecoderFrameInfo::STATUS_STARTED);
pTemp->SetNextAU(0);
pTemp->SetPrevAU(pPrev);
/*if (pTemp->IsIntraAU())
pTemp->SetRefAU(0);
else*/
pTemp->SetRefAU(refAU);
if (pTemp->IsReference())
{
refAU = pTemp;
}
pPrev->SetNextAU(pTemp);
pPrev = pTemp;
}
}
bool TaskBroker::IsFrameCompleted() const
{
return IsFrameCompleted(m_pCurrentFrame);
}
bool TaskBroker::IsFrameCompleted(H264DecoderFrame * pFrame) const
{
if (!pFrame)
return true;
if (!pFrame->GetAU(0)->IsCompleted())
return false;
//pFrame->GetAU(0)->SetStatus(H264DecoderFrameInfo::STATUS_COMPLETED); //quuu
H264DecoderFrameInfo::FillnessStatus status1 = pFrame->GetAU(1)->GetStatus();
bool ret;
switch (status1)
{
case H264DecoderFrameInfo::STATUS_NOT_FILLED:
ret = false;
case H264DecoderFrameInfo::STATUS_COMPLETED:
ret = true;
default:
ret = pFrame->GetAU(1)->IsCompleted();
}
return ret;
}
Ipp32s TaskBroker::GetNumberOfSlicesToReconstruct(H264DecoderFrameInfo * info, bool bOnlyReadySlices)
{
Ipp32s i, iCount = 0;
Ipp32s sliceCount = info->GetSliceCount();
for (i = 0; i < sliceCount; i ++)
{
H264Slice *pSlice = info->GetSlice(i);
if (pSlice->m_iMaxMB > pSlice->m_iCurMBToRec)
{
// we count up all decoding slices
if ((false == bOnlyReadySlices) ||
// or only ready to reconstruct
((pSlice->m_bRecVacant) && (pSlice->m_CoeffsBuffers.IsOutputAvailable())))
iCount += 1;
}
}
return iCount;
} // Ipp32s TaskBroker::GetNumberOfSlicesToReconstruct(void)
bool TaskBroker::IsFrameDeblocked(H264DecoderFrameInfo * info)
{
// this is guarded function, safe to touch any variable
Ipp32s i;
// there is nothing to do
Ipp32s sliceCount = info->GetSliceCount();
if (0 == sliceCount)
return true;
for (i = 0; i < sliceCount; i += 1)
{
H264Slice *pSlice = info->GetSlice(i);
if ((pSlice) &&
(false == pSlice->m_bDeblocked))
return false;
}
return true;
} // bool TaskBroker::IsFrameDeblocked(void)
Ipp32s TaskBroker::GetNumberOfSlicesToDecode(H264DecoderFrameInfo * info)
{
Ipp32s i, iCount = 0;
Ipp32s sliceCount = info->GetSliceCount();
for (i = 0; i < sliceCount; i += 1)
{
H264Slice *pSlice = info->GetSlice(i);
if (pSlice->m_iMaxMB > pSlice->m_iCurMBToDec)
iCount += 1;
}
return iCount;
} // Ipp32s TaskBroker::GetNumberOfSlicesToDecode(void)
bool TaskBroker::GetNextTask(H264Task *pTask)
{
#ifndef LIGHT_SYNC
AutomaticUMCMutex guard(m_mGuard);
#endif
// check error(s)
if (!m_FirstAU)
{
return false;
}
bool res = GetNextTaskInternal(pTask);
return res;
} // bool TaskBroker::GetNextTask(H264Task *pTask)
bool TaskBroker::GetNextSlice(H264DecoderFrameInfo * info, H264Task *pTask)
{
// this is guarded function, safe to touch any variable
// check error(s)
if (!info)
return false;
if (GetNextSliceToDecoding(info, pTask))
return true;
// try to get slice to decode
/*if ((false == GetSliceFromCurrentFrame(0)->IsSliceGroups()) ||
(0 == pTask->m_iThreadNumber))
{
if (GetNextSliceToDecoding(pTask))
return true;
}*/
// try to get slice to deblock
//if ((false == GetSliceFromCurrentFrame(0)->IsSliceGroups()) ||
// (0 == pTask->m_iThreadNumber))
if (info->IsNeedDeblocking())
return GetNextSliceToDeblocking(info, pTask);
return false;
} // bool TaskBroker::GetNextSlice(H264Task *pTask)
void TaskBroker::InitTask(H264DecoderFrameInfo * info, H264Task *pTask, H264Slice *pSlice)
{
pTask->m_bDone = false;
pTask->m_bError = false;
pTask->m_iMaxMB = pSlice->m_iMaxMB;
pTask->m_pSlice = pSlice;
pTask->m_pSlicesInfo = info;
}
bool TaskBroker::GetNextSliceToDecoding(H264DecoderFrameInfo * info, H264Task *pTask)
{
// this is guarded function, safe to touch any variable
Ipp32s i;
bool bDoDeblocking;
// skip some slices, more suitable for first thread
// and first slice is always reserved for first slice decoder
/*if (pTask->m_iThreadNumber)
{
i = IPP_MAX(1, GetNumberOfSlicesFromCurrentFrame() / m_iConsumerNumber);
bDoDeblocking = false;
}
else
{
i = 0;
bDoDeblocking = true;
}*/
i = 0;
bDoDeblocking = false;
// find first uncompressed slice
Ipp32s sliceCount = info->GetSliceCount();
for (; i < sliceCount; i += 1)
{
H264Slice *pSlice = info->GetSlice(i);
if ((false == pSlice->m_bInProcess) &&
(false == pSlice->m_bDecoded))
{
InitTask(info, pTask, pSlice);
pTask->m_iFirstMB = pSlice->m_iFirstMB;
pTask->m_iMBToProcess = IPP_MIN(pSlice->m_iMaxMB - pSlice->m_iFirstMB, pSlice->m_iAvailableMB);
pTask->m_iTaskID = TASK_PROCESS;
pTask->m_pBuffer = NULL;
pTask->pFunction = &H264SegmentDecoderMultiThreaded::ProcessSlice;
// we can do deblocking only on independent slices or
// when all previous slices are deblocked
if (DEBLOCK_FILTER_ON != pSlice->m_SliceHeader.disable_deblocking_filter_idc)
bDoDeblocking = true;
pSlice->m_bPrevDeblocked = bDoDeblocking;
pSlice->m_bInProcess = true;
pSlice->m_bDecVacant = 0;
pSlice->m_bRecVacant = 0;
pSlice->m_bDebVacant = 0;
#ifdef ECHO
DEBUG_PRINT((VM_STRING("(%d) slice dec - % 4d to % 4d\n"), pTask->m_iThreadNumber,
pTask->m_iFirstMB, pTask->m_iFirstMB + pTask->m_iMBToProcess));
#endif // ECHO
return true;
}
}
return false;
} // bool TaskBroker::GetNextSliceToDecoding(H264Task *pTask)
bool TaskBroker::GetNextSliceToDeblocking(H264DecoderFrameInfo * info, H264Task *pTask)
{
// this is guarded function, safe to touch any variable
Ipp32s sliceCount = info->GetSliceCount();
bool bSliceGroups = info->GetSlice(0)->IsSliceGroups();
// slice group deblocking
if (bSliceGroups)
{
Ipp32s iFirstMB = info->GetSlice(0)->m_iFirstMB;
bool bNothingToDo = true;
Ipp32s i;
for (i = 0; i < sliceCount; i += 1)
{
H264Slice *pSlice = info->GetSlice(i);
VM_ASSERT(false == pSlice->m_bInProcess);
pSlice->m_bInProcess = true;
pSlice->m_bDebVacant = 0;
iFirstMB = IPP_MIN(iFirstMB, pSlice->m_iFirstMB);
if (false == pSlice->m_bDeblocked)
bNothingToDo = false;
}
// we already deblocked
if (bNothingToDo)
return false;
H264Slice *pSlice = info->GetSlice(0);
InitTask(info, pTask, pSlice);
pTask->m_iFirstMB = iFirstMB;
Ipp32s iMBInFrame = (pSlice->m_iMBWidth * pSlice->m_iMBHeight) /
((pSlice->m_SliceHeader.field_pic_flag) ? (2) : (1));
pTask->m_iMaxMB = iFirstMB + iMBInFrame;
pTask->m_iMBToProcess = iMBInFrame;
pTask->m_iTaskID = TASK_DEB_FRAME;
pTask->m_pBuffer = 0;
pTask->pFunction = &H264SegmentDecoder::DeblockSlice;
#ifdef ECHO_DEB
DEBUG_PRINT((VM_STRING("(%d) frame deb - % 4d to % 4d\n"), pTask->m_iThreadNumber,
pTask->m_iFirstMB, pTask->m_iFirstMB + pTask->m_iMBToProcess));
#endif // ECHO_DEB
return true;
}
else
{
Ipp32s i;
bool bPrevDeblocked = true;
for (i = 0; i < sliceCount; i += 1)
{
H264Slice *pSlice = info->GetSlice(i);
// we can do deblocking only on vacant slices
if ((false == pSlice->m_bInProcess) &&
(true == pSlice->m_bDecoded) &&
(false == pSlice->m_bDeblocked))
{
// we can do this only when previous slice was deblocked or
// deblocking isn't going through slice boundaries
if ((true == bPrevDeblocked) ||
(false == pSlice->DeblockThroughBoundaries()))
{
InitTask(info, pTask, pSlice);
pTask->m_iFirstMB = pSlice->m_iFirstMB;
pTask->m_iMBToProcess = pSlice->m_iMaxMB - pSlice->m_iFirstMB;
pTask->m_iTaskID = TASK_DEB_SLICE;
pTask->m_pBuffer = NULL;
pTask->pFunction = &H264SegmentDecoder::DeblockSlice;
pSlice->m_bPrevDeblocked = true;
pSlice->m_bInProcess = true;
pSlice->m_bDebVacant = 0;
#ifdef ECHO_DEB
DEBUG_PRINT((VM_STRING("(%d) slice deb - % 4d to % 4d\n"), pTask->m_iThreadNumber,
pTask->m_iFirstMB, pTask->m_iFirstMB + pTask->m_iMBToProcess));
#endif // ECHO_DEB
return true;
}
}
// save previous slices deblocking condition
if (false == pSlice->m_bDeblocked)
bPrevDeblocked = false;
}
}
return false;
} // bool TaskBroker::GetNextSliceToDeblocking(H264Task *pTask)
void TaskBroker::AddPerformedTask(H264Task *pTask)
{
H264Slice *pSlice = pTask->m_pSlice;
H264DecoderFrameInfo * info = pTask->m_pSlicesInfo;
#if defined(ECHO)
switch (pTask->m_iTaskID)
{
case TASK_PROCESS:
DEBUG_PRINT((VM_STRING("(%d) (%d) slice dec done % 4d to % 4d - error - %d\n"), pTask->m_iThreadNumber, info->m_pFrame->m_PicOrderCnt[0], pTask->m_iFirstMB, pTask->m_iFirstMB + pTask->m_iMBToProcess, pTask->m_bError));
break;
case TASK_DEC:
DEBUG_PRINT((VM_STRING("(%d) (%d) (%d) dec done % 4d to % 4d - error - %d\n"), pTask->m_iThreadNumber, info->m_pFrame->m_PicOrderCnt[0], (Ipp32s)(pSlice->IsBottomField()), pTask->m_iFirstMB, pTask->m_iFirstMB + pTask->m_iMBToProcess, pTask->m_bError));
break;
case TASK_REC:
DEBUG_PRINT((VM_STRING("(%d) (%d) (%d) rec done % 4d to % 4d - error - %d\n"), pTask->m_iThreadNumber, info->m_pFrame->m_PicOrderCnt[0], (Ipp32s)(pSlice->IsBottomField()), pTask->m_iFirstMB, pTask->m_iFirstMB + pTask->m_iMBToProcess, pTask->m_bError));
break;
case TASK_DEC_REC:
DEBUG_PRINT((VM_STRING("(%d) (%d) (%d) dec_rec done % 4d to % 4d - error - %d\n"), pTask->m_iThreadNumber, info->m_pFrame->m_PicOrderCnt[0], (Ipp32s)(pSlice->IsBottomField()), pTask->m_iFirstMB, pTask->m_iFirstMB + pTask->m_iMBToProcess, pTask->m_bError));
break;
case TASK_DEB:
#if defined(ECHO_DEB)
DEBUG_PRINT((VM_STRING("(%d) (%d) (%d) deb done % 4d to % 4d - error - %d\n"), pTask->m_iThreadNumber, info->m_pFrame->m_PicOrderCnt[0], (Ipp32s)(pSlice->IsBottomField()), pTask->m_iFirstMB, pTask->m_iFirstMB + pTask->m_iMBToProcess, pTask->m_bError));
#else
case TASK_DEB_FRAME:
case TASK_DEB_FRAME_THREADED:
case TASK_DEB_SLICE:
case TASK_DEB_THREADED:
#endif // defined(ECHO_DEB)
break;
default:
DEBUG_PRINT((VM_STRING("(%d) default task done % 4d to % 4d - error - %d\n"), pTask->m_iThreadNumber, pTask->m_iFirstMB, pTask->m_iFirstMB + pTask->m_iMBToProcess, pTask->m_bError));
break;
}
#endif // defined(ECHO)
#ifdef TIME
timer.ThreadFinished(pTask->m_iThreadNumber, pTask->m_iTaskID);
#endif // TIME
// when whole slice was processed
if (TASK_PROCESS == pTask->m_iTaskID)
{
// it is possible only in "slice group" mode
if (pTask->m_pSlice->IsSliceGroups())
{
pSlice->m_iMaxMB = pTask->m_iMaxMB;
pSlice->m_iAvailableMB -= pTask->m_iMBToProcess;
// correct remain uncompressed macroblock count.
// we can't relay on slice number cause of field pictures.
if (pSlice->m_iAvailableMB)
{
Ipp32s pos = info->GetPositionByNumber(pSlice->GetSliceNum());
VM_ASSERT(pos >= 0);
H264Slice * pNextSlice = info->GetSlice(pos + 1);
if (pNextSlice)
{
pNextSlice->m_iAvailableMB = pSlice->m_iAvailableMB;
}
}
}
// slice is deblocked only when deblocking was available
if (false == pSlice->IsSliceGroups())
{
// check condition for frame deblocking
//if (DEBLOCK_FILTER_ON_NO_SLICE_EDGES == pSlice->m_SliceHeader.disable_deblocking_filter_idc)
//m_bDoFrameDeblocking = false; // DEBUG : ADB
if (false == pSlice->m_bDeblocked)
pSlice->m_bDeblocked = pSlice->m_bPrevDeblocked;
}
// slice is decoded
pSlice->m_bDecoded = true;
pSlice->m_bDecVacant = 0;
pSlice->m_bRecVacant = 0;
pSlice->m_bDebVacant = 1;
pSlice->m_bInProcess = false;
}
else if (TASK_DEB_SLICE == pTask->m_iTaskID)
{
pSlice->m_bDebVacant = 1;
pSlice->m_bDeblocked = 1;
pSlice->m_bInProcess = false;
}
else if (TASK_DEB_FRAME == pTask->m_iTaskID)
{
Ipp32s sliceCount = m_FirstAU->GetSliceCount();
// frame is deblocked
for (Ipp32s i = 0; i < sliceCount; i += 1)
{
H264Slice *pTemp = m_FirstAU->GetSlice(i);
pTemp->m_bDebVacant = 1;
pTemp->m_bDeblocked = true;
pTemp->m_bInProcess = false;
}
}
else
{
switch (pTask->m_iTaskID)
{
case TASK_DEC:
{
VM_ASSERT(pTask->m_iFirstMB == pSlice->m_iCurMBToDec);
pSlice->m_iCurMBToDec += pTask->m_iMBToProcess;
// move filled buffer to reconstruct queue
pSlice->m_CoeffsBuffers.UnLockInputBuffer(pTask->m_WrittenSize);
bool isReadyIncrease = (pTask->m_iFirstMB == info->m_iDecMBReady);
if (isReadyIncrease)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -