www.pudn.com > wm2.5.zip > loopfilter.c


/*! 
 ************************************************************************************* 
 * \file loopfiter.c 
 * 
 * \brief 
 *    deblocking the Reconstructed frame 
 * 
 * \date: updating  
 *      
 * \author     
 *     
 ************************************************************************************* 
 */ 
#include  
#include  
#include "global.h" 
#include "defines.h" 
#include "loopfilter.h" 
 
byte ALPHA_TABLE[64] =  
{ 
  0, 0, 0, 0, 0, 0, 1, 1, 
  1, 1, 1, 2, 2, 2, 3, 3, 
  4, 4, 5, 5, 6, 7, 8, 9, 
  10,11,12,13,15,16,18,20, 
  22,24,26,28,30,33,33,35, 
  35,36,37,37,39,39,42,44, 
  46,48,50,52,53,54,55,56, 
  57,58,59,60,61,62,63,64  
}; 
 
int CLIP_TAB[64] =  
{ 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 1, 1,  
  1, 1, 1, 1, 1, 2, 2, 2, 
  2, 2, 2, 3, 4, 4, 4, 4, 
  5, 5, 5, 5, 5, 6, 6, 6, 
  6, 7, 7, 8, 9, 9, 10,11, 
  12,13,14,15,16,16,16,16 
} ; 
 
/*!  
 ************************************************************************************* 
 * \brief : Deblocking  Rec-frame 
 * \param : \imgY[pixel_y][pixel_x]      Image Luma Component 
 *          \imgUV[UV][pixel_y][pixel_x] Image Chroma Componet 
 * \return: deblocked frame 
 ************************************************************************************* 
 */ 
void DeblockFrame(byte **imgY , byte ***imgUV) 
{ 
	int  mb_x, mb_y; 
	for( mb_y=0 ; mb_y<(pgImage->height>>4) ; mb_y++ ) 
    for( mb_x=0 ; mb_x<(pgImage->width>>4) ; mb_x++ ) 
    { 
		  DeblockMb(imgY , imgUV, mb_y , mb_x); 
    } 
 
} 
 
/*!  
 ************************************************************************************* 
 * \brief : Deblocking Rec-MB in Rec-frame 
 * \param : \imgY[pixel_y][pixel_x]      Image Luma Component 
 *          \imgUV[UV][pixel_y][pixel_x] Image Chroma Componet 
 *          \mb_y,mb_x                   MB coordinate in picture 
 * \return: deblocked MB  
 ************************************************************************************* 
 */ 
