/** Same as previous but without SliceIGroup table. */ void PpsSliceGroupHeaderCut(unsigned char *data, int *Position, PPS *pt_pps) { int i; int iGroup; if ( pt_pps -> num_slice_groups_minus1 > 0 ) { pt_pps -> slice_group_map_type = (unsigned char) read_ue(data, Position); if ( pt_pps -> slice_group_map_type == 0 ) for ( iGroup = 0 ; iGroup <= pt_pps -> num_slice_groups_minus1 ; iGroup++ ) pt_pps -> run_length_minus1 [iGroup] = (short) read_ue(data, Position); else if ( pt_pps -> slice_group_map_type == 2 ) for ( iGroup = 0 ; iGroup < pt_pps -> num_slice_groups_minus1 ; iGroup++ ) { pt_pps -> top_left_tab [iGroup] = (short) read_ue(data, Position);// pt_pps -> bottom_right_tab [iGroup] = (short) read_ue(data, Position);// } else if ( pt_pps -> slice_group_map_type == 3 || pt_pps -> slice_group_map_type == 4 || pt_pps -> slice_group_map_type == 5 ) { pt_pps -> slice_group_change_direction_flag = (unsigned char) getNbits(data, Position, 1); pt_pps -> slice_group_change_rate_minus1 = (short) read_ue(data, Position) + 1; } else if ( pt_pps -> slice_group_map_type == 6 ) { short log2_num_slice_groups_minus1 = (short) log_base2(pt_pps -> num_slice_groups_minus1 + 1); short pic_size_in_map_units_minus1 = (short) read_ue(data, Position); for ( i = 0 ; i <= pic_size_in_map_units_minus1 ; i++ ) { getNbits(data, Position, log2_num_slice_groups_minus1); } } } }
void seq_parameter_set( unsigned char *data, SPS *sps){ int position = 8; int profile_idc = getNbits(data, &position, 8); int constraint = getNbits(data, &position, 8); int level_idc = getNbits(data, &position, 8); //level_idc = if (profile_idc && !(constraint & 0xf)){ char Sps_id = read_ue(data, &position); char seq_parameter_set_id = CLIP3(0, SPS_BUF_SIZE, Sps_id); SPS *pt_sps = &sps [seq_parameter_set_id]; //To save parameter before resetting short b_stride = pt_sps -> b_stride; short b8_stride = pt_sps -> b8_stride; //Initialization of the maximun number of sps if(seq_parameter_set_id > sps[0] . MaxSpsId){ sps[0] . MaxSpsId = seq_parameter_set_id; } //Intilaize the SPS to zero memset(pt_sps, 0, sizeof(SPS)); pt_sps -> b_stride = b_stride; pt_sps -> b8_stride = b8_stride; pt_sps -> profile_idc = profile_idc; pt_sps -> level_idc = level_idc; seq_parameter_set_data(data, &position, pt_sps); pt_sps -> slice_header_restriction_flag = -1; rbsp_trailing_bits(&position); } }
/** Parses the rest of header. */ void PpsEndOfHeader(unsigned char *data, int *Position, PPS *pt_pps) { pt_pps -> num_RefIdxL0_active_minus1 = (unsigned char) read_ue(data, Position); pt_pps -> num_RefIdxL1_active_minus1 = (unsigned char) read_ue(data, Position); pt_pps -> WeightedPredFlag = (unsigned char) getNbits(data, Position, 1); pt_pps -> WeightedBipredIdc = (unsigned char) getNbits(data, Position, 2); //pt_pps -> weighted_bipred_idc = pt_pps -> pic_init_qp = (unsigned char) (read_se(data, Position) + 26); read_se(data, Position); //pic_init_qs_minus26 = pt_pps -> second_chroma_qp_index_offset = pt_pps -> chroma_qp_index_offset = (char) read_se(data, Position); pt_pps -> deblocking_filter_control_present_flag = (unsigned char) getNbits(data, Position, 1); pt_pps -> constrained_intra_pred_flag = (unsigned char) getNbits(data, Position, 1); pt_pps -> redundant_pic_cnt_present_flag = (unsigned char) getNbits(data, Position, 1); }
ERROR_CODE pvmp3_frame_synch(tPVMP3DecoderExternal *pExt, void *pMem) /* bit stream structure */ { uint16 val; ERROR_CODE err; tmp3dec_file *pVars; pVars = (tmp3dec_file *)pMem; pVars->inputStream.pBuffer = pExt->pInputBuffer; pVars->inputStream.usedBits = (pExt->inputBufferUsedLength << 3); // in bits pVars->inputStream.inputBufferCurrentLength = (pExt->inputBufferCurrentLength); // in bits err = pvmp3_header_sync(&pVars->inputStream); if (err == NO_DECODING_ERROR) { /* validate synchronization by checking two consecutive sync words */ // to avoid multiple bitstream accesses uint32 temp = getNbits(&pVars->inputStream, 21); // put back whole header pVars->inputStream.usedBits -= 21 + SYNC_WORD_LNGTH; int32 version; switch (temp >> 19) /* 2 */ { case 0: version = MPEG_2_5; break; case 2: version = MPEG_2; break; case 3: version = MPEG_1; break; default: version = INVALID_VERSION; break; } int32 freq_index = (temp << 20) >> 30; if (version != INVALID_VERSION && (freq_index != 3)) { int32 numBytes = fxp_mul32_Q28(mp3_bitrate[version][(temp<<16)>>28] << 20, inv_sfreq[freq_index]); numBytes >>= (20 - version); if (version != MPEG_1) { numBytes >>= 1; }
/** Parses the additional information. */ void PpsHighProfile(unsigned char *data, int *Position, PPS *pt_pps, SPS *pt_sps) { pt_pps -> transform_8x8_mode_flag = (unsigned char) getNbits(data, Position, 1); decode_scaling_matrices(data, Position, pt_sps, 0, pt_pps -> scaling_matrix4, pt_pps -> scaling_matrix8); pt_pps -> second_chroma_qp_index_offset = (char) read_se(data, Position); if ( abs(pt_pps -> second_chroma_qp_index_offset) > 12){ pt_pps -> second_chroma_qp_index_offset = pt_pps -> chroma_qp_index_offset; } }
void DecRefBasePicMarking(unsigned char *data, int *position, MMO *Mmo, SPS *sps, NAL *Nal) { if (getNbits(data, position, 1) ) { int BaseDependency = (Nal -> DqId >> 4) - 1; int LayerId = GetLayerNumber(Nal, BaseDependency << 4); LAYER_MMO *LayerMmo = &Mmo -> LayerMMO [LayerId]; GetMMCOOperationCode(sps, LayerMmo, data, position); SetDecRefLayer(Nal, Mmo, LayerMmo, BaseDependency); }
void ParseIPCM(const unsigned char *ai_pcData, int *Position, RESIDU *picture_residu, unsigned char *NonZeroCountCache){ int i; for ( i = 0 ; i < 256 /** ChromaFormatFactor */; i++ ) { picture_residu -> LumaLevel[i] = (short) getNbits(ai_pcData, Position, 8); } for ( i = 0 ; i < 64 /** ChromaFormatFactor */; i++ ) { picture_residu -> ChromaACLevel_Cb[i] = (short) getNbits(ai_pcData, Position, 8); } for ( i = 0 ; i < 64 /** ChromaFormatFactor */; i++ ) { picture_residu -> ChromaACLevel_Cr[i] = (short) getNbits(ai_pcData, Position, 8); } init_mb_IPCM(NonZeroCountCache); picture_residu -> Qp = 0; }
/** This function permits to get from the NAL unit additional parameters. @param data The NAL unit. @param position The current position in the NAL. */ void hrd_parameters ( unsigned char *data, int *position, SPS *sps ) { int SchedSelIdx ; sps -> cpb_cnt = read_ue(data, position) + 1; getNbits(data, position, 4);//bit_rate_scale = getNbits(data, position, 4);// cpb_size_scale = for ( SchedSelIdx = 0 ; SchedSelIdx <= sps -> cpb_cnt -1 ; SchedSelIdx++ ) { read_ue(data, position);// /* bit_rate_value_minus1 [SchedSelIdx] = */ read_ue(data, position);///* cpb_size_value_minus1 [SchedSelIdx] = */ getNbits(data, position, 1);///* cbr_flag [SchedSelIdx] = */ } sps -> initial_cpb_removal_delay_length = getNbits(data, position, 5) + 1; sps -> cpb_removal_delay_length = getNbits(data, position, 5) + 1;// = getNbits(data, position, 5);// dpb_output_delay_length_minus1 = sps -> time_offset_length = getNbits(data, position, 5);//time_offset_length = }
/** Parses first data of pps. */ void PpsFirstHeader(unsigned char *data, int *Position, PPS *pt_pps) { pt_pps -> entropy_coding_mode_flag = (unsigned char) getNbits(data, Position, 1); pt_pps -> pic_order_present_flag = (unsigned char) getNbits(data, Position, 1); pt_pps -> num_slice_groups_minus1 = (unsigned char) read_ue(data, Position); }
//for init access unit int slice_header_svc_cut(unsigned char *data, SPS *sps, PPS *pps, int *position, SLICE *Slice, NAL *Nal) { PPS *pt_pps_id ; SPS *pt_sps_id ; int PicParameterId; int SeqParameterId; //Read header data Slice -> first_mb_in_slice = read_ue(data, position); Slice -> slice_type = read_ue(data, position); if ( Slice -> slice_type > 4 ) { Slice -> slice_type -= 5 ; } PicParameterId = read_ue(data, position); Nal -> pic_parameter_id[Nal -> LayerId] = PicParameterId = CLIP3(0, PPS_BUF_SIZE - 1, PicParameterId); pt_pps_id = &pps[PicParameterId]; //Should be in slice header //Sometimes Subset SPS are after PPS (rtsp) if(pt_pps_id -> seq_parameter_set_id > sps[0] . MaxSpsId){ pt_pps_id -> seq_parameter_set_id = sps[0] . MaxSpsId; } SeqParameterId = pt_pps_id -> seq_parameter_set_id + (Nal -> LayerId ? 16: 0); pt_sps_id = &sps[SeqParameterId]; Slice -> frame_num = getNbits(data, position, pt_sps_id -> log2_max_frame_num ); //Read Frame parameter if ( !pt_sps_id -> frame_mbs_only_flag ) { Slice -> field_pic_flag = getNbits(data, position, 1); if ( Slice -> field_pic_flag ) { Slice->bottom_field_flag = getNbits(data, position, 1); } } else { Slice->field_pic_flag = 0; } if ( 1 == Nal -> IdrFlag) { Slice->idr_pic_id = read_ue(data, position);//idr_pic_id = } if ( pt_sps_id -> pic_order_cnt_type == 0 ) { Slice -> pic_order_cnt_lsb = getNbits(data, position, pt_sps_id -> log2_max_pic_order_cnt_lsb ); if ( pt_pps_id -> pic_order_present_flag && !Slice -> field_pic_flag ) Slice -> delta_pic_order_cnt_bottom = read_se(data, position); } if ( pt_sps_id -> pic_order_cnt_type == 1 && !pt_sps_id -> delta_pic_order_always_zero_flag ) { Slice -> delta_pic_order_cnt [0] = read_se(data, position); if ( pt_pps_id -> pic_order_present_flag && !Slice -> field_pic_flag ) Slice -> delta_pic_order_cnt [1] = read_se(data, position); } if ( pt_pps_id -> redundant_pic_cnt_present_flag ) { read_ue(data, position);//redundant_pic_cnt = } return 0; }
/** This function permits to decode from the bitstream the Sequence Parameter Set NAL unit. All the parameters decoded will be stored in the sps structure. @param data The NAL unit. @param position The current position in the NAL. @param NalBytesInNalunit The sizes of the NAL unit in bytes. @param sps The sps structure which contains all parameters decoded in this NAL. */ void seq_parameter_set_data ( unsigned char *data, int *position, SPS *pt_sps){ int i = 0 ; if( pt_sps -> profile_idc == 100 || pt_sps -> profile_idc == 110 || pt_sps -> profile_idc == 122 || pt_sps -> profile_idc == 244 || pt_sps -> profile_idc == 44 || pt_sps -> profile_idc == 83 || pt_sps -> profile_idc == 86 ) { pt_sps -> chroma_format_idc = read_ue(data, position); if( pt_sps -> chroma_format_idc == 3 ){ getNbits(data, position, 1);//separate_colour_plane_flag } pt_sps -> bit_depth_luma = read_ue(data, position) + 8; pt_sps -> bit_depth_chroma = read_ue(data, position) + 8; getNbits(data, position, 1);//qpprime_y_zero_transform_bypass_flag decode_scaling_matrices(data, position, pt_sps,1, pt_sps -> scaling_matrix4 , pt_sps -> scaling_matrix8); } pt_sps -> log2_max_frame_num = read_ue(data, position) + 4; pt_sps -> pic_order_cnt_type = read_ue(data, position); if ( pt_sps -> pic_order_cnt_type == 0 ) { pt_sps -> log2_max_pic_order_cnt_lsb = read_ue(data, position) + 4; } else if ( pt_sps -> pic_order_cnt_type == 1 ) { pt_sps -> delta_pic_order_always_zero_flag = getNbits(data, position, 1); pt_sps -> offset_for_non_ref_pic = read_se(data, position); pt_sps -> offset_for_top_to_bottom_field = read_se(data, position); pt_sps -> num_ref_frames_in_pic_order_cnt_cycle = read_ue(data, position); for (; i < pt_sps -> num_ref_frames_in_pic_order_cnt_cycle ; i++ ) { pt_sps -> offset_for_ref_frame [i] = read_se(data, position); } } pt_sps -> num_ref_frames = read_ue(data, position);// getNbits(data, position, 1);//gaps_in_frame_num_value_allowed_flag = pt_sps -> pic_width_in_mbs = read_ue(data, position) + 1; pt_sps -> pic_height_in_map_units = read_ue(data, position) + 1; pt_sps -> frame_mbs_only_flag = getNbits(data, position, 1); pt_sps -> PicSizeInMbs = pt_sps -> pic_width_in_mbs * pt_sps -> pic_height_in_map_units; if ( !pt_sps -> frame_mbs_only_flag ) { pt_sps -> MbAdaptiveFrameFieldFlag = getNbits(data, position, 1); } //To initialize the number of decoded frame before displaying. get_max_dpb(pt_sps); pt_sps -> direct_8x8_inference_flag = getNbits(data, position, 1); if ( getNbits(data, position, 1)) {//frame_cropping_flag pt_sps -> CropLeft = (read_ue(data, position)) << 1;//frame_crop_left_offset = pt_sps -> CropRight = (read_ue(data, position)) << 1;//frame_crop_right_offset = pt_sps -> CropTop = (read_ue(data, position)) << 1;//frame_crop_top_offset = pt_sps -> CropBottom = (read_ue(data, position)) << 1;//frame_crop_bottom_offset = } if ( getNbits(data, position, 1) ) { vui_parameters(data, position, pt_sps); } }
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 {
void pvmp3_get_scale_factors(mp3ScaleFactors *scalefac, mp3SideInfo *si, int32 gr, int32 ch, tmp3Bits *pMainData) { int32 sfb; int32 i; int32 window; granuleInfo *gr_info = &(si->ch[ch].gran[gr]); if (gr_info->window_switching_flag && (gr_info->block_type == 2)) { if (gr_info->mixed_block_flag) { /* MIXED */ for (sfb = 0; sfb < 8; sfb++) { scalefac->l[sfb] = getNbits(pMainData, slen[0][gr_info->scalefac_compress]); } for (sfb = 3; sfb < 6; sfb++) { for (window = 0; window < 3; window++) { scalefac->s[window][sfb] = getNbits(pMainData, slen[0][gr_info->scalefac_compress]); } } for (sfb = 6; sfb < 12; sfb++) { for (window = 0; window < 3; window++) { scalefac->s[window][sfb] = getNbits(pMainData, slen[1][gr_info->scalefac_compress]); } } } else { /* SHORT*/ for (i = 0; i < 2; i++) { for (sfb = sfbtable.s[i]; sfb < sfbtable.s[i+1]; sfb++) { for (window = 0; window < 3; window++) { scalefac->s[window][sfb] = getNbits(pMainData, slen[i][gr_info->scalefac_compress]); } } } } scalefac->s[0][12] = 0; /* sfb = 12 win= 0 */ scalefac->s[1][12] = 0; /* sfb = 12 win= 1 */ scalefac->s[2][12] = 0; /* sfb = 12 win= 2 */ } else { /* LONG types 0,1,3 */ int32 *ptr = &scalefac->l[0]; for (i = 0; i < 4; i++) { int32 tmp4 = long_sfbtable[i]; if ((si->ch[ch].scfsi[i] == 0) || (gr == 0)) { int32 tmp1 = slen[(i>>1)][gr_info->scalefac_compress]; if (tmp1) { int32 tmp2 = tmp1 * tmp4; uint32 tmp3 = getNbits(pMainData, tmp2); tmp4 = 32 - tmp1; for (; tmp2 > 0; tmp2 -= tmp1) { *(ptr++) = (tmp3 << (32 - tmp2)) >> tmp4; } } else { for (sfb = tmp4; sfb != 0; sfb--) { *(ptr++) = 0; } } } else {
/** 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; }
//============================================================================================ //函数功能:量化因子(scale factor)的解码工作,目的是在解出反量化模组(requantization)需要的量化因子, // 而每个frame中都是有两个granule组成,每个granule中含有左右两个声道,而每个声道内均存放有 // 经过编码的量化因子与经过Huffman编码后的压缩资料 // 因为量化因子在编码时依照余弦转换(MDCT)运算时所采用的不同的窗口框函数划分成数个量化 // 区(scale factor band),长窗划分成21个量化区;而短窗则划分成12个量化区,而每个量化区的 // 量化因子可能采用不同的位元数来编码的,所以必须先从旁资讯中解出不同量化区中的量化因子 // 的编码位元数,再根据所使用的窗框解出所有的量化因子 //函数参数:"si"表示旁信息,"gr"表示granule,"ch"表示声道,"pMainData"表示 //============================================================================================ void pvmp3_get_scale_factors(mp3ScaleFactors *scalefac, mp3SideInfo *si, int32 gr, int32 ch, tmp3Bits *pMainData) { //定义变量 int32 sfb; int32 i; int32 window; granuleInfo *gr_info = &(si->ch[ch].gran[gr]); //若"window_switching_flag"为1并且"block_type"为2 if (gr_info->window_switching_flag && (gr_info->block_type == 2)) { //如果"mixed_block_flag"为1,即为混合型 if (gr_info->mixed_block_flag) { //得到"l[sfb]"的所有量化因子,其中sfb属于0-7,"l[]"表示长窗框 for (sfb = 0; sfb < 8; sfb++) { scalefac->l[sfb] = getNbits(pMainData, slen[0][gr_info->scalefac_compress]); } //得到"s[window][sfb]"的所有量化因子,其中window属于0-2,sfb属于3-5,"s[][]"表示短窗框 for (sfb = 3; sfb < 6; sfb++) { for (window = 0; window < 3; window++) { scalefac->s[window][sfb] = getNbits(pMainData, slen[0][gr_info->scalefac_compress]); } } //得到"s[window][sfb]"的所有量化因子,其中window属于0-2,sfb属于6-11,"s[][]"表示短窗框 for (sfb = 6; sfb < 12; sfb++) { for (window = 0; window < 3; window++) { scalefac->s[window][sfb] = getNbits(pMainData, slen[1][gr_info->scalefac_compress]); } } } //如果"mixed_block_flag"不为1,即为短窗框 else { //获得"s[window][region]"的所有量化因子,其中"window"属于0-2,"region"属于0-11 //对"sfbtabe"中"s[]"数组的前两个元素,即"s[0]"和"s[1]" for (i = 0; i < 2; i++) { //对每个位于"s[i]","s[i+1]"区间内的元素 for (sfb = sfbtable.s[i]; sfb < sfbtable.s[i+1]; sfb++) { //对每个"window",其中"window"属于0-2 for (window = 0; window < 3; window++) { scalefac->s[window][sfb] = getNbits(pMainData, slen[i][gr_info->scalefac_compress]); } } } } //分别对每个短窗框的第12个量化区赋值为0 scalefac->s[0][12] = 0; /* sfb = 12 win= 0 */ scalefac->s[1][12] = 0; /* sfb = 12 win= 1 */ scalefac->s[2][12] = 0; /* sfb = 12 win= 2 */ //若"window_switching_flag"为1并且"block_type"为2的if语句结束 } //若不满足"window_switching_flag"为1并且"block_type",即为长窗口,LONG types为0,1,3 else { int32 *ptr = &scalefac->l[0]; //针对每个"long_sfbtable"元素 for (i = 0; i < 4; i++) { int32 tmp4 = long_sfbtable[i]; //若"side iformation"的"scfi band"为0或者"granule"为0 if ((si->ch[ch].scfsi[i] == 0) || (gr == 0)) { int32 tmp1 = slen[(i>>1)][gr_info->scalefac_compress]; //若tmp1大于0 if (tmp1) { int32 tmp2 = tmp1 * tmp4; uint32 tmp3 = getNbits(pMainData, tmp2); tmp4 = 32 - tmp1; //为每个相应的长框量化区"l[]"赋值 for (; tmp2 > 0; tmp2 -= tmp1) { *(ptr++) = (tmp3 << (32 - tmp2)) >> tmp4; } } //若tmp1为0 else { //为每个相应的长框量化区"l[]"赋值为0 for (sfb = tmp4; sfb != 0; sfb--) { *(ptr++) = 0; } } } //若不满足("side iformation"的"scfi band"为0或者"granule"为0),则为相应的"l[]"赋值 else {
/** This function permits to get from the NAL unit additional parameters. VUI parameters are not required for constructing the luma and chroma samples by teh decoding process. @param data The NAL unit. @param position The current position in the NAL. */ void vui_parameters ( unsigned char *data, int *position, SPS *sps ) { int overscan_info_present_flag ; int video_signal_type_present_flag ; int bitstream_restriction_flag ; int aspect_ratio_info_present_flag = getNbits(data, position, 1); if ( aspect_ratio_info_present_flag ) { int aspect_ratio_idc = getNbits(data, position, 8); if ( aspect_ratio_idc == Extended_SAR ) { getNbits(data, position, 16);//sar_width = getNbits(data, position, 16);// sar_height = } } //scanner dans ffmpeg mais pas pris en compte overscan_info_present_flag = getNbits(data, position, 1); if ( overscan_info_present_flag ) getNbits(data, position, 1);// overscan_appropriate_flag = video_signal_type_present_flag = getNbits(data, position, 1); if ( video_signal_type_present_flag ) { getNbits(data, position, 3);//video_format = getNbits(data, position, 1);// video_full_range_flag = if (getNbits(data, position, 1)) { getNbits(data, position, 8);// colour_primaries = getNbits(data, position, 8);// transfer_characteristics = getNbits(data, position, 8);// matrix_coefficients = } } if (getNbits(data, position, 1)) { read_ue(data, position);//chroma_sample_loc_type_top_field = read_ue(data, position);// chroma_sample_loc_type_bottom_field = } //****************************************** if (getNbits(data, position, 1)) { get32bits(data, position);// num_units_in_tick = get32bits(data, position);//time_scale = getNbits(data, position, 1);// fixed_frame_rate_flag = } sps -> nal_hrd_parameters_present_flag = getNbits(data, position, 1); if ( sps -> nal_hrd_parameters_present_flag ) hrd_parameters(data, position,sps); sps -> vlc_hrd_parameters_present_flag = getNbits(data, position, 1); if ( sps -> vlc_hrd_parameters_present_flag ) hrd_parameters(data, position,sps); //scanner dans ffmpeg mais pas pris en compte if ( sps -> nal_hrd_parameters_present_flag || sps -> vlc_hrd_parameters_present_flag ) getNbits(data, position, 1);//low_delay_hrd_flag = //******************************************** sps -> pic_present_flag = getNbits(data, position, 1);// = bitstream_restriction_flag = getNbits(data, position, 1); if ( bitstream_restriction_flag ) { //scanner dans ffmpeg mais pas pris en compte getNbits(data, position, 1);// motion_vectors_over_pic_boundaries_flag = read_ue(data, position);//max_bytes_per_pic_denom = read_ue(data, position);//max_bits_per_mb_denom = read_ue(data, position);//log2_max_mv_length_horizontal = read_ue(data, position);//log2_max_mv_length_vertical = //****************************************** read_ue(data, position);//num_reorder_frames = read_ue(data, position);//max_dec_frame_buffering = } }