📄 umc_h264_dec_decode_mb_cabac.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_dec_internal_cabac.h"#include "vm_types.h"#include "vm_debug.h"#include <ippi.h>*/namespace UMC{///////////////////////////////////////////////////////////////////////////////// lookup table to translate B frame type code to MB type// codes used to indicate the coding state of each blockconst Ipp32u CodNone = 0; // no codeconst Ipp32u CodInBS = 1; // read code from bitstreamconst Ipp32u CodLeft = 2; // code same as left 4x4 subblockconst Ipp32u CodAbov = 3; // code same as above 4x4 subblockconst Ipp32u CodSkip = 4; // skip for direct modeStatus H264VideoDecoder::DecodeMotionVectors_CABAC(){ // this variable used only in debug purposes Ipp32u i, j, k; Status status = UMC_OK; Ipp8s curmb_fdf = pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo); Ipp32u numRefIdxL0Active = m_CurSliceHeader.num_ref_idx_l0_active<<curmb_fdf; Ipp32u numRefIdxL1Active = m_CurSliceHeader.num_ref_idx_l1_active<<curmb_fdf; // initialize blocks coding pattern maps Ipp32u pCodRIxL0[16] = { CodNone, CodLeft, CodLeft, CodLeft, CodAbov, CodLeft, CodLeft, CodLeft, CodAbov, CodLeft, CodLeft, CodLeft, CodAbov, CodLeft, CodLeft, CodLeft }; Ipp32u pCodRIxL1[16] = { CodNone, CodLeft, CodLeft, CodLeft, CodAbov, CodLeft, CodLeft, CodLeft, CodAbov, CodLeft, CodLeft, CodLeft, CodAbov, CodLeft, CodLeft, CodLeft }; Ipp32u pCodMVdL0[16] = { CodNone, CodLeft, CodLeft, CodLeft, CodAbov, CodLeft, CodLeft, CodLeft, CodAbov, CodLeft, CodLeft, CodLeft, CodAbov, CodLeft, CodLeft, CodLeft }; Ipp32u pCodMVdL1[16] = { CodNone, CodLeft, CodLeft, CodLeft, CodAbov, CodLeft, CodLeft, CodLeft, CodAbov, CodLeft, CodLeft, CodLeft, CodAbov, CodLeft, CodLeft, CodLeft }; // block decoding order Ipp32u BlkOrder[2][16] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, { 0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15 } }; Ipp32u* pBlkIdx; // subblock indices const Ipp32u sb16x8[] = { 0, 8 }; const Ipp32u sb8x16[] = { 0, 2 }; const Ipp32u sb8x8[4] = { 0, 2, 8, 10 }; switch (m_cur_mb.GlobalMacroblockInfo->mbtype) { case MBTYPE_FORWARD: pBlkIdx = BlkOrder[0]; pCodRIxL0[0] = CodInBS; pCodRIxL1[0] = CodNone; pCodMVdL0[0] = CodInBS; pCodMVdL1[0] = CodNone; break; case MBTYPE_BACKWARD: pBlkIdx = BlkOrder[0]; pCodRIxL0[0] = CodNone; pCodRIxL1[0] = CodInBS; pCodMVdL0[0] = CodNone; pCodMVdL1[0] = CodInBS; break; case MBTYPE_BIDIR: pBlkIdx = BlkOrder[0]; pCodRIxL0[0] = CodInBS; pCodRIxL1[0] = CodInBS; pCodMVdL0[0] = CodInBS; pCodMVdL1[0] = CodInBS; break; case MBTYPE_INTER_16x8: pBlkIdx = BlkOrder[0]; for (i = 0; i < 2; i ++) { j = sb16x8[i]; Ipp32u cL0 = (m_cur_mb.LocalMacroblockInfo->sbdir[i] == D_DIR_BWD) ? CodNone : CodInBS; Ipp32u cL1 = (m_cur_mb.LocalMacroblockInfo->sbdir[i] == D_DIR_FWD) ? CodNone : CodInBS; pCodRIxL0[j] = cL0; pCodRIxL1[j] = cL1; pCodMVdL0[j] = cL0; pCodMVdL1[j] = cL1; } break; case MBTYPE_INTER_8x16: pBlkIdx = BlkOrder[0]; for (i = 0; i < 2; i ++) { j = sb8x16[i]; Ipp32u cL0 = (m_cur_mb.LocalMacroblockInfo->sbdir[i] == D_DIR_BWD) ? CodNone : CodInBS; Ipp32u cL1 = (m_cur_mb.LocalMacroblockInfo->sbdir[i] == D_DIR_FWD) ? CodNone : CodInBS; pCodRIxL0[j] = cL0; pCodRIxL1[j] = cL1; pCodMVdL0[j] = cL0; pCodMVdL1[j] = cL1; } pCodRIxL0[6] = pCodRIxL0[10] = pCodRIxL0[14] = CodAbov; pCodRIxL1[6] = pCodRIxL1[10] = pCodRIxL1[14] = CodAbov; pCodMVdL0[6] = pCodMVdL0[10] = pCodMVdL0[14] = CodAbov; pCodMVdL1[6] = pCodMVdL1[10] = pCodMVdL1[14] = CodAbov; break; case MBTYPE_INTER_8x8: case MBTYPE_INTER_8x8_REF0: pBlkIdx = BlkOrder[1]; for (i = k = 0; i < 4; i ++, k += 4) { j = sb8x8[i]; pBlkIdx[k] = j; pBlkIdx[k + 1] = j + 1; pBlkIdx[k + 2] = j + 4; pBlkIdx[k + 3] = j + 5; Ipp32u cL0 = (m_cur_mb.LocalMacroblockInfo->sbdir[i] == D_DIR_BWD) ? CodNone : CodInBS; Ipp32u cL1 = (m_cur_mb.LocalMacroblockInfo->sbdir[i] == D_DIR_FWD) ? CodNone : CodInBS; switch (m_cur_mb.GlobalMacroblockInfo->sbtype[i]) { case SBTYPE_8x8: cL0 = (m_cur_mb.LocalMacroblockInfo->sbdir[i] == D_DIR_BWD) ? CodNone : CodInBS; cL1 = (m_cur_mb.LocalMacroblockInfo->sbdir[i] == D_DIR_FWD) ? CodNone : CodInBS; pCodRIxL0[j] = cL0; pCodRIxL1[j] = cL1; pCodRIxL0[j + 4] = CodAbov; pCodRIxL1[j + 4] = CodAbov; pCodMVdL0[j] = cL0; pCodMVdL1[j] = cL1; pCodMVdL0[j + 4] = CodAbov; pCodMVdL1[j + 4] = CodAbov; break; case SBTYPE_8x4: cL0 = (m_cur_mb.LocalMacroblockInfo->sbdir[i] == D_DIR_BWD) ? CodNone : CodInBS; cL1 = (m_cur_mb.LocalMacroblockInfo->sbdir[i] == D_DIR_FWD) ? CodNone : CodInBS; pCodRIxL0[j] = cL0; pCodRIxL1[j] = cL1; pCodRIxL0[j + 4] = CodAbov; pCodRIxL1[j + 4] = CodAbov; pCodMVdL0[j] = cL0; pCodMVdL1[j] = cL1; pCodMVdL0[j + 4] = cL0; pCodMVdL1[j + 4] = cL1; break; case SBTYPE_4x8: cL0 = (m_cur_mb.LocalMacroblockInfo->sbdir[i] == D_DIR_BWD) ? CodNone : CodInBS; cL1 = (m_cur_mb.LocalMacroblockInfo->sbdir[i] == D_DIR_FWD) ? CodNone : CodInBS; pCodRIxL0[j] = cL0; pCodRIxL1[j] = cL1; pCodRIxL0[j + 4] = CodAbov; pCodRIxL1[j + 4] = CodAbov; pCodMVdL0[j] = cL0; pCodMVdL1[j] = cL1; pCodMVdL0[j + 1] = cL0; pCodMVdL1[j + 1] = cL1; pCodMVdL0[j + 4] = pCodMVdL0[j + 5] = CodAbov; pCodMVdL1[j + 4] = pCodMVdL1[j + 5] = CodAbov; break; case SBTYPE_4x4: cL0 = (m_cur_mb.LocalMacroblockInfo->sbdir[i] == D_DIR_BWD) ? CodNone : CodInBS; cL1 = (m_cur_mb.LocalMacroblockInfo->sbdir[i] == D_DIR_FWD) ? CodNone : CodInBS; pCodRIxL0[j] = cL0; pCodRIxL1[j] = cL1; pCodRIxL0[j + 4] = CodAbov; pCodRIxL1[j + 4] = CodAbov; pCodMVdL0[j] = pCodMVdL0[j + 1] = pCodMVdL0[j + 4] = pCodMVdL0[j + 5] = cL0; pCodMVdL1[j] = pCodMVdL1[j + 1] = pCodMVdL1[j + 4] = pCodMVdL1[j + 5] = cL1; break; case SBTYPE_DIRECT: cL0 = (m_cur_mb.LocalMacroblockInfo->sbdir[i] == D_DIR_DIRECT_SPATIAL_BWD) ? CodNone : CodSkip; cL1 = (m_cur_mb.LocalMacroblockInfo->sbdir[i] == D_DIR_DIRECT_SPATIAL_FWD) ? CodNone : CodSkip; pCodRIxL0[j] = pCodRIxL0[j + 1] = pCodRIxL0[j + 4] = pCodRIxL0[j + 5] = cL0; pCodRIxL1[j] = pCodRIxL1[j + 1] = pCodRIxL1[j + 4] = pCodRIxL1[j + 5] = cL1; pCodMVdL0[j] = pCodMVdL0[j + 1] = pCodMVdL0[j + 4] = pCodMVdL0[j + 5] = cL0; pCodMVdL1[j] = pCodMVdL1[j + 1] = pCodMVdL1[j + 4] = pCodMVdL1[j + 5] = cL1; break; default: status = UMC_BAD_STREAM; goto done; } } break; default: status = UMC_BAD_STREAM; goto done; } // switch // get all ref_idx_L0 status = GetRefIdx4x4_CABAC( numRefIdxL0Active, pBlkIdx, pCodRIxL0, 0); if (status != UMC_OK) goto done; // get all ref_idx_L1 status = GetRefIdx4x4_CABAC( numRefIdxL1Active, pBlkIdx, pCodRIxL1, 1); if (status != UMC_OK) goto done; // get all mvd_L0 status = GetMVD4x4_CABAC( pBlkIdx, pCodMVdL0, 0); if (status != UMC_OK) goto done; // get all mvd_L1 status = GetMVD4x4_CABAC( pBlkIdx, pCodMVdL1, 1);done: return status;} // Status H264VideoDecoder::DecodeMotionVectors_CABAC(bool bIsBSlice)// ---------------------------------------------------------------------------// H264VideoDecoder::GetRefIdx4x4_CABAC()// get ref_idx and update info for all 4x4 blocks// ---------------------------------------------------------------------------Status H264VideoDecoder::GetRefIdx4x4_CABAC( const Ipp32u nActive, Ipp32u* pBlkIdx, Ipp32u* pCodRIx, Ipp32s ListNum){ // this variable used only in debug purposes Status status = UMC_OK; Ipp32u i, j, k; // new Ipp8s *pRIx = m_cur_mb.RefIdxs[ListNum]->RefIdxs; Ipp8s *pMVflag = m_cur_mb.MVFlags[ListNum]->MVFlags; // old if (nActive > 1) { for (i = 0; i < 16; i ++) { j = pBlkIdx[i]; k = (j >> 2) * 4+ (j & 3); switch (pCodRIx[j]) { case CodNone: pRIx[k] = -1; break; case CodInBS: Ipp32s refIdx; refIdx = (Ipp32s) GetSE_RefIdx_CABAC(/*pMBInfo,*/ListNum,k);//&pRIx[k], &pMVflag[k]);//, bLeftAvail[j], bTopAvail[j]); if (refIdx >= (Ipp8s) nActive || refIdx < 0) { status = UMC_BAD_STREAM; goto done; } pRIx[k] = (Ipp8s) refIdx; pMVflag[k] = 1; break; case CodLeft: pRIx[k] = pRIx[k - 1]; pMVflag[k] = pMVflag[k - 1]; break; case CodAbov: pRIx[k] = pRIx[k - 4]; pMVflag[k] = pMVflag[k - 4]; break; case CodSkip: break; } } // for i } else { for (i = 0; i < 16; i ++) { j = pBlkIdx[i]; k = (j >> 2) * 4+ (j & 3); switch (pCodRIx[j]) { case CodNone: pRIx[k] = -1; break; case CodInBS: pRIx[k] = 0; pMVflag[k] = 1; break; case CodLeft: pRIx[k] = pRIx[k - 1]; pMVflag[k] = pMVflag[k - 1]; break; case CodAbov: pRIx[k] = pRIx[k - 4]; pMVflag[k] = pMVflag[k - 4]; break; case CodSkip: break; } } // for i }done: return status;} // Status H264VideoDecoder::GetRefIdx4x4_CABAC(const Ipp32u nActive,// ---------------------------------------------------------------------------// H264VideoDecoder::GetMVD4x4_CABAC()// get mvd and update info for all 4x4 blocks// ---------------------------------------------------------------------------Status H264VideoDecoder::GetMVD4x4_CABAC( Ipp32u* pBlkIdx, Ipp32u* pCodMVd, Ipp32s ListNum//, ){ // this variable used only in debug purposes Status status = UMC_OK; Ipp32u i, j, k, m = 0; // new const H264DecoderMotionVector MV0 = {0, 0}; H264DecoderMotionVector *pMV = m_cur_mb.MVs[ListNum]->MotionVectors; H264DecoderMotionVector *pMVd = m_cur_mb.MVs[ListNum + 2]->MotionVectors; Ipp8s *pRIx = m_cur_mb.RefIdxs[ListNum]->RefIdxs; // old for (i = 0; i < 16; i ++) { j = pBlkIdx[i]; k = (j >> 2) * 4 + (j & 3); if ((m_cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_INTER_8x8 || m_cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_INTER_8x8_REF0) && !(i & 3)) m = i; // new H264DecoderMotionVector mv; H264DecoderMotionVector mvd; Ipp32s mvpx, mvpy; switch (pCodMVd[j]) { case CodNone: pMV[k] = MV0; pMVd[k] = MV0; m++; break; case CodInBS: mvd = GetSE_MVD_CABAC(ListNum, k); // TBD optimization - modify to compute predictors here instead of calling this method ComputeMotionVectorPredictors( (Ipp8u) ListNum, pRIx[k],
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -