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

📄 umc_h264_task_broker.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    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 + -