📄 umc_h264_dec_decode_reconstruct.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"using namespace IppLevel;namespace UMC{Status H264VideoDecoder::DecRecSegment_CAVLC( Ipp32u unumMBs // updated on return with actual number decoded ){ Status status = UMC_OK;/* Ipp32s i;*/ Ipp32u mbcount; // counts number of MB's decoded in loop Ipp8u mbtype = 0, quant_prev; Ipp32s iSQUANT; bool bIsBSlice; bool bClearMV; Ipp32u *pMBIntraTypes; Ipp32u mbXOffset, mbYOffset; Ipp16s SliceNum; Ipp8u CurrPicParamSetId; Ipp8u CurrSeqParamSetId; bool bUseConstrainedIntra; bool bUseDirect8x8Inference; Ipp32s MBSkipCount=0; Ipp32s PassFDFDecode=0; Ipp32s DBCount; H264DecoderMBAddr NextMB; Ipp32s QPChromaIndex = 0; Ipp8u QPChroma = 0; // new mb_width = m_pCurrentFrame->macroBlockSize().width; mb_height = m_pCurrentFrame->macroBlockSize().height; quant_prev = m_mbinfo.mbs[m_CurSliceHeader.first_mb_in_slice].QP; SliceNum = m_pCurrentFrame->m_mbinfo.mbs[m_CurSliceHeader.first_mb_in_slice].slice_id; // Reset buffer pointers to start bIsBSlice = (m_CurSliceHeader.slice_type == BPREDSLICE); CurrPicParamSetId = m_CurSliceHeader.pic_parameter_set_id; bUseConstrainedIntra = m_PicParamSet[CurrPicParamSetId].constrained_intra_pred_flag != 0; CurrSeqParamSetId = m_PicParamSet[CurrPicParamSetId].seq_parameter_set_id; bUseDirect8x8Inference = m_SeqParamSet[CurrSeqParamSetId].direct_8x8_inference_flag != 0; H264DecoderFrame **pRefPicList0; H264DecoderFrame **pRefPicList1; pRefPicList0 = m_pCurrentFrame->GetRefPicList(SliceNum, 0)->m_RefPicList; pRefPicList1 = m_pCurrentFrame->GetRefPicList(SliceNum, 1)->m_RefPicList; Ipp8s pFields_stub=0; m_CurMBAddr = m_CurSliceHeader.first_mb_in_slice; bool mbaff = (0 != m_CurSliceHeader.MbaffFrameFlag); H264PicParamSet *pps = &m_PicParamSet[m_CurSliceHeader.pic_parameter_set_id]; Ipp32u uNumSliceGroups = pps->num_slice_groups;// reconstruct Data IppStatus sts = ippStsNoErr; bool intra; bool intra16x16; Ipp8u *pYPlane, *pUPlane, *pVPlane; Ipp32u uPitch = m_pCurrentFrame->pitch(); Ipp32u offsetY, offsetC; Ipp32s ChromaQPOffset = m_PicParamSet[m_CurrentPicParamSet].chroma_qp_index_offset; // Current plane pointers pYPlane = m_pCurrentFrame->m_pYPlane; pUPlane = m_pCurrentFrame->m_pUPlane; pVPlane = m_pCurrentFrame->m_pVPlane; // Reset buffer pointers to start // This works only as long as "batch size" for VLD and reconstruct // is the same. When/if want to make them different, need to change this. if (m_broken_buffer) { mbcount = m_broken_buffer_start_mb; SliceNum = m_broken_buffer_start_slice; DBCount = -1; goto start_slice_header; } for (mbcount=0,DBCount=0; mbcount<unumMBs; mbcount++,DBCount++) { // Reset buffer pointers to start m_pCoeffBlocksWrite = m_pCoeffBlocksBufStatic.Coeffs(); // Reset buffer pointers to start // This works only as long as "batch size" for VLD and reconstruct // is the same. When/if want to make them different, need to change this. m_pCoeffBlocksRead = m_pCoeffBlocksBufStatic.Coeffs(); pMBIntraTypes = m_pMBIntraTypes + m_CurMBAddr*NUM_INTRA_TYPE_ELEMENTS; // pel position of current macroblock in the luma plane m_CurMB_X = (m_CurMBAddr % mb_width); m_CurMB_Y = (m_CurMBAddr / mb_width); mbXOffset = m_CurMB_X * 16; mbYOffset = m_CurMB_Y * 16; VM_ASSERT(mbXOffset < m_pCurrentFrame->lumaSize().width); VM_ASSERT(mbYOffset < m_pCurrentFrame->lumaSize().height); UpdateCurrentMBInfo(); // MV and RefIndex store for subblock 0 of the current macroblock. bClearMV = true; //bClearNC = true; NextMB = m_mbinfo.active_next_mb_table[m_CurMBAddr]; m_cur_mb.LocalMacroblockInfo->QP = quant_prev; m_cur_mb.GlobalMacroblockInfo->slice_id = (Ipp16s) SliceNum; m_cur_mb.LocalMacroblockInfo->cbp4x4 = m_cur_mb.LocalMacroblockInfo->cbp_bits = m_cur_mb.LocalMacroblockInfo->cbp = m_cur_mb.LocalMacroblockInfo->intra_chroma_mode = 0; m_cur_mb.LocalMacroblockInfo->sbdir[0] = m_cur_mb.LocalMacroblockInfo->sbdir[1] = m_cur_mb.LocalMacroblockInfo->sbdir[2] = m_cur_mb.LocalMacroblockInfo->sbdir[3] =D_DIR_FWD; // Assume all subblocks have no transmitted coefficients initially. // Update cbp4x4 when we see a coefficient. UpdateNeighbouringAddresses(); // Set prediction direction for all partitions as forward, so it // is correctly set for SKIPPED and P frame MB for motion comp. { // Set L1 refidx for all blocks to default value of -1 (no reference). // For any bidir blocks, code below sets it to correct refidx. The // init to default is required even in non-B slices so the refidx // is correctly set for the loop filter for a picture containing // both P and B slices. Ipp32u *pRefIndexTmp = (Ipp32u *)m_cur_mb.RefIdxs[1]->RefIdxs; // pRefIndexTmp is 4-byte aligned for a MB, mb_width=(uSubBlockWidth>>2) pRefIndexTmp[0] = 0xffffffff; pRefIndexTmp[1] = 0xffffffff; pRefIndexTmp[2] = 0xffffffff; pRefIndexTmp[3] = 0xffffffff; } if (MBSkipCount <= 0) { while (1) // not really a loop, while used to enable use of break { // First decode the "macroblock header", e.g., macroblock type, // intra-coding types, motion vectors and CBP. // Get MB type, possibly change MBSKipCount to non-zero status = DecodeMacroBlockType(/*pMB,*/ pMBIntraTypes, &MBSkipCount, &PassFDFDecode); UpdateNeighbouringBlocks();//new version if (status != UMC_OK) break; mbtype = m_cur_mb.GlobalMacroblockInfo->mbtype;// pMB->mbtype; if (mbtype == MBTYPE_SKIPPED) break; if (mbtype == MBTYPE_INTRA) { status = DecodeIntraTypes4x4_CAVLC(/*pMB,*/ pMBIntraTypes, bUseConstrainedIntra); if (status != UMC_OK) break; } if (mbtype == MBTYPE_PCM) { status = DecodeCoefficients_PCM(1); // For PCM type MB, num coeffs are set by above call, cbp is // set to all blocks coded (for deblock filter), MV are set to zero, // QP is unchanged. //bClearNC = false; m_cur_mb.LocalMacroblockInfo->cbp4x4 = D_CBP_LUMA_DC | D_CBP_LUMA_AC | D_CBP_CHROMA_DC | D_CBP_CHROMA_AC; break; // no more to read from bitstream } if (IS_INTRA_MBTYPE(mbtype)) { // Get chroma prediction mode m_cur_mb.LocalMacroblockInfo->intra_chroma_mode = (Ipp8u) m_pBitStream->GetVLCElement(false); if (m_cur_mb.LocalMacroblockInfo->intra_chroma_mode > 3) { status = UMC_BAD_STREAM; break; } } if ( (!IS_INTRA_MBTYPE(mbtype)) && (mbtype != MBTYPE_DIRECT)) { // Motion Vector Computation if (bIsBSlice && (mbtype == MBTYPE_INTER_8x8 || mbtype == MBTYPE_INTER_8x8_REF0)) { // First, if B slice and MB is 8x8, set the MV for any DIRECT // 8x8 partitions. The MV for the 8x8 DIRECT partition need to // be properly set before the MV for subsequent 8x8 partitions // can be computed, due to prediction. The DIRECT MV are computed // by a separate function and do not depend upon block neighbors for // predictors, so it is done here first. if (!m_bUseSpatialDirectMode) { // temporal DIRECT prediction Ipp32u sb, sboffset; sboffset = 0; for (sb=0; sb<4; sb++) { if (m_cur_mb.GlobalMacroblockInfo->sbtype[sb] == SBTYPE_DIRECT) { // set DIRECT motion vectors Ipp32s yM=subblock_block_mapping[sb]; Ipp32s mb_col = GetColocatedLocation(pRefPicList1[0],0,yM); if (!bUseDirect8x8Inference && IS_INTER_MBTYPE(pRefPicList1[0]->m_mbinfo.mbs[mb_col].mbtype)) DecodeDirectMotionVectorsTemporal(/*pMB,*/sboffset, pRefPicList0, pRefPicList1,&pFields_stub,&pFields_stub, true); else DecodeDirectMotionVectorsTemporal_8x8Inference( //pMB, pRefPicList0, pRefPicList1,&pFields_stub,&pFields_stub, sb); } if (sb == 1) sboffset += 8 - 2; else sboffset += 2; } // for sb } // temporal DIRECT else { if (m_cur_mb.GlobalMacroblockInfo->sbtype[0] == SBTYPE_DIRECT || m_cur_mb.GlobalMacroblockInfo->sbtype[1] == SBTYPE_DIRECT || m_cur_mb.GlobalMacroblockInfo->sbtype[2] == SBTYPE_DIRECT || m_cur_mb.GlobalMacroblockInfo->sbtype[3] == SBTYPE_DIRECT) // spatial DIRECT, will set MV for any DIRECT 8x8 subblock DecodeDirectMotionVectorsSpatial( //pMB, pRefPicList0, pRefPicList1,0, bUseDirect8x8Inference); } // spatial DIRECT } // set 8x8 DIRECT in B slice // MV and Ref Index status = DecodeMotionVectors(/*pMB,*/ bIsBSlice); if (status != UMC_OK) break; bClearMV = false; } // cbp if (mbtype != MBTYPE_INTRA_16x16) { m_cur_mb.LocalMacroblockInfo->cbp = DecodeCBP_CAVLC(mbtype,1); if (m_cur_mb.LocalMacroblockInfo->cbp == 255) { status = UMC_BAD_STREAM; break; } } if (m_cur_mb.LocalMacroblockInfo->cbp || (mbtype == MBTYPE_INTRA_16x16)) { // check for usual case of zero QP delta if (!m_pBitStream->NextBit()) { // Update QP with delta from bitstream Ipp8s qpdelta = (Ipp8s) m_pBitStream->GetVLCElement(true); m_cur_mb.LocalMacroblockInfo->QP = m_cur_mb.LocalMacroblockInfo->QP + qpdelta; if (qpdelta > QP_MAX/2 || qpdelta < (-QP_MAX-1)/2) { /* status = UMC_BAD_STREAM; break;*/ //disabled since old h.264 files incompatibility } } // // Now, decode the coefficients // // Get the nonzero block coefficients from the bitstream. //if (cbp || (mbtype == MBTYPE_INTRA_16x16)) { Ipp32u cbp = m_mbinfo.mbs[m_CurMBAddr].cbp; if (mbtype == MBTYPE_INTRA_16x16) status = DecodeCoeffsIntra16x16_CAVLC(cbp); else status = DecodeCoeffs4x4_CAVLC(cbp); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -