📄 loopfilter.c
字号:
/*!
*************************************************************************************
* \file loopfiter.c
*
* \brief
* deblocking the Reconstructed frame
*
* \date: zhan ma <updated@Aug 1 2005>
*
* \author
*
*************************************************************************************
*/
#include <stdlib.h>
#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 ;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -