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

📄 umc_h264_segment_decoder_decode_mb_types_cabac.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        // see subclause 9.3.3.1.1.8 of the h264 standard

        // get left macrobock condition
        nNum = m_cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num;
        if (0 <= nNum)
        {
            if (IS_INTRA_MBTYPE(m_gmbinfo->mbs[nNum].mbtype) && m_mbinfo.mbs[nNum].IntraTypes.intra_chroma_mode)
                condTermFlagA = 1;
        }

        // get above macroblock condition
        nNum = m_cur_mb.CurrentBlockNeighbours.mb_above.mb_num;
        if (0 <= nNum)
        {
            if (IS_INTRA_MBTYPE(m_gmbinfo->mbs[nNum].mbtype) && m_mbinfo.mbs[nNum].IntraTypes.intra_chroma_mode)
                condTermFlagB = 1;
        }

        ctxIdxInc = condTermFlagA + condTermFlagB;
    }

    // decode chroma mode
    {
        Ipp32u nVal;

        nVal = m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[INTRA_CHROMA_PRED_MODE] +
                                                   ctxIdxInc);

        if (nVal)
        {
            nVal = m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[INTRA_CHROMA_PRED_MODE] +
                                                       3);

            if (nVal)
            {
                nVal = m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[INTRA_CHROMA_PRED_MODE] +
                                                           3) + 1;
            }

            nVal += 1;
        }

        m_cur_mb.LocalMacroblockInfo->IntraTypes.intra_chroma_mode = (Ipp8u) nVal;
    }

} // void H264SegmentDecoder::DecodeIntraPredChromaMode_CABAC(void)

Ipp32u H264SegmentDecoder::DecodeMBSkipFlag_CABAC(Ipp32s ctxIdx)
{
    Ipp32s mbAddrA = -1, mbAddrB = -1;
    Ipp32s iFirstMB = m_pSlice->GetFirstMBNumber();

    // obtain neigbouring blocks
    if (0 == m_pSliceHeader->MbaffFrameFlag)
    {
        // obtain left macroblock addres
        if ((m_CurMB_X) &&
            (iFirstMB <= m_CurMBAddr - 1))
            mbAddrA = m_CurMBAddr - 1;

        // obtain above macroblock addres
        if ((m_CurMB_Y) &&
            (iFirstMB <= m_CurMBAddr - mb_width))
            mbAddrB = m_CurMBAddr - mb_width;
    }
    else
    {
        Ipp32s iCurrentField = 0;

        //
        // determine type of current macroblock
        // See subclause 7.4.4 of H.264 standard
        //

        if (0 == (m_CurMBAddr & 1))
        {
            Ipp32s mbAddr;

            // try to get left MB pair info
            mbAddr = m_CurMBAddr - 2;
            if ((iFirstMB <= mbAddr) &&
                (m_CurMB_X))
            {
                iCurrentField = GetMBFieldDecodingFlag(m_gmbinfo->mbs[mbAddr]);
            }
            else
            {
                // get above MB pair info
                mbAddr = m_CurMBAddr - mb_width * 2;
                if ((iFirstMB <= mbAddr) &&
                    (m_CurMB_Y))
                    iCurrentField = GetMBFieldDecodingFlag(m_gmbinfo->mbs[mbAddr]);
            }

            pSetPairMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo,
                                        m_cur_mb.GlobalMacroblockPairInfo,
                                        iCurrentField);
        }
        else
            iCurrentField = GetMBFieldDecodingFlag(m_gmbinfo->mbs[m_CurMBAddr]);

        //
        // calculate neighbouring blocks
        // See table 6-4 of H.264 standard
        //

        // top MB from macroblock pair
        if (0 == (m_CurMBAddr & 1))
        {
            // determine A macroblock
            if ((m_CurMB_X) &&
                (iFirstMB <= m_CurMBAddr - 2))
                mbAddrA = m_CurMBAddr - 2;

            // determine B macroblock
            if ((m_CurMB_Y) &&
                (iFirstMB <= m_CurMBAddr - mb_width * 2))
            {
                if (iCurrentField &
                    GetMBFieldDecodingFlag(m_gmbinfo->mbs[m_CurMBAddr - mb_width * 2]))
                    mbAddrB = m_CurMBAddr - mb_width * 2;
                else
                    mbAddrB = m_CurMBAddr - mb_width * 2 + 1;
            }
        }
        // bottom MB from macroblock pair
        else
        {
            // determine A macroblock
            if ((m_CurMB_X) &&
                (iFirstMB <= m_CurMBAddr - 2))
            {
                if (iCurrentField == GetMBFieldDecodingFlag(m_gmbinfo->mbs[m_CurMBAddr - 2]))
                    mbAddrA = m_CurMBAddr - 2;
                else
                    mbAddrA = m_CurMBAddr - 3;
            }

            // determine B macroblock
            if (0 == iCurrentField)
                mbAddrB = m_CurMBAddr - 1;
            else
            {
                if ((m_CurMB_Y) &&
                    (iFirstMB <= m_CurMBAddr - mb_width * 2))
                {
                    mbAddrB = m_CurMBAddr - mb_width * 2;
                }
            }
        }
    }

    // decode skip flag
    {
        Ipp32s condTermFlagA = 0, condTermFlagB = 0;
        Ipp32s ctxIdxInc;

        // obtain left macroblock info
        if ((0 <= mbAddrA) &&
            (!GetMBSkippedFlag(m_gmbinfo->mbs[mbAddrA])))
            condTermFlagA = 1;

        // obtain above macroblock info
        if ((0 <= mbAddrB) &&
            (!GetMBSkippedFlag(m_gmbinfo->mbs[mbAddrB])))
            condTermFlagB = 1;

        ctxIdxInc = condTermFlagA + condTermFlagB;

        return m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[ctxIdx] + ctxIdxInc);
    }

} // Ipp32u H264SegmentDecoder::DecodeMBSkipFlag_CABAC(Ipp32s ctxIdx)

