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

📄 umc_h264_task_supplier.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:

    DEBUG_PRINT((VM_STRING("frame gap - %d\n"), frameNumGap));

    // Fill the frame_num gap with non-existing frames. For each missing
    // frame:
    //  - allocate a frame
    //  - set frame num and pic num
    //  - update FrameNumWrap for all reference frames
    //  - use sliding window frame marking to free oldest reference
    //  - mark the frame as short-term reference
    // The picture part of the generated frames is unimportant -- it will
    // not be used for reference.

    // set to first missing frame. Note that if frame number wrapped during
    // the gap, the first missing frame_num could be larger than the
    // current frame_num. If that happened, FrameNumGap will be negative.
    //VM_ASSERT((Ipp32s)sliceHeader->frame_num > frameNumGap);
    Ipp32s frame_num = sliceHeader->frame_num - frameNumGap;

    while ((frame_num != sliceHeader->frame_num) &&
        (umcRes == UMC_OK))
    {
        // allocate a frame
        // Traverse list for next disposable frame
        H264DecoderFrame *pFrame = GetFreeFrame();

        // Did we find one?
        if (!pFrame)
        {
            return UMC_ERR_ALLOC;
        }

        m_pDecodedFramesList->MoveToTail(pFrame);

        Status umcRes = InitFreeFrame(pFrame, slice);

        if (umcRes != UMC_OK)
        {
            return UMC_ERR_ALLOC;
        }

        pFrame->DefaultFill(2, false);

        frameNumGap--;

        if (sps->pic_order_cnt_type != 0)
        {
            Ipp32s tmp1 = sliceHeader->delta_pic_order_cnt[0];
            Ipp32s tmp2 = sliceHeader->delta_pic_order_cnt[1];
            sliceHeader->delta_pic_order_cnt[0] = sliceHeader->delta_pic_order_cnt[1] = 0;

            DecodePictureOrderCount(slice, frame_num);

            sliceHeader->delta_pic_order_cnt[0] = tmp1;
            sliceHeader->delta_pic_order_cnt[1] = tmp2;
        }

        // Set frame num and pic num for the missing frame
        pFrame->setFrameNum(frame_num);
        m_PrevFrameRefNum = frame_num;
        m_FrameNum = frame_num;

        if (sliceHeader->field_pic_flag)
        {
            pFrame->setPicOrderCnt(m_PicOrderCnt,0);
            pFrame->setPicOrderCnt(m_PicOrderCnt,1);
        }
        else
        {
            pFrame->setPicOrderCnt(m_TopFieldPOC, 0);
            pFrame->setPicOrderCnt(m_BottomFieldPOC, 1);
        }

        DEBUG_PRINT((VM_STRING("frame gap - with poc %d %d added\n"), pFrame->m_PicOrderCnt[0], pFrame->m_PicOrderCnt[1]));

        if (sliceHeader->field_pic_flag == 0)
        {
            pFrame->setPicNum(frame_num, 0);
        }
        else
        {
            pFrame->setPicNum(frame_num*2+1, 0);
            pFrame->setPicNum(frame_num*2+1, 1);
        }

        // Update frameNumWrap and picNum for all decoded frames

        H264DecoderFrame *pFrm;
        H264DecoderFrame * pHead = m_pDecodedFramesList->head();
        for (pFrm = pHead; pFrm; pFrm = pFrm->future())
        {
            // TBD: modify for fields
            pFrm->UpdateFrameNumWrap(frame_num,
                uMaxFrameNum,
                pFrame->m_PictureStructureForRef+
                pFrame->m_bottom_field_flag[field]);
        }

        // sliding window ref pic marking
        SlideWindow(slice, 0);

        pFrame->SetisShortTermRef(0);
        pFrame->SetisShortTermRef(1);

        {
            // reset frame global data
            H264DecoderMacroblockGlobalInfo *pMBInfo = pFrame->m_mbinfo.mbs;
            memset(pMBInfo, 0, pFrame->totalMBs*sizeof(H264DecoderMacroblockGlobalInfo));

            // DEBUG : temporal fix !!! for deblocking
            /*memset(pFrame->m_mbinfo.MV[0], 0, iMBCount*sizeof(H264DecoderMacroblockMVs));
            memset(pFrame->m_mbinfo.MV[1], 0, iMBCount*sizeof(H264DecoderMacroblockMVs));
            memset(pFrame->m_mbinfo.RefIdxs[0], 0, iMBCount*sizeof(H264DecoderMacroblockRefIdxs));
            memset(pFrame->m_mbinfo.RefIdxs[0], 0, iMBCount*sizeof(H264DecoderMacroblockRefIdxs));*/
        }

        // next missing frame
        frame_num++;
        if (frame_num >= uMaxFrameNum)
            frame_num = 0;

        // Set current as displayable and was outputted.
        pFrame->SetBusyState(2);
        pFrame->SetisDisplayable();
        pFrame->SetSkipped(true);
        pFrame->SetFrameExistFlag(false);

    }   // while

    return m_pDecodedFramesList->IsDisposableExist() ? UMC_OK : UMC_ERR_ALLOC;
}   // ProcessFrameNumGap

