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

📄 umc_h264_task_broker.cpp

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