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

📄 umc_h264_segment_decoder_decode_mb.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                        Ipp32s *pDistScaleFactorMV,
                        Ipp32s RefIndexL0,
                        Ipp32s scale,
                        Ipp32s scale_idx,
                        H264DecoderMotionVector &pFwdMV,
                        H264DecoderMotionVector &pBwdMV,
                        Ipp32s mvDistortion[2])
{
    H264DecoderMotionVector MV = directMVs[pos];

    switch(scale)
    {
    case 1:
        MV.mvy /= 2;
        break;
    case -1:
        MV.mvy *= 2;
        break;
    }

    pFwdMV.mvx = (Ipp16s)((MV.mvx * pDistScaleFactorMV[RefIndexL0 >> scale_idx] + 128) >> 8);
    pFwdMV.mvy = (Ipp16s)((MV.mvy * pDistScaleFactorMV[RefIndexL0 >> scale_idx] + 128) >> 8);
    pBwdMV.mvx = (Ipp16s)(pFwdMV.mvx - MV.mvx);
    pBwdMV.mvy = (Ipp16s)(pFwdMV.mvy - MV.mvy);

    if (pFwdMV.mvy > mvDistortion[0])
        mvDistortion[0] = pFwdMV.mvy;

    if (pBwdMV.mvy > mvDistortion[1])
        mvDistortion[1] = pBwdMV.mvy;
}

