📄 umc_h264_dec_decode_mb.cpp
字号:
StatusH264VideoDecoder::DecodeMotionVectors( bool bIsBSlice){ Ipp32s num_vectorsL0, block, subblock, mvdx, mvdy, pmvx, pmvy, i, j; Ipp32s num_vectorsL1; Ipp32s dec_vectorsL0; Ipp32s dec_vectorsL1; Ipp32s num_refIxL0; Ipp32s num_refIxL1; Ipp32s dec_refIxL0; Ipp32s dec_refIxL1; Ipp32u uVLCCodes[64+MAX_NUM_REF_FRAMES*2]; // sized for max possible: // 16 MV * 2 codes per MV * 2 directions // plus L0 and L1 ref indexes Ipp32u *pVLCCodes; // pointer to pass to VLC function Ipp32u *pVLCCodesL0MV; Ipp32u *pVLCCodesL1MV; Ipp32u *pVLCCodesL0RefIndex; Ipp32u *pVLCCodesL1RefIndex; Ipp32s mvxL0, mvyL0; Ipp32s mvxL1, mvyL1;// Ipp32u length; Status status = UMC_OK; Ipp32u dirPart; // prediction direction of current MB partition Ipp32s numParts; Ipp32s partCtr; Ipp8s RefIxL0; Ipp8s RefIxL1; Ipp8s *pRefIndexL0; Ipp8s *pRefIndexL1; H264DecoderMotionVector *pMVL0; H264DecoderMotionVector *pMVL1; Ipp32s uNumRefIdxL0Active; Ipp32s uNumRefIdxL1Active; Ipp32s uNumVLCCodes; switch (m_cur_mb.GlobalMacroblockInfo->mbtype) { case MBTYPE_FORWARD: num_vectorsL0 = 1; num_refIxL0 = 1; num_vectorsL1 = 0; num_refIxL1 = 0; dirPart = D_DIR_FWD; numParts = 1; break; case MBTYPE_BACKWARD: num_vectorsL0 = 0; num_refIxL0 = 0; num_vectorsL1 = 1; num_refIxL1 = 1; dirPart = D_DIR_BWD; numParts = 1; break; case MBTYPE_BIDIR: num_vectorsL0 = 1; num_refIxL0 = 1; num_vectorsL1 = 1; num_refIxL1 = 1; dirPart = D_DIR_BIDIR; numParts = 1; break; case MBTYPE_INTER_8x8: case MBTYPE_INTER_8x8_REF0: num_vectorsL0 = 0; num_refIxL0 = 0; num_vectorsL1 = 0; num_refIxL1 = 0; numParts = 0; for (block = 0; block<4; block++) { switch (m_cur_mb.GlobalMacroblockInfo->sbtype[block]) { case SBTYPE_8x8: if ((m_cur_mb.LocalMacroblockInfo->sbdir[block] == D_DIR_FWD) || (m_cur_mb.LocalMacroblockInfo->sbdir[block] == D_DIR_BIDIR)) { num_vectorsL0++; num_refIxL0++; } if ((m_cur_mb.LocalMacroblockInfo->sbdir[block] == D_DIR_BWD) || (m_cur_mb.LocalMacroblockInfo->sbdir[block] == D_DIR_BIDIR)) { num_vectorsL1++; num_refIxL1++; } numParts++; break; case SBTYPE_8x4: case SBTYPE_4x8: if ((m_cur_mb.LocalMacroblockInfo->sbdir[block] == D_DIR_FWD) || (m_cur_mb.LocalMacroblockInfo->sbdir[block] == D_DIR_BIDIR)) { num_vectorsL0 += 2; num_refIxL0++; // only one per refIx per 8x8 } if ((m_cur_mb.LocalMacroblockInfo->sbdir[block] == D_DIR_BWD) || (m_cur_mb.LocalMacroblockInfo->sbdir[block] == D_DIR_BIDIR)) { num_vectorsL1 += 2; num_refIxL1++; } numParts += 2; break; case SBTYPE_4x4: if ((m_cur_mb.LocalMacroblockInfo->sbdir[block] == D_DIR_FWD) || (m_cur_mb.LocalMacroblockInfo->sbdir[block] == D_DIR_BIDIR)) { num_vectorsL0 += 4; num_refIxL0++; } if ((m_cur_mb.LocalMacroblockInfo->sbdir[block] == D_DIR_BWD) || (m_cur_mb.LocalMacroblockInfo->sbdir[block] == D_DIR_BIDIR)) { num_vectorsL1 += 4; num_refIxL1++; } numParts += 4; break; case SBTYPE_DIRECT: numParts++; break; default: status = UMC_BAD_STREAM; goto done; } } dirPart = m_cur_mb.LocalMacroblockInfo->sbdir[0]; break; case MBTYPE_INTER_16x8: case MBTYPE_INTER_8x16: num_vectorsL0 = 0; num_refIxL0 = 0; num_vectorsL1 = 0; num_refIxL1 = 0; if ((m_cur_mb.LocalMacroblockInfo->sbdir[0] == D_DIR_FWD) || (m_cur_mb.LocalMacroblockInfo->sbdir[0] == D_DIR_BIDIR)) { num_vectorsL0++; num_refIxL0++; } if ((m_cur_mb.LocalMacroblockInfo->sbdir[0] == D_DIR_BWD) || (m_cur_mb.LocalMacroblockInfo->sbdir[0] == D_DIR_BIDIR)) { num_vectorsL1++; num_refIxL1++; } if ((m_cur_mb.LocalMacroblockInfo->sbdir[1] == D_DIR_FWD) || (m_cur_mb.LocalMacroblockInfo->sbdir[1] == D_DIR_BIDIR)) { num_vectorsL0++; num_refIxL0++; } if ((m_cur_mb.LocalMacroblockInfo->sbdir[1] == D_DIR_BWD) || (m_cur_mb.LocalMacroblockInfo->sbdir[1] == D_DIR_BIDIR)) { num_vectorsL1++; num_refIxL1++; } numParts = 2; dirPart = m_cur_mb.LocalMacroblockInfo->sbdir[0]; break; default: goto done; } // Get all of the reference index and MV VLC codes from the bitstream // The bitstream contains them in the following order, which is the // order they are returned in uVLCCodes: // L0 reference index for all MB parts using L0 prediction // L1 reference index for all MB parts using L1 prediction // L0 MV delta for all MB parts using L0 prediction // L1 MV delta for all MB parts using L1 prediction // Reference index data is present only when the number of active // reference frames is greater than one. Also, MBTYPE_INTER_8x8_REF0 // type MB has no ref index info in the bitstream (use 0 for all). uNumRefIdxL0Active = m_CurSliceHeader.num_ref_idx_l0_active<<pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo); uNumRefIdxL1Active = m_CurSliceHeader.num_ref_idx_l1_active<<pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo); if (uNumRefIdxL0Active == 1 || MBTYPE_INTER_8x8_REF0 == m_cur_mb.GlobalMacroblockInfo->mbtype) num_refIxL0 = 0; if (uNumRefIdxL1Active == 1 || MBTYPE_INTER_8x8_REF0 == m_cur_mb.GlobalMacroblockInfo->mbtype) num_refIxL1 = 0; // set pointers into VLC codes array pVLCCodes = uVLCCodes; pVLCCodesL0RefIndex = uVLCCodes; pVLCCodesL1RefIndex = pVLCCodesL0RefIndex + num_refIxL0; pVLCCodesL0MV = pVLCCodesL1RefIndex + num_refIxL1; pVLCCodesL1MV = pVLCCodesL0MV + num_vectorsL0*2; uNumVLCCodes = (num_vectorsL0+num_vectorsL1)*2 + num_refIxL0 + num_refIxL1; // When possible ref index range is 0..1, the reference index is coded // as 1 bit. When that occurs, get the ref index codes separate from // the motion vectors. Otherwise get all of the codes at once. if (uNumRefIdxL0Active == 2 || uNumRefIdxL1Active == 2) { // 1 bit codes for at least one set of ref index codes if (uNumRefIdxL0Active == 2) { for (i=0; i<num_refIxL0; i++) { pVLCCodesL0RefIndex[i] = !m_pBitStream->Get1Bit(); } } else if (uNumRefIdxL0Active > 2) { for (i=0;i<num_refIxL0;i++) { pVLCCodesL0RefIndex[i]=m_pBitStream->GetVLCElement(0); } } if (uNumRefIdxL1Active == 2) { for (i=0; i<num_refIxL1; i++) { pVLCCodesL1RefIndex[i] = !m_pBitStream->Get1Bit(); } } else if (uNumRefIdxL1Active > 2) { for (i=0;i<num_refIxL1;i++) { pVLCCodesL1RefIndex[i]=m_pBitStream->GetVLCElement(0); } } // to get the MV for the MB uNumVLCCodes -= num_refIxL0 + num_refIxL1; pVLCCodes = pVLCCodesL0MV; } // get all MV and possibly Ref Index codes for the MB for (i=0;i<uNumVLCCodes;i++,pVLCCodes++) { *pVLCCodes=m_pBitStream->GetVLCElement(0); if (uNumRefIdxL0Active > 2 && uNumRefIdxL1Active > 2 && i<num_refIxL0 + num_refIxL1) { } } block = 0; subblock = 0; dec_vectorsL0 = 0; dec_vectorsL1 = 0; dec_refIxL0 = 0; dec_refIxL1 = 0; Ipp32u sboffset; for (partCtr = 0,sboffset=0; partCtr < numParts; partCtr++) { pMVL0 = &m_cur_mb.MVs[0]->MotionVectors[sboffset]; pRefIndexL0 = &m_cur_mb.RefIdxs[0]->RefIdxs[sboffset]; if (dirPart == D_DIR_FWD || dirPart == D_DIR_BIDIR) { // L0 if (num_refIxL0) { RefIxL0 = (Ipp8s)pVLCCodesL0RefIndex[dec_refIxL0]; // dec_refIxL0 is incremented in mbtype-specific code below // instead of here because there is only one refIx for each // 8x8 block, so number of refIx values is not the same as // numParts. if (RefIxL0 >= (Ipp8s)uNumRefIdxL0Active || RefIxL0 < 0) { status = UMC_BAD_STREAM; } } else RefIxL0 = 0; mvdx = (pVLCCodesL0MV[dec_vectorsL0*2]+1)>>1; if (!(pVLCCodesL0MV[dec_vectorsL0*2]&1)) mvdx = -mvdx; mvdy = (pVLCCodesL0MV[dec_vectorsL0*2+1]+1)>>1; if (!(pVLCCodesL0MV[dec_vectorsL0*2+1]&1)) mvdy = -mvdy; dec_vectorsL0++; // Find MV predictor ComputeMotionVectorPredictors(0, RefIxL0, block+subblock, &pmvx, &pmvy); mvxL0 = Ipp32s(mvdx + pmvx); mvyL0 = Ipp32s(mvdy + pmvy); } // L0 else { mvxL0 = mvyL0 = 0; RefIxL0 = -1; } if (bIsBSlice) { pMVL1 = &m_cur_mb.MVs[1]->MotionVectors[sboffset]; pRefIndexL1 = &m_cur_mb.RefIdxs[1]->RefIdxs[sboffset]; if (dirPart == D_DIR_BWD || dirPart == D_DIR_BIDIR) { if (num_refIxL1) { RefIxL1 = (Ipp8s)pVLCCodesL1RefIndex[dec_refIxL1]; // dec_refIxL1 is incremented in mbtype-specific code below // instead of here because there is only one refIx for each // 8x8 block, so number of refIx values is not the same as // numParts. if (RefIxL1 >= (Ipp8s)uNumRefIdxL1Active || RefIxL1 < 0) { status = UMC_BAD_STREAM; } } else RefIxL1 = 0; mvdx = (Ipp16s)(pVLCCodesL1MV[dec_vectorsL1*2]+1)>>1; if (!(pVLCCodesL1MV[dec_vectorsL1*2]&1)) mvdx = -mvdx; mvdy = (Ipp16s)(pVLCCodesL1MV[dec_vectorsL1*2+1]+1)>>1; if (!(pVLCCodesL1MV[dec_vectorsL1*2+1]&1)) mvdy = -mvdy; dec_vectorsL1++; // Find MV predictor ComputeMotionVectorPredictors( 1, RefIxL1,block+subblock, &pmvx, &pmvy); mvxL1 = Ipp32s(mvdx + pmvx); mvyL1 = Ipp32s(mvdy + pmvy); } // L1 else { mvxL1 = mvyL1 = 0; RefIxL1 = -1; } } // B slice // Store motion vectors and reference indexes into this frame's buffers switch (m_cur_mb.GlobalMacroblockInfo->mbtype)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -