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

📄 umc_h264_segment_decoder_decode_mb_types.cpp

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

} // void H264SegmentDecoder::DecodeIntraTypes4x4_CAVLC(Ipp32u *pMBIntraTypes,

void H264SegmentDecoder::DecodeIntraTypes8x8_CAVLC(IntraType *pMBIntraTypes,
                                                     bool bUseConstrainedIntra)
{
    Ipp32u uModeAbove[2];
    Ipp32u uModeLeft[2];
    Ipp32u uPredMode;        // predicted mode for current 4x4 block
    Ipp32u uBSMode;          // mode bits from bitstream

    IntraType *pRefIntraTypes;
    Ipp32u uLeftIndex;      // indexes into mode arrays, dependent on 8x8 block
    Ipp32u uAboveIndex;
    H264DecoderMacroblockGlobalInfo *gmbinfo=m_gmbinfo->mbs;
    Ipp32u predictors=31;//5 lsb bits set
    //new version
    {
        // above, left MB available only if they are INTRA
        if ((m_cur_mb.CurrentBlockNeighbours.mb_above.mb_num<0) || ((!IS_INTRA_MBTYPE(gmbinfo[m_cur_mb.CurrentBlockNeighbours.mb_above.mb_num].mbtype) && bUseConstrainedIntra)))
            predictors &= (~1);//clear 1-st bit
        if ((m_cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num<0) || ((!IS_INTRA_MBTYPE(gmbinfo[m_cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num].mbtype) && bUseConstrainedIntra)))
            predictors &= (~2); //clear 2-nd bit
        if ((m_cur_mb.CurrentBlockNeighbours.mbs_left[2].mb_num<0) || ((!IS_INTRA_MBTYPE(gmbinfo[m_cur_mb.CurrentBlockNeighbours.mbs_left[2].mb_num].mbtype) && bUseConstrainedIntra)))
            predictors &= (~4); //clear 4-th bit
    }

    // Get modes of blocks above and to the left, substituting 0
    // when above or to left is outside this MB slice. Substitute mode 2
    // when the adjacent macroblock is not 4x4 INTRA. Add 1 to actual
    // modes, so mode range is 1..9.

    if (predictors&1)
    {
        if (gmbinfo[m_cur_mb.CurrentBlockNeighbours.mb_above.mb_num].mbtype == MBTYPE_INTRA)
        {
            pRefIntraTypes = m_pMBIntraTypes + m_cur_mb.CurrentBlockNeighbours.mb_above.mb_num * NUM_INTRA_TYPE_ELEMENTS;
            uModeAbove[0] = pRefIntraTypes[10] + 1;
            uModeAbove[1] = pRefIntraTypes[14] + 1;
        }
        else
        {   // MB above in slice but not INTRA, use mode 2 (+1)
            uModeAbove[0] = uModeAbove[1] = 2 + 1;
        }
    }
    else
    {
        uModeAbove[0] = uModeAbove[1] = 0;
    }
    if (predictors&2)
    {
        if (gmbinfo[m_cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num].mbtype  == MBTYPE_INTRA)
        {
            pRefIntraTypes = m_pMBIntraTypes + m_cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num*NUM_INTRA_TYPE_ELEMENTS;
            uModeLeft[0] = pRefIntraTypes[NIT2LIN[m_cur_mb.CurrentBlockNeighbours.mbs_left[0].block_num]] + 1;
        }
        else
        {   // MB left in slice but not INTRA, use mode 2 (+1)
            uModeLeft[0] = 2+1;
        }
    }
    else
    {
        uModeLeft[0] = 0;
    }

    if (predictors&4)
    {
        if (gmbinfo[m_cur_mb.CurrentBlockNeighbours.mbs_left[2].mb_num].mbtype == MBTYPE_INTRA)
        {
            pRefIntraTypes = m_pMBIntraTypes + m_cur_mb.CurrentBlockNeighbours.mbs_left[2].mb_num*NUM_INTRA_TYPE_ELEMENTS;
            uModeLeft[1] = pRefIntraTypes[NIT2LIN[m_cur_mb.CurrentBlockNeighbours.mbs_left[2].block_num]] + 1;
        }
        else
        {   // MB left in slice but not INTRA, use mode 2 (+1)
            uModeLeft[1] = 2+1;
        }
    }
    else
    {
        uModeLeft[1] = 0;
    }

    uAboveIndex = 0;
    uLeftIndex = 0;

    // upper left 8x8

    // Predicted mode is minimum of the above and left modes, or
    // mode 2 if above or left is outside slice, indicated by 0 in
    // mode array.
    uPredMode = IPP_MIN(uModeLeft[uLeftIndex], uModeAbove[uAboveIndex]);
    if (uPredMode)
        uPredMode--;
    else
        uPredMode = 2;

    // If next bitstream bit is 1, use predicted mode, else read new mode
    if (m_pBitStream->Get1Bit() == 0)
    {
        // get 3 more bits to determine new mode
        uBSMode = m_pBitStream->GetBits(3);
        if (uBSMode < uPredMode)
            uPredMode = uBSMode;
        else
            uPredMode = uBSMode + 1;
    }
    // Save mode
    pMBIntraTypes[0] =
    pMBIntraTypes[1] =
    pMBIntraTypes[2] =
    pMBIntraTypes[3] =
        (IntraType)uPredMode;
    uModeAbove[uAboveIndex] = uPredMode + 1;

    // upper right 8x8
    uPredMode = IPP_MIN(uPredMode+1, uModeAbove[uAboveIndex+1]);
    if (uPredMode)
        uPredMode--;
    else
        uPredMode = 2;

    if (m_pBitStream->Get1Bit() == 0)
    {
        uBSMode = m_pBitStream->GetBits(3);
        if (uBSMode < uPredMode)
            uPredMode = uBSMode;
        else
            uPredMode = uBSMode + 1;
    }

    pMBIntraTypes[4] =
    pMBIntraTypes[5] =
    pMBIntraTypes[6] =
    pMBIntraTypes[7] =
        (IntraType)uPredMode;
    uModeAbove[uAboveIndex+1] = uPredMode + 1;
    uModeLeft[uLeftIndex] = uPredMode + 1;

    // lower left 4x4
    uPredMode = IPP_MIN(uModeLeft[uLeftIndex+1], uModeAbove[uAboveIndex]);
    if (uPredMode)
        uPredMode--;
    else
        uPredMode = 2;

    if (m_pBitStream->Get1Bit() == 0)
    {
        uBSMode = m_pBitStream->GetBits(3);
        if (uBSMode < uPredMode)
            uPredMode = uBSMode;
        else
            uPredMode = uBSMode + 1;
    }
    pMBIntraTypes[8] =
    pMBIntraTypes[9] =
    pMBIntraTypes[10] =
    pMBIntraTypes[11] =
     (IntraType)uPredMode;
    uModeAbove[uAboveIndex] = uPredMode + 1;

    // lower right 4x4 (above and left must always both be in slice)
    uPredMode = IPP_MIN(uPredMode+1, uModeAbove[uAboveIndex+1]) - 1;

    if (m_pBitStream->Get1Bit() == 0)
    {
        uBSMode = m_pBitStream->GetBits(3);
        if (uBSMode < uPredMode)
            uPredMode = uBSMode;
        else
            uPredMode = uBSMode + 1;
    }
    pMBIntraTypes[12] =
    pMBIntraTypes[13] =
    pMBIntraTypes[14] =
    pMBIntraTypes[15] =
        (IntraType)uPredMode;
    uModeAbove   [uAboveIndex+1] = uPredMode + 1;
    uModeLeft    [uLeftIndex+1]  = uPredMode + 1;

    // copy last IntraTypes to first 4 for reconstruction since they're not used for further prediction
    pMBIntraTypes[1] = pMBIntraTypes[4];
    pMBIntraTypes[2] = pMBIntraTypes[8];
    pMBIntraTypes[3] = pMBIntraTypes[12];

} // void H264SegmentDecoder::DecodeIntraTypes8x8_CAVLC(Ipp32u *pMBIntraTypes,

