📄 umc_h264_dec_decode_mb_types.cpp
字号:
/*//// 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 + -