www.pudn.com > wm2.5.zip > loopfilter.c
/* *********************************************************************** * COPYRIGHT AND WARRANTY INFORMATION * * Copyright 2004, 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. ************************************************************************ */ #include#include #include "global.h" #include "types.h" #include "define.h" #include "loopfilter.h" #define _OLD_METHOD_ // #define TT1 1 // #define CC 0 #define QP_OFset 0 #define ALPHA_ofset 0 #define C_OFFSET -1 //! make chroma QP from quant #define IClip( Min, Max, Val) (((Val)<(Min))? (Min):(((Val)>(Max))? (Max):(Val))) // NOTE: to change the tables below for instance when the QP doubling is changed from 6 to 8 values // send an e-mail to Peter.List@t-systems.com to get a little programm that calculates them automatically extern const short QP_SCALE_CR[64]; int 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 } ; int ININT_STRENGTH[4] = {0x04040404, 0x03030303, 0x03030303, 0x03030303} ; Byte BLK_NUM[2][4][4] = {{{0,4,8,12},{1,5,9,13},{2,6,10,14},{3,7,11,15}},{{0,1,2,3},{4,5,6,7},{8,9,10,11},{12,13,14,15}}} ; void DeblockFrame(Image *img , Byte ***curr_frame) { int mb_x, mb_y ; int i, j; for (j=0;j img_height;j++) { for (i=0;i img_width;i++) { imgY_rec[j][i]=curr_frame[0][j+PAD_SIZE][i+PAD_SIZE]; } } for(j=0;j img_height/2;j++) { for(i=0;i img_width/2;i++) { imgU_rec[j][i]=current_frame[1][j][i]; imgV_rec[j][i]=current_frame[2][j][i]; } } for( mb_y=0 ; mb_y<(img->img_height>>4) ; mb_y++ ) for( mb_x=0 ; mb_x<(img->img_width>>4) ; mb_x++ ) { DeblockMb(img , curr_frame , mb_y , mb_x); } for (j=0;j img_height;j++) { for (i=0;i img_width;i++) { current_frame[0][j+PAD_SIZE][i+PAD_SIZE]=imgY_rec[j][i]; } } for(j=0;j img_height/2;j++) { for(i=0;i img_width/2;i++) { current_frame[1][j][i]=imgU_rec[j][i]; current_frame[2][j][i]=imgV_rec[j][i]; } } } void DeblockMb(Image *img , Byte ***curr_frame , int mb_y , int mb_x) { int EdgeCondition; int dir,edge,QP; Byte *SrcY, *SrcU, *SrcV ; MacroblockHeader *MbPheader, *MbQheader ; MacroblockData *MbP , *MbQ; int QPC; int loopfilter_qp_offset; int alpha_ci_offset; int cp_offset; int threshold; // WJP FOR SLICE_DEBLOCK 050321 int mb_width = pgImage->img_width/16; int current_mb_nr = mb_width*mb_y + mb_x; int mb_available_up = (mb_y == 0) ? 0 : (pgImage->mb_data_forlf[current_mb_nr].slice_nr == pgImage->mb_data_forlf[current_mb_nr-mb_width].slice_nr); int mb_available_left = (mb_x == 0) ? 0 : (pgImage->mb_data_forlf[current_mb_nr].slice_nr == pgImage->mb_data_forlf[current_mb_nr-1].slice_nr); if(!pgImage->disable_loop_filter_slice_flag) { mb_available_up = 1; mb_available_left = 1; } // WJP END 050321 if(active_pps->loop_filter_parameter_flag) { loopfilter_qp_offset = pgImage->loopfilter_qp_offset; alpha_ci_offset = pgImage->alpha_ci_offset; cp_offset = pgImage->cp_offset; } else { loopfilter_qp_offset = 0; alpha_ci_offset = 0; cp_offset = 0; } SrcY = imgY_rec[mb_y<<4] + (mb_x<<4) ; if (imgUV!=NULL) { SrcU = imgU_rec[mb_y<<3] + (mb_x<<3) ; SrcV = imgV_rec[mb_y<<3] + (mb_x<<3) ; } MbQheader = &img->mb_headerdata[mb_y*(img->img_width>>4) + mb_x] ; MbQ = &img->mb_data_forlf[mb_y*(img->img_width>>4) + mb_x ] ; threshold=40 + loopfilter_qp_offset; if (MbQheader->mb_type!=0 || (MbQ->qp_mb>=threshold)) { for( dir=0 ; dir<2 ; dir++ ) //1st hor, 2nd ver { EdgeCondition = (dir && mb_available_up) || (!dir && mb_available_left);//WJP FOR SLICE_DEBLOCK 050321 for( edge=0 ; edge<4 ; edge++ ) { if( edge || EdgeCondition ) { MbPheader = (edge)? MbQheader : ((dir)? (MbQheader - (img->img_width>>4)) : (MbQheader-1)); MbP = (edge)? MbQ : ((dir)? (MbQ - (img->img_width>>4)) : (MbQ-1) ) ; QP = (MbP->qp_mb + MbQ->qp_mb +1)>>1; // if (MbQheader->mb_type==6) if (MbQheader->mb_type==I4MB) //JX 05-4-1 { EdgeLoop( SrcY + (edge<<2)* ((dir)? img->img_width:1 ), QP, alpha_ci_offset, dir, img->img_width, 0) ; if(!(edge & 1) ) { QPC =(MbP->qp_mb + MbQ->qp_mb +1)>>1; EdgeLoop( SrcU + (edge<<1) * ((dir)? img->img_width>>1:1 ), QPC, alpha_ci_offset, dir, img->img_width>>1, 1 ) ; EdgeLoop( SrcV + (edge<<1) * ((dir)? img->img_width>>1:1 ), QPC, alpha_ci_offset, dir, img->img_width>>1, 1 ) ; } } else if (!(MbQ->qp_mb mb_type==0))//1230 { EdgeLoopweak( SrcY + (edge<<2)* ((dir)? img->img_width:1 ), QP, alpha_ci_offset, cp_offset, dir, img->img_width, 0) ; if(!(edge & 1) ) { QPC =(MbP->qp_mb + MbQ->qp_mb +1)>>1; EdgeLoopweak( SrcU + (edge<<1) * ((dir)? img->img_width>>1:1 ), QPC, alpha_ci_offset, cp_offset, dir, img->img_width>>1, 1 ) ; EdgeLoopweak ( SrcV + (edge<<1) * ((dir)? img->img_width>>1:1 ), QPC, alpha_ci_offset, cp_offset, dir, img->img_width>>1, 1 ) ; } } } } } } } void EdgeLoop(Byte* SrcPtr, int QP, int alpha_ci_offset, int dir,int width,int yuv) { int pel, ap = 0, aq = 0, PtrInc /*Strng*/ ; int inc, inc2, inc3, inc4 ; int Delta, dif, AbsDelta ; int L2 = 0, L1, L0, L3, R0, R1, R2 = 0, R3 /*RL0*/ ; 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)];//1230 // 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 ] ; dif = IClip( -C0, C0, ( (R0-L0)*4 + (L1 - R1) + 4) >> 3 ); dif1=dif>>1; //left if (L1==L0/*&& !yuv*/)//1230 { 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 /*&& !yuv*/)//1230 { 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 ; } } void EdgeLoopweak(Byte* SrcPtr,int QP, int alpha_ci_offset, int cp_offset, int dir,int width,int yuv) { int pel, ap = 0, aq = 0, PtrInc /*Strng*/ ; int inc, inc2, inc3, inc4 ; int Delta, dif, AbsDelta ; int L2 = 0, L1, L0, L3, R0, R1, R2 = 0, R3 /*RL0*/ ; 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)];//1230 // 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;//1230 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 )//1230 { 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 )//1230 { 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 ; } }