/** This function is used to decode the sub macroblock information in a B slice. */ int SubMbBCabacSVC ( int *dct_allowed, int Dir8x8infFlag, CABACContext *c, unsigned char *state, SLICE *slice, DATA *macroblock, RESIDU *CurrentResidu, short mv_cache_l0[][2], short ref_cache_l0[], short mv_cache_l1[][2], short ref_cache_l1[]) { int mbPartIdx ; //Recovery of the sub-macroblock type for ( mbPartIdx = 0 ; mbPartIdx < 4 ; mbPartIdx++ ) { CurrentResidu -> SubMbType [mbPartIdx] = decode_cabac_b_mb_sub_type( c, state); } #ifdef ERROR_DETECTION //Error detection if(ErrorsCheckSubMbType( CurrentResidu -> SubMbType, MaxBSubMbType)){ //should be set to zero because the macroblock will be decoded. memset(ref_cache_l0, 0, 48 * sizeof(short)); memset(ref_cache_l1, 0, 48 * sizeof(short)); return 1; } #endif if(GetCabacSVCBSubMotionPred(c, state, slice, macroblock -> MotionPredL0, CurrentResidu -> SubMbType, 4, CurrentResidu -> InCropWindow, 0, Pred_L1)){ return 1; } if(GetCabacSVCBSubMotionPred(c, state, slice, macroblock -> MotionPredL1, CurrentResidu -> SubMbType, 4, CurrentResidu -> InCropWindow, 1, Pred_L0)){ return 1; } //L0 and L1 reference index if(GetCabacBSubRefList(c, state, macroblock -> RefIdxL0, ref_cache_l0, macroblock -> MotionPredL0, CurrentResidu -> SubMbType, slice -> num_RefIdxL0_active_minus1, Pred_L1)){ return 1; } if(GetCabacBSubRefList(c, state, macroblock -> RefIdxL1, ref_cache_l1, macroblock -> MotionPredL1, CurrentResidu -> SubMbType, slice -> num_RefIdxL1_active_minus1, Pred_L0)){ return 1; } //Recovery of the motion vector of each sub-macroblock ReadCabac8x8MotionVector(c, state, CurrentResidu, slice, mv_cache_l0, macroblock -> MvdL0, Pred_L1); ReadCabac8x8MotionVector(c, state, CurrentResidu, slice, mv_cache_l1, macroblock -> MvdL1, Pred_L0); for ( mbPartIdx = 0; mbPartIdx < 4 && *dct_allowed; mbPartIdx ++){ if ( !((sub_num_b_part[ CurrentResidu -> SubMbType[mbPartIdx]] == 1) || (Dir8x8infFlag && sub_mb_b_name[CurrentResidu -> SubMbType[mbPartIdx]] == B_direct))){ *dct_allowed = 0; } } return 0; }
char sub_mb_pred_cabac ( int *dct_allowed, CABACContext *c, unsigned char *state, SLICE *slice, RESIDU *Current_residu, short mv_cache_l0[][2], short mv_cache_l1[][2], short *ref_cache_l0, short *ref_cache_l1, short mvl0_cache[][2], short mvl1_cache[][2], short *refl0_cache, short *refl1_cache, short *mvl1_l0, short *mvl1_l1, short *refl1_l0, short *refl1_l1, int direct_8x8_inference_flag, int long_term, int slice_type, int is_svc) { int mbPartIdx ; char RefIdxL0[4] = {0, 0, 0, 0}; char RefIdxL1[4] = {0, 0, 0, 0}; //Recovery of the sub-macroblock type for ( mbPartIdx = 0 ; mbPartIdx < 4 ; mbPartIdx++ ) { Current_residu -> SubMbType [mbPartIdx] = decode_cabac_b_mb_sub_type( c, state); } #ifdef ERROR_DETECTION //Error detection if(ErrorsCheckSubMbType( Current_residu -> SubMbType, MaxBSubMbType)){ //should be set to zero because the macroblock will be decoded. refl0_cache [12] = refl0_cache [14] = refl0_cache [28] = refl0_cache [30] = 0; refl1_cache [12] = refl1_cache [14] = refl1_cache [28] = refl1_cache [30] = 0; return 1; } #endif //L0 and L1 reference index if(GetCabacBSubRefList(c, state, RefIdxL0, ref_cache_l0, RefIdxL0, Current_residu -> SubMbType, slice -> num_RefIdxL0_active_minus1, Pred_L1)){ refl0_cache [12] = refl0_cache [14] = refl0_cache [28] = refl0_cache [30] = 0; refl1_cache [12] = refl1_cache [14] = refl1_cache [28] = refl1_cache [30] = 0; return 1; } if(GetCabacBSubRefList(c, state, RefIdxL1, ref_cache_l1, RefIdxL1, Current_residu -> SubMbType, slice -> num_RefIdxL1_active_minus1, Pred_L0)){ refl1_cache [12] = refl1_cache [14] = refl1_cache [28] = refl1_cache [30] = 0; return 1; } //Recovery of the motion vector of each sub-macroblock for ( mbPartIdx = 0 ; mbPartIdx < 4 ; mbPartIdx++ ) { int sub_mb_type = Current_residu -> SubMbType [mbPartIdx]; if ( sub_mb_b_name[sub_mb_type] == B_direct){ int ind = SCAN8(mbPartIdx << 2); short mv[2] = {0, 0}; refill_mv(2, 2, mv, &mv_cache_l0[ind]); if (slice -> direct_spatial_mv_pred_flag){ spatial_direct_prediction_l0(mvl0_cache, mvl1_l0, mvl1_l1, refl0_cache, refl1_cache, refl1_l0, refl1_l1, mbPartIdx, slice -> b_stride, slice -> b8_stride, direct_8x8_inference_flag, long_term, is_svc, slice_type); }else{ temporal_direct_prediction_l0(mvl0_cache, mvl1_l0, refl0_cache, refl1_l0, refl1_l1, slice, mbPartIdx, direct_8x8_inference_flag, is_svc, slice_type); } }else if (sub_mb_b_name[sub_mb_type] != Pred_L1 ) { ReadAndComputeCabac8x8MotionVector( c, state, mbPartIdx, sub_mb_type, RefIdxL0, refl0_cache, mv_cache_l0, mvl0_cache, 1); }else { int ind = SCAN8(mbPartIdx << 2); short mv[2] = {0, 0}; refill_mv(2, 2, mv, &mv_cache_l0[ind]); refill_ref(2, 2, -1, &refl0_cache[ind]); } } //Recovery of the motion vector of each sub-macroblock for ( mbPartIdx = 0 ; mbPartIdx < 4 ; mbPartIdx++ ) { int sub_mb_type = Current_residu -> SubMbType [mbPartIdx]; if ( sub_mb_b_name[ sub_mb_type] == B_direct){ int ind = SCAN8(mbPartIdx << 2); short mv[2] = {0, 0}; refill_mv(2, 2, mv, &mv_cache_l1[ind]); if (slice -> direct_spatial_mv_pred_flag){ spatial_direct_prediction_l1(mvl1_cache, mvl1_l0, mvl1_l1, refl0_cache, refl1_cache, refl1_l0, refl1_l1 , mbPartIdx, slice -> b_stride, slice -> b8_stride, direct_8x8_inference_flag, long_term, is_svc , slice_type); }else{ temporal_direct_prediction_l1(mvl1_cache, mvl1_l0, refl1_cache, refl1_l0, refl1_l1,slice , mbPartIdx, direct_8x8_inference_flag, is_svc, slice_type); } }else if (sub_mb_b_name[sub_mb_type] != Pred_L0 ) { ReadAndComputeCabac8x8MotionVector( c, state, mbPartIdx, sub_mb_type, RefIdxL1, refl1_cache, mv_cache_l1, mvl1_cache, 1); }else{ int ind = SCAN8(mbPartIdx << 2); short mv[2] = {0, 0}; refill_mv(2, 2, mv, &mv_cache_l1[ind]); refill_ref(2, 2, -1, &refl1_cache[ind]); } } for ( mbPartIdx = 0; mbPartIdx < 4 && *dct_allowed; mbPartIdx ++){ if ( !((sub_num_b_part[Current_residu -> SubMbType[mbPartIdx]] == 1) || ( direct_8x8_inference_flag && sub_mb_b_name[Current_residu -> SubMbType[mbPartIdx]] == B_direct))){ *dct_allowed = 0; } } return 0; }