void DeblockMb(byte **imgY , byte ***imgUV , int mb_y , int mb_x) 
{ 
	int           EdgeCondition; 
	int           dir,edge,QP; 
	byte          Strength[4], *SrcY, *SrcU, *SrcV ; 
	Macroblock    *MbQ,*MbP; 
	int           QPC; 
	int           threshold; 
 
	//	WJP FOR SLICE_DEBLOCK 050321 
	int mb_width          = pgImage->width/16; 
	int current_mb_nr     = mb_width*mb_y + mb_x; 
  int mb_available_up   = (mb_y == 0) ? 0 :  
							(mb_data[current_mb_nr].slice_nr == mb_data[current_mb_nr-mb_width].slice_nr); 
  int mb_available_left = (mb_x == 0) ? 0 :  
							(mb_data[current_mb_nr].slice_nr == mb_data[current_mb_nr-1].slice_nr); 
 
	if(!pgImage->disable_loop_filter_slice_flag) 
	{ 
		mb_available_up = 1; 
		mb_available_left = 1; 
	} 
	//	WJP END 050321 
	 
	SrcY = imgY    [mb_y<<4] + (mb_x<<4) ;                                                      // pointers to source 
	SrcU = imgUV[0][mb_y<<3] + (mb_x<<3) ; 
	SrcV = imgUV[1][mb_y<<3] + (mb_x<<3) ; 
 
	MbQ  = &mb_data[mb_y*(pgImage->width>>4) + mb_x] ;  
	threshold = 40 + loopfilter_qp_offset; 
	if (MbQ->mb_type!=0 || (MbQ->qp>=threshold)) 
	{ 
	  for( dir=0 ; dir<2 ; dir++ ) 
		{ 
		  EdgeCondition = (dir && mb_available_up) || (!dir && mb_available_left);//WJP FOR SLICE_DEBLOCK 050321 
		  for( edge=0 ; edge<4 ; edge++ ) 
			{ 
			  if( edge || EdgeCondition ) 
				{ 
				  MbP       = (edge)? MbQ : ((dir)? (MbQ - (pgImage->width>>4))  : (MbQ-1) ) ;  
				  QP  = ( MbP->qp + MbQ->qp+1) >> 1 ; 
				   
          if (MbQ->mb_type==I4MB) //JX 05-4-1 
					{ 
					  EdgeLoop( SrcY + (edge<<2)* ((dir)? pgImage->width:1 ), Strength, QP, MbQ->lf_alpha_c0_offset, MbQ->lf_beta_offset, dir, pgImage->width, 0) ; 
						if(!(edge & 1)) 
						{ 
							QPC  = ( MbP->qp + MbQ->qp+1) >> 1 ; 
							EdgeLoop( SrcU +  (edge<<1) * ((dir)? pgImage->width>>1:1 ), Strength, QPC, MbQ->lf_alpha_c0_offset, MbQ->lf_beta_offset, dir, pgImage->width>>1, 1 ) ;  
							EdgeLoop( SrcV +  (edge<<1) * ((dir)? pgImage->width>>1:1 ), Strength, QPC, MbQ->lf_alpha_c0_offset, MbQ->lf_beta_offset, dir, pgImage->width>>1, 1 ) ;  
						} 
					} 
				  else if (!(MbQ->qp< threshold && MbQ->mb_type==0))//WJP FOR DEBLOCK 
					{ 
						EdgeLoopweak( SrcY + (edge<<2)* ((dir)? pgImage->width:1 ), Strength, QP, MbQ->lf_alpha_c0_offset, MbQ->lf_beta_offset, dir, pgImage->width, 0) ; 
					  if(!(edge & 1)) 
						{ 
						  QPC  = ( MbP->qp + MbQ->qp+1) >> 1 ; 
						  EdgeLoopweak( SrcU +  (edge<<1) * ((dir)? pgImage->width>>1:1 ), Strength, QPC, MbQ->lf_alpha_c0_offset, MbQ->lf_beta_offset, dir, pgImage->width>>1, 1 ) ;  
						  EdgeLoopweak( SrcV +  (edge<<1) * ((dir)? pgImage->width>>1:1 ), Strength, QPC, MbQ->lf_alpha_c0_offset, MbQ->lf_beta_offset, dir, pgImage->width>>1, 1 ) ;  
						} 
					} 
				} 
			} 
		} 
	} 
} 
 
/*!  
 ************************************************************************************* 
 * \brief : deblock edge 
 * 
 * \return: deblocked edge data  
 ************************************************************************************* 
 */ 
void EdgeLoop(byte* SrcPtr, 
              byte Strength[4],  
              int QP,  
              int AlphaC0Offset,  
              int BetaOffset,  
              int dir, 
              int width, 
              int yuv) 
{ 
  int      pel, ap = 0, aq = 0, PtrInc ; 
  int      inc, inc2, inc3, inc4 ; 
  int      Delta, dif, AbsDelta ; 
  int      L2 = 0, L1, L0, L3, R0, R1, R2 = 0, R3; 
  int      dif1; 
  int      Alpha = 0, Beta = 0 ; 
  byte*    ClipTab = NULL, C0;    
   
  PtrInc  = dir?      1 : width ; 
  inc     = dir?  width : 1 ;                     // vertical filtering increment to next pixel is 1 else width 
  inc2    = inc<<1 ;     
  inc3    = inc + inc2 ;     
  inc4    = inc<<2 ; 
  
  Alpha=ALPHA_TABLE[IClip(0,63,QP+alpha_ci_offset)];//WJP FOR DEBLOCK 
  //Beta=BETA_TABLE[QP];   
       
  for( pel=0 ; pel<16 ; pel++ ) 
  { 
		L0  = SrcPtr[-inc] ; 
		R0  = SrcPtr[0] ; 
		L1  = SrcPtr[-inc2] ; 
		R1  = SrcPtr[ inc] ; 
		L2  = SrcPtr[-inc3] ; 
		R2  = SrcPtr[ inc2] ; 
		L3  = SrcPtr[-inc4] ; 
		R3  = SrcPtr[ inc3] ; 
		AbsDelta  = abs( Delta = R0 - L0 )  ; 
       
    if( AbsDelta < Alpha ) 
    { 
		C0  = CLIP_TAB[ QP ] ; 
		dif = IClip( -C0, C0, ( (R0-L0)*4 + (L1 - R1) + 4) >> 3 ); 
		dif1=dif>>1; 
			 
		//left 
		// LL=abs(L1-L0); 
		if (L1==L0)//WJP FOR DEBLOCK 
		{ 
			SrcPtr[-inc]  = IClip(0, 255, L0 + dif) ;    //l0 
			SrcPtr[-inc2] = IClip(0, 255, L0 + dif1) ;    //l1 
		} 
		else  
		{ 
			SrcPtr[-inc]  = IClip(0, 255, L0 + dif1) ;    //l0 
		} 
		 
		//right 
		//RR=abs(R1-R0); 
		if (R1==R0 )//WJP FOR DEBLOCK 
		{ 
			SrcPtr[0]     = IClip(0, 255, R0 - dif) ;    //r0 
			SrcPtr[ inc]  = IClip(0, 255, R0 - dif1) ;    //r1 
		} 
		else  
		{ 
			SrcPtr[0]     = IClip(0, 255, R0 - dif1) ;    //r0 
		} 
    }  
 
    SrcPtr += PtrInc ;      // Increment to next set of pixel 
    pel    += yuv ; 
  } 
} 
 
/*!  
 ************************************************************************************* 
 * \brief : deblock edge 
 * 
 * \return: deblocked edge data  
 ************************************************************************************* 
 */ 
void EdgeLoopweak(byte* SrcPtr, 
                  byte Strength[4],  
                  int QP,  
                  int AlphaC0Offset,  
                  int BetaOffset,  
                  int dir, 
                  int width, 
                  int yuv) 
{ 
  int      pel, ap = 0, aq = 0, PtrInc; 
  int      inc, inc2, inc3, inc4 ; 
  int      Delta, dif, AbsDelta ; 
  int      L2 = 0, L1, L0, L3, R0, R1, R2 = 0, R3 ; 
	int      LL,RR;//yf 
	int      dif1; 
  int      Alpha = 0, Beta = 0 ; 
  byte*    ClipTab = NULL, C0;    
   
  PtrInc  = dir?      1 : width ; 
  inc     = dir?  width : 1 ;                     // vertical filtering increment to next pixel is 1 else width 
  inc2    = inc<<1 ;     
  inc3    = inc + inc2 ;     
  inc4    = inc<<2 ; 
	 
   
  Alpha=ALPHA_TABLE[IClip(0,63,QP+alpha_ci_offset)];//WJP FOR DEBLOCK 
  //Beta=BETA_TABLE[QP];   
	 
  for( pel=0 ; pel<16 ; pel++ ) 
  { 
		L0  = SrcPtr[-inc] ; 
		R0  = SrcPtr[0] ; 
		L1  = SrcPtr[-inc2] ; 
		R1  = SrcPtr[ inc] ; 
		L2  = SrcPtr[-inc3] ; 
		R2  = SrcPtr[ inc2] ; 
		L3  = SrcPtr[-inc4] ; 
		R3  = SrcPtr[ inc3] ; 
		AbsDelta  = abs( Delta = R0 - L0 )  ; 
		LL=abs(L1-L0); 
		RR=abs(R1-R0); 
		 
    if( AbsDelta < Alpha ) 
    { 
		//C0  = (CLIP_TAB[ QP ]>>1)+cp_offset ; 
		if ((CLIP_TAB[ QP ]>>1)+cp_offset<0) 
			C0=0; 
		else 
			C0  = (CLIP_TAB[ QP ]>>1)+cp_offset; 
	 
		dif = IClip( -C0, C0, ( (R0-L0)*4 + (L1 - R1) + 4) >> 3 ); 
		dif1=dif>>1; 
		 
		//left 
		 
		if (L1==L0 && AbsDelta < (Alpha>>2)+2)//WJP FOR DEBLOCK 
		{ 
			SrcPtr[-inc]  = IClip(0, 255, L0 + dif) ;    //l0 
			SrcPtr[-inc2] = IClip(0, 255, L0 + dif1) ;    //l1 
		} 
		else  
		{ 
			SrcPtr[-inc]  = IClip(0, 255, L0 + dif1) ;    //l0 
		} 
		 
		//right 
		 
		if (R1==R0 && AbsDelta < (Alpha>>2)+2 )//WJP FOR DEBLOCK 
		{ 
			SrcPtr[0]     = IClip(0, 255, R0 - dif) ;    //r0 
			SrcPtr[ inc]  = IClip(0, 255, R0 - dif1) ;    //r1 
		} 
		else  
		{ 
			SrcPtr[0]     = IClip(0, 255, R0 - dif1) ;    //r0 
		} 
    }  
		 
    SrcPtr += PtrInc ;      // Increment to next set of pixel 
    pel    += yuv ; 
  } 
}