www.pudn.com > avs-m3.rar > loopfilter.c


/*! 
 ************************************************************************************* 
 * \file loopfiter.c 
 * 
 * \brief 
 *    deblocking the Reconstructed frame 
 * 
 * \date: zhan ma  
 *      
 * \author     
 *     
 ************************************************************************************* 
 */ 
 
#include  
#include "global.h" 
 
 
//!< Global Indexing Table 
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 
} ; 
 
static void DeblockMb(byte **imgY, byte ***imgUV, int mb_y, int mb_x); 
static void EdgeLoop(byte* SrcPtr, int QP, int AlphaCIOffset, int dir, int width, int yuv); 
static void EdgeLoopweak(byte* SrcPtr, int QP, int AlphaCIOffset, int CPOffset, int dir,  int width, int yuv); 
/*!  
 ************************************************************************************* 
 * \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,QPC; 
  byte          *SrcY, *SrcU, *SrcV ; 
  Macroblock    *MbQ,*MbP; 
  int           mb_width          = pgImage->width/16; 
  int           current_mb_nr     = mb_width*mb_y + mb_x; 
    
  int           SliceLFDisable        = pgImage->SliceLFDisbaleFlag[mb_data[current_mb_nr].slice_nr] ;   /* slice edge filter indicator*/ 
  int           alpha_ci_offset       = pgImage->loop_filter_alpha_ci_offset    ; 
	int           cp_offset             = pgImage->loop_filter_cp_offset          ; 
	int           loopfilter_qp_offset  = pgImage->loop_filter_qp_offset          ; 
  int           threshold_qp          = 40 + loopfilter_qp_offset               ;   /* 40 is defined in FCD 7.2.6 */ 
   
 // fprintf(stdout,"%2d",pgImage->disable_loop_filter_slice_flag); 
  //	WJP FOR SLICE_DEBLOCK 050321 
 
  int mb_available_up   = (mb_y == 0) ? 0 : ((mb_data[current_mb_nr].slice_nr == mb_data[current_mb_nr-mb_width].slice_nr) || (!SliceLFDisable)); 
  int mb_available_left = (mb_x == 0) ? 0 : ((mb_data[current_mb_nr].slice_nr == mb_data[current_mb_nr-1].slice_nr) || (!SliceLFDisable)); 
 
  //fprintf(stdout,"%2d",pgImage->loop_filter_disable_flag); 
  //fprintf(stdout,"%2d",pgImage->SliceLFDisbaleFlag[mb_data[current_mb_nr].slice_nr]); 
  if (pgImage->loop_filter_disable_flag) 
  { 
    return; 
  } 
 
  //if (!SliceLFDisable) 
  //{ 
  //  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] ;  
  
 
  if (MbQ->mb_type!= SKIP_MB || (MbQ->qp>=threshold_qp)) 
  { 
    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 ), QP, alpha_ci_offset, dir, pgImage->width, 0) ; 
            if(!(edge & 1)) 
            { 
              QPC  = ( MbP->qp + MbQ->qp+1) >> 1 ; 
              EdgeLoop( SrcU +  (edge<<1) * ((dir)? pgImage->width>>1:1 ), QPC, alpha_ci_offset, dir, pgImage->width>>1, 1 ) ;  
              EdgeLoop( SrcV +  (edge<<1) * ((dir)? pgImage->width>>1:1 ), QPC, alpha_ci_offset, dir, pgImage->width>>1, 1 ) ;  
            } 
          } 
          else if (!(MbQ->qp< threshold_qp && MbQ->mb_type==0))//WJP FOR DEBLOCK 
          { 
            EdgeLoopweak( SrcY + (edge<<2)* ((dir)? pgImage->width:1 ), QP, alpha_ci_offset, cp_offset, dir, pgImage->width, 0) ; 
            if(!(edge & 1)) 
            { 
              QPC  = ( MbP->qp + MbQ->qp+1) >> 1 ; 
              EdgeLoopweak( SrcU +  (edge<<1) * ((dir)? pgImage->width>>1:1 ), QPC, alpha_ci_offset, cp_offset, dir, pgImage->width>>1, 1 ) ;  
              EdgeLoopweak( SrcV +  (edge<<1) * ((dir)? pgImage->width>>1:1 ), QPC, alpha_ci_offset, cp_offset, dir, pgImage->width>>1, 1 ) ;  
            } 
          } 
        } 
      } 
    } 
  } 
} 
 
/*!  
 ************************************************************************************* 
 * \brief : deblock edge 
 * 
 * \return: deblocked edge data  
 ************************************************************************************* 
 */ 
void EdgeLoop(byte* SrcPtr, int QP, int AlphaCIOffset, int dir, int width, int yuv) 
{ 
  int      pel,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+AlphaCIOffset)];//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, L1 + 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, R1 - 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,int QP, int AlphaCIOffset, int CPOffset, int dir, int width, int yuv) 
{ 
  int      pel, 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 ; 
  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+AlphaCIOffset)];//WJP FOR DEBLOCK 
	 
  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)+CPOffset<0)   //cp table 
      	C0  = 0; 
      else 
      	C0  = (CLIP_TAB[ QP ]>>1)+CPOffset; 
       
      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, L1 + 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, R1 - dif1) ;    //r1 
      } 
      else  
      { 
      	SrcPtr[0]     = IClip(0, 255, R0 - dif1) ;    //r0 
      } 
    }  
		 
    SrcPtr += PtrInc ;      // Increment to next set of pixel 
    pel    += yuv ; 
  } 
}