int macroblock_layer_in_scalable_extension(const NAL *Nal, const PPS *Pps, RESIDU *Current_residu, RESIDU *BaseResidu, const unsigned char *ai_pcData, int *position, const SLICE *ai_pstSlice, DATA Tab_Block[], const VLC_TABLES *vlc, unsigned char aio_tiNon_zero_count_cache [ ], unsigned char aio_tiSlice_table [ ], const short iMb_x, const short iMb_y, int direct_8x8_inference_flag, int *last_QP) { int noSubMbPartSizeLessThan8x8; int BaseModeFlag = 0; const int iCurrMbAddr = iMb_x + iMb_y * (short)(ai_pstSlice -> mb_stride); short intra4x4_pred_mode_cache[40]; DATA * aio_pstBlock = &Tab_Block[iCurrMbAddr]; //TODO if( ai_pstSlice -> AdaptiveBaseModeFlag && Current_residu -> InCropWindow) { Current_residu -> BaseModeFlag = BaseModeFlag = getNbits(ai_pcData, position, 1); //u(1) }else if (ai_pstSlice -> DefaultBaseModeFlag){ Current_residu -> BaseModeFlag = BaseModeFlag = 1; } if(!BaseModeFlag){ int mb_type = read_ue(ai_pcData, position); //According to the slice type and the macroblock type //the parameters are adjusted switch ( ai_pstSlice -> slice_type ) { case EI : #ifdef ERROR_DETECTION //Error detection if(ErrorsCheckMbType(mb_type, I_BL)){ return 1; } #endif aio_pstBlock -> MbPartPredMode [0] = i_mb_type_info[mb_type] . type; Current_residu -> MbType = i_mb_type_info[mb_type] . type; Current_residu -> Cbp = i_mb_type_info[mb_type] . Cbp; Current_residu -> Intra16x16PredMode = i_mb_type_info[mb_type] . pred_mode; break ; case EP : if (mb_type < 5){ #ifdef ERROR_DETECTION //Error detection if(ErrorsCheckMbType(mb_type, P_BL)){ return 1; } #endif aio_pstBlock -> NumMbPart = p_mb_type_info[mb_type] . partcount; aio_pstBlock -> MbPartPredMode [0] = p_mb_type_info[mb_type] . type_0; aio_pstBlock -> MbPartPredMode [1] = p_mb_type_info[mb_type] . type_1; Current_residu -> MbType = p_mb_type_info[mb_type] . name; Current_residu -> Mode = p_mb_type_info[mb_type] . Mode; } else { mb_type -= 5; #ifdef ERROR_DETECTION //Error detection if(ErrorsCheckMbType(mb_type, I_BL)){ return 1; } #endif aio_pstBlock -> MbPartPredMode [0] = i_mb_type_info[mb_type] . type; Current_residu -> MbType = i_mb_type_info[mb_type] . type; Current_residu -> Cbp = i_mb_type_info[mb_type] . Cbp; Current_residu -> Intra16x16PredMode = i_mb_type_info[mb_type] . pred_mode; } break ; case EB : if (mb_type < 23) { #ifdef ERROR_DETECTION //Error detection if(ErrorsCheckMbType(mb_type, B_BL)){ return 1; } #endif aio_pstBlock -> NumMbPart = b_mb_type_info[mb_type] . partcount; aio_pstBlock -> MbPartPredMode [0] = b_mb_type_info[mb_type] . type_0; aio_pstBlock -> MbPartPredMode [1] = b_mb_type_info[mb_type] . type_1; Current_residu -> MbType = b_mb_type_info[mb_type] . name; Current_residu -> Mode = b_mb_type_info[mb_type] . Mode; } else { mb_type -= 23; #ifdef ERROR_DETECTION //Error detection if(ErrorsCheckMbType(mb_type, I_BL)){ return 1; } #endif aio_pstBlock -> MbPartPredMode [0] = i_mb_type_info[mb_type] . type; Current_residu -> MbType = i_mb_type_info[mb_type] . type; Current_residu -> Cbp = i_mb_type_info[mb_type] . Cbp; Current_residu -> Intra16x16PredMode = i_mb_type_info[mb_type] . pred_mode; } break; } //Initialize base macroblock address GetBaseMbAddr(Nal, aio_pstBlock, iMb_x << 4, iMb_y << 4); } else{ aio_pstBlock -> MbPartPredMode [0] = Current_residu -> MbType = GetBaseType(Nal, BaseResidu, aio_pstBlock, iMb_x, iMb_y); } //Updating the slice table in order to save in which slice each macroblock belong to Current_residu -> SliceNum = aio_tiSlice_table [iCurrMbAddr] = ai_pstSlice -> slice_num ; if ( !BaseModeFlag && Current_residu -> MbType == INTRA_PCM ) { while ( !bytes_aligned(*position) ) { getNbits(ai_pcData, position, 1);//pcm_alignment_zero_bit = } ParseIPCM(ai_pcData, position, Current_residu, aio_tiNon_zero_count_cache); } else { //Updating the parameter in order to decode the VLC fill_caches_svc( ai_pstSlice, Current_residu, BaseResidu, 0, aio_tiNon_zero_count_cache, aio_tiSlice_table, aio_pstBlock, intra4x4_pred_mode_cache, iMb_x, iMb_y, Pps -> constrained_intra_pred_flag, Nal -> TCoeffPrediction); if (!BaseModeFlag){ //Recovery of the motion vectors for the sub_macroblock if ( !IS_I(Current_residu -> MbType) && (aio_pstBlock -> NumMbPart == 4)) { int mbPartIdx; if(sub_mb_pred_svc(ai_pcData, position, ai_pstSlice, aio_pstBlock, Current_residu)){ return 1; } noSubMbPartSizeLessThan8x8 = 0; if ( direct_8x8_inference_flag ){ noSubMbPartSizeLessThan8x8 = 1; } for ( mbPartIdx = 0; mbPartIdx < 4; mbPartIdx ++){ if ( sub_mb_type_name[ai_pstSlice -> slice_type][Current_residu -> SubMbType[mbPartIdx]] != B_direct){ if ( sub_num_part[ai_pstSlice -> slice_type][Current_residu -> SubMbType[mbPartIdx]] > 1 ) noSubMbPartSizeLessThan8x8 = 0; } } } else { noSubMbPartSizeLessThan8x8 = 1; if ( Pps -> transform_8x8_mode_flag && Current_residu -> MbType == INTRA_4x4 && getNbits(ai_pcData, position, 1)){ Current_residu -> MbType = Current_residu -> Transform8x8 = aio_pstBlock -> Transform8x8 = aio_pstBlock -> MbPartPredMode[0] = INTRA_8x8; } //Recovery of the prediction mode and the motion vectors for the macroblock if(mb_pred_svc(ai_pcData, position, ai_pstSlice, aio_pstBlock, Current_residu, intra4x4_pred_mode_cache)){ return 1; } } } //Decoding process of the VLC if( ai_pstSlice -> AdaptiveResidualPredictionFlag && ai_pstSlice -> slice_type != EI && (BaseModeFlag || ( !IS_I( Current_residu -> MbType) && Current_residu -> InCropWindow ))){ Current_residu -> ResidualPredictionFlag = getNbits(ai_pcData, position, 1); }else{ Current_residu -> ResidualPredictionFlag = ai_pstSlice -> DefaultResidualPredictionFlag; } if ( BaseModeFlag || aio_pstBlock -> MbPartPredMode[0] != INTRA_16x16 ){ Current_residu -> Cbp = read_me_svc(ai_pcData, position, aio_pstBlock -> MbPartPredMode[0],Current_residu, iCurrMbAddr, ai_pstSlice, iMb_x); if ( (Current_residu -> Cbp & 15) && Pps -> transform_8x8_mode_flag && (BaseModeFlag || (!IS_I(Current_residu -> MbType) && noSubMbPartSizeLessThan8x8 && ( Current_residu -> MbType == B_direct || direct_8x8_inference_flag))) && getNbits(ai_pcData, position, 1)){ Current_residu -> Transform8x8 = aio_pstBlock -> Transform8x8 = INTRA_8x8; } } if ( Current_residu -> Cbp > 0 || (Current_residu -> MbType == INTRA_16x16)) { int mb_qp_delta = read_se(ai_pcData, position); residual(ai_pcData, position, Current_residu, vlc, aio_tiNon_zero_count_cache); //In case of cbp is equal to zéro, we check if there is a DC level if (Current_residu -> Cbp == 0 && aio_tiNon_zero_count_cache[0] != 0){ Current_residu -> Cbp = 15; } if ( Current_residu -> MbType == INTRA_16x16 && !(Current_residu -> Cbp & 15) && (Current_residu -> Cbp & 0x30) && aio_tiNon_zero_count_cache[0]){ Current_residu -> Cbp += 15; } #ifdef TI_OPTIM *last_QP = Current_residu -> Qp = divide(*last_QP + mb_qp_delta + 52, 52) >> 8 ; #else *last_QP = Current_residu -> Qp = (*last_QP + mb_qp_delta + 52) % 52; #endif }else {
/** 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 {