static
Ipp32s PREDMBTYPETBL[] =
{
    MBTYPE_FORWARD,   MBTYPE_INTER_16x8,
    MBTYPE_INTER_8x16,MBTYPE_INTER_8x8,
    -1,               MBTYPE_INTRA,
    MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
    MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
    MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
    MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
    MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
    MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
    MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
    MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
    MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
    MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
    MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
    MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
    MBTYPE_PCM, MBTYPE_PCM, MBTYPE_PCM
};

static
Ipp32s SBTYPETBL[] =
{
    SBTYPE_8x8, SBTYPE_8x4, SBTYPE_4x8, SBTYPE_4x4
};

void H264SegmentDecoder::DecodeMBTypeISlice_CABAC(void)
{
    Ipp32s condTermFlagA = 0, condTermFlagB = 0;
    Ipp32s mbAddr;
    Ipp32s ctxIdxInc;
    Ipp32s mb_type;

    // get left macroblock type
    mbAddr = m_cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num;
    if (0 <= mbAddr)
    {
        if (MBTYPE_INTRA != m_gmbinfo->mbs[mbAddr].mbtype)
            condTermFlagA = 1;
    }

    // get abouve macroblock type
    mbAddr = m_cur_mb.CurrentBlockNeighbours.mb_above.mb_num;
    if (0 <= mbAddr)
    {
        if (MBTYPE_INTRA != m_gmbinfo->mbs[mbAddr].mbtype)
            condTermFlagB = 1;
    }

    ctxIdxInc = condTermFlagA + condTermFlagB;
    if (0 == m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_TYPE_I] + ctxIdxInc))
    {
        // we have I_NxN macroblock type
        m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA;
    }
    else
    {
        if (0 == m_pBitStream->DecodeSymbolEnd_CABAC())
        {
            Ipp32u code;

            // luma CBP bit
            if (m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_TYPE_I] + 3))
            {
                m_cur_mb.LocalMacroblockInfo->cbp = 0x0f;
                mb_type = 16;
            }
            else
            {
                m_cur_mb.LocalMacroblockInfo->cbp = 0x00;
                mb_type = 0;
            }

            // chroma CBP bits
            if (m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_TYPE_I] + 4))
            {
                if (m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_TYPE_I] + 5))
                {
                    m_cur_mb.LocalMacroblockInfo->cbp |= 0x20;
                    mb_type |= 12;
                }
                else
                {
                    m_cur_mb.LocalMacroblockInfo->cbp |= 0x10;
                    mb_type |= 8;
                }
            }

            // prediction bits
            code = m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_TYPE_I] + 6);
            code = (code << 1) |
                    m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_TYPE_I] + 7);
            mb_type |= code;

            m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA_16x16;
            original_mb_type = (Ipp8u) mb_type;
        }
        else
        {
            // we have I_PCM macroblock type
            m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_PCM;
        }
    }

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

static
Ipp8u MBTypesInPSlice[] =
{
    MBTYPE_FORWARD,
    MBTYPE_INTER_8x8,
    MBTYPE_INTER_8x16,
    MBTYPE_INTER_16x8
};

void H264SegmentDecoder::DecodeMBTypePSlice_CABAC(void)
{
    // macroblock has P type
    if (0 == m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_TYPE_P_SP] + 0))
    {
        Ipp32u code;

        code = m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_TYPE_P_SP] + 1);
        code = m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_TYPE_P_SP] + code + 2) +
               code * 2;

        // See table 9-28 of H.264 standard
        // for translating bin string (code) to mb_type
        m_cur_mb.GlobalMacroblockInfo->mbtype = (Ipp8u) MBTypesInPSlice[code];

        // decode subblock types
        if (MBTYPE_INTER_8x8 == m_cur_mb.GlobalMacroblockInfo->mbtype)
        {
            Ipp32s subblock;
            Ipp32u uCodeNum;

            for (subblock = 0; subblock < 4; subblock++)
            {
                // block type decoding
                if (m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[SUB_MB_TYPE_P_SP] + 0))
                    uCodeNum = 0;
                else
                {
                    if (m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[SUB_MB_TYPE_P_SP] + 1))
                        uCodeNum = 3 - m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[SUB_MB_TYPE_P_SP] + 2);
                    else
                        uCodeNum = 1;
                }

                m_cur_mb.GlobalMacroblockInfo->sbtype[subblock] = (Ipp8u) SBTYPETBL[uCodeNum];
            }
        }
    }
    // decode intra macroblock type in P slice
    else
    {
        // macroblock has I_NxN type
        if (0 == m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_TYPE_P_SP] + 3))
        {
            m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA;
        }
        else
        {

⌨️ 快捷键说明

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