⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loopfilter.c

📁 AVS视频编解码器 能实现视频图像的高效率压缩 能在VC上高速运行
💻 C
字号:
/*
***********************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2003, Advanced Audio Video Coding Standard, Part II
*
* DISCLAIMER OF WARRANTY
*
* These software programs are available to the users without any
* license fee or royalty on an "as is" basis. The AVS disclaims
* any and all warranties, whether express, implied, or statutory,
* including any implied warranties of merchantability or of fitness
* for a particular purpose. In no event shall the contributors or 
* the AVS be liable for any incidental, punitive, or consequential
* damages of any kind whatsoever arising from the use of this program.
*
* This disclaimer of warranty extends to the user of this program
* and user's customers, employees, agents, transferees, successors,
* and assigns.
*
* The AVS does not represent or warrant that the program furnished
* hereunder are free of infringement of any third-party patents.
* Commercial implementations of AVS, including shareware, may be
* subject to royalty fees to patent holders. Information regarding
* the AVS patent policy is available from the AVS Web site at
* http://www.avs.org.cn
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY.
************************************************************************
*/

/*
*************************************************************************************
* File name: 
* Function: 
*
*************************************************************************************
*/
#include <stdlib.h>
#include <string.h>
#include "global.h"
extern const byte QP_SCALE_CR[64] ;

/*********************************************************************************************************/

#define  IClip( Min, Max, Val) (((Val)<(Min))? (Min):(((Val)>(Max))? (Max):(Val)))

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 
};
byte  BETA_TABLE[64]  = {
		 0, 0, 0, 0, 0, 0, 1, 1,
     1, 1, 1, 1, 1, 2, 2, 2,
     2, 2, 3, 3, 3, 3, 4, 4,
     4, 4, 5, 5, 5, 5, 6, 6,
     6, 7, 7, 7, 8, 8, 8, 9,
     9,10,10,11,11,12,13,14,
    15,16,17,18,19,20,21,22,
    23,23,24,24,25,25,26,27
};
byte CLIP_TAB[64] = {
  0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0,
  1, 1, 1, 1, 1, 1, 1, 1, 
  1, 1, 1, 1, 1, 1, 2, 2,
  2, 2, 2, 2, 2, 2, 3, 3,
  3, 3, 3, 3, 3, 4, 4, 4,
  5, 5, 5, 6, 6, 6, 7, 7,
  7, 7, 8, 8, 8, 9, 9, 9
} ;


void GetStrength(byte Strength[2],Macroblock* MbP,Macroblock* MbQ,int dir,int edge,int block_y,int block_x);
void EdgeLoop(byte* SrcPtr,byte Strength[2],int QP,  int dir,int width,int Chro);
void DeblockMb(ImageParameters *img, byte **imgY, byte ***imgUV, int blk_y, int blk_x) ;

/*
*************************************************************************
* Function:The main MB-filtering function
* Input:
* Output:
* Return: 
* Attention:
*************************************************************************
*/


void DeblockFrame(ImageParameters *img, byte **imgY, byte ***imgUV)
{
	  int       mb_x, mb_y ;
	  img->current_mb_nr = -1;
		for( mb_y=0 ; mb_y<(img->height>>4) ; mb_y++ )
	    for( mb_x=0 ; mb_x<(img->width>>4) ; mb_x++ )
		{
	        img->current_mb_nr++;
			DeblockMb( img, imgY, imgUV, mb_y, mb_x ) ;
		}
} 


