📄 umc_h264_task_broker.cpp
字号:
Ipp32s locked = TryToGet(&pSlice->m_bDecVacant);
if (!locked)
return false;
#endif
// this is guarded function, safe to touch any variable
if ((1 == pSlice->m_bDecVacant) &&
(pSlice->m_CoeffsBuffers.IsInputAvailable()))
{
pSlice->m_bInProcess = true;
pSlice->m_bDecVacant = 0;
Ipp32s iMBWidth = pSlice->GetMBRowWidth();
// error handling
/*if (0 >= ((signed) pSlice->m_BitStream.BytesLeft()))
{
pSlice->m_iMaxMB = pSlice->m_iCurMBToDec;
return false;
}*/
InitTask(info, pTask, pSlice);
pTask->m_iFirstMB = pSlice->m_iCurMBToDec;
pTask->m_iMBToProcess = IPP_MIN(pSlice->m_iCurMBToDec -
(pSlice->m_iCurMBToDec % iMBWidth) +
iMBWidth,
pSlice->m_iMaxMB) - pSlice->m_iCurMBToDec;
pTask->m_iMBToProcess = IPP_MIN(pTask->m_iMBToProcess, pSlice->m_iAvailableMB);
pTask->m_iTaskID = TASK_DEC;
pTask->m_pBuffer = (UMC::CoeffsPtrCommon)pSlice->m_CoeffsBuffers.LockInputBuffer();
pTask->pFunction = &H264SegmentDecoderMultiThreaded::DecodeSegment;
#ifdef ECHO
DEBUG_PRINT((VM_STRING("(%d) (%d) (%d) dec - % 4d to % 4d\n"), pTask->m_iThreadNumber,
info->m_pFrame->m_PicOrderCnt[0], (Ipp32s)(pSlice->IsBottomField()), pTask->m_iFirstMB, pTask->m_iFirstMB + pTask->m_iMBToProcess));
#endif // ECHO
return true;
}
#ifdef LIGHT_SYNC
else
{
pSlice->m_bDecVacant = 1;
}
#endif
return false;
} // bool TaskBrokerTwoThread::WrapDecodingTask(H264Task *pTask, H264Slice *pSlice)
bool TaskBrokerTwoThread::WrapReconstructTask(H264DecoderFrameInfo * info, H264Task *pTask, H264Slice *pSlice)
{
VM_ASSERT(pSlice);
// this is guarded function, safe to touch any variable
#ifdef LIGHT_SYNC
Ipp32s locked = TryToGet(&pSlice->m_bRecVacant);
if (!locked)
return false;
#endif
if ((1 == pSlice->m_bRecVacant) &&
(pSlice->m_CoeffsBuffers.IsOutputAvailable()))
{
pSlice->m_bRecVacant = 0;
Ipp32s iMBWidth = pSlice->GetMBRowWidth();
InitTask(info, pTask, pSlice);
pTask->m_iFirstMB = pSlice->m_iCurMBToRec;
pTask->m_iMBToProcess = IPP_MIN(pSlice->m_iCurMBToRec -
(pSlice->m_iCurMBToRec % iMBWidth) +
iMBWidth,
pSlice->m_iMaxMB) - pSlice->m_iCurMBToRec;
pTask->m_iTaskID = TASK_REC;
Ipp8u* pointer;
size_t size;
pSlice->m_CoeffsBuffers.LockOutputBuffer(pointer, size);
pTask->m_pBuffer = ((UMC::CoeffsPtrCommon) pointer);
pTask->pFunction = &H264SegmentDecoderMultiThreaded::ReconstructSegment;
#ifdef ECHO
DEBUG_PRINT((VM_STRING("(%d) (%d) (%d) rec - % 4d to % 4d\n"), pTask->m_iThreadNumber,
info->m_pFrame->m_PicOrderCnt[0], (Ipp32s)(pSlice->IsBottomField()), pTask->m_iFirstMB, pTask->m_iFirstMB + pTask->m_iMBToProcess));
#endif // ECHO
return true;
}
#ifdef LIGHT_SYNC
else
{
pSlice->m_bRecVacant = 1;
}
#endif
return false;
} // bool TaskBrokerTwoThread::WrapReconstructTask(H264Task *pTaskm H264Slice *pSlice)
bool TaskBrokerTwoThread::WrapDecRecTask(H264DecoderFrameInfo * info, H264Task *pTask, H264Slice *pSlice)
{
VM_ASSERT(pSlice);
// this is guarded function, safe to touch any variable
#ifdef LIGHT_SYNC
Ipp32s locked = TryToGet(&pSlice->m_bRecVacant);
if (!locked)
return false;
#endif
if ((1 == pSlice->m_bRecVacant) && (1 == pSlice->m_bDecVacant) &&
(pSlice->m_iCurMBToDec == pSlice->m_iCurMBToRec) &&
(pSlice->m_CoeffsBuffers.IsInputAvailable()))
{
pSlice->m_bRecVacant = 0;
pSlice->m_bDecVacant = 0;
Ipp32s iMBWidth = pSlice->GetMBRowWidth();
InitTask(info, pTask, pSlice);
pTask->m_iFirstMB = pSlice->m_iCurMBToDec;
pTask->m_iMBToProcess = IPP_MIN(pSlice->m_iCurMBToDec -
(pSlice->m_iCurMBToDec % iMBWidth) +
iMBWidth,
pSlice->m_iMaxMB) - pSlice->m_iCurMBToDec;
pTask->m_iTaskID = TASK_DEC_REC;
pTask->m_pBuffer = 0;
pTask->pFunction = &H264SegmentDecoderMultiThreaded::DecRecSegment;
#ifdef ECHO
DEBUG_PRINT((VM_STRING("(%d) (%d) (%d) dec_rec - % 4d to % 4d\n"), pTask->m_iThreadNumber,
info->m_pFrame->m_PicOrderCnt[0], (Ipp32s)(pSlice->IsBottomField()), pTask->m_iFirstMB, pTask->m_iFirstMB + pTask->m_iMBToProcess));
#endif // ECHO
return true;
}
#ifdef LIGHT_SYNC
else
{
pSlice->m_bDecVacant = 1;
pSlice->m_bRecVacant = 1;
}
#endif
return false;
} // bool TaskBrokerTwoThread::WrapDecRecTask(H264Task *pTaskm H264Slice *pSlice)
bool TaskBrokerTwoThread::GetDecodingTask(H264DecoderFrameInfo * info, H264Task *pTask)
{
// this is guarded function, safe to touch any variable
Ipp32s i;
H264DecoderFrameInfo * refAU = info->GetRefAU();
bool is_need_check = refAU != 0;
Ipp32s readyCount = 0;
Ipp32s additionalLines = 0;
if (is_need_check)
{
readyCount = refAU->m_iDecMBReady;
additionalLines = GetDecodingOffset(info, readyCount);
}
Ipp32s sliceCount = info->GetSliceCount();
for (i = 0; i < sliceCount; i += 1)
{
H264Slice *pSlice = info->GetSlice(i);
if (pSlice->m_bDecVacant != 1)
continue;
if (is_need_check)
{
if (pSlice->m_iCurMBToDec + (1 + additionalLines)*pSlice->GetMBRowWidth() >= readyCount)
break;
}
if (WrapDecodingTask(info, pTask, pSlice))
return true;
}
return false;
} // bool TaskBrokerTwoThread::GetDecodingTask(H264DecoderFrameInfo * info, H264Task *pTask)
bool TaskBrokerTwoThread::GetReconstructTask(H264DecoderFrameInfo * info, H264Task *pTask)
{
// this is guarded function, safe to touch any variable
H264DecoderFrameInfo * refAU = info->GetRefAU();
bool is_need_check = refAU != 0;
Ipp32s readyCount = 0;
Ipp32s additionalLines = 0;
if (is_need_check)
{
readyCount = refAU->m_iRecMBReady;
additionalLines = GetDecodingOffset(info, readyCount);
}
Ipp32s i;
Ipp32s sliceCount = info->GetSliceCount();
for (i = 0; i < sliceCount; i += 1)
{
H264Slice *pSlice = info->GetSlice(i);
if (pSlice->m_bRecVacant != 1 ||
!pSlice->m_CoeffsBuffers.IsOutputAvailable())
{
continue;
}
if (is_need_check)
{
Ipp32s k = (( (pSlice->m_MVsDistortion + 15) / 16) + 1); // +2 - (1 - for padding, 2 - current line)
k += refAU->IsNeedDeblocking() ? 1 : 0;
if (pSlice->m_iCurMBToRec + (k + additionalLines)*pSlice->GetMBRowWidth() >= readyCount)
break;
}
if (WrapReconstructTask(info, pTask, pSlice))
{
return true;
}
}
return false;
} // bool TaskBrokerTwoThread::GetReconstructTask(H264Task *pTask)
bool TaskBrokerTwoThread::GetDecRecTask(H264DecoderFrameInfo * info, H264Task *pTask)
{
// this is guarded function, safe to touch any variable
Ipp32s i;
Ipp32s sliceCount = info->GetSliceCount();
for (i = 0; i < sliceCount; i += 1)
{
H264Slice *pSlice = info->GetSlice(i);
if (pSlice->m_bRecVacant != 1 || pSlice->m_bDecVacant != 1)
{
continue;
}
if (WrapDecRecTask(info, pTask, pSlice))
{
return true;
}
}
return false;
}
bool TaskBrokerTwoThread::GetDeblockingTask(H264DecoderFrameInfo * info, H264Task *pTask)
{
// this is guarded function, safe to touch any variable
Ipp32s i;
bool bPrevDeblocked = true;
Ipp32s sliceCount = info->GetSliceCount();
for (i = 0; i < sliceCount; i += 1)
{
H264Slice *pSlice = info->GetSlice(i);
Ipp32s iMBWidth = pSlice->GetMBRowWidth(); // DEBUG : always deblock two lines !!!
Ipp32s iAvailableToDeblock;
Ipp32s iDebUnit = (pSlice->GetSliceHeader()->MbaffFrameFlag) ? (2) : (1);
iAvailableToDeblock = pSlice->m_iCurMBToRec -
pSlice->m_iCurMBToDeb;
if ((false == pSlice->m_bDeblocked) &&
((true == bPrevDeblocked) || (false == pSlice->DeblockThroughBoundaries())) &&
(1 == pSlice->m_bDebVacant) &&
((iAvailableToDeblock > iMBWidth) || (pSlice->m_iCurMBToRec >= pSlice->m_iMaxMB)))
{
InitTask(info, pTask, pSlice);
pTask->m_iFirstMB = pSlice->m_iCurMBToDeb;
{
pTask->m_iMBToProcess = IPP_MIN(iMBWidth - (pSlice->m_iCurMBToDeb % iMBWidth),
iAvailableToDeblock);
pTask->m_iMBToProcess = IPP_MAX(pTask->m_iMBToProcess,
iDebUnit);
pTask->m_iMBToProcess = align_value<Ipp32s> (pTask->m_iMBToProcess, iDebUnit);
}
pTask->m_iTaskID = TASK_DEB;
pTask->pFunction = &H264SegmentDecoderMultiThreaded::DeblockSegmentTask;
pSlice->m_bDebVacant = 0;
#ifdef ECHO_DEB
DEBUG_PRINT((VM_STRING("(%d) deb - % 4d to % 4d\n"), pTask->m_iThreadNumber,
pTask->m_iFirstMB, pTask->m_iFirstMB + pTask->m_iMBToProcess));
#endif // ECHO_DEB
return true;
}
else
{
if ((0 >= iAvailableToDeblock) && (pSlice->m_iCurMBToRec >= pSlice->m_iMaxMB))
{
pSlice->m_bDeblocked = true;
bPrevDeblocked = true;
}
}
// save previous slices deblocking condition
if (false == pSlice->m_bDeblocked || pSlice->m_iCurMBToRec < pSlice->m_iMaxMB)
{
bPrevDeblocked = false;
break; // for mbaff deblocking could be performaed outside boundaries.
}
}
return false;
} // bool TaskBrokerTwoThread::GetDeblockingTask(H264Task *pTask)
bool TaskBrokerTwoThread::GetNextTaskManySlices(H264DecoderFrameInfo * info, H264Task *pTask)
{
if (!info)
return false;
//if (info == m_FirstAU && true == GetNextSlice(info, pTask))
// return true;
if (info->IsNeedDeblocking())
{
if (true == GetDeblockingTask(info, pTask))
return true;
}
// try to get reconstruct task from main queue
if (true == GetReconstructTask(info, pTask))
{
return true;
}
if (!info->GetRefAU() && info->GetSliceCount() > 1)
{
if (true == GetDecRecTask(info, pTask))
{
return true;
}
}
// try to get decoding task from main frame
if (true == GetDecodingTask(info, pTask))
{
return true;
}
return false;
}
void TaskBrokerTwoThread::AddPerformedTask(H264Task *pTask)
{
#ifndef LIGHT_SYNC
AutomaticUMCMutex guard(m_mGuard);
#endif
TaskBrokerSingleThread::AddPerformedTask(pTask);
//if (TASK_DEB != pTask->m_iTaskID)
{
AwakeThreads();
}
} // void TaskBrokerTwoThread::AddPerformedTask(H264Task *pTask)
void TaskBrokerTwoThread::AwakeThreads()
{
DEBUG_PRINT((VM_STRING("awaken threads\n")));
if (m_nWaitingThreads)
{
Ipp32s i;
Ipp32s iMask = 1;
for (i = 0; i < m_iConsumerNumber; i += 1)
{
if (m_nWaitingThreads & iMask)
m_eWaiting[i]->Set();
iMask <<= 1;
} // DEBUG : ADB
}
//m_nWaitingThreads = 0;
} // void TaskBrokerTwoThread::AwakeThreads()
bool TaskBrokerTwoThread::GetFrameDeblockingTaskThreaded(H264DecoderFrameInfo * , H264Task *)
{
#if 1
return false;
#else
// this is guarded function, safe to touch any variable
Ipp32s sliceCount = info->GetSliceCount();
H264Slice * firstSlice = info->GetSlice(0);
if (m_bFirstDebThreadedCall)
{
Ipp32s i;
Ipp32s iFirstMB = -1, iMaxMB = -1;
Ipp32s iMBWidth = firstSlice->GetMBRowWidth();
Ipp32s iDebUnit = (firstSlice->m_SliceHeader.MbaffFrameFlag) ? (2) : (1);
bool bError = false;
// check all other threads are sleep
for (i = 0; i < sliceCount; i++)
{
H264Slice *pSlice = info->GetSlice(i);
if ((pSlice) && (0 == pSlice->m_bDebVacant))
return false;
if (pSlice->m_bError)
bError = true;
}
// handle little slices
if ((iDebUnit * 2 > iMBWidth / m_iConsumerNumber) || bError)
return GetDeblockingTask(pTask);
// calculate deblocking range
for (i = 0; i < sliceCount; i++)
{
H264Slice *pSlice = info->GetSlice(i);
if ((pSlice) &&
(false == pSlice->m_bDeblocked))
{
// find deblocking range
if (-1 == iFirstMB)
iFirstMB = pSlice->m_iCurMBToDeb;
if (iMaxMB < pSlice->m_iMaxMB)
iMaxMB = pSlice->m_iMaxMB;
}
}
m_DebTools.Reset(iFirstMB,
iMaxMB,
iDebUnit,
iMBWidth);
m_bFirstDebThreadedCall = false;
}
// get next piece to deblock
if (false == m_DebTools.GetMBToProcess(pTask))
return false;
// correct task to slice range
{
Ipp32s i;
for (i = 0; i < sliceCount; i += 1)
{
H264Slice *pSlice = info->GetSlice(i);
if ((pTask->m_iFirstMB >= pSlice->m_iFirstMB) &&
(pTask->m_iFirstMB < pSlice->m_iMaxMB))
{
pTask->m_iTaskID = TASK_DEB_FRAME_THREADED;
pTask->m_pSlice = pSlice;
if (pTask->m_iFirstMB + pTask->m_iMBToProcess > pSlice->m_iMaxMB)
pTask->m_iMBToProcess = pSlice->m_iMaxMB - pTask->m_iFirstMB;
break;
}
}
}
return true;
#endif
} // bool TaskBrokerTwoThread::GetFrameDeblockingTaskThreaded(H264Task *pTask)
} // namespace UMC
#endif // UMC_ENABLE_H264_VIDEO_DECODER
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -