/**
This function calculates the Scoeff residual of the current macroblock.
Here, base macroblock coefficents are rescaled, when base layer was a AVC one,
and added to the current macroblock coefficient. The sum is stored in the current macroblock,
in order to be used for upper SNR layer.
The residual is also calculated in a short picture in order to be used for upper spatial enhancement, or to add to the prediction.
*/
void SCoeffResidualAddRes(const NAL *Nal, RESIDU *CurrResidu, RESIDU *BaseResidu, const PPS *Pps, const short PicWidthInPix, const W_TABLES *Quantif
						 , short *Residu_Luma, short *Residu_Cb, short *Residu_Cr)
{



	//We have to keep base and current layer rescale coefficient for Scoeff prediction
	//For upper layer
	if( CurrResidu -> Cbp){
		// In case of new SNR enhancement based on this one
		RescaleCurrentCoeff(CurrResidu, BaseResidu, Pps, Quantif);
	}else if ( CurrResidu -> ResidualPredictionFlag){
		//===== modify QP values (as specified in G.8.1.5.1.2) =====
		//cbp == 0 && (Scoeff || Tcoeff) && (I_BL || ResidualPredictionFlag)
		CurrResidu -> Qp = BaseResidu -> Qp;
		CurrResidu -> Transform8x8 = BaseResidu -> Transform8x8;
	}


	//Test if cbp != 0 and if we are in the first enhancement layer in MGS or CGS
	if( (!IS_I(CurrResidu -> MbType)) && CurrResidu -> ResidualPredictionFlag && (!IS_I(BaseResidu -> MbType))){
		ComputeCurrentCoeff(Nal, CurrResidu, BaseResidu, Pps, Quantif);
	}

	if (Nal -> PicToDecode){
		if ( !CurrResidu -> Transform8x8){
			SCoeff4x4AddRes(Residu_Luma, CurrResidu, PicWidthInPix);
		} else {
			SCoeff8x8AddRes(Residu_Luma, CurrResidu, PicWidthInPix);
		}

		//Decode the chrominance
		SCoeffChromaAddRes(Residu_Cb, Residu_Cr, CurrResidu, PicWidthInPix >> 1);
	}
}
void fill_caches_cabac ( SLICE *slice, CABAC_NEIGH *neigh, unsigned char slice_table [], int mb_xy, int qp_delta, RESIDU *residu )
{



	int	top_type;
    int left_type = 0;
    
	//Updating the adress of the macroblock which belong to the neighbourhood.
    int top_xy = mb_xy - slice -> mb_stride;
    int left_xy = mb_xy - 1 ;
	

	if ( top_xy >= 0 && slice_table [top_xy] == slice -> slice_num) {
        top_type =  residu [- slice -> mb_stride] . MbType;
		neigh -> intra_chroma_pred_mode_top = residu [- slice -> mb_stride] . IntraChromaPredMode;
	}else{
		top_type = 0;
	}


	if ( left_xy  >= 0 ) {
		left_type = slice_table [left_xy] == slice -> slice_num ? residu [-1] . MbType : 0 ;
		neigh -> intra_chroma_pred_mode_left = residu [-1] . IntraChromaPredMode;
		neigh -> last_cbp = residu [-1] . Cbp;
		neigh -> last_qp_diff = qp_delta;
	}else{
		neigh -> last_cbp = 0;
		neigh -> last_qp_diff = 0;
	}

	if ( mb_xy > 0 && !(mb_xy % (slice -> mb_stride ))){
		left_type =  0;
	}	
	

	neigh -> intra_chroma_pred_mode_left = residu [-1] . IntraChromaPredMode;
	neigh -> intra_chroma_pred_mode_top = residu [- slice -> mb_stride] . IntraChromaPredMode;


    // top_cbp
    if(top_type) {
        neigh -> Cbp_b = residu[- slice -> mb_stride] . Cbp;
	} else if (IS_I(residu -> MbType )){
		neigh -> Cbp_b = 0x1c0;
	}else{
       neigh -> Cbp_b = 0;
    }

    // left_cbp
    if (left_type) {
        neigh -> Cbp_a = residu[-1] . Cbp & 0xffA;
    } else if (IS_I(residu -> MbType )){
		 neigh -> Cbp_a = 0x1c0;
	}else {
        neigh -> Cbp_a = 0;
    }
}
Beispiel #3
0
/**
This function permits to update the neighbourhood of the current macroblock in a P or B slice.
This function stock in table the data calculated for the macroblock which belong to the neighbourhood of the current macroblock.

@param aio_pstSlice The aio_pstSlice strucutre.
@param aio_tstBlock Contains all parameters of each macroblock of the current picture.
@param ai_iEntropy_coding_mode_flag The type of the VLC coding, CABAC or CAVLC.
@param aio_tiNon_zero_count_cache A cache table where coeff_token is stocked for each 4x4 block of the current macroblock.
@param ai_tstNon_zero_count A table where each coeff_token calculated is stocked for each macroblock decoded.
@param aio_pstSlice_table A table which resume in which aio_pstSlice each macroblock belongs to.
@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 constrained_intra_pred_flag Enables to determine if the intra decoding process is contrained.
*/
void fill_caches (  const SLICE *aio_pstSlice, const RESIDU CurrResidu[], const int ai_iEntropy_coding_mode_flag, 
				  unsigned char aio_tiNon_zero_count_cache [ RESTRICT ], const DATA *CurrBlock, 
				  const unsigned char aio_pstSlice_table [ ], const short ai_iMb_x , const short ai_iMb_y)
{


    int		top_type;
    int     left_type;
    int     top_xy;
	int     left_xy;
    const int	iMb_xy = ai_iMb_x + ai_iMb_y * (short)(aio_pstSlice -> mb_stride);
	const int	ai_iMb_type_name = CurrResidu -> MbType;
	const int val_init = ai_iEntropy_coding_mode_flag && !(IS_I(ai_iMb_type_name)) ? 0 : 64 ;
	init_non_zero_count_cache(aio_tiNon_zero_count_cache, val_init);

	if ( ai_iMb_y > 0 ) {
		top_xy = iMb_xy - aio_pstSlice -> mb_stride;
		top_type = (aio_pstSlice_table [top_xy] == aio_pstSlice -> slice_num) ? CurrResidu [-  aio_pstSlice -> mb_stride] . MbType : 0 ;
	}else {
		top_type = 0;
	}

	if ( iMb_xy > 0 && ai_iMb_x != 0 )  {
		left_xy = iMb_xy - 1 ;
		left_type = aio_pstSlice_table [left_xy] == aio_pstSlice -> slice_num ? CurrResidu [-1] . MbType : 0 ;
	}else {
		left_type = 0;
	}

	FillNonZeroCount(CurrResidu, CurrBlock, aio_pstSlice -> mb_stride, top_type, left_type, aio_tiNon_zero_count_cache);
}
Beispiel #4
0
/**
This function deocdes an I macroblock into an P or B slice.
*/
void MbISVCDecoding(const SPS *Sps, const PPS *Pps, const NAL* Nal, const W_TABLES *Quantif, const STRUCT_PF *BaselineVectors, 
			 RESIDU *CurrResidu, RESIDU *BaseResidu, DATA *Block,
			 const short PicWidthInPix, short iMb_x, short iMb_y,
			 unsigned char *Y, unsigned char *U, unsigned char *V, 
			 unsigned char *BaseY, unsigned char *BaseU, unsigned char *BaseV)
{
	if(!Nal -> SpatialScalability || IS_I(CurrResidu -> MbType)){
		//AVC I macroblock or SNR I macroblock
		const short iMb_xy = iMb_x + iMb_y * ((PicWidthInPix - 32) >> 4);
		MbISnr(Pps, Nal, Quantif, BaselineVectors, CurrResidu, &BaseResidu[iMb_xy], PicWidthInPix, 
			Y, U, V, &BaseY[((iMb_x + (iMb_y * PicWidthInPix)) << 4)], 
			&BaseU[((iMb_x + (iMb_y * PicWidthInPix >> 1)) << 3)], 
			&BaseV[((iMb_x + (iMb_y * PicWidthInPix >> 1)) << 3)]);
	}else{
Beispiel #5
0
/**
Process to get the neighbouring and their availability

@param aio_pstMacro Macro the availability of the neighbouring macroblock.
@param iAddr_x Abciss of the current macroblock in the current picture.
@param PicWidthInPix Width of the sample to interpolate.
@param SliceTable Table which contains for each macroblock the number of the slice they belong to.
@param aio_tstBlock Contains all parameters of each macroblock of the current picture.
@param constained_pred_flag Parameter to determine the intra prediction constrained or not.
*/
void GetNeighbour(short Addr, short iAddr_x, const short PicWidthInMbs, const short PicSizeInMbs, 
				  const unsigned char *SliceTable, RESIDU *CurrResidu, const int constained_pred_flag)
{


	const int iAddr_xp1 = (iAddr_x + 1) != PicWidthInMbs;

	int Mask = 0;
	//6.4.4
	int mbAddrA = Addr - 1 ;
	int mbAddrE = Addr + 1;
	int mbAddrD = Addr - PicWidthInMbs - 1;
	int mbAddrB = Addr - PicWidthInMbs;
	int mbAddrC = Addr - PicWidthInMbs + 1;
	int mbAddrF = Addr + PicWidthInMbs - 1;
	int mbAddrG = Addr + PicWidthInMbs;
	int mbAddrH = Addr + PicWidthInMbs + 1 ;


	if (constained_pred_flag){
		if(mbAddrA >= 0) Mask =   IS_I( CurrResidu [mbAddrA] . MbType) && (iAddr_x != 0)   && NeighbourAvail(mbAddrA, PicSizeInMbs, SliceTable[mbAddrA], SliceTable[Addr]);
		if(mbAddrB >= 0) Mask += (IS_I( CurrResidu [mbAddrB] . MbType) &&					  NeighbourAvail(mbAddrB, PicSizeInMbs, SliceTable[mbAddrB], SliceTable[Addr])) << 1;
		if(mbAddrC >= 0) Mask += (IS_I( CurrResidu [mbAddrC] . MbType) && (iAddr_xp1 != 0) && NeighbourAvail(mbAddrC, PicSizeInMbs, SliceTable[mbAddrC], SliceTable[Addr])) << 2;
		if(mbAddrD >= 0) Mask += (IS_I( CurrResidu [mbAddrD] . MbType) && (iAddr_x != 0)   && NeighbourAvail(mbAddrD, PicSizeInMbs, SliceTable[mbAddrD], SliceTable[Addr])) << 3;

		//For SVC
		//Working only with on slice per frame
		if(mbAddrE >= 0) Mask += (IS_I( CurrResidu [mbAddrE] . MbType) && (iAddr_xp1 != 0) && NeighbourAvail(mbAddrE, PicSizeInMbs, SliceTable[mbAddrE], SliceTable[Addr])) << 4;
		if(mbAddrF >= 0) Mask += (IS_I( CurrResidu [mbAddrF] . MbType) && (iAddr_x != 0)   && NeighbourAvail(mbAddrF, PicSizeInMbs, SliceTable[mbAddrF], SliceTable[Addr])) << 5;
		if(mbAddrG >= 0) Mask += (IS_I( CurrResidu [mbAddrG] . MbType)					   && NeighbourAvail(mbAddrG, PicSizeInMbs, SliceTable[mbAddrG], SliceTable[Addr])) << 6;
		if(mbAddrH >= 0) Mask += (IS_I( CurrResidu [mbAddrH] . MbType) && (iAddr_xp1 != 0) && NeighbourAvail(mbAddrH, PicSizeInMbs, SliceTable[mbAddrH], SliceTable[Addr])) << 7;
	}else{
		if(mbAddrA >= 0) Mask =  ((iAddr_x != 0)   && NeighbourAvail(mbAddrA, PicSizeInMbs, SliceTable[mbAddrA], SliceTable[Addr]));
		if(mbAddrB >= 0) Mask +=	(				  NeighbourAvail(mbAddrB, PicSizeInMbs, SliceTable[mbAddrB], SliceTable[Addr])) << 1;
		if(mbAddrC >= 0) Mask += ((iAddr_xp1 != 0) && NeighbourAvail(mbAddrC, PicSizeInMbs, SliceTable[mbAddrC], SliceTable[Addr])) << 2;
		if(mbAddrD >= 0) Mask += ((iAddr_x != 0)   && NeighbourAvail(mbAddrD, PicSizeInMbs, SliceTable[mbAddrD], SliceTable[Addr])) << 3;
		if(mbAddrE >= 0) Mask += ((iAddr_xp1 != 0) && NeighbourAvail(mbAddrE, PicSizeInMbs, SliceTable[mbAddrE], SliceTable[Addr])) << 4;
		if(mbAddrF >= 0) Mask += ((iAddr_x != 0)   && NeighbourAvail(mbAddrF, PicSizeInMbs, SliceTable[mbAddrF], SliceTable[Addr])) << 5;
		if(mbAddrG >= 0) Mask +=	(			      NeighbourAvail(mbAddrG, PicSizeInMbs, SliceTable[mbAddrG], SliceTable[Addr])) << 6;
		if(mbAddrH >= 0) Mask += ((iAddr_xp1 != 0) && NeighbourAvail(mbAddrH, PicSizeInMbs, SliceTable[mbAddrH], SliceTable[Addr])) << 7;
	}

	CurrResidu [Addr] . AvailMask = Mask;
}								
Beispiel #6
0
/**
Decode a I_BL marcoblock using SNR prediction.
*/
void MbISnr (const PPS *Pps, const NAL* Nal, const W_TABLES *Quantif, const STRUCT_PF *BaselineVectors, 
			 RESIDU *CurrResidu, RESIDU *BaseResidu, const short PicWidthInPix, 
			 unsigned char *Y, unsigned char *U, unsigned char *V,
			 unsigned char *BaseY, unsigned char *BaseU, unsigned char *BaseV)
{

	//Construction process for one macroblock
	if (IS_I(CurrResidu -> MbType)){
		//I type macroblock decoding process
		decode_MB_I(Y, U, V, Pps, CurrResidu, PicWidthInPix, Quantif, BaselineVectors);
	}else if (Nal -> TCoeffPrediction){
		//Decoding proces of the macroblock, as an INTRA_BL
		DecodeITCoeff(CurrResidu, BaseResidu, Pps, PicWidthInPix, Quantif, BaselineVectors, Y, U, V);
	}else if (Nal -> SCoeffPrediction){
		if ((CurrResidu -> Cbp & 0x0f) == 0){
			//===== modify QP values (as specified in G.8.1.5.1.2) =====
			//cbp == 0 && (Scoeff || Tcoeff) && (I_BL || ResidualPredictionFlag)
			CurrResidu -> Transform8x8 = BaseResidu -> Transform8x8;
			if (!CurrResidu -> Cbp){
				CurrResidu -> Qp = BaseResidu -> Qp;
			}
		}

		//Bring back base layeer sample into current layer
		GetBaseSample(Y, U, V, BaseY, BaseU, BaseV, PicWidthInPix);


		if ( IS_BL (BaseResidu -> MbType)){
			//In case of two SNR enchancement
			//We have to get the zero quality prediction
			//And to add to this all Scoeff 
			SCoeffResidualAddPic(Nal, CurrResidu, BaseResidu, Pps, PicWidthInPix, Quantif, Y, U, V);
		}else if (Nal -> PicToDecode){
			//We have only one layer prediction, so we can just add the residual to it.
			ComputeResidual(Pps, CurrResidu, PicWidthInPix, Y, U, V, Quantif);
		}else{
			if( CurrResidu -> Cbp){
				// In case of new SNR enhancement based on this one
				RescaleCurrentCoeff(CurrResidu, BaseResidu, Pps, Quantif, Nal -> SpatialScalability);
			}
		}
	}
}
Beispiel #7
0
void filter_mb_B( unsigned char *image, unsigned char *image_Cb, unsigned char *image_Cr, SLICE *slice, PPS *pps, 
				 unsigned char *SliceTable,  short mv_cache_l0[][2], short mv_cache_l1[][2], 
				 short *ref_cache_l0, short *ref_cache_l1, int mb_xy, short PicWidthInMbs, 
				 short poc_l0[], short poc_l1[], const int transform_8x8_size, 
				 const int x, const int y, RESIDU *residu) 
{


    int dir;
	int edge;
	int i;
    int mv_done;
	int qp;
	int mbm_type;
	int mode_mbm;
	int mbn_type;
	int qp_mbn_xy;
	int mask_par1;

	const int mode = residu [mb_xy] . Mode;
	const int mb_type = residu [mb_xy] . MbType;
	const int top_mb_xy = mb_xy - slice -> mb_stride ;
	const int qp_mb_xy = residu [mb_xy] . Qp;
	int mbm_xy =  mb_xy -1;

	char bS[4];

    /* dir : 0 -> vertical edge, 1 -> horizontal edge */
    for( dir = 0; dir < 2; dir++ )
    {
        int start = 0;

		// how often to recheck mv-based bS when iterating between edges
		const int cond = (( mode == 1 && !dir) || (mode == 2 && dir));
		const int mask_edge = (mode == 3 || (mode == 2 && !dir) || (mode == 1 && dir)) ? 3 :cond ? 1 : 0;

		// how often to recheck mv-based bS when iterating along each edge
	    const int  mask_par0 = (mode == 3) * (1 << 3);

	   	 if (mbm_xy >= 0){
	   	 	mbm_type = residu [mbm_xy] . MbType;
			mode_mbm = residu[mbm_xy] . Mode;
		}else{
			mbm_type = 0;
			mode_mbm = 0;
		}


		if ((!dir && (x == 0)) || (dir && y == 0)){
			start = 1;
		}

		if (slice -> disable_deblocking_filter_idc  == 2 && SliceTable[mbm_xy] != SliceTable[mb_xy]){
			start = 1;
		}

        /* Calculate bS */
        for( edge = start; edge < 4; edge++ ) {

			//In case of  8x8 macroblock, only edge 0 and 2 to be done
			if ( transform_8x8_size && ( edge&1))
				continue;

            /* mbn_xy: neighbor_ macroblock */
			if (edge > 0){
				mbn_type = mb_type;
				mbm_xy = mb_xy;
				qp = qp_mbn_xy = qp_mb_xy;
			}else{
				mbn_type = mbm_type;
				qp_mbn_xy = residu[mbm_xy].Qp;
				qp = (qp_mb_xy + qp_mbn_xy + 1) >> 1;
			}

			// if it's an intra macroblock
			if( IS_I(mb_type) ||  IS_I(mbn_type)){
				if ((edge == 0)) {
					bS[0] = bS[1] = bS[2] = bS[3] = 4;
				} else {
					bS[0] = bS[1] = bS[2] = bS[3] = 3;
				}
			}else{
				
				mask_par1 = (IS_B(mbn_type) && (mode_mbm == 3)) * (1 << 3);
				if( edge & mask_edge ) {
					bS[0] = bS[1] = bS[2] = bS[3] = 0;
					mv_done = 1;

				} else if( mask_par0 && (edge || mask_par1)){
					int b_idx = 8 + 4 + edge * (dir ? 8:1);
					int bn_idx = b_idx - (dir ? 8:1);

					bS[0] = bS[1] = bS[2] = bS[3] = GetBoudaryStrenght(mv_cache_l0, mv_cache_l1, ref_cache_l0, ref_cache_l1, 
						poc_l0, poc_l1, b_idx, bn_idx, slice -> slice_type, mb_type, mbm_type);
					mv_done = 1;

				}else{
					mv_done = 0;
				}

				for( i = 0; i < 4; i++ ) {
					int x_pos = dir == 0 ? edge : i;
					int y_pos = dir == 0 ? i    : edge;
					int b_idx = 8 + 4 + x_pos + (y_pos << 3);
					int bn_idx = b_idx - (dir ? 8:1);
					int xn_pos = dir == 0 ? (x_pos + 4 - 1) % 4 : x_pos;
					int yn_pos = dir == 0 ? y_pos: (y_pos + 4 - 1) % 4;
					int BMask = (1 << (x_pos + 4 * y_pos));
					int BnMask = (1 << (xn_pos + 4 * yn_pos));

					if( (residu[mb_xy] . blk4x4 & BMask) || (residu[mbm_xy] . blk4x4 & BnMask)) {
						bS[i] = 2;
					}else if(!mv_done) {
						bS[i] = GetBoudaryStrenght(mv_cache_l0, mv_cache_l1, ref_cache_l0, ref_cache_l1, 
							poc_l0, poc_l1, b_idx, bn_idx, slice -> slice_type, mb_type, mbm_type);
					}
				}
				if(bS[0] + bS[1] + bS[2] + bS[3] == 0)
					continue;
			}

           
			//Application of the loop filter on the horizontal direction 
			if(!dir){
				int qPCb = (qP_tab[qp_mb_xy + pps -> chroma_qp_index_offset] + qP_tab[qp_mbn_xy + pps -> chroma_qp_index_offset] + 1) >> 1;
				int qPCr = (qP_tab[qp_mb_xy + pps -> second_chroma_qp_index_offset] + qP_tab[qp_mbn_xy + pps -> second_chroma_qp_index_offset] + 1) >> 1;	
				HorizontalEdgeFilter(slice -> disable_deblocking_filter_idc, edge, PicWidthInMbs, qp, qPCb, qPCr, bS, pps -> AlphaOffset, pps -> BetaOffset, image, image_Cb, image_Cr);
			}else {
				int qPCb = (qP_tab[qp_mb_xy + pps -> chroma_qp_index_offset] + qP_tab[qp_mbn_xy + pps -> chroma_qp_index_offset] + 1) >> 1;
				int qPCr = (qP_tab[qp_mb_xy + pps -> second_chroma_qp_index_offset] + qP_tab[qp_mbn_xy + pps -> second_chroma_qp_index_offset] + 1) >> 1;
				VerticalEdgeFilter(slice -> disable_deblocking_filter_idc, edge, PicWidthInMbs, qp, qPCb, qPCr, bS, pps -> AlphaOffset, pps -> BetaOffset, image, image_Cb, image_Cr);
			}
		}
Beispiel #8
0
void filter_mb_P( unsigned char *image, unsigned char *image_Cb, unsigned char *image_Cr, const  SLICE *Slice, 
				 unsigned char *SliceTable, short mv_cache_l0[][2], short *ref_cache_l0, int PicWidthInMbs, 
				 const PPS *pps, const int x, const int y, const RESIDU *residu)
{
	int dir, edge, i, mv_done, qp, mbm_type;
	int mbn_type, qp_mbn_xy, edges;
	const int mb_xy = x + y * Slice -> mb_stride;
	const int mb_type = residu[mb_xy] . MbType;
	const int mode = residu[mb_xy] . Mode;
	const int qp_mb_xy = residu[mb_xy] . Qp;
	int mbm_xy = mb_xy - 1; 
	char bS[4];

	/* dir : 0 -> vertical edge, 1 -> horizontal edge */
	for( dir = 0; dir < 2; dir++ ){
		int start = 0;

		// how often to recheck mv-based bS when iterating between edges
		// 8x16 and vertical filter or 16x8 and horizontal filter 
		const int cond = (( mode == 1 && !dir) || (mode == 2 && dir));
		const int mask_edge = ( mode == 3 || (mode == 2 && !dir) || (mode == 1 && dir)) ? 3 :	cond ? 1 : 0;

		// how often to recheck mv-based bS when iterating along each edge
		const int mask_par0 = (mode == 3 || cond) * (1 << (6 - mode));

		if (mbm_xy >= 0){
			mbm_type = residu [mbm_xy] . MbType;
		}
		else{
			mbm_type = 0; 
		}

		edges = ((mb_type == P_Skip) && (mbm_type == P_Skip))? 1: 4;

		if ((!dir && (x == 0)) || (dir && y == 0)){
			start = 1;	
		}

		if (Slice -> disable_deblocking_filter_idc  == 2 && SliceTable[mbm_xy] != SliceTable[mb_xy]){
			start = 1;	
		}

		/* Calculate bS */
		for( edge = start; edge < edges; edge++ ) {
			/* mbn_xy: neighbour_ macroblock */
			if (edge > 0){
				mbn_type = mb_type;
				mbm_xy = mb_xy;
				qp = qp_mbn_xy = qp_mb_xy;
			}else{
				mbn_type = mbm_type;
				qp_mbn_xy = residu[mbm_xy].Qp;
				qp = (qp_mb_xy + qp_mbn_xy + 1) >> 1;
			}

			// if it's an intra macroblock
			if( IS_I(mb_type) ||  IS_I(mbn_type)){

				if ((edge == 0)) {
					bS[0] = bS[1] = bS[2] = bS[3] = 4;
				} 
				else {
					bS[0] = bS[1] = bS[2] = bS[3] = 3;
				}

			}else{
				if( edge & mask_edge ) {
					bS[0] = bS[1] = bS[2] = bS[3] = 0;
					mv_done = 1;
				} else if( mask_par0 && (edge || (mbn_type == P_Skip))){
					int b_idx= 8 + 4 + edge * (dir ? 8:1);
					int bn_idx= b_idx - (dir ? 8:1);
					int v = ref2frm[ref_cache_l0[b_idx] + 2] != ref2frm[ref_cache_l0[bn_idx] + 2] || bSCheckMvShort( mv_cache_l0[b_idx],  mv_cache_l0[bn_idx]);

					bS[0] = bS[1] = bS[2] = bS[3] = v;
					mv_done = 1;
				}else{
					mv_done = 0;
				}

				for( i = 0; i < 4; i++ ) {
					int x_pos = dir == 0 ? edge : i;
					int y_pos = dir == 0 ? i    : edge;
					int b_idx = 8 + 4 + x_pos + (y_pos << 3);
					int bn_idx = b_idx - (dir ? 8:1);
					int xn_pos = dir == 0 ? (x_pos + 4 - 1) % 4 : x_pos;
					int yn_pos = dir == 0 ? y_pos: (y_pos + 4 - 1) % 4;
					int BMask = (1 << (x_pos + 4 * y_pos));
					int BnMask = (1 << (xn_pos + 4 * yn_pos));

					if( (residu[mb_xy] . blk4x4 & BMask) || (residu[mbm_xy] . blk4x4 & BnMask)) {
						bS[i] = 2;
					}else if(!mv_done) {
						bS[i] = 0;
						if ( ref2frm[ref_cache_l0[b_idx] + 2] != ref2frm[ref_cache_l0[bn_idx] + 2] || bSCheckMvShort( mv_cache_l0[b_idx],  mv_cache_l0[bn_idx])){
							bS[i] = 1;
						}
					}
				}

				if(bS[0] + bS[1] + bS[2] + bS[3] == 0)
					continue;
			}

			//Application of the loop filter on the horizontal direction 
			if(!dir){
				int qPCb = (qP_tab[qp_mb_xy + pps -> chroma_qp_index_offset] + qP_tab[qp_mbn_xy + pps -> chroma_qp_index_offset] + 1) >> 1;
				int qPCr = (qP_tab[qp_mb_xy + pps -> second_chroma_qp_index_offset] + qP_tab[qp_mbn_xy + pps -> second_chroma_qp_index_offset] + 1) >> 1;	
				HorizontalEdgeFilter( Slice -> disable_deblocking_filter_idc, edge, PicWidthInMbs, qp, qPCb, qPCr, bS, pps -> AlphaOffset, pps -> BetaOffset, image, image_Cb, image_Cr);
			}else {
				int qPCb = (qP_tab[qp_mb_xy + pps -> chroma_qp_index_offset] + qP_tab[qp_mbn_xy + pps -> chroma_qp_index_offset] + 1) >> 1;
				int qPCr = (qP_tab[qp_mb_xy + pps -> second_chroma_qp_index_offset] + qP_tab[qp_mbn_xy + pps -> second_chroma_qp_index_offset] + 1) >> 1;
				VerticalEdgeFilter(Slice -> disable_deblocking_filter_idc, edge, PicWidthInMbs, qp, qPCb, qPCr, bS, pps -> AlphaOffset, pps -> BetaOffset, image, image_Cb, image_Cr);
			}
		}
Beispiel #9
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 { 
Beispiel #10
0
/**
This function permits to decode the prediction mode or the image reference. 

@param ai_pcData The NAL unit.
@param position The current position in the NAL.
@param block Contains all parameters of the current macroblock.
@param ai_pstSlice The slice structure.
@param ao_pstIntra_pred_mode Contains the prediction mode for the current macroblock.

*/
int mb_pred_svc( const unsigned char *ai_pcData, int *position, const SLICE *ai_pstSlice, 
				DATA *aio_pstMacroblock, RESIDU *Current_residu, short *intra4x4_pred_mode_cache)
{



	int mbPartIdx ;



	//Recovery of the prediction mode
	if(IS_I(aio_pstMacroblock -> MbPartPredMode [0])){
		if(mb_pred_I(ai_pcData, position, Current_residu, Current_residu -> Intra16x16DCLevel, intra4x4_pred_mode_cache)){
			return 1;
		}
	}
	else if ( aio_pstMacroblock -> MbPartPredMode [0] != B_direct ) {
		if( ai_pstSlice -> AdaptiveMotionPredictionFlag && Current_residu -> InCropWindow ) {
			if(ReadMotionPredSVC(ai_pcData, position, aio_pstMacroblock -> MotionPredL0, aio_pstMacroblock, Pred_L1)) return 1;
			if(ReadMotionPredSVC(ai_pcData, position, aio_pstMacroblock -> MotionPredL1, aio_pstMacroblock, Pred_L0)) return 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 < aio_pstMacroblock -> NumMbPart ; mbPartIdx++ ) {
				if ( (aio_pstMacroblock -> MbPartPredMode [mbPartIdx] != Pred_L1 ) && (!aio_pstMacroblock -> MotionPredL0[mbPartIdx])) {
					aio_pstMacroblock -> RefIdxL0 [mbPartIdx] = read_te(ai_pcData, position, ai_pstSlice -> num_RefIdxL0_active_minus1);
				}
			}
		}

#ifdef ERROR_DETECTION
		//Error detection
		if(ErrorsCheckRefLx(aio_pstMacroblock -> RefIdxL0, ai_pstSlice -> num_RefIdxL0_active_minus1)){
			return 1;
		}
#endif

		//Recovery of of the image reference for the frame 
		if ( ai_pstSlice -> num_RefIdxL1_active_minus1 != 0 ){
			for ( mbPartIdx = 0 ; mbPartIdx < aio_pstMacroblock -> NumMbPart ; mbPartIdx++ )  {
				if ((aio_pstMacroblock -> MbPartPredMode [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(ErrorsCheckRefLx(aio_pstMacroblock -> RefIdxL1, ai_pstSlice -> num_RefIdxL1_active_minus1)){
			return 1;
		}
#endif

		//Recovery of of the motion vector for the frame P
		for ( mbPartIdx = 0 ; mbPartIdx < aio_pstMacroblock -> NumMbPart ; mbPartIdx++ ) {
			/* Pour eviter de traiter les Images B*/
			if ( aio_pstMacroblock -> MbPartPredMode [mbPartIdx] != Pred_L1 )	{
				aio_pstMacroblock -> MvdL0 [mbPartIdx << 2][0] = read_se(ai_pcData, position);
				aio_pstMacroblock -> MvdL0 [mbPartIdx << 2][1] = read_se(ai_pcData, position);
			}
		}

		//Recovery of of the motion vector for the frame B
		for ( mbPartIdx = 0 ; mbPartIdx < aio_pstMacroblock -> NumMbPart ; mbPartIdx++ ) {
			if ( aio_pstMacroblock -> MbPartPredMode [mbPartIdx] != Pred_L0 ) 	{
				aio_pstMacroblock -> MvdL1 [ mbPartIdx << 2][0] = read_se(ai_pcData, position);
				aio_pstMacroblock -> MvdL1 [ mbPartIdx << 2][1] = read_se(ai_pcData, position);
			}
		}
	}else{
		Current_residu -> Mode = 4;
		for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++){
			Current_residu -> SubMbType [mbPartIdx] = 3;
		}
	}
	return 0;
}
/**
This function permits to update the neighbourhood of the current macroblock.
This function stock in table the motion vector for the macroblock which belong to the neighbourhood of the current macroblock. 

@param slice The aio_pstSlice strucutre.
@param b_stride The width of sample in the ai_tiMv table.
@param b8_stride The width of sample in the ai_tiRef table.
@param ref_cache_l0 A cache table where the reference is stocked for each 4x4 block of the current macroblock.
@param ref_cache_l1 A cache table where the reference is stocked for each 4x4 block of the current macroblock.
@param mv_cache_l0 A cache table where the motion vector are stocked for each 4x4 block of the current macroblock.
@param mv_cache_l1 A cache table where the motion vector are stocked for each 4x4 block of the current macroblock.
@param slice_table A table which resume in which aio_pstSlice each macroblock belongs to.
@param Tab_Block Contains all parameters of each macroblock of the current picture. 
@param mv_l0 A table where each motion vector calculated is stocked for each macroblock decoded.
@param mv_l1 A table where each motion vector calculated is stocked for each macroblock decoded.
@param ref_l0 A table where each reference mode calculated is stocked for each macroblock decoded.
@param ref_l1 A table where each reference mode calculated is stocked for each macroblock decoded.
@param iCurrMbAddr Address of the current macroblock.
@param ai_iMb_x The x position of the macroblock in the picture.
*/
void fill_caches_motion_vector_B(SLICE *slice, int b_stride, int b8_stride, short ref_cache_l0 [], short ref_cache_l1 [], 
								 short mv_cache_l0[][2], short  mv_cache_l1[][2], unsigned char slice_table [], RESIDU *CurrResidu, 
								 short mv_l0[], short mv_l1[], short ref_l0[], short ref_l1[], int iCurrMbAddr, int ai_iX)

{

	int    top_type = 0 ;
    int    topleft_type;
    int    topright_type;
    int    left_type;

	
	//Updating the adress of the macroblock which belong to the neighbourhood.
    int top_xy = iCurrMbAddr - slice -> mb_stride ;
    int topleft_xy = top_xy - 1 ;
	int topright_xy = top_xy >= 0? top_xy + 1: -1 ;
    int left_xy = iCurrMbAddr - 1 ;


	//Updating their availability according to the slice.
	if ( top_xy >= 0 )    {
		top_type = slice_table [top_xy] == slice -> slice_num ? CurrResidu [- slice -> mb_stride] . MbType : 0 ;

		if ( topleft_xy >= 0 && ai_iX != 0 && slice_table [topleft_xy] == slice -> slice_num){
				topleft_type = CurrResidu [- slice -> mb_stride - 1] . MbType;
		}else{
			topleft_type = 0;
			ref_cache_l0[12 - 1 - 8] = ref_cache_l1[12 - 1 - 8] = PART_NOT_AVAILABLE;
		}

		
		if ( topright_xy >= 0 && (ai_iX != slice -> mb_stride - 1) && slice_table [topright_xy] == slice -> slice_num){
				topright_type = CurrResidu [- slice -> mb_stride + 1] . MbType;
		}else{
			topright_type = 0;
			ref_cache_l0[12 + 4 - 8] = ref_cache_l1[12 + 4 - 8] = PART_NOT_AVAILABLE;
		}

	}else{
		top_type = 0;
		topleft_type = 0;
		topright_type = 0;

		//Update top right and top left reference
		 ref_cache_l0[12 - 1 - 8] = ref_cache_l1[12 - 1 - 8] = PART_NOT_AVAILABLE;
		 ref_cache_l0[12 + 4 - 8] = ref_cache_l1[12 + 4 - 8] = PART_NOT_AVAILABLE;
	}


   if ( left_xy >= 0 && ai_iX != 0 && slice_table [left_xy] == slice -> slice_num){
			left_type = CurrResidu [-1] . MbType;
	}else{
		left_type = 0;

		//Update left reference
		FillRefCacheLeftPosition(ref_cache_l0, PART_NOT_AVAILABLE, PART_NOT_AVAILABLE);
		FillRefCacheLeftPosition(ref_cache_l1, PART_NOT_AVAILABLE, PART_NOT_AVAILABLE);
	}


            
	//In case of a skipped or a P macroblock
	if( top_type && !IS_I(top_type)){
		FillMvCacheTopPosition(mv_cache_l0, &mv_l0[-b_stride]);
		FillMvCacheTopPosition(mv_cache_l1, &mv_l1[-b_stride]);
		FillRefCacheTopPosition(ref_cache_l0, ref_l0 [- b8_stride], ref_l0[1 - b8_stride]);
		FillRefCacheTopPosition(ref_cache_l1, ref_l1 [- b8_stride], ref_l1[1 - b8_stride]);

	}else if (!top_type){
		FillRefCacheTopPosition(ref_cache_l0, PART_NOT_AVAILABLE, PART_NOT_AVAILABLE);
		FillRefCacheTopPosition(ref_cache_l1, PART_NOT_AVAILABLE, PART_NOT_AVAILABLE); ;
	}

	//In case of a skipped or a P macroblock
	if(left_type && !IS_I(left_type)){
		FillMvCacheLeftPosition(mv_cache_l0, &mv_l0[-2], b_stride);
		FillMvCacheLeftPosition(mv_cache_l1, &mv_l1[-2], b_stride);
		FillRefCacheLeftPosition (ref_cache_l0, ref_l0[-1], ref_l0[-1 + b8_stride]);
		FillRefCacheLeftPosition (ref_cache_l1, ref_l1[-1], ref_l1[-1 + b8_stride]);
	}


	//In case of a skipped or a P macroblock
	if(topleft_type && !IS_I(topleft_type)){
		mv_cache_l0 [12 - 1 - 8][0] = mv_l0[-2 - b_stride];
		mv_cache_l0 [12 - 1 - 8][1] = mv_l0[-1 - b_stride];
		mv_cache_l1 [12 - 1 - 8][0] = mv_l1[-2 - b_stride];
		mv_cache_l1 [12 - 1 - 8][1] = mv_l1[-1 - b_stride];
		ref_cache_l0[12 - 1 - 8] =  ref_l0[-1 - b8_stride];
		ref_cache_l1[12 - 1 - 8] =  ref_l1[-1 - b8_stride];
	}

	//In case of a skipped or a P macroblock
	if(topright_type && !IS_I(topright_type)){
		mv_cache_l0 [12 + 4 - 8][0] = mv_l0[8 - b_stride];
		mv_cache_l0 [12 + 4 - 8][1] = mv_l0[9 - b_stride];
		mv_cache_l1 [12 + 4 - 8][0] = mv_l1[8 - b_stride];
		mv_cache_l1 [12 + 4 - 8][1] = mv_l1[9 - b_stride];
		ref_cache_l0[12 + 4 - 8]=  ref_l0[2 - b8_stride];
		ref_cache_l1[12 + 4 - 8]=  ref_l1[2 - b8_stride];

	}

	ref_cache_l0[15+1] = ref_cache_l0[23+1] = ref_cache_l0[31+1] = ref_cache_l0[14] = ref_cache_l0[30] = 
	ref_cache_l1[15+1] = ref_cache_l1[23+1] = ref_cache_l1[31+1] = ref_cache_l1[14] = ref_cache_l1[30] = PART_NOT_AVAILABLE;
}
Beispiel #12
0
/**
This function permits to update the neighbourhood of the current macroblock in a I slice.
This function stock in table the data calculated for the macroblock which belong to the neighbourhood of the current macroblock.

@param aio_pstSlice The aio_pstSlice strucutre.
@param aio_tstBlock Contains all parameters of each macroblock of the current picture.
@param ai_iEntropy_coding_mode_flag The type of the VLC coding, CABAC or CAVLC.
@param aio_tiNon_zero_count_cache A cache table where coeff_token is stocked for each 4x4 block of the current macroblock.
@param ai_tstNon_zero_count A table where each coeff_token calculated is stocked for each macroblock decoded.
@param aio_pstSlice_table A table which resume in which aio_pstSlice each macroblock belongs to.
@param intra_pred_mod_cache Contains the prediction mode for each block 4x4 of the current macroblock.
@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 constrained_intra_pred_flag Enables to determine if the intra decoding process is contrained.
*/
void fill_caches_I (const SLICE *aio_pstSlice, const RESIDU CurrResidu[], const int ai_iEntropy_coding_mode_flag, 
					unsigned char aio_tiNon_zero_count_cache [ RESTRICT ], const DATA *CurrBlock, 
					const unsigned char aio_pstSlice_table [ ], short aio_tiIntra4x4_pred_mode_cache[], 
					const short ai_iMb_x , const short ai_iMb_y, const int ai_iConstrained_intra_pred)
{
    int		top_type;
    int     left_type;
    int     top_xy;
	int     left_xy;
    const int iMb_xy = ai_iMb_x + ai_iMb_y * (short)(aio_pstSlice -> mb_stride);
	const int ai_iMb_type_name = CurrResidu -> MbType;
	const int val_init = ai_iEntropy_coding_mode_flag && !(IS_I(ai_iMb_type_name)) ? 0 : 64 ;
	init_non_zero_count_cache(aio_tiNon_zero_count_cache, val_init);

	if ( ai_iMb_y > 0 ) {
		top_xy = iMb_xy - aio_pstSlice -> mb_stride;
		top_type = (aio_pstSlice_table [top_xy] == aio_pstSlice -> slice_num) ? CurrResidu [-  aio_pstSlice -> mb_stride] . MbType : 0 ;
	}else {
		top_type = 0;
	}

	if ( iMb_xy > 0 && ai_iMb_x != 0 )  {
		left_xy = iMb_xy - 1 ;
		left_type = aio_pstSlice_table [left_xy] == aio_pstSlice -> slice_num ? CurrResidu [-1] . MbType : 0 ;
	}else {
		left_type = 0;
	}

	FillNonZeroCount(CurrResidu, CurrBlock, aio_pstSlice -> mb_stride, top_type, left_type, aio_tiNon_zero_count_cache);

	//Updating the aio_tiIntra4x4_pred_mode_cache table from the current macroblock.
	if(IS_NxN(top_type)){
		aio_tiIntra4x4_pred_mode_cache[4] = CurrResidu [- aio_pstSlice -> mb_stride] . Intra16x16DCLevel[10];
		aio_tiIntra4x4_pred_mode_cache[5] = CurrResidu [- aio_pstSlice -> mb_stride] . Intra16x16DCLevel[11];
		aio_tiIntra4x4_pred_mode_cache[6] = CurrResidu [- aio_pstSlice -> mb_stride] . Intra16x16DCLevel[14];
		aio_tiIntra4x4_pred_mode_cache[7] = CurrResidu [- aio_pstSlice -> mb_stride] . Intra16x16DCLevel[15];
    }
    else{
		if(top_type  && (!ai_iConstrained_intra_pred || IS_I(top_type))){
            aio_tiIntra4x4_pred_mode_cache[4] = aio_tiIntra4x4_pred_mode_cache[5] =
			aio_tiIntra4x4_pred_mode_cache[6] = aio_tiIntra4x4_pred_mode_cache[7] = 2;
		}else{
			aio_tiIntra4x4_pred_mode_cache[4] = aio_tiIntra4x4_pred_mode_cache[5] =
			aio_tiIntra4x4_pred_mode_cache[6] = aio_tiIntra4x4_pred_mode_cache[7] = -1;
		}
    }

    if(IS_NxN(left_type))  {
        aio_tiIntra4x4_pred_mode_cache[3 + 8] = CurrResidu [- 1] . Intra16x16DCLevel[5];
        aio_tiIntra4x4_pred_mode_cache[3 + 16] = CurrResidu [- 1] . Intra16x16DCLevel[7];
        aio_tiIntra4x4_pred_mode_cache[3 + 24] = CurrResidu [- 1] . Intra16x16DCLevel[13];
        aio_tiIntra4x4_pred_mode_cache[3 + 32] = CurrResidu [- 1] . Intra16x16DCLevel[15];
    }
    else   {
		if(left_type && (!ai_iConstrained_intra_pred || IS_I(left_type))){
            aio_tiIntra4x4_pred_mode_cache[3 + 8] = aio_tiIntra4x4_pred_mode_cache[3 + 24] =
			aio_tiIntra4x4_pred_mode_cache[3 + 16]= aio_tiIntra4x4_pred_mode_cache[3 + 32] = 2;

		}else{
			aio_tiIntra4x4_pred_mode_cache[3 + 8] = aio_tiIntra4x4_pred_mode_cache[3 + 24] =
			aio_tiIntra4x4_pred_mode_cache[3 + 16]= aio_tiIntra4x4_pred_mode_cache[3 + 32] = -1;
		}
    }
}