Status TaskSupplier::SetDPBSize()
{
    Status umcRes = UMC_OK;
    Ipp32u MaxDPBx2;
    Ipp32u dpbLevel;
    Ipp32u dpbSize;

    H264SeqParamSet* sps = m_Headers.GetSeqParamSet(m_CurrentSeqParamSet);

    // MaxDPB, per Table A-1, Level Limits
    switch (sps->level_idc)
    {
    case 10:
        MaxDPBx2 = 297;
        break;
    case 11:
        MaxDPBx2 = 675;
        break;
    case 12:
    case 13:
    case 20:
        MaxDPBx2 = 891*2;
        break;
    case 21:
        MaxDPBx2 = 1782*2;
        break;
    case 22:
    case 30:
        MaxDPBx2 = 6075;
        break;
    case 31:
        MaxDPBx2 = 6750*2;
        break;
    case 32:
        MaxDPBx2 = 7680*2;
        break;
    case 40:
    case 41:
    case 42:
        MaxDPBx2 = 12288*2;
        break;
    case 50:
        MaxDPBx2 = 41400*2;
        break;
    case 51:
        MaxDPBx2 = 69120*2;
        break;
    default:
        MaxDPBx2 = 69120*2; //get as much as we may
        //umcRes = UMC_ERR_INVALID_STREAM;
    }

    if (umcRes == UMC_OK)
    {
        Ipp32u width, height;

        width = sps->frame_width_in_mbs*16;
        height = sps->frame_height_in_mbs*16;

        dpbLevel = (MaxDPBx2 * 512) / ((width * height) + ((width * height)>>1));
        dpbSize = IPP_MIN(16, dpbLevel);

        // we must have enough additional frames to do good frame parallelization
        m_dpbSize = dpbSize;
    }

    return umcRes;

}    // setDPBSize

bool TaskSupplier::GetFrameToDisplay(MediaData *dst, bool force)
{
    // Perform output color conversion and video effects, if we didn't
    // already write our output to the application's buffer.
    VideoData *pVData = DynamicCast<VideoData> (dst);
    if (!pVData)
        return false;


    m_pLastDisplayed = 0;

    H264DecoderFrame * pFrame = GetFrameToDisplayInternal(dst, force);
    if (!pFrame)
    {
        return false;
    }

    m_pLastDisplayed = pFrame;
    pVData->SetInvalid(pFrame->GetError());

    if (m_pLastDisplayed->IsSkipped())
    {
        pVData->SetDataSize(1);
        pFrame->setWasOutputted();
        return true;
    }

    InitColorConverter(pFrame, 0);
    m_LastDecodedFrame.SetTime(dst->GetTime());

    {
        if (m_PostProcessing->GetFrame(&m_LastDecodedFrame, pVData) != UMC_OK)
        {
            pVData->SetDataSize(0);
            pFrame->setWasOutputted();
            return false;
        }
    }

    pVData->SetDataSize(pVData->GetMappingSize());
    pFrame->setWasOutputted();

    return true;
}

bool TaskSupplier::IsWantToShowFrame(bool force)
{
    if (m_pDecodedFramesList->countNumDisplayable() > m_maxDecFrameBuffering ||
        force)
    {
        H264DecoderFrame * pTmp = m_pDecodedFramesList->findOldestDisplayable(m_dpbSize);
        return !!pTmp;
    }

    return false;
}

