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

📄 umc_h264_task_broker.cpp

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