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

📄 umc_h264_dec_decode_mb_types.cpp

📁 这是在PCA下的基于IPP库示例代码例子,在网上下了IPP的库之后,设置相关参数就可以编译该代码.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*////              INTEL CORPORATION PROPRIETARY INFORMATION//  This software is supplied under the terms of a license  agreement or//  nondisclosure agreement with Intel Corporation and may not be copied//  or disclosed except in  accordance  with the terms of that agreement.//        Copyright (c) 2003-2005 Intel Corporation. All Rights Reserved.////*/#include "umc_h264_dec.h"#include "umc_h264_bitstream.h"namespace UMC{///////////////////////////////////////////////////////////////////////////////// lookup table to translate B frame type code to MB typeIpp8u CodeToMBTypeB[] = {    MBTYPE_DIRECT,          // 0    MBTYPE_FORWARD,    MBTYPE_BACKWARD,    MBTYPE_BIDIR,    MBTYPE_INTER_16x8,    MBTYPE_INTER_8x16,      // 5    MBTYPE_INTER_16x8,    MBTYPE_INTER_8x16,    MBTYPE_INTER_16x8,    MBTYPE_INTER_8x16,    MBTYPE_INTER_16x8,      // 10    MBTYPE_INTER_8x16,    MBTYPE_INTER_16x8,    MBTYPE_INTER_8x16,    MBTYPE_INTER_16x8,    MBTYPE_INTER_8x16,      // 15    MBTYPE_INTER_16x8,    MBTYPE_INTER_8x16,    MBTYPE_INTER_16x8,    MBTYPE_INTER_8x16,    MBTYPE_INTER_16x8,      // 20    MBTYPE_INTER_8x16,    MBTYPE_INTER_8x8};// lookup table to extract prediction direction from MB type code for// 16x8 and 8x16 MB types. Contains direction for first and second// subblocks at each entry.Ipp8u CodeToBDir[][2] = {    {D_DIR_FWD, D_DIR_FWD},    {D_DIR_BWD, D_DIR_BWD},    {D_DIR_FWD, D_DIR_BWD},    {D_DIR_BWD, D_DIR_FWD},    {D_DIR_FWD, D_DIR_BIDIR},    {D_DIR_BWD, D_DIR_BIDIR},    {D_DIR_BIDIR, D_DIR_FWD},    {D_DIR_BIDIR, D_DIR_BWD},    {D_DIR_BIDIR, D_DIR_BIDIR}};// lookup table to translate B frame 8x8 subblock code to type and// prediction directionstatic const struct {    Ipp8u type;    Ipp8u dir;} CodeToSBTypeAndDir[] = {    {SBTYPE_DIRECT, D_DIR_DIRECT},    {SBTYPE_8x8, D_DIR_FWD},    {SBTYPE_8x8, D_DIR_BWD},    {SBTYPE_8x8, D_DIR_BIDIR},    {SBTYPE_8x4, D_DIR_FWD},    {SBTYPE_4x8, D_DIR_FWD},    {SBTYPE_8x4, D_DIR_BWD},    {SBTYPE_4x8, D_DIR_BWD},    {SBTYPE_8x4, D_DIR_BIDIR},    {SBTYPE_4x8, D_DIR_BIDIR},    {SBTYPE_4x4, D_DIR_FWD},    {SBTYPE_4x4, D_DIR_BWD},    {SBTYPE_4x4, D_DIR_BIDIR}};const Ipp8u H264VideoDecoder::ICBPTAB[6] = {0,16,32,15,31,47};const int NIT2LIN[16]={     0, 1, 4, 5,     2, 3, 6, 7,     8, 9,12,13,    10,11,14,15};// Lookup table to get the 4 bit positions for the 4x4 blocks in the// blockcbp from the coded bits in 8x8 bitstream cbp.static const Ipp32u blockcbp_table[6] ={(0xf<<1),(0xf0<<1),(0xf00<<1),(0xf000<<1),(0x30000<<1),(0x3ff0000<<1)};// Lookup table to obtain NumCoefToLeft index (0..7) from block number in// decodeCoefficients, block 0 is INTRA16 DC. Used for luma and chroma.static const Ipp32u BlockNumToMBRow[] ={ 0,0,0,1,1,0,0,1,1,2,2,3,3,2,2,3,3,0,0,0,0,1,1,0,0,1,1};// Lookup table to obtain NumCoefAbove index (0..7) from block number in// decodeCoefficients, block 0 is INTRA16 DC. Used for luma and chroma.static const Ipp32u BlockNumToMBCol[] ={ 0,0,1,0,1,2,3,2,3,0,1,0,1,2,3,2,3,0,0,0,1,0,1,0,1,0,1};StatusH264VideoDecoder::DecodeMacroBlockType(    Ipp32u *pMBIntraTypes,    Ipp32s *MBSkipCount, // On entry if < 0, run of skipped MBs has just been completed                        // On return, zero or skip MB run count read from bitstream    Ipp32s *PassFDFDecode){    Status status = UMC_OK;    Ipp32u uCodeNum;    // interpretation of code depends upon slice type    if (m_CurSliceHeader.slice_type == INTRASLICE)    {        if (m_CurSliceHeader.MbaffFrameFlag)        {            if (pGetMBBottomFlag(m_cur_mb.GlobalMacroblockInfo)==0)            {                    Ipp32u bit = m_pBitStream->Get1Bit();                    pSetPairMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo,m_cur_mb.GlobalMacroblockPairInfo,bit);            }        }        else        {            pSetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo,0);        }        uCodeNum = m_pBitStream->GetVLCElement(false);        if (uCodeNum == 0)             m_cur_mb.GlobalMacroblockInfo->mbtype =  MBTYPE_INTRA;        else if (uCodeNum == 25)            m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_PCM;        else        {            m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA_16x16;            uCodeNum--;        }    }   // intra    else    {   // not Intra        if (*MBSkipCount >= 0) //actually it has to be = 0        {            VM_ASSERT(*MBSkipCount<=0);            uCodeNum = m_pBitStream->GetVLCElement(false);            // skipped MB count            if (uCodeNum)            {                *PassFDFDecode = 0;                *MBSkipCount = uCodeNum;                m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_SKIPPED;                goto done;            }        }        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_CurSliceHeader.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_CurSliceHeader.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;                            status = UMC_BAD_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                {                    status = UMC_BAD_STREAM;                }                break;            }        }   // P frame        else if (m_CurSliceHeader.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                        {                            status = UMC_BAD_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            {                status = UMC_BAD_STREAM;            }        }   // B frame        else        {            status = UMC_BAD_STREAM;        }    }   // not Intra    if (m_cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_INTRA_16x16)    {        // 16x16 INTRA, code includes prediction mode and cbp info        m_cur_mb.LocalMacroblockInfo->cbp = ICBPTAB[(uCodeNum)>>2];        pMBIntraTypes[0] =        pMBIntraTypes[1] =        pMBIntraTypes[2] =        pMBIntraTypes[3] = (uCodeNum) & 0x03;            //*pMBIntraTypes = (Ipp8u)(uCodeNum & 3); // 0..3, mode            if (uCodeNum > 11)            {                m_cur_mb.LocalMacroblockInfo->cbp4x4 |= D_CBP_LUMA_AC;// at least one luma AC coeff. present                uCodeNum -= 12; // for chroma cbp extraction            }            uCodeNum >>= 2;            if (uCodeNum > 0)            {                m_cur_mb.LocalMacroblockInfo->cbp4x4 |= D_CBP_CHROMA_DC;// DC chroma coeff present                if (uCodeNum > 1)                {                    m_cur_mb.LocalMacroblockInfo->cbp4x4 |= D_CBP_CHROMA_AC;// at least one AC chroma coeff.                }            }    }   // INTRA_16x16done:    m_cur_mb.LocalMacroblockInfo->mbtypeBS = m_cur_mb.GlobalMacroblockInfo->mbtype;    return status;}   // DecodeMacroBlockTypeStatus H264VideoDecoder::DecodeIntraTypes4x4_CAVLC( Ipp32u *pMBIntraTypes,bool bUseConstrainedIntra){    Ipp32u block;//    Ipp32u mb_width = m_pCurrentFrame->macroBlockSize().width;    //Ipp32s mb_left_offset = -(mb_width*pMB->bottom_mb)-1;    //Ipp32s mb_above_offset = -(mb_width*pMB->bottom_mb)-mb_width;    // Temp arrays for modes from above and left, initially filled from    // outside the MB, then updated with modes within the MB    Ipp32u dummyAbove;    Ipp32u dummyLeft;    Ipp8u *uModeAbove = (Ipp8u*)&dummyAbove;    Ipp8u *uModeLeft  = (Ipp8u*)&dummyLeft;    Ipp8u uPredMode;        // predicted mode for current 4x4 block    Ipp8u uBSMode;          // mode bits from bitstream    Ipp32u *pRefIntraTypes;    Ipp32u uLeftIndex;      // indexes into mode arrays, dependent on 8x8 block    Ipp32u uAboveIndex;    H264DecoderMacroblockGlobalInfo *gmbinfo=m_pCurrentFrame->m_mbinfo.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] = (Ipp8u) (pRefIntraTypes[10] + 1);            uModeAbove[1] = (Ipp8u) (pRefIntraTypes[11] + 1);            uModeAbove[2] = (Ipp8u) (pRefIntraTypes[14] + 1);            uModeAbove[3] = (Ipp8u) (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;            dummyAbove = 0x03030303;        }    }    else    {        //uModeAbove[0]=uModeAbove[1]=uModeAbove[2]=uModeAbove[3] = 0;        dummyAbove = 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] = (Ipp8u) (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)        {

⌨️ 快捷键说明

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