Ipp32u H264SegmentDecoder::DecodeCBP_CAVLC(Ipp32u color_format)
{
    Ipp32u index;
    Ipp32u cbp;

    index = (Ipp32u) m_pBitStream->GetVLCElement(false);

    if (index < 48)
    {
        if (MBTYPE_INTRA == m_cur_mb.GlobalMacroblockInfo->mbtype)
            cbp = dec_cbp_intra[0 != color_format][index];
        else
            cbp = dec_cbp_inter[0 != color_format][index];
    }
    else
    {
        throw h264_exception(UMC_ERR_INVALID_STREAM);
    }

    return cbp;

} // Ipp32u H264SegmentDecoder::DecodeCBP_CAVLC(Ipp32u color_format)

void H264SegmentDecoder::DecodeEdgeType()
{
    Ipp8u edge_type = 0;
    Ipp8u edge_type_2t = 0;
    Ipp8u edge_type_2b = 0;
    Ipp8u special_MBAFF_case =0;

    Ipp32s nLeft = m_cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num;
    Ipp32s nTop = m_cur_mb.CurrentBlockNeighbours.mb_above.mb_num;
    Ipp32s nTopLeft = m_cur_mb.CurrentBlockNeighbours.mb_above_left.mb_num;
    Ipp32s nTopRight = m_cur_mb.CurrentBlockNeighbours.mb_above_right.mb_num;
    if (m_isMBAFF)
    {
        Ipp32s currmb_fdf = pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo);
        if (m_IsUseConstrainedIntra)
        {
            Ipp32s mbA_fdf=1;
            Ipp32s mbA_is_intra=0;
            Ipp32s mbpA_is_intra=0;

            if (nLeft >= 0)
            {
                mbA_fdf = GetMBFieldDecodingFlag(m_gmbinfo->mbs[m_cur_mb.CurrentMacroblockNeighbours.mb_A]);
                mbA_is_intra = IS_INTRA_MBTYPE(m_gmbinfo->mbs[m_cur_mb.CurrentMacroblockNeighbours.mb_A].mbtype);
                mbpA_is_intra = IS_INTRA_MBTYPE(m_gmbinfo->mbs[m_cur_mb.CurrentMacroblockNeighbours.mb_A+1].mbtype);
            }

            if (currmb_fdf) //current mb coded as field MB
            {
                if (!mbA_fdf) //(special case is allowed only in this branch)
                {
                    if (mbA_is_intra && !mbpA_is_intra) special_MBAFF_case = 1;//only 2 top blocks can use left samples
                    if (!mbA_is_intra && mbpA_is_intra) special_MBAFF_case = 2;//only 2 bottom blocks can use left samples
                }
            }

            switch (special_MBAFF_case)
            {
            case 1:
                if (0 > nTop)
                    edge_type_2t |= IPPVC_TOP_EDGE;
                else
                    if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTop].mbtype)) edge_type_2t |= IPPVC_TOP_EDGE;

                if (0 > nTopLeft)
                    edge_type_2t |= IPPVC_TOP_LEFT_EDGE;
                else
                    if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTopLeft].mbtype)) edge_type_2t |= IPPVC_TOP_LEFT_EDGE;

                if (0 > nTopRight)
                    edge_type_2t |= IPPVC_TOP_RIGHT_EDGE;
                else
                    if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTopRight].mbtype)) edge_type_2t |= IPPVC_TOP_RIGHT_EDGE;

                edge_type_2b = IPPVC_LEFT_EDGE | IPPVC_TOP_RIGHT_EDGE;
                break;
            case 2:
                edge_type_2t |= IPPVC_LEFT_EDGE;

                if (0 > nTop)
                    edge_type_2t |= IPPVC_TOP_EDGE;
                else
                    if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTop].mbtype)) edge_type_2t |= IPPVC_TOP_EDGE;

                if (0 > nTopLeft)
                    edge_type_2t |= IPPVC_TOP_LEFT_EDGE;
                else
                    if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTopLeft].mbtype)) edge_type_2t |= IPPVC_TOP_LEFT_EDGE;

                if (0 > nTopRight)
                    edge_type_2t |= IPPVC_TOP_RIGHT_EDGE;
                else
                    if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTopRight].mbtype)) edge_type_2t |= IPPVC_TOP_RIGHT_EDGE;

                edge_type_2b = IPPVC_TOP_LEFT_EDGE | IPPVC_TOP_RIGHT_EDGE;

                break;
            default:
                if (0 > nLeft)
                    edge_type |= IPPVC_LEFT_EDGE;
                else
                {
                    if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nLeft].mbtype)) edge_type |= IPPVC_LEFT_EDGE;
                    if (mbA_fdf && !currmb_fdf && (!mbpA_is_intra || !mbA_is_intra)) edge_type |= IPPVC_LEFT_EDGE;
                }
                if (0 > nTop)
                    edge_type |= IPPVC_TOP_EDGE;
                else
                    if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTop].mbtype)) edge_type |= IPPVC_TOP_EDGE;
                if (0 > nTopLeft)
                    edge_type |= IPPVC_TOP_LEFT_EDGE;
                else
                    if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTopLeft].mbtype)) edge_type |= IPPVC_TOP_LEFT_EDGE;
                if (0 > nTopRight)
                    edge_type |= IPPVC_TOP_RIGHT_EDGE;
                else
                    if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTopRight].mbtype)) edge_type |= IPPVC_TOP_RIGHT_EDGE;
                break;
            }
        }
        else
        {
            if (0 > nLeft)
                edge_type |= IPPVC_LEFT_EDGE;
            if (0 > nTop)
                edge_type |= IPPVC_TOP_EDGE;
            if (0 > nTopLeft)
                edge_type |= IPPVC_TOP_LEFT_EDGE;
            if (0 > nTopRight)
                edge_type |= IPPVC_TOP_RIGHT_EDGE;

        }

        if (special_MBAFF_case)
        {
            m_mbinfo.mbs[m_CurMBAddr].IntraTypes.edge_type = (edge_type_2t << 8) | edge_type_2b;
            m_mbinfo.mbs[m_CurMBAddr].IntraTypes.edge_type |= 0x8000;
        }
        else
        {
            m_mbinfo.mbs[m_CurMBAddr].IntraTypes.edge_type = edge_type;
        }
    }
    else
    {
        if (m_IsUseConstrainedIntra)
        {
            if (0 > nLeft)
                edge_type |= IPPVC_LEFT_EDGE;
            else
                if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nLeft].mbtype)) edge_type |= IPPVC_LEFT_EDGE;
            if (0 > nTop)
                edge_type |= IPPVC_TOP_EDGE;
            else
                if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTop].mbtype)) edge_type |= IPPVC_TOP_EDGE;
            if (0 > nTopLeft)
                edge_type |= IPPVC_TOP_LEFT_EDGE;
            else
                if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTopLeft].mbtype)) edge_type |= IPPVC_TOP_LEFT_EDGE;
            if (0 > nTopRight)
                edge_type |= IPPVC_TOP_RIGHT_EDGE;
            else
                if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTopRight].mbtype)) edge_type |= IPPVC_TOP_RIGHT_EDGE;
        }
        else
        {
            if (0 > nLeft)
                edge_type |= IPPVC_LEFT_EDGE;
            if (0 > nTop)
                edge_type |= IPPVC_TOP_EDGE;
            if (0 > nTopLeft)
                edge_type |= IPPVC_TOP_LEFT_EDGE;
            if (0 > nTopRight)
                edge_type |= IPPVC_TOP_RIGHT_EDGE;
        }

        m_cur_mb.LocalMacroblockInfo->IntraTypes.edge_type = edge_type;
    }

} // void H264SegmentDecoder::DecodeEdgeType()

void H264SegmentDecoder::ReconstructEdgeType(Ipp8u &edge_type_2t, Ipp8u &edge_type_2b, Ipp32s &special_MBAFF_case)
{
    if (m_cur_mb.LocalMacroblockInfo->IntraTypes.edge_type > 0xff)
    {
        edge_type_2t = (Ipp8u)((m_cur_mb.LocalMacroblockInfo->IntraTypes.edge_type >> 8) & 0x7f);
        edge_type_2b = (Ipp8u)(m_cur_mb.LocalMacroblockInfo->IntraTypes.edge_type & 0xff);
        //m_cur_mb.LocalMacroblockInfo->IntraTypes.edge_type |= 0x8000;

        special_MBAFF_case = (edge_type_2t & IPPVC_LEFT_EDGE) ? 2 : 1;
    }
    else
    {
        special_MBAFF_case = 0;
        edge_type_2t = (Ipp8u)m_cur_mb.LocalMacroblockInfo->IntraTypes.edge_type;
    }
}

} // namespace UMC
#endif // UMC_ENABLE_H264_VIDEO_DECODER

⌨️ 快捷键说明

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