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

📄 umc_h264_segment_decoder_decode_mb_types.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            if (uCodeNum)
            {
                *PassFDFDecode = 0;
                *MBSkipCount = uCodeNum;
                m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_SKIPPED;
                return;
            }
        }
        else
        {
            // first MB after run of skipped MBs, no new skip count
            // in bitstream to read, clear MBSkipCount to detect next skip run
            *MBSkipCount = 0;
        }
        if (m_pSliceHeader->MbaffFrameFlag)
        {
            if (*PassFDFDecode==0)
            {
                Ipp32u bit = m_pBitStream->Get1Bit();
                pSetPairMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo,m_cur_mb.GlobalMacroblockPairInfo,bit);
                *PassFDFDecode = 1;
            }
            else
            {
                *PassFDFDecode = 0;
            }
        }
        else
        {
            pSetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo,0);
            *PassFDFDecode = 0;
        }
        uCodeNum = m_pBitStream->GetVLCElement(false);

        if (m_pSliceHeader->slice_type == PREDSLICE)
        {
            switch (uCodeNum)
            {
            case 0:
                // 16x16
                m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_FORWARD;
                break;
            case 1:
                // 16x8
                m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTER_16x8;
                break;
            case 2:
                // 8x16
                m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTER_8x16;
                break;
            case 3:
            case 4:
                // 8x8
                m_cur_mb.GlobalMacroblockInfo->mbtype = (Ipp8u) ((uCodeNum == 4) ? MBTYPE_INTER_8x8_REF0 : MBTYPE_INTER_8x8);
                {
                    // read subblock types
                    Ipp32u subblock;
                    Ipp8u sbtype;

                    for (subblock=0; subblock<4; subblock++)
                    {
                        uCodeNum = m_pBitStream->GetVLCElement(false);
                        switch (uCodeNum)
                        {
                        case 0:
                            sbtype = SBTYPE_8x8;
                            break;
                        case 1:
                            sbtype = SBTYPE_8x4;
                            break;
                        case 2:
                            sbtype = SBTYPE_4x8;
                            break;
                        case 3:
                            sbtype = SBTYPE_4x4;
                            break;
                        default:
                            sbtype = (Ipp8u) -1;
                            throw h264_exception(UMC_ERR_INVALID_STREAM);
                            break;
                        }
                        m_cur_mb.GlobalMacroblockInfo->sbtype[subblock] = sbtype;

                    }   // for subblock
                }   // 8x8 subblocks
                break;
            case 5:
                m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA;
                break;
            default:
                if (uCodeNum < 30)
                {
                    m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA_16x16;
                    uCodeNum -= 6;
                }
                else if (uCodeNum == 30)
                {
                    m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_PCM;
                }
                else
                {
                    throw h264_exception(UMC_ERR_INVALID_STREAM);
                }
                break;
            }
        }   // P frame
        else if (m_pSliceHeader->slice_type == BPREDSLICE)
        {
            if (uCodeNum < 23)
            {
                m_cur_mb.GlobalMacroblockInfo->mbtype = CodeToMBTypeB[uCodeNum];
                if (m_cur_mb.GlobalMacroblockInfo->mbtype  == MBTYPE_INTER_16x8 ||
                    m_cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_INTER_8x16)
                {
                    // direction for the two subblocks
                    m_cur_mb.LocalMacroblockInfo->sbdir[0] = CodeToBDir[(uCodeNum-4)>>1][0];
                    m_cur_mb.LocalMacroblockInfo->sbdir[1] = CodeToBDir[(uCodeNum-4)>>1][1];
                }
                if (m_cur_mb.GlobalMacroblockInfo->mbtype  == MBTYPE_INTER_8x8 || m_cur_mb.GlobalMacroblockInfo->mbtype  == MBTYPE_INTER_8x8_REF0)
                {
                    // read subblock types and prediction direction
                    Ipp32u subblock;
                    for (subblock=0; subblock<4; subblock++)
                    {
                        uCodeNum = m_pBitStream->GetVLCElement(false);
                        if (uCodeNum < 13)
                        {
                            m_cur_mb.GlobalMacroblockInfo->sbtype[subblock] =  CodeToSBTypeAndDir[uCodeNum].type;
                            m_cur_mb.LocalMacroblockInfo->sbdir[subblock] = CodeToSBTypeAndDir[uCodeNum].dir;
                        }
                        else
                        {
                            throw h264_exception(UMC_ERR_INVALID_STREAM);
                        }
                    }   // for subblock
                }   // 8x8 subblocks
            }
            else if (uCodeNum == 23)
                m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA;
            else if (uCodeNum < 48)
            {
                    m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA_16x16;
                    uCodeNum -= 24;
            }
            else if (uCodeNum == 48)
            {
                m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_PCM;
            }
            else
            {
                throw h264_exception(UMC_ERR_INVALID_STREAM);
            }
        }   // B frame
        else
        {
            throw h264_exception(UMC_ERR_INVALID_STREAM);
        }


    }   // not Intra

    if (m_cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_INTRA_16x16)
    {
        // 16x16 INTRA, code includes prediction mode and cbp info
        pMBIntraTypes[0] =
        pMBIntraTypes[1] =
        pMBIntraTypes[2] =
        pMBIntraTypes[3] = (IntraType)((uCodeNum) & 0x03);

        if (uCodeNum > 11)
        {
            m_cur_mb.LocalMacroblockInfo->cbp = 0x0f;
            uCodeNum -= 12;
        }
        else
            m_cur_mb.LocalMacroblockInfo->cbp = 0x00;
        uCodeNum <<= 2;
        m_cur_mb.LocalMacroblockInfo->cbp = (Ipp8u) (m_cur_mb.LocalMacroblockInfo->cbp | (uCodeNum & 0x30));

    } // INTRA_16x16
} // void H264SegmentDecoder::DecodeMacroBlockType(Ipp32u *pMBIntraTypes,

void H264SegmentDecoder::DecodeIntraTypes4x4_CAVLC(IntraType *pMBIntraTypes,
                                                     bool bUseConstrainedIntra)
{
    Ipp32u block;
    // Temp arrays for modes from above and left, initially filled from
    // outside the MB, then updated with modes within the MB
    Ipp32u uModeAbove[4];
    Ipp32u uModeLeft[4];
    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[1].mb_num<0) || ((!IS_INTRA_MBTYPE(gmbinfo[m_cur_mb.CurrentBlockNeighbours.mbs_left[1].mb_num].mbtype) && bUseConstrainedIntra)))
            predictors &= (~4); //clear 3-rd 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 &= (~8); //clear 4-th bit
        if ((m_cur_mb.CurrentBlockNeighbours.mbs_left[3].mb_num<0) || ((!IS_INTRA_MBTYPE(gmbinfo[m_cur_mb.CurrentBlockNeighbours.mbs_left[3].mb_num].mbtype) && bUseConstrainedIntra)))
            predictors &= (~16); //clear 5-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[11] + 1;
            uModeAbove[2] = pRefIntraTypes[14] + 1;
            uModeAbove[3] = pRefIntraTypes[15] + 1;
        }
        else
        {   // MB above in slice but not INTRA, use mode 2 (+1)
            uModeAbove[0] = uModeAbove[1] = uModeAbove[2] = uModeAbove[3] = 2 + 1;
        }
    }
    else
    {
        uModeAbove[0] = uModeAbove[1] = uModeAbove[2] = uModeAbove[3] = 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[1].mb_num].mbtype == MBTYPE_INTRA)
        {
            pRefIntraTypes = m_pMBIntraTypes + m_cur_mb.CurrentBlockNeighbours.mbs_left[1].mb_num*NUM_INTRA_TYPE_ELEMENTS;
            uModeLeft[1] = pRefIntraTypes[NIT2LIN[m_cur_mb.CurrentBlockNeighbours.mbs_left[1].block_num]] + 1;
        }
        else
        {
            // MB left in slice but not INTRA, use mode 2 (+1)
            uModeLeft[1] = 2+1;
        }
    }
    else
    {
        uModeLeft[1] = 0;
    }
    if (predictors&8)
    {
        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[2] = 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[2] = 2+1;
        }
    }
    else
    {
        uModeLeft[2] = 0;
    }

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

        // upper left 4x4

        // 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] = (IntraType)uPredMode;
        uModeAbove[uAboveIndex] = uPredMode + 1;

        // upper right 4x4
        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[1] = (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[2] = (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[3]             = (IntraType)uPredMode;
        uModeAbove   [uAboveIndex+1] = uPredMode + 1;
        uModeLeft    [uLeftIndex+1]  = uPredMode + 1;

        pMBIntraTypes += 4;

⌨️ 快捷键说明

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