/** This function permits to decode the prediction mode or the image reference. @param ai_pcData The NAL unit. @param position The current position in the NAL. @param block Contains all parameters of the current macroblock. @param ai_pstSlice The slice structure. @param ao_pstIntra_pred_mode Contains the prediction mode for the current macroblock. */ int mb_pred_svc( const unsigned char *ai_pcData, int *position, const SLICE *ai_pstSlice, DATA *aio_pstMacroblock, RESIDU *Current_residu, short *intra4x4_pred_mode_cache) { int mbPartIdx ; //Recovery of the prediction mode if(IS_I(aio_pstMacroblock -> MbPartPredMode [0])){ if(mb_pred_I(ai_pcData, position, Current_residu, Current_residu -> Intra16x16DCLevel, intra4x4_pred_mode_cache)){ return 1; } } else if ( aio_pstMacroblock -> MbPartPredMode [0] != B_direct ) { if( ai_pstSlice -> AdaptiveMotionPredictionFlag && Current_residu -> InCropWindow ) { if(ReadMotionPredSVC(ai_pcData, position, aio_pstMacroblock -> MotionPredL0, aio_pstMacroblock, Pred_L1)) return 1; if(ReadMotionPredSVC(ai_pcData, position, aio_pstMacroblock -> MotionPredL1, aio_pstMacroblock, Pred_L0)) return 1; }else{ aio_pstMacroblock -> MotionPredL0[0] = aio_pstMacroblock -> MotionPredL0[1] = aio_pstMacroblock -> MotionPredL0[2] = aio_pstMacroblock -> MotionPredL0[3] = aio_pstMacroblock -> MotionPredL1[0] = aio_pstMacroblock -> MotionPredL1[1] = aio_pstMacroblock -> MotionPredL1[2] = aio_pstMacroblock -> MotionPredL1[3] = ai_pstSlice -> DefaultMotionPredictionFlag; } if ( ai_pstSlice -> num_RefIdxL0_active_minus1 != 0 ){ for ( mbPartIdx = 0 ; mbPartIdx < aio_pstMacroblock -> NumMbPart ; mbPartIdx++ ) { if ( (aio_pstMacroblock -> MbPartPredMode [mbPartIdx] != Pred_L1 ) && (!aio_pstMacroblock -> MotionPredL0[mbPartIdx])) { aio_pstMacroblock -> RefIdxL0 [mbPartIdx] = read_te(ai_pcData, position, ai_pstSlice -> num_RefIdxL0_active_minus1); } } } #ifdef ERROR_DETECTION //Error detection if(ErrorsCheckRefLx(aio_pstMacroblock -> RefIdxL0, ai_pstSlice -> num_RefIdxL0_active_minus1)){ return 1; } #endif //Recovery of of the image reference for the frame if ( ai_pstSlice -> num_RefIdxL1_active_minus1 != 0 ){ for ( mbPartIdx = 0 ; mbPartIdx < aio_pstMacroblock -> NumMbPart ; mbPartIdx++ ) { if ((aio_pstMacroblock -> MbPartPredMode [mbPartIdx] != Pred_L0) && (!aio_pstMacroblock -> MotionPredL1[mbPartIdx])) { aio_pstMacroblock -> RefIdxL1 [mbPartIdx] = read_te(ai_pcData, position, ai_pstSlice -> num_RefIdxL1_active_minus1); } } } #ifdef ERROR_DETECTION //Error detection if(ErrorsCheckRefLx(aio_pstMacroblock -> RefIdxL1, ai_pstSlice -> num_RefIdxL1_active_minus1)){ return 1; } #endif //Recovery of of the motion vector for the frame P for ( mbPartIdx = 0 ; mbPartIdx < aio_pstMacroblock -> NumMbPart ; mbPartIdx++ ) { /* Pour eviter de traiter les Images B*/ if ( aio_pstMacroblock -> MbPartPredMode [mbPartIdx] != Pred_L1 ) { aio_pstMacroblock -> MvdL0 [mbPartIdx << 2][0] = read_se(ai_pcData, position); aio_pstMacroblock -> MvdL0 [mbPartIdx << 2][1] = read_se(ai_pcData, position); } } //Recovery of of the motion vector for the frame B for ( mbPartIdx = 0 ; mbPartIdx < aio_pstMacroblock -> NumMbPart ; mbPartIdx++ ) { if ( aio_pstMacroblock -> MbPartPredMode [mbPartIdx] != Pred_L0 ) { aio_pstMacroblock -> MvdL1 [ mbPartIdx << 2][0] = read_se(ai_pcData, position); aio_pstMacroblock -> MvdL1 [ mbPartIdx << 2][1] = read_se(ai_pcData, position); } } }else{ Current_residu -> Mode = 4; for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++){ Current_residu -> SubMbType [mbPartIdx] = 3; } } return 0; }
/** This function permits to recover the macroblock's data from the vlc All the parameters decoded will be stored in differents structures or tables. @param Pps PPS structure of the current video. @param picture_residu Structure whixh contains information about the macroblock. @param data The NAL unit. @param aio_piPosition The current aio_piPosition in the NAL. @param Slice The Slice structure. @param block Contains all parameters of the current macroblock. @param vlc The VLC tables in order to decode the Nal Unit. @param non_zero_count_cache Specifies the coeff_token of each blocks 4x4 of a macroblock. @param non_zero_count Specifies the coeff_token of each block of the picture. @param SliceTable Specifies in which Slice belongs each macroblock of the picture. @param intra_pred_mod Contains the prediction mode for each macroblock. @param ai_iMb_x The x position of the macroblock in the picture. @param ai_iMb_y The y position of the macroblock in the picture. @param last_QP Give the QP of the last decoded macroblock. @param iCurrMbAddr Number of the current macroblock. */ char macroblock_I_partitionning(const PPS *Pps, RESIDU *picture_residu, const unsigned char *ai_pcData, int *aio_piPosition, SLICE *Slice, DATA *aio_pstBlock, const VLC_TABLES * Vlc, unsigned char *NonZeroCountCache, unsigned char *SliceTable, const short ai_iMb_x, const short ai_iMb_y, unsigned char *last_QP, int iCurrMbAddr) { short intra4x4_pred_mode_cache[40]; #ifdef ERROR_DETECTION //Error detection if(ErrorsCheckIMbType(picture_residu -> MbType)){ return 1; } #endif //Updating the Slice table in order to save in which slice each macroblock belong to picture_residu -> SliceNum = SliceTable [iCurrMbAddr] = Slice -> slice_num ; if ( picture_residu -> MbType == INTRA_PCM ) { while ( !bytes_aligned(*aio_piPosition) ) { getNbits(ai_pcData, aio_piPosition, 1);//pcm_alignment_zero_bit = } ParseIPCM(ai_pcData, aio_piPosition, picture_residu, NonZeroCountCache); } else { //Updating the parameter in order to decode the VLC fill_caches_I( Slice, picture_residu, 0, NonZeroCountCache, aio_pstBlock, SliceTable, intra4x4_pred_mode_cache, ai_iMb_x, ai_iMb_y, Pps -> constrained_intra_pred_flag); if ( Pps -> transform_8x8_mode_flag && picture_residu -> MbType == INTRA_4x4 && getNbits(ai_pcData, aio_piPosition, 1)){ picture_residu -> Transform8x8 = picture_residu -> MbType = aio_pstBlock -> Transform8x8 = INTRA_8x8; } //Recovery of the prediction mode and the motion vectors for the macroblock if(mb_pred_I(ai_pcData, aio_piPosition, picture_residu, picture_residu -> Intra16x16DCLevel, intra4x4_pred_mode_cache)){ return 1; } if ( aio_pstBlock -> MbPartPredMode[0] != INTRA_16x16 ) { picture_residu -> Cbp = read_me(ai_pcData, aio_piPosition, aio_pstBlock -> MbPartPredMode[0]); } if ( picture_residu -> Cbp > 0 || (picture_residu -> MbType == INTRA_16x16)){ int mb_qp_delta = read_se(ai_pcData, aio_piPosition); #ifdef TI_OPTIM *last_QP = picture_residu -> Qp = divide(*last_QP + mb_qp_delta + 52, 52) >> 8 ; #else *last_QP = picture_residu -> Qp = (*last_QP + mb_qp_delta + 52) % 52; #endif //Decoding process of the VLC residual(ai_pcData, aio_piPosition, picture_residu, Vlc, NonZeroCountCache); } else {