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

📄 umc_h264_segment_decoder_decode_mb.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                        block2lin[block&(-4)]+4*(block&1);
                    TopRight.block_num=
                        block2lin[block&(-4)]+4*(block&1)+1;

                        GetLeftLocationForCurrentMBLumaMBAFF(&Left);
                        GetTopLocationForCurrentMBLumaMBAFF(&Top,0);
                        GetTopRightLocationForCurrentMBLumaMBAFF(&TopRight);
                        GetTopLeftLocationForCurrentMBLumaMBAFF(&TopLeft);

                    left_edge_block = left_edge_tab16_8x4[block];
                    top_edge_block = top_edge_tab16_8x4[block];
                    right_edge_block = right_edge_tab16_8x4[block];

                    if (!top_edge_block)
                    {
                        isRightUnavailable = (above_right_avail_8x4[block] == 0);
                        if (isRightUnavailable)
                            if (left_edge_block)
                                isLeftUnavailable = (Left.mb_num<0);
                            else
                                isLeftUnavailable = 0;
                    }
                    else
                    {
                        // top edge of 8x4
                        if (!right_edge_block)
                        {
                            isRightUnavailable = (Top.mb_num<0);
                            isLeftUnavailable = (TopLeft.mb_num<0);
                        }
                        else
                        {
                            isRightUnavailable = (TopRight.mb_num<0);
                            isLeftUnavailable = (Top.mb_num<0);
                        }
                    }
                    break;
                case SBTYPE_4x8:
                    Top.block_num=
                        Left.block_num=
                        TopLeft.block_num=
                        block2lin[block&(-4)]+(block&1);
                    TopRight.block_num=
                        block2lin[block&(-4)]+(block&1);

                        GetLeftLocationForCurrentMBLumaMBAFF(&Left);
                        GetTopLocationForCurrentMBLumaMBAFF(&Top,0);
                        GetTopRightLocationForCurrentMBLumaMBAFF(&TopRight);
                        GetTopLeftLocationForCurrentMBLumaMBAFF(&TopLeft);
                    //            diff = 1;
                    left_edge_block = left_edge_tab16_4x8[block];
                    top_edge_block = top_edge_tab16_4x8[block];
                    right_edge_block = right_edge_tab16_4x8[block];
                    if (!top_edge_block)
                    {
                        isRightUnavailable = (above_right_avail_4x8[block] == 0);
                        isLeftUnavailable = 0;  // always, when above right not available
                    }
                    else
                    {
                        if (!right_edge_block)
                            isRightUnavailable = (Top.mb_num<0);
                        else
                            isRightUnavailable = (TopRight.mb_num<0);
                        if (isRightUnavailable)
                        {
                            if (!left_edge_block)
                                isLeftUnavailable = (Top.mb_num<0);
                            else
                                isLeftUnavailable = (TopLeft.mb_num<0);
                        }
                    }
                    break;
                case SBTYPE_4x4:
                    Top.block_num=
                        Left.block_num=
                        TopLeft.block_num=
                        TopRight.block_num=
                        block2lin[block];

                        GetLeftLocationForCurrentMBLumaMBAFF(&Left);
                        GetTopLocationForCurrentMBLumaMBAFF(&Top,0);
                        GetTopRightLocationForCurrentMBLumaMBAFF(&TopRight);
                        GetTopLeftLocationForCurrentMBLumaMBAFF(&TopLeft);
                    VM_ASSERT(block >= 0 && block <= 15);
                    //            diff = 1;
                    left_edge_block = left_edge_tab16[block];
                    top_edge_block = top_edge_tab16[block];
                    right_edge_block = right_edge_tab16[block];
                    if (!top_edge_block)
                        isRightUnavailable = (above_right_avail_4x4[block] == 0);
                    else
                    {
                        if (!right_edge_block)
                            isRightUnavailable = (Top.mb_num<0);
                        else
                            isRightUnavailable = (TopRight.mb_num<0);
                    }
                    if (isRightUnavailable)
                    {
                        // When not on top edge of MB, for blocks for which right may not
                        // be available, left is always available.
                        if (top_edge_block == 0)
                            isLeftUnavailable = 0;
                        else
                        {
                            if (!left_edge_block)
                                isLeftUnavailable = (Top.mb_num<0);
                            else
                                isLeftUnavailable = (TopLeft.mb_num<0);
                        }
                    }
                    break;
                }
            }
            break;
        default:
            *pMVx = 0;
            *pMVy = 0;
            return;  // DEBUG : may be throw ???
        }

        // correct for left edge
        if (Left.mb_num<0)
        {
            sl = &null;
            pRefIxl = &nullRefIx;
        }
        else
        {
            sl = &MVs[Left.mb_num].MotionVectors[Left.block_num];
            pRefIxl = &RefIdxs[Left.mb_num].RefIdxs[Left.block_num];
            lbls=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[Left.mb_num]))>0;
            lbrs=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[Left.mb_num]))<0;
        }

        // correct for top edge
        if (Top.mb_num<0)
        {
            sa = &null;
            pRefIxa = &nullRefIx;
        }
        else
        {
            sa = &MVs[Top.mb_num].MotionVectors[Top.block_num];
            pRefIxa = &RefIdxs[Top.mb_num].RefIdxs[Top.block_num];
            tbls=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[Top.mb_num]))>0;
            tbrs=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[Top.mb_num]))<0;

        }

        // correct for upper right
        if (isRightUnavailable)
        {
            // replace with block above left if available
            if (isLeftUnavailable)
            {
                sr = &null;
                pRefIxr = &nullRefIx;
            }
            else
            {
                sr = &MVs[TopLeft.mb_num].MotionVectors[TopLeft.block_num];
                pRefIxr = &RefIdxs[TopLeft.mb_num].RefIdxs[TopLeft.block_num];
                rbls=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[TopLeft.mb_num]))>0;
                rbrs=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[TopLeft.mb_num]))<0;
            }
        }
        else
        {
            sr = &MVs[TopRight.mb_num].MotionVectors[TopRight.block_num];
            pRefIxr = &RefIdxs[TopRight.mb_num].RefIdxs[TopRight.block_num];
            rbls=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[TopRight.mb_num]))>0;
            rbrs=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[TopRight.mb_num]))<0;

        }

        // If above AND right are unavailable AND left is available, use left
        if ((sa == &null) && (sr == &null) && (sl != &null))
        {
            // return MV at sl
            *pMVx = sl->mvx;
            *pMVy = ((sl->mvy+((sl->mvy<0)&&lbls))<<lbrs)>>lbls;
        }
        else
        {
            // Check for more than one predictor from different reference frame
            // If there is only one predictor from this ref frame, then sonly will
            // be pointing to it.
            Ipp32s ls = 0, rs = 0;
            if (((*pRefIxl<<lbls)>>lbrs) != RefIndex)
                uSameRefPicCount--;
            else
            {
                sonly = sl;
                ls=lbls;
                rs=lbrs;
            }
            if (((*pRefIxa<<tbls)>>tbrs) != RefIndex)
                uSameRefPicCount--;
            else
            {
                sonly = sa;
                ls=tbls;
                rs=tbrs;
            }
            if (((*pRefIxr<<rbls)>>rbrs) != RefIndex)
                uSameRefPicCount--;
            else
            {
                sonly = sr;
                ls=rbls;
                rs=rbrs;
            }

            if (uSameRefPicCount != 1)
            {
                // "normal" median prediction
                px0 = sl->mvx;
                px1 = sa->mvx;
                px2 = sr->mvx;

#define MEDIAN_OF_3(a, b, c) (IPP_MIN((a),(b))) ^ (IPP_MIN((b),(c))) ^ (IPP_MIN((c),(a)))

                *pMVx = MEDIAN_OF_3(px0, px1, px2);

                py0 = ((sl->mvy+((sl->mvy<0)&&lbls))<<lbrs)>>lbls;
                py1 = ((sa->mvy+((sa->mvy<0)&&tbls))<<tbrs)>>tbls;
                py2 = ((sr->mvy+((sr->mvy<0)&&rbls))<<rbrs)>>rbls;

                *pMVy = MEDIAN_OF_3(py0, py1, py2);
            }
            else
            {
                // return MV at sonly
                *pMVx = sonly->mvx;
                *pMVy = ((sonly->mvy+((sonly->mvy<0)&&ls))<<rs)>>ls;
            }
        }
    }
    else
    {
        switch (m_cur_mb.GlobalMacroblockInfo->mbtype)
        {
        case MBTYPE_FORWARD:
        case MBTYPE_BACKWARD:
        case MBTYPE_BIDIR:
        case MBTYPE_SKIPPED:
            VM_ASSERT(block == 0);

            Left = m_cur_mb.CurrentBlockNeighbours.mbs_left[0];
            Top = m_cur_mb.CurrentBlockNeighbours.mb_above;
            TopRight = m_cur_mb.CurrentBlockNeighbours.mb_above_right;
            TopLeft= m_cur_mb.CurrentBlockNeighbours.mb_above_left;

            isRightUnavailable = (TopRight.mb_num<0);
            isLeftUnavailable = (TopLeft.mb_num<0);

            break;
        case MBTYPE_INTER_16x8:
            VM_ASSERT(block >= 0 && block <= 1);
            // First check for availability of directional predictor which is
            // just used if available.
            if (block == 0)
            {
                // upper half, use predictor from above
                Top= m_cur_mb.CurrentBlockNeighbours.mb_above;
                if (Top.mb_num>=0)
                {

                    if (IS_INTER_MBTYPE(gmbs[Top.mb_num].mbtype) &&
                        (((RefIdxs[Top.mb_num].RefIdxs[Top.block_num])) == RefIndex))
                    {
                        *pMVx = MVs[Top.mb_num].MotionVectors[Top.block_num].mvx;
                        *pMVy = MVs[Top.mb_num].MotionVectors[Top.block_num].mvy;
                        return;
                    }
                    else
                    {
                        goto median16x8_0;
                    }
                }
                else
                {
median16x8_0:
                    Left = m_cur_mb.CurrentBlockNeighbours.mbs_left[0];
                    TopRight = m_cur_mb.CurrentBlockNeighbours.mb_above_right;
                    TopLeft = m_cur_mb.CurrentBlockNeighbours.mb_above_left;

                    // init vars for median prediction
                    isRightUnavailable = (TopRight.mb_num<0);
                    if (isRightUnavailable)
                        isLeftUnavailable = (TopLeft.mb_num<0);
                }
            }
            else
            {
                Left = m_cur_mb.CurrentBlockNeighbours.mbs_left[2];
                // lower half, use predictor from left
                if ( Left.mb_num>=0)
                {

                    if (IS_INTER_MBTYPE(gmbs[Left.mb_num].mbtype) &&
                        (((RefIdxs[Left.mb_num].RefIdxs[Left.block_num])) == RefIndex))
                    {
                        *pMVx = MVs[Left.mb_num].MotionVectors[Left.block_num].mvx;
                        *pMVy = MVs[Left.mb_num].MotionVectors[Left.block_num].mvy;
                        return;
                    }
                    else
                    {
                        goto median_16x8_1;
                    }
                }
                else
                {
median_16x8_1:

                    Top.mb_num = m_CurMBAddr;
                    Top.block_num = 4;

                    TopLeft.block_num = 8;
                    GetTopLeftLocationForCurrentMBLumaNonMBAFF(&TopLeft);

                    // init vars for median prediction
                    isRightUnavailable = 1;

⌨️ 快捷键说明

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