char sub_mb_P_cabac ( int *dct_allowed, CABACContext *c, unsigned char *state, SLICE *slice, RESIDU *Current_residu, short mv_cache_l0[][2], short *ref_cache_l0, short mvl0_cache[][2], short *refl0_cache) { int mbPartIdx ; int subMbPartIdx ; char RefIdxL0[4] = {0, 0, 0, 0}; //Recovery of the sub-macroblock type for ( mbPartIdx = 0 ; mbPartIdx < 4 ; mbPartIdx++ ) { Current_residu -> SubMbType [mbPartIdx] = decode_cabac_p_mb_sub_type(c, state); } #ifdef ERROR_DETECTION //Error detection if(ErrorsCheckSubMbType( Current_residu -> SubMbType, MaxPSubMbType)){ //should be set to zero because the macroblock will be decoded. refl0_cache [12] = refl0_cache [14] = refl0_cache [28] = refl0_cache [30] = 0; return 1; } #endif //Recovery of the image reference of each sub-macroblock if (slice -> num_RefIdxL0_active_minus1 > 0) { if(GetCabacPSubRefIdx(c, state, RefIdxL0, ref_cache_l0, RefIdxL0, slice -> num_RefIdxL0_active_minus1)){ refl0_cache [12] = refl0_cache [14] = refl0_cache [28] = refl0_cache [30] = 0; return 1; } } else { ref_cache_l0[12] = ref_cache_l0[14] = ref_cache_l0[28] = ref_cache_l0[30] = 0; } //Recovery of the motion vector of each sub-macroblock for ( mbPartIdx = 0 ; mbPartIdx < 4 ; mbPartIdx++ ) { short MvdL0[2]; int sub_mb_type = Current_residu -> SubMbType [mbPartIdx]; for ( subMbPartIdx = 0 ; subMbPartIdx < sub_num_p_part[ sub_mb_type] ; subMbPartIdx++ ) { int index = SCAN8(( mbPartIdx << 2) + (sub_mb_type == 1 ? 2 * subMbPartIdx: subMbPartIdx)); //Decode cabac ReadCabacSubMotionVector(c, state, mv_cache_l0, MvdL0, mbPartIdx, subMbPartIdx, sub_mb_type, index, slice -> slice_type); //Compute Mv refill_ref(2 - (sub_mb_type > 1), 2 - (sub_mb_type & 1), RefIdxL0[mbPartIdx], &refl0_cache[index]); motion_vector(mvl0_cache, MvdL0, refl0_cache, &mvl0_cache[index][0], RefIdxL0[mbPartIdx], index, 2 / ( 1 + ( sub_mb_type > 1))); } refill_motion_vector(0, sub_mb_type, &mvl0_cache[SCAN8(( mbPartIdx << 2))]); } for ( mbPartIdx = 0; mbPartIdx < 4 && dct_allowed; mbPartIdx ++){ if ( !(sub_num_p_part[Current_residu -> SubMbType[mbPartIdx]] == 1) ){ *dct_allowed = 0; } } return 0; }
/** This function decode the motion vector of a macroblock with 8x8 partition */ void ReadCabac8x8MotionVector(CABACContext *c, unsigned char *state, RESIDU *CurrentResidu, SLICE *slice, short mv_cache_lx[][2], short MvdLx[][2], int Pred_Lx) { int mbPartIdx, subMbPartIdx; for ( mbPartIdx = 0 ; mbPartIdx < 4 ; mbPartIdx++ ) { int SubMbType = CurrentResidu -> SubMbType [mbPartIdx]; if ( (sub_mb_b_name [SubMbType] != B_direct) && (sub_mb_b_name [SubMbType] != Pred_Lx )) { for ( subMbPartIdx = 0 ; subMbPartIdx < sub_num_b_part[SubMbType] ; subMbPartIdx++ ) { int xpart = (SubMbType < 5 || SubMbType == 6 || SubMbType == 8) ? 2:1; int index = SCAN8(( mbPartIdx << 2) + subMbPartIdx * xpart); ReadCabacSubMotionVector(c, state, mv_cache_lx, &MvdLx [(mbPartIdx << 2) + subMbPartIdx][0], mbPartIdx, subMbPartIdx, SubMbType, index, slice -> slice_type); } } } }