/*
*************************************************************************
* Function: Deblocks one macroblock
* Input:
* Output:
* Return: 
* Attention:
*************************************************************************
*/

  
void DeblockMb(ImageParameters *img, byte **imgY, byte ***imgUV, int mb_y, int mb_x)
{
  int           EdgeCondition;
  int           dir,edge,QP;
  byte          Strength[2], *SrcY, *SrcU = NULL, *SrcV = NULL;
  Macroblock    *MbP, *MbQ ; 
  const int mb_width = img->width/16;
  const int mb_nr    = img->current_mb_nr;
  Macroblock *currMB = &mb_data[mb_nr];
  	int QPchroma;

  SrcY = imgY    [mb_y<<4] + (mb_x<<4) ;                                                      // pointers to source
  if (imgUV != NULL)
  {
	  SrcU = imgUV[0][mb_y<<3] + (mb_x<<3) ;
		SrcV = imgUV[1][mb_y<<3] + (mb_x<<3) ;
	}
  MbQ  = &mb_data[mb_y*(img->width>>4) + mb_x] ;                                                 // current Mb

  // This could also be handled as a filter offset of -51 
  if (MbQ->lf_disable) return;


  for( dir=0 ; dir<2 ; dir++ )                                             // vertical edges, than horicontal edges
  {
    EdgeCondition = (dir && mb_y) || (!dir && mb_x)  ;                     // can not filter beyond frame boundaries
	
	if(dir && mb_y)
	{
		EdgeCondition = (currMB->slice_nr == mb_data[img->current_mb_nr-mb_width].slice_nr)? EdgeCondition:0;  //  can not filter beyond slice boundaries   jlzheng 7.8
	}
    for( edge=0 ; edge<2 ; edge++ )                                            // first 4 vertical strips of 16 pel
    {                                                                          // then  4 horicontal
      if( edge || EdgeCondition )
      {
        MbP = (edge)? MbQ : ((dir)? (MbQ -(img->width>>4))  : (MbQ-1) ) ;    // MbP = Mb of the remote 4x4 block   MbP是否需要重新得到?
        QP = (MbP->qp + MbQ->qp+1) >> 1 ;                                   // Average QP of the two blocks
        GetStrength( Strength, MbP, MbQ, dir, edge, mb_y<<2, mb_x<<2);           //Strength for 4 pairs of blks in 1 stripe
		if( *((short*)Strength) )  // && (QP>= 8) )                    // only if one of the 4 Strength bytes is != 0
        { 
          EdgeLoop( SrcY + (edge<<3)* ((dir)? img->width:1 ), Strength,QP,dir, img->width, 0 );
          if( (imgUV != NULL) && !(edge & 1) )
          {
            //EdgeLoop( SrcU +  (edge<<2) * ((dir)? img->width_cr:1 ), Strength,QP_SCALE_CR[QP], dir, img->width_cr, 1 ) ; 
            //EdgeLoop( SrcV +  (edge<<2) * ((dir)? img->width_cr:1 ), Strength, QP_SCALE_CR[QP], dir, img->width_cr, 1 ) ; 

	     //modified by cjw 20060310
	     QPchroma=(QP_SCALE_CR[MbP->qp]+QP_SCALE_CR[MbQ->qp]+1)/2;
	     EdgeLoop( SrcU +  (edge<<2) * ((dir)? img->width_cr:1 ), Strength, QPchroma, dir, img->width_cr, 1 ) ; 
	     EdgeLoop( SrcV +  (edge<<2) * ((dir)? img->width_cr:1 ), Strength, QPchroma, dir, img->width_cr, 1 ) ;
          }
        }
      }
    }//end edge
  }//end loop dir
}


byte BLK_NUM[2][2][2]  = {{{0,8},{2,10}},{{0,2},{8,10}}} ;
/*
*************************************************************************
* Function:
* Input:
* Output:
* Return: 
* Attention:
*************************************************************************
*/
void GetStrength(byte Strength[2],Macroblock* MbP,Macroblock* MbQ,int dir,int edge,int block_y,int block_x)
{
	int    blkQ, idx ;
	int    blk_x, blk_x2, blk_y, blk_y2 ;
	int    ***tmp_fwMV = img->fw_mv;
	int    ***tmp_mv   =  img->mv;
	int    ***tmp_bwMV = img->bw_mv;
	int    **fw_refFrArr = img->fw_refFrArr;
	int    **bw_refFrArr = img->bw_refFrArr;
	
	for( idx=0 ; idx<2 ; idx++ )
	{ 
		blkQ = BLK_NUM[dir][edge][idx] ;
		blk_y = (block_y + (blkQ>>2))>>1;
		blk_x = ((block_x + (blkQ&3))>>1) + 4;
		
		blk_y2 = blk_y -  dir ;
		blk_x2 = blk_x - !dir ;
		
		if((MbP->mb_type==I4MB) || (MbQ->mb_type==I4MB) )
			Strength[idx] = 2;
		
		else if(img->type==P_IMG)
			
		    	Strength[idx] = (abs(tmp_mv[blk_x][blk_y][0] - tmp_mv[blk_x2][blk_y2][0]) >= 4 ) |
			(abs(tmp_mv[blk_x][blk_y][1] - tmp_mv[blk_x2][blk_y2][1]) >= 4) |
			(refFrArr [blk_y][blk_x-4] != refFrArr[blk_y2][blk_x2-4]) ;
		else
			Strength[idx] = (abs(tmp_fwMV[blk_x][blk_y][0]  - tmp_fwMV[blk_x2][blk_y2][0]) >= 4)|
			(abs( tmp_fwMV[blk_x][blk_y][1] - tmp_fwMV[blk_x2][blk_y2][1]) >= 4) |
			(abs( tmp_bwMV[blk_x][blk_y][0] - tmp_bwMV[blk_x2][blk_y2][0]) >= 4) |
			(abs( tmp_bwMV[blk_x][blk_y][1] - tmp_bwMV[blk_x2][blk_y2][1]) >= 4) |
			(fw_refFrArr [blk_y][blk_x-4] !=   fw_refFrArr[blk_y2][blk_x2-4])    | 
			(bw_refFrArr [blk_y][blk_x-4] !=   bw_refFrArr[blk_y2][blk_x2-4]);		
	}
}

/*
*************************************************************************
* Function:
* Input:
* Output:
* Return: 
* Attention:
*************************************************************************
*/
void EdgeLoop(byte* SrcPtr,byte Strength[2],int QP, int dir,int width,int Chro)
{
  int      pel, ap, aq, PtrInc, Strng ;
  int      inc, inc2, inc3, inc4 ;
  int      C0, Delta, dif, AbsDelta ;
  int      L2, L1, L0, R0, R1, R2, RL0 ;
  int      Alpha, Beta ;
  int			 small_gap;
  
  PtrInc  = dir?  1 : width ;
  inc     = dir?  width : 1 ;                    
  inc2    = inc<<1 ;    
  inc3    = inc + inc2 ;    
  inc4    = inc<<2 ;
 
  Alpha = ALPHA_TABLE[Clip3(0,63,QP+alpha_offset)];     // jlzheng  7.8                       

  Beta = BETA_TABLE[Clip3(0,63,QP+beta_offset)];         // jlzheng  7.8     

  for( pel=0 ; pel<16 ; pel++ )
  {
    if( (Strng = Strength[pel >> 3]) )
    {
      L2  = SrcPtr[-inc3] ;
      L1  = SrcPtr[-inc2] ;
      L0  = SrcPtr[-inc ] ;
      R0  = SrcPtr[    0] ;
      R1  = SrcPtr[ inc ] ;
      R2  = SrcPtr[ inc2] ;
      AbsDelta = abs(Delta = R0 - L0) ;
      if( AbsDelta < Alpha )
      {
		  if((abs(R0 - R1) < Beta) && (abs(L0 - L1) < Beta))
		  {
			  aq = (abs( R0 - R2) < Beta) ;
			  ap = (abs( L0 - L2) < Beta) ;
			  if(Strng == 2)
			  {
				  RL0 = L0 + R0 ;
				  small_gap = (AbsDelta < ((Alpha >> 2) + 2));
				  aq &= small_gap;
				  ap &= small_gap;
				  
				  SrcPtr[   0 ] = aq ? ( R1 + RL0 +  R0 + 2) >> 2 : ((R1 << 1) + R0 + L0 + 2) >> 2 ;
				  SrcPtr[-inc ] = ap ? ( L0 +  L1 + RL0 + 2) >> 2 : ((L1 << 1) + L0 + R0 + 2) >> 2 ;
				  
				  SrcPtr[ inc ] = (aq && !Chro) ? ( R0 + R1 + L0 + R1 + 2) >> 2 : SrcPtr[ inc ];
				  SrcPtr[-inc2] = (ap && !Chro) ? ( L1 + L1 + L0 + R0 + 2) >> 2 : SrcPtr[-inc2];
			  }
			  else	//Strng == 1
			  {
				  C0  = CLIP_TAB[Clip3(0,63,QP+alpha_offset)] ;    // jlzheng  7.12
				  dif             = IClip( -C0, C0, ( (R0 - L0) * 3 + (L1 - R1) + 4) >> 3 ) ;
				  SrcPtr[  -inc ] = IClip(0, 255, L0 + dif) ;
				  SrcPtr[     0 ] = IClip(0, 255, R0 - dif) ;
				  if( !Chro )
				  {
					  L0 = SrcPtr[-inc] ;
					  R0 = SrcPtr[   0] ;
					  if(ap)
					  {
						  dif           = IClip( -C0, C0, ( (L0 - L1) * 3 + (L2 - R0) + 4) >> 3 ) ;
						  SrcPtr[-inc2] = IClip(0, 255, L1 + dif) ;
					  }
					  if(aq)
					  {
						  dif           = IClip( -C0, C0, ( (R1 - R0) * 3 + (L0 - R2) + 4) >> 3 ) ;
						  SrcPtr[ inc ] = IClip(0, 255, R1 - dif) ;
					  }
				  }
			  }
		  }
      }
      SrcPtr += PtrInc ;
      pel    += Chro ;
    }
    else                      //如果没有滤波强度,则不作滤波,跳到该边的下一半
    {
      SrcPtr += PtrInc << (3 - Chro) ;
      pel    += 7 ;
    }  ;
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -