예제 #1
0
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 
		{