void H264SegmentDecoder::DecodeDirectMotionVectorsTemporal_8x8Inference()
{
    // Use forward and backward ratios to scale the reference vectors to
    // produce the forward and backward vectors, for either a 16x16 macroblock
    // (16 vectors) or an 8x8 block (4 vectors)

    // When bRefMBIsInter is false, set the MV to zero.

    FactorArrayValue *pDistScaleFactorMV;
    Ipp32u sb;
    Ipp32s ref_mvoffset, sboffset = 0;
    Ipp8s RefIndexL0 = 0, RefIndexL1 = 0;
    H264DecoderMotionVector  MV = {0};
    Ipp32s mvxf, mvyf, mvxb, mvyb;

    // set up pointers to where MV and RefIndex will be stored
    H264DecoderMotionVector *pFwdMV = m_cur_mb.MVs[0]->MotionVectors;
    H264DecoderMotionVector *pBwdMV = m_cur_mb.MVs[1]->MotionVectors;
    Ipp8s *pRefIndexL0 = m_cur_mb.RefIdxs[0]->RefIdxs;
    Ipp8s *pRefIndexL1 = m_cur_mb.RefIdxs[1]->RefIdxs;
    Ipp32u scale_idx = pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo);

    bool isAll8x8Same = true;
    H264DecoderMotionVector * first_mv_fwd_all = &(pFwdMV[0]);
    H264DecoderMotionVector * first_mv_bwd_all = &(pBwdMV[0]);
    Ipp8s *first_refL0_all = &pRefIndexL0[0];
    Ipp8s *first_refL1_all = &pRefIndexL1[0];

    for (sb = 0; sb<4; sb++)
    {
        if (m_cur_mb.GlobalMacroblockInfo->sbtype[sb] != SBTYPE_DIRECT)
        {
            isAll8x8Same = false;
            continue;
        }

        switch (sb)
        {
        case 0:
            ref_mvoffset = 0;   // upper left corner
            sboffset = 0;
            break;
        case 1:
            ref_mvoffset = 3;   // upper right corner
            sboffset = 2;
            break;
        case 2:
            ref_mvoffset = 12;   // lower left corner
            sboffset = 8;
            break;
        case 3:
            ref_mvoffset = 3 + 12;   // lower right corner
            sboffset = 2 + 8;
            break;
        }
        Ipp32s MBCol;
        Ipp32s scale;
        MBCol = GetColocatedLocation(m_pRefPicList[1][0], GetReferenceField(m_pFields[1], 0), ref_mvoffset, &scale);
        bool bRefMBIsInter = IS_INTER_MBTYPE(m_pRefPicList[1][0]->m_mbinfo.mbs[MBCol].mbtype);
        RefIndexL1 = 0;
        if (bRefMBIsInter)
        {
            H264DecoderMotionVector * directMVs;

            // Get colocated MV and translated ref index
            switch(m_pCurrentFrame->m_PictureStructureForDec)
            {
            case FLD_STRUCTURE:
                GetDirectTemporalMVFLD(MBCol, ref_mvoffset, directMVs, RefIndexL0);
                break;
            case FRM_STRUCTURE:
                GetDirectTemporalMV(MBCol,ref_mvoffset, directMVs, RefIndexL0);
                break;
            case AFRM_STRUCTURE:
                GetDirectTemporalMVMBAFF(MBCol,ref_mvoffset, directMVs, RefIndexL0);
                break;
            default:
                VM_ASSERT(false);
                directMVs = 0;
            }

            if (scale_idx)
            {
                Ipp32s curfield = (m_CurMBAddr & 1);
                Ipp32s ref0field = curfield ^ (RefIndexL0&1);
                pDistScaleFactorMV = m_pSlice->GetDistScaleFactorMVAFF()->values[curfield][ref0field][curfield];
            }
            else
            {
                pDistScaleFactorMV = m_pSlice->GetDistScaleFactorMV()->values;
            }

            MV = directMVs[ref_mvoffset];
            switch(scale)
            {
            case 1: MV.mvy/=2;
                break;
            case -1:MV.mvy*=2;
                break;
            }
            // Reference MV from outside corner 4x4
            mvxf = Ipp32s
                ((MV.mvx * pDistScaleFactorMV[RefIndexL0>>scale_idx] + 128) >> 8);
            mvxb = mvxf - MV.mvx;
            mvyf = Ipp32s
                ((MV.mvy * pDistScaleFactorMV[RefIndexL0>>scale_idx] + 128) >> 8);
            mvyb = mvyf - MV.mvy;
        }
        else
        {
            mvxf = 0;
            mvyf = 0;
            mvxb = 0;
            mvyb = 0;
            RefIndexL0 = 0;
        }

        if (mvyf > m_MVDistortion[0])
            m_MVDistortion[0] = mvyf;

        if (mvyb > m_MVDistortion[1])
            m_MVDistortion[1] = mvyb;

        // Save MV to all 4 4x4's for this 8x8.
        pFwdMV[sboffset].mvx = (Ipp16s) mvxf;
        pFwdMV[sboffset].mvy = (Ipp16s) mvyf;
        pBwdMV[sboffset].mvx = (Ipp16s) mvxb;
        pBwdMV[sboffset].mvy = (Ipp16s) mvyb;

        pFwdMV[sboffset+1].mvx = (Ipp16s) mvxf;
        pFwdMV[sboffset+1].mvy = (Ipp16s) mvyf;
        pBwdMV[sboffset+1].mvx = (Ipp16s) mvxb;
        pBwdMV[sboffset+1].mvy = (Ipp16s) mvyb;

        pFwdMV[sboffset+4].mvx = (Ipp16s) mvxf;
        pFwdMV[sboffset+4].mvy = (Ipp16s) mvyf;
        pBwdMV[sboffset+4].mvx = (Ipp16s) mvxb;
        pBwdMV[sboffset+4].mvy = (Ipp16s) mvyb;

        pFwdMV[sboffset+4+1].mvx = (Ipp16s) mvxf;
        pFwdMV[sboffset+4+1].mvy = (Ipp16s) mvyf;
        pBwdMV[sboffset+4+1].mvx = (Ipp16s) mvxb;
        pBwdMV[sboffset+4+1].mvy = (Ipp16s) mvyb;

        pRefIndexL0[sboffset] = RefIndexL0;
        pRefIndexL1[sboffset] = RefIndexL1;

        pRefIndexL0[sboffset+1] = RefIndexL0;
        pRefIndexL1[sboffset+1] = RefIndexL1;

        pRefIndexL0[sboffset+4] = RefIndexL0;
        pRefIndexL1[sboffset+4] = RefIndexL1;

        pRefIndexL0[sboffset+4+1] = RefIndexL0;
        pRefIndexL1[sboffset+4+1] = RefIndexL1;
        m_cur_mb.LocalMacroblockInfo->sbdir[sb]=D_DIR_DIRECT;
        m_cur_mb.GlobalMacroblockInfo->sbtype[sb]=SBTYPE_8x8;


        if (isAll8x8Same)
        {
            isAll8x8Same &=
                (pFwdMV[sboffset].mvx == first_mv_fwd_all->mvx) &
                (pFwdMV[sboffset].mvy == first_mv_fwd_all->mvy) &
                (pBwdMV[sboffset].mvx == first_mv_bwd_all->mvx) &
                (pBwdMV[sboffset].mvy == first_mv_bwd_all->mvy) &
                (RefIndexL0 == *first_refL0_all) &
                (RefIndexL1 == *first_refL1_all);
        }
    }   // for sb


    // set mbtype to 8x8 if it was not; use larger type if possible
    if (isAll8x8Same)
    {
        m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_BIDIR;
    }
    else
    {
        m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTER_8x8;
    }

} // void H264SegmentDecoder::DecodeDirectMotionVectorsTemporal_8x8Inference(H264DecoderFrame **pRefPicList0,