H264DecoderFrame *TaskSupplier::GetFrameToDisplayInternal(MediaData *dst, bool force)
{
    H264DecoderFrame *pTmp;

    if (!dst)
        return 0;

    for (;;)
    {
        // show oldest frame
        if (m_pDecodedFramesList->countNumDisplayable() >= m_maxDecFrameBuffering ||
            force)
        {
            pTmp = m_pDecodedFramesList->findOldestDisplayable(m_dpbSize);

            if (pTmp && pTmp->GetBusyState() < 2)
            {
                Ipp64f time;

                if (!pTmp->IsFrameExist())
                {
                    pTmp->setWasOutputted();
                    continue;
                }

                // set time
                if (pTmp->m_dFrameTime > -1.0)
                {
                    time = pTmp->m_dFrameTime;
                    dst->SetTime(time);
                    //m_LastDecodedFrame.SetTime(time);
                    m_local_frame_time = time;
                }
                else
                {
                    //m_LastDecodedFrame.SetTime(m_local_frame_time);
                    pTmp->m_dFrameTime = m_local_frame_time;
                    dst->SetTime(m_local_frame_time);
                }

                if (!pTmp->post_procces_complete)
                {
                    //static Ipp32s count = 0;
                    m_local_frame_time += m_local_delta_frame_time;
                    pTmp->post_procces_complete = true;
                    DEBUG_PRINT((VM_STRING("Outputted POC - %d, busyState - %d\n"), pTmp->m_PicOrderCnt[0], pTmp->GetBusyState()));

                    /*if (!CutPlanes(pTmp, m_Headers.GetSeqParamSet(m_CurrentSeqParamSet)))
                    {
                        m_pDecodedFramesList->DebugPrint();
                    }*/
                }

                if (pTmp->IsSkipped())
                {
                    return pTmp;
                }
            }
            else
            {
                return 0;
            }

            return pTmp;
        }
        else // there are no frames to show
            return NULL;
    }
}

void TaskSupplier::SetMBMap(H264DecoderFrame *frame)
{
    Ipp32u mbnum, i;
    Ipp32s prevMB;
    Ipp32u uNumMBCols;
    Ipp32u uNumMBRows;
    Ipp32u uNumSliceGroups;
    Ipp32u uNumMapUnits;
    H264Slice * slice = frame->GetAU(0)->GetAnySlice();
    H264PicParamSet *pps = slice->GetPicParam();
    H264SliceHeader * sliceHeader = slice->GetSliceHeader();
    Ipp32s PrevMapUnit[MAX_NUM_SLICE_GROUPS];
    Ipp32s SliceGroup, FirstMB;
    Ipp8u *pMap = NULL;
    bool bSetFromMap = false;

    uNumMBCols = frame->macroBlockSize().width;
    uNumMBRows = frame->macroBlockSize().height;
    FirstMB = 0;
    // TBD: update for fields:
    uNumMapUnits = uNumMBCols*uNumMBRows;
    uNumSliceGroups = pps->num_slice_groups;

    if (uNumSliceGroups == 1)
    {
        m_pMBInfo[frame->m_iResourceNumber].active_next_mb_table = next_mb_tables[0];
    }
    else
    {
        Ipp32s times = frame->m_PictureStructureForDec < FRM_STRUCTURE ? 2 : 1;
        for (Ipp32s j = 0; j < times; j++)
        {

            if (frame->m_PictureStructureForDec < FRM_STRUCTURE)
            {
                if (j)
                {
                    FirstMB = frame->totalMBs;
                    uNumMapUnits <<= 1;
                }
                else
                {
                    uNumMapUnits >>= 1;
                    uNumMBRows >>= 1;
                }
            }

            //since main profile doesn't allow slice groups to be >1 and in baseline no fields (or mbaffs) allowed
            //the following memset is ok.
            // > 1 slice group
            switch (pps->SliceGroupInfo.slice_group_map_type)
            {
            case 0:
                {
                    // interleaved slice groups: run_length for each slice group,
                    // repeated until all MB's are assigned to a slice group
                    Ipp32u NumThisGroup;

                    // Init PrevMapUnit to -1 (none), for first unit of each slice group
                    for (i=0; i<uNumSliceGroups; i++)
                        PrevMapUnit[i] = -1;

                    SliceGroup = 0;
                    NumThisGroup = 0;
                    prevMB = -1;
                    for (mbnum = FirstMB; mbnum < uNumMapUnits; mbnum++)
                    {
                        if (NumThisGroup == pps->SliceGroupInfo.run_length[SliceGroup])
                        {
                            // new slice group
                            PrevMapUnit[SliceGroup] = prevMB;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -