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 ; } }