void H264SegmentDecoder::ComputeDirectSpatialRefIdx(Ipp32s *pRefIndexL0,
                                                    Ipp32s *pRefIndexL1)
{
    Ipp32s refIdxL0 = -1;
    Ipp32s refIdxL1 = -1;

    // usual case
    if (0 == m_pSliceHeader->MbaffFrameFlag)
    {
        H264DecoderBlockLocation mbAddr;

        // get left block location
        mbAddr = m_cur_mb.CurrentBlockNeighbours.mbs_left[0];
        if (0 <= mbAddr.mb_num)
        {
            refIdxL0 = m_gmbinfo->RefIdxs[0][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
            refIdxL1 = m_gmbinfo->RefIdxs[1][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
        }

        // get aboue location
        mbAddr = m_cur_mb.CurrentBlockNeighbours.mb_above;
        if (0 <= mbAddr.mb_num)
        {
            Ipp32u tmp;

            tmp = m_gmbinfo->RefIdxs[0][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
            refIdxL0 = (((Ipp32u) refIdxL0) <= tmp) ? (refIdxL0) : (tmp);
            tmp = m_gmbinfo->RefIdxs[1][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
            refIdxL1 = (((Ipp32u) refIdxL1) <= tmp) ? (refIdxL1) : (tmp);
        }

        // get above left (right) location
        mbAddr = m_cur_mb.CurrentBlockNeighbours.mb_above_right;
        if (0 <=  mbAddr.mb_num)
        {
            Ipp32u tmp;

            tmp = m_gmbinfo->RefIdxs[0][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
            refIdxL0 = (((Ipp32u) refIdxL0) <= tmp) ? (refIdxL0) : (tmp);
            tmp = m_gmbinfo->RefIdxs[1][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
            refIdxL1 = (((Ipp32u) refIdxL1) <= tmp) ? (refIdxL1) : (tmp);
        }
        else
        {
            mbAddr = m_cur_mb.CurrentBlockNeighbours.mb_above_left;
            if (0 <= mbAddr.mb_num)
            {
                Ipp32u tmp;

                tmp = m_gmbinfo->RefIdxs[0][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
                refIdxL0 = (((Ipp32u) refIdxL0) <= tmp) ? (refIdxL0) : (tmp);
                tmp = m_gmbinfo->RefIdxs[1][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
                refIdxL1 = (((Ipp32u) refIdxL1) <= tmp) ? (refIdxL1) : (tmp);
            }
        }
    }
    // MBAFF case
    else
    {
        H264DecoderBlockLocation mbAddr;
        H264DecoderMacroblockGlobalInfo *pInfo;
        Ipp32s cur_field;

        pInfo = m_gmbinfo->mbs;
        cur_field = GetMBFieldDecodingFlag(pInfo[m_CurMBAddr]);

        //
        // do not try to find corresponding place in the standard
        // we use optimized calculations
        //

        // get left block location
        mbAddr = m_cur_mb.CurrentBlockNeighbours.mbs_left[0];
        if (0 <= mbAddr.mb_num)
        {
            Ipp32s neighbour_frame = GetMBFieldDecodingFlag(pInfo[mbAddr.mb_num]) ^ 1;

            refIdxL0 = m_gmbinfo->RefIdxs[0][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
            refIdxL1 = m_gmbinfo->RefIdxs[1][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
            refIdxL0 <<= (cur_field + neighbour_frame);
            refIdxL1 <<= (cur_field + neighbour_frame);
        }

        // get aboue location
        mbAddr = m_cur_mb.CurrentBlockNeighbours.mb_above;
        if (0 <= mbAddr.mb_num)
        {
            Ipp32u tmp;
            Ipp32s neighbour_frame = GetMBFieldDecodingFlag(pInfo[mbAddr.mb_num]) ^ 1;

            tmp = m_gmbinfo->RefIdxs[0][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
            tmp <<= (cur_field + neighbour_frame);
            refIdxL0 = (((Ipp32u) refIdxL0) <= tmp) ? (refIdxL0) : (tmp);
            tmp = m_gmbinfo->RefIdxs[1][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
            tmp <<= (cur_field + neighbour_frame);
            refIdxL1 = (((Ipp32u) refIdxL1) <= tmp) ? (refIdxL1) : (tmp);
        }

        // get above left (right) location
        mbAddr = m_cur_mb.CurrentBlockNeighbours.mb_above_right;
        if (0 <=  mbAddr.mb_num)
        {
            Ipp32u tmp;
            Ipp32s neighbour_frame = GetMBFieldDecodingFlag(pInfo[mbAddr.mb_num]) ^ 1;

            tmp = m_gmbinfo->RefIdxs[0][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
            tmp <<= (cur_field + neighbour_frame);
            refId

⌨️ 快捷键说明

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