📄 umc_h264_dec_decode_reconstruct.cpp
字号:
// spatial DIRECT, will set MV for any DIRECT 8x8 subblock DecodeDirectMotionVectorsSpatial( pRefPicList0, pRefPicList1,0, bUseDirect8x8Inference); } } // spatial DIRECT } // set 8x8 DIRECT in B slice // MV and Ref Index status = DecodeMotionVectors_CABAC(); if (status != UMC_OK) break; bClearMV = false; } // cbp if (mbtype != MBTYPE_INTRA_16x16) { Ipp32u cbp; cbp = DecodeCBP_CABAC(1); m_cur_mb.LocalMacroblockInfo->cbp = (Ipp8u) cbp; if(!cbp) m_prev_dquant = 0; if (cbp == 255) { status = UMC_BAD_STREAM; break; } } // delta QP if (m_cur_mb.LocalMacroblockInfo->cbp || (mbtype == MBTYPE_INTRA_16x16)) { // check for usual case of zero QP delta Ipp32u ct, code; Ipp32u ctxIdxInc; Ipp8s qpdelta; ct = (m_prev_dquant) ? (1) : (0); ctxIdxInc = ct; code = m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_QP_DELTA] + ctxIdxInc); if (code) { ctxIdxInc = 2; code = m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_QP_DELTA] + ctxIdxInc); if (code) { ctxIdxInc = 3; code = 1; while (m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_QP_DELTA] + ctxIdxInc)) code++; } code++; } qpdelta = (Ipp8s) ((code + 1) / 2); // lsb is signed bit if ((code & 0x01) == 0) { qpdelta = -qpdelta; } 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 } m_prev_dquant = qpdelta; // // Now, decode the coefficients // status = DecodeCoefficients4x4_CABAC(m_cur_mb.LocalMacroblockInfo->cbp); } m_cur_mb.LocalMacroblockInfo->QP = QPFromCode(m_cur_mb.LocalMacroblockInfo->QP); quant_prev = m_cur_mb.LocalMacroblockInfo->QP; break; } // while 1 // quit if error detected if (status != UMC_OK) break; if (MBSkipFlag) { // Note DecodeMacroBlockType above will change MBSkipCount value if (!pGetMBBottomFlag(m_cur_mb.GlobalMacroblockInfo) && mbaff) { Ipp32s temp=m_CurMBAddr; //temporal modiry current mb address m_CurMBAddr = m_PairMBAddr; m_PairMBAddr = temp; UpdateCurrentMBInfo(); DecodeMBSkipAndFDF(&MBSkipFlag, bIsBSlice); skip_next_fdf=true; m_PairMBAddr = m_CurMBAddr; m_CurMBAddr = temp; UpdateCurrentMBInfo(); //restore current mb address UpdateNeighbouringBlocks(); } } if ((m_cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_DIRECT) || (m_cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_SKIPPED)) { if (!bIsBSlice) { bClearMV = DecodeSkipMotionVectors(/*pMB*/); } else { // set DIRECT motion vectors for the MB if (!m_bUseSpatialDirectMode) { // temporal prediction Ipp32s yM=0; Ipp32u nNum; nNum = GetColocatedLocation(pRefPicList1[0],0, yM); if (!bUseDirect8x8Inference && IS_INTER_MBTYPE(m_pCurrentFrame->m_mbinfo.mbs[nNum].mbtype)) { DecodeDirectMotionVectorsTemporal( 0, pRefPicList0, pRefPicList1,&pFields_stub,&pFields_stub, false); } else { DecodeDirectMotionVectorsTemporal_8x8Inference( pRefPicList0, pRefPicList1,&pFields_stub,&pFields_stub, -1); } } else { // spatial prediction DecodeDirectMotionVectorsSpatial(/*pMB,*/ pRefPicList0, pRefPicList1,0, bUseDirect8x8Inference); } bClearMV = false; } if (status != UMC_OK) break; } if (bClearMV) { //++++++++++++++++++++++++++++++++++++++++++ // zero out stored motion vectors. 4 mvx,mvy pairs, 4 rows // also init ref index to -1 for all subblocks (4 bytes per row) // or to 0 when MB was P frame skipped. // pMV is 8-byte aligned for a MB H264DecoderMacroblockMVs *pMV = m_cur_mb.MVs[0]; H264DecoderMacroblockRefIdxs *pRefIndex = m_cur_mb.RefIdxs[0]; // zero out stored motion vectors. 4 mvx,mvy pairs, 4 rows // also init ref index to -1 for all subblocks (4 bytes per row) // or to 0 when MB was P frame skipped. // pMV is 8-byte aligned for a MB if ((m_cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_SKIPPED) && !bIsBSlice) memset((void *)pRefIndex,0,sizeof(H264DecoderMacroblockRefIdxs)); else memset((void *)pRefIndex,-1,sizeof(H264DecoderMacroblockRefIdxs)); memset((void *)pMV, 0, sizeof(H264DecoderMacroblockMVs));//clear all 16 vectors if (bIsBSlice) { // INTRA MB in B slice // zero MV in backward MV storage for all subblocks pMV = m_cur_mb.MVs[1]; memset((void *)pMV, 0, sizeof(H264DecoderMacroblockMVs));//clear all 16 vectors } } // reconstruct starts here // Perform motion compensation to reconstruct the YUV data // offsetY = mbXOffset + (mbYOffset * uPitch); offsetC = offsetY >> 1; intra = bool(IS_INTRA_MBTYPE(mbtype)); intra16x16 = bool(mbtype == MBTYPE_INTRA_16x16); QPChromaIndex = m_cur_mb.LocalMacroblockInfo->QP + ChromaQPOffset; QPChromaIndex = MIN(QPChromaIndex, (Ipp32s)QP_MAX); QPChromaIndex = MAX(0, QPChromaIndex); QPChroma = QPtoChromaQP[QPChromaIndex]; if (intra) { if (mbtype != MBTYPE_PCM) { Ipp8u edge_type = 0; Ipp8u edge_type_2t = 0; Ipp8u edge_type_2b = 0; Ipp32s nLeft, nTop, nTopLeft, nTopRight; Ipp32u rec_pitch = uPitch; Ipp8u special_MBAFF_case =0; nLeft = m_cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num; nTop = m_cur_mb.CurrentBlockNeighbours.mb_above.mb_num; nTopLeft = m_cur_mb.CurrentBlockNeighbours.mb_above_left.mb_num; nTopRight = m_cur_mb.CurrentBlockNeighbours.mb_above_right.mb_num; if (mbaff) { Ipp8u currmb_fdf = pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo); Ipp8u currmb_bf = pGetMBBottomFlag(m_cur_mb.GlobalMacroblockInfo); if (bUseConstrainedIntra) { Ipp8u mbA_fdf=1; Ipp8u mbA_is_intra=0; Ipp8u mbpA_is_intra=0; if (nLeft>=0) { mbA_fdf = GetMBFieldDecodingFlag(m_pCurrentFrame->m_mbinfo.mbs[m_cur_mb.CurrentMacroblockNeighbours.mb_A]); mbA_is_intra = IS_INTRA_MBTYPE(m_pCurrentFrame->m_mbinfo.mbs[m_cur_mb.CurrentMacroblockNeighbours.mb_A].mbtype); mbpA_is_intra = IS_INTRA_MBTYPE(m_pCurrentFrame->m_mbinfo.mbs[m_cur_mb.CurrentMacroblockNeighbours.mb_A+mb_width].mbtype); } if (currmb_fdf) {//current mb coded as field MB if (!mbA_fdf) {//(special case is allowed only in this branch) if (mbA_is_intra && !mbpA_is_intra) special_MBAFF_case = 1;//only 2 top blocks can use left samples if (!mbA_is_intra && mbpA_is_intra) special_MBAFF_case = 2;//only 2 bottom blocks can use left samples } if (currmb_bf) { offsetY -= 15 * rec_pitch; offsetC -= 7 * rec_pitch; } rec_pitch *= 2; } switch (special_MBAFF_case) { case 1: if (0 > nTop) edge_type_2t |= IPPVC_TOP_EDGE; else if (!IS_INTRA_MBTYPE(m_pCurrentFrame->m_mbinfo.mbs[nTop].mbtype)) edge_type_2t |= IPPVC_TOP_EDGE; if (0 > nTopLeft) edge_type_2t |= IPPVC_TOP_LEFT_EDGE; else if (!IS_INTRA_MBTYPE(m_pCurrentFrame->m_mbinfo.mbs[nTopLeft].mbtype)) edge_type_2t |= IPPVC_TOP_LEFT_EDGE; if (0 > nTopRight) edge_type_2t |= IPPVC_TOP_RIGHT_EDGE; else if (!IS_INTRA_MBTYPE(m_pCurrentFrame->m_mbinfo.mbs[nTopRight].mbtype)) edge_type_2t |= IPPVC_TOP_RIGHT_EDGE; edge_type_2b = IPPVC_LEFT_EDGE | IPPVC_TOP_RIGHT_EDGE; break; case 2: edge_type_2t |= IPPVC_LEFT_EDGE; if (0 > nTop) edge_type_2t |= IPPVC_TOP_EDGE; else if (!IS_INTRA_MBTYPE(m_pCurrentFrame->m_mbinfo.mbs[nTop].mbtype)) edge_type_2t |= IPPVC_TOP_EDGE; if (0 > nTopLeft) edge_type_2t |= IPPVC_TOP_LEFT_EDGE; else if (!IS_INTRA_MBTYPE(m_pCurrentFrame->m_mbinfo.mbs[nTopLeft].mbtype)) edge_type_2t |= IPPVC_TOP_LEFT_EDGE; if (0 > nTopRight) edge_type_2t |= IPPVC_TOP_RIGHT_EDGE; else if (!IS_INTRA_MBTYPE(m_pCurrentFrame->m_mbinfo.mbs[nTopRight].mbtype)) edge_type_2t |= IPPVC_TOP_RIGHT_EDGE; edge_type_2b = IPPVC_TOP_LEFT_EDGE | IPPVC_TOP_RIGHT_EDGE; break; default: if (0 > nLeft) edge_type |= IPPVC_LEFT_EDGE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -