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 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; }
/** This function is used to decode the sub macroblock information in a P slice. */ int SubMbPCabacSVC ( int *dct_allowed, CABACContext *c, unsigned char *state, SLICE *slice, DATA *macroblock, RESIDU *CurrentResidu, short mv_cache_l0[][2], short ref_cache_l0[]) { int mbPartIdx ; int subMbPartIdx ; int compIdx ; int mva; int mvb; //Recovery of the sub-macroblock type for ( mbPartIdx = 0 ; mbPartIdx < 4 ; mbPartIdx++ ) { CurrentResidu -> SubMbType [mbPartIdx] = decode_cabac_p_mb_sub_type( c, state); } #ifdef ERROR_DETECTION //Error detection if(ErrorsCheckSubMbType( CurrentResidu -> SubMbType, MaxPSubMbType)){ //should be set to zero because the macroblock will be decoded. memset(ref_cache_l0, 0, 48 * sizeof(short)); return 1; } #endif if(GetCabacSVCPMotionPred(c, state, slice, macroblock, macroblock -> MotionPredL0, CurrentResidu -> InCropWindow, Pred_L1, 0)){ return 1; } //Recovery of the image reference of each sub-macroblock if (slice -> num_RefIdxL0_active_minus1 > 0) { if(GetCabacPSubRefIdx(c, state, macroblock -> RefIdxL0, ref_cache_l0, macroblock -> MotionPredL0, slice -> num_RefIdxL0_active_minus1)){ return 1; } }else { ref_cache_l0[12] = ref_cache_l0[13] = ref_cache_l0[14] = ref_cache_l0[15] = ref_cache_l0[20] = ref_cache_l0[21] = ref_cache_l0[22] = ref_cache_l0[23] = ref_cache_l0[28] = ref_cache_l0[29] = ref_cache_l0[30] = ref_cache_l0[21] = ref_cache_l0[36] = ref_cache_l0[37] = ref_cache_l0[38] = ref_cache_l0[39] = 0; } //Recovery of the motion vector of each sub-macroblock for ( mbPartIdx = 0 ; mbPartIdx < 4 ; mbPartIdx++ ) { short MvdL0[2]; int sub_mb_type = CurrentResidu -> 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)); for ( compIdx = 0 ; compIdx < 2 ; compIdx++ ) { get_mv_neighbourhood(&mva, &mvb, mv_cache_l0, sub_mb_type, mbPartIdx , subMbPartIdx , compIdx, slice -> slice_type); macroblock -> MvdL0 [(mbPartIdx << 2) + subMbPartIdx][compIdx] = MvdL0[compIdx] = decode_cabac_mb_mvd( c, state, mva, mvb, compIdx); } FillSubMotionVector(MvdL0, &mv_cache_l0[index], sub_mb_type, slice -> slice_type); } } for ( mbPartIdx = 0; mbPartIdx < 4 && *dct_allowed; mbPartIdx ++){ if ( !(sub_num_p_part[CurrentResidu -> SubMbType[mbPartIdx]] == 1) ){ *dct_allowed = 0; } } return 0; }
/** This function permits to decode the image reference of each sub-macroblock. @param data The NAL unit. @param position The current position in the NAL. @param block Contains all parameters of the current macroblock. @param slice The slice structure. */ int sub_mb_pred_svc ( const unsigned char *ai_pcData, int *position, const SLICE *ai_pstSlice, DATA *aio_pstMacroblock, RESIDU *Current_residu) { int mbPartIdx ; int subMbPartIdx ; //Recovery of the sub-macroblock type GetCavlcSubMbType(ai_pcData, position, Current_residu); #ifdef ERROR_DETECTION //Error detection if(ErrorsCheckSubMbType( Current_residu -> SubMbType, ai_pstSlice -> slice_type? MaxBSubMbType:MaxPSubMbType)){ return 1; } #endif //Recovery of the image reference of each sub-macroblock if( ai_pstSlice -> AdaptiveMotionPredictionFlag && Current_residu -> InCropWindow ) { for ( mbPartIdx = 0 ; mbPartIdx < 4 ; mbPartIdx++ ) { if (sub_mb_type_name[ai_pstSlice -> slice_type][Current_residu -> SubMbType [mbPartIdx]] != Pred_L1 && sub_mb_type_name[ai_pstSlice -> slice_type][Current_residu -> SubMbType [mbPartIdx]] != B_direct) { aio_pstMacroblock -> MotionPredL0 [mbPartIdx] = getNbits(ai_pcData, position, 1); } } //Recovery of the image reference of each sub-macroblock for ( mbPartIdx = 0 ; mbPartIdx < 4 ; mbPartIdx++ ) { if ( sub_mb_type_name[ai_pstSlice -> slice_type][Current_residu -> SubMbType [mbPartIdx]] != Pred_L0 && sub_mb_type_name[ai_pstSlice -> slice_type][Current_residu -> SubMbType [mbPartIdx]] != B_direct) { aio_pstMacroblock -> MotionPredL1 [mbPartIdx] = getNbits(ai_pcData, position, 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 < 4 ; mbPartIdx++ ) { if ((Current_residu -> MbType != P_8x8ref0) && (!aio_pstMacroblock -> MotionPredL0[mbPartIdx]) && (sub_mb_type_name[ai_pstSlice -> slice_type][Current_residu -> SubMbType [mbPartIdx]] != B_direct) && (sub_mb_type_name[ai_pstSlice -> slice_type][Current_residu -> SubMbType [mbPartIdx]] != Pred_L1)) { aio_pstMacroblock -> RefIdxL0 [mbPartIdx] = read_te(ai_pcData, position, ai_pstSlice -> num_RefIdxL0_active_minus1); } } } #ifdef ERROR_DETECTION //Error Detection if(ErrorsCheckSubRefLx(aio_pstMacroblock -> RefIdxL0, ai_pstSlice -> num_RefIdxL0_active_minus1)){ return 1; } #endif //Recovery of the image reference of each sub-macroblock if (ai_pstSlice -> num_RefIdxL1_active_minus1 != 0){ for ( mbPartIdx = 0 ; mbPartIdx < 4 ; mbPartIdx++ ) { if ((sub_mb_type_name[ai_pstSlice -> slice_type][Current_residu -> SubMbType [mbPartIdx]] != B_direct) && (sub_mb_type_name[ai_pstSlice -> slice_type][Current_residu -> SubMbType [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(ErrorsCheckSubRefLx(aio_pstMacroblock -> RefIdxL1, ai_pstSlice -> num_RefIdxL1_active_minus1)){ return 1; } #endif //Recovery of the motion vector of each sub-macroblock for ( mbPartIdx = 0 ; mbPartIdx < 4 ; mbPartIdx++ ) { if ( sub_mb_type_name[ai_pstSlice -> slice_type][Current_residu -> SubMbType [mbPartIdx]] != B_direct && sub_mb_type_name[ai_pstSlice -> slice_type][Current_residu -> SubMbType [mbPartIdx]] != Pred_L1 ) { for ( subMbPartIdx = 0 ; subMbPartIdx < sub_num_part[ ai_pstSlice -> slice_type][ Current_residu -> SubMbType [mbPartIdx]] ; subMbPartIdx++ ) { int index = ( mbPartIdx << 2) + subMbPartIdx; aio_pstMacroblock -> MvdL0 [index][0] = read_se(ai_pcData, position); aio_pstMacroblock -> MvdL0 [index][1] = read_se(ai_pcData, position); } } } //Recovery of the motion vector of each sub-macroblock for ( mbPartIdx = 0 ; mbPartIdx < 4 ; mbPartIdx++ ) { if ( sub_mb_type_name[ai_pstSlice -> slice_type][Current_residu -> SubMbType [mbPartIdx]] != B_direct && sub_mb_type_name[ai_pstSlice -> slice_type][Current_residu -> SubMbType [mbPartIdx]] != Pred_L0 ) { for ( subMbPartIdx = 0 ; subMbPartIdx < sub_num_part[ ai_pstSlice -> slice_type][ Current_residu -> SubMbType [mbPartIdx]] ; subMbPartIdx++ ) { int index = ( mbPartIdx << 2) + subMbPartIdx; aio_pstMacroblock -> MvdL1 [index][0] = read_se(ai_pcData, position); aio_pstMacroblock -> MvdL1 [index][1] = read_se(ai_pcData, position); } } } 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; }