www.pudn.com > wm2.5.zip > block.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. ************************************************************************ */ /* ************************************************************************************* * File name: block.c * Function: Description * ************************************************************************************* */ #include#include #include #include #include #include "defines.h" #include "global.h" #include "elements.h" #include "block.h" #include "vlc.h" static const int dequant_coef[6][2][2] = { //qwang 2004-4-4 { {16, 13}, {13, 10} }, { {18, 14}, {14, 11} }, { {20, 16}, {16, 13} }, { {23, 18}, {18, 14} }, { {26, 20}, {20, 16} }, { {29, 23}, {23, 18} } }; #define EP (edgepixels+20) unsigned short IQ_TAB[64] = { 32768,36061,38968,42495,46341,50535,55437,60424, 32932,35734,38968,42495,46177,50535,55109,59933, 65535,35734,38968,42577,46341,50617,55027,60097, 32809,35734,38968,42454,46382,50576,55109,60056, 65535,35734,38968,42495,46320,50515,55109,60076, 65535,35744,38968,42495,46341,50535,55099,60087, 65535,35734,38973,42500,46341,50535,55109,60097, 32771,35734,38965,42497,46341,50535,55109,60099 }; short IQ_SHIFT[64] = { 14,14,14,14,14,14,14,14, 13,13,13,13,13,13,13,13, 13,12,12,12,12,12,12,12, 11,11,11,11,11,11,11,11, 11,10,10,10,10,10,10,10, 10,9,9,9,9,9,9,9, 9,8,8,8,8,8,8,8, 7,7,7,7,7,7,7,7 }; /* ************************************************************************* * Function:Dequantization of 4x4 block. * Input: * Output: * Return: * Attention:input curr_blk has to be [lines][pixels] /[y][x] ************************************************************************* */ void Dequant_B4(int qp, int b8, int b4) { int i, j; int val; int shift, QPI; //if chroma, CurrentQP is indexed by the global table. //if luma, CurrentQP = qp; if(b8>=4) qp = QP_SCALE_CR[qp]; for (j=0; j<4; j++) for (i=0; i<4; i++) { val = pgcurrMB->pred_residual[b8][b4][j][i]; //VLD's residual before IQ shift = IQ_SHIFT[qp]; QPI = IQ_TAB[qp]; pgcurrMB->pred_residual[b8][b4][j][i] = (val*QPI+(1<<(shift-1)))>>shift; //IQ coefficients after Dequantization #if TRACE if(b8<4) MB_IQ_Y[((b8>>1)<<3)+((b4>>1)<<2)+j][((b8 &1)<<3)+((b4 &1)<<2)+i] = pgcurrMB->pred_residual[b8][b4][j][i]; else MB_IQ_UV[b8-4][((b4>>1)<<2)+j][((b4 &1)<<2)+i] = pgcurrMB->pred_residual[b8][b4][j][i]; #endif } } /* ************************************************************************* * Function:Inverse transform 4x4 block. * Input: * Output: * Return: * Attention:input curr_blk has to be [lines][pixels] ************************************************************************* */ #ifndef AVS_1_0 void Inv_Transform_B4(int b8,int b4) { int i, j, i1, j1; int tmp[4]; int tmp_blk[BLOCK_SIZE][BLOCK_SIZE]; //using intermediate array tmp_blk[4][4] as transform unit. //4x4 image data swapping for(j=0; j<4; j++) for(i=0; i<4; i++) tmp_blk[j][i] = pgcurrMB->pred_residual[b8][b4][j][i]; //horizontal transform for (j=0; j<4; j++) { tmp[0] = (tmp_blk[j][0]+tmp_blk[j][2])<<1; tmp[1] = (tmp_blk[j][0]-tmp_blk[j][2])<<1; tmp[3] = (tmp_blk[j][1]*3)+tmp_blk[j][3]; tmp[2] = tmp_blk[j][1]-(tmp_blk[j][3]*3); for (i=0; i<2; i++) { i1=3-i; tmp_blk[j][i] = tmp[i]+tmp[i1]; tmp_blk[j][i1]= tmp[i]-tmp[i1]; } } //vertical transform for (i=0; i<4; i++) { tmp[0] =(tmp_blk[0][i]+tmp_blk[2][i])<<1; tmp[1] =(tmp_blk[0][i]-tmp_blk[2][i])<<1; tmp[3]= (tmp_blk[1][i]*3)+tmp_blk[3][i]; tmp[2]= tmp_blk[1][i]- (tmp_blk[3][i]*3); for (j=0; j<2; j++) { j1=3-j; tmp_blk[j][i] =(tmp[j]+tmp[j1]+16)>>5; tmp_blk[j1][i]=(tmp[j]-tmp[j1]+16)>>5; // } } //swapping for(j=0; j<4; j++) for(i=0; i<4; i++) {pgcurrMB->pred_residual[b8][b4][j][i] = tmp_blk[j][i]; //Just as a intermediate variable for decoding trace #if TRACE if(b8<4) MB_IDCT_Y[((b8>>1)<<3)+((b4>>1)<<2)+j][((b8 &1)<<3)+((b4 &1)<<2)+i] = pgcurrMB->pred_residual[b8][b4][j][i]; else MB_IDCT_UV[b8-4][((b4>>1)<<2)+j][((b4 &1)<<2)+i] = pgcurrMB->pred_residual[b8][b4][j][i]; #endif } } #else void Inv_Transform_B4(int b8,int b4) { int i, j, i1, j1; int tmp[4]; int tmp_blk[BLOCK_SIZE][BLOCK_SIZE]; for(j=0; j<4; j++) for(i=0; i<4; i++) tmp_blk[j][i] = pgcurrMB->pred_residual[b8][b4][j][i]; //horizontal for (j=0; j<4; j++) { tmp[0]= (tmp_blk[j][0]+tmp_blk[j][2])<<2; tmp[1]= (tmp_blk[j][0]-tmp_blk[j][2])<<2; tmp[3]= (tmp_blk[j][1]*5)+tmp_blk[j][3]*2; tmp[2]= tmp_blk[j][1]*2-(tmp_blk[j][3]*5); //zzy for (i=0; i<2; i++) { i1=3-i; tmp_blk[j][i]=(tmp[i]+tmp[i1]+2)>>2; tmp_blk[j][i1]=(tmp[i]-tmp[i1]+2)>>2; } } //vertical for (i=0; i<4; i++) { tmp[0]=(tmp_blk[0][i]+tmp_blk[2][i])<<2; //zzy tmp[1]=(tmp_blk[0][i]-tmp_blk[2][i])<<2; //zzy tmp[3]= (tmp_blk[1][i]*5)+tmp_blk[3][i]*2; //zzy tmp[2]= tmp_blk[1][i]*2- (tmp_blk[3][i]*5); //zzy for (j=0; j<2; j++) { j1=3-j; tmp_blk[j][i] =(tmp[j]+tmp[j1]+16)>>5; tmp_blk[j1][i]=(tmp[j]-tmp[j1]+16)>>5; } } for(j=0; j<4; j++) for(i=0; i<4; i++) pgcurrMB->pred_residual[b8][b4][j][i] = tmp_blk[j][i]; } #endif /* ************************************************************************* * Function:Reconstruction of a 4x4 block. * Input: * Output: * Return: * Attention:input curr_blk has to be [lines][pixels] ************************************************************************* */ void Recon_B4(int b8, int b4) //qwang 2004-3-9 { int i,j; short temp; int blk_off_x, blk_off_y; int Mb_off_x, Mb_off_y; blk_off_x = ((b4 &1)<<2); blk_off_y = ((b4>>1)<<2); Mb_off_x = ((b8 &1)<<3) + blk_off_x; Mb_off_y = ((b8>>1)<<3) + blk_off_y; for(j=0; j<4; j++) { for(i=0; i<4; i++) { if(b8 < 4) //luma { temp = (pgcurrMB->pred_sample[b8][b4][i][j] + pgcurrMB->pred_residual[b8][b4][j][i]); pgImage->m7[Mb_off_x+i][Mb_off_y+j] = pgcurrMB->pred_residual[b8][b4][j][i] = clamp(temp,0,255); imgY[pgImage->pix_y+Mb_off_y+j][pgImage->pix_x+Mb_off_x+i] = pgcurrMB->pred_residual[b8][b4][j][i]; #if TRACE MB_Y[Mb_off_y+j][Mb_off_x+i] = pgcurrMB->pred_residual[b8][b4][j][i]; #endif } else //chroma { temp = (pgcurrMB->pred_sample[b8][b4][i][j] + pgcurrMB->pred_residual[b8][b4][j][i] ); pgcurrMB->pred_residual[b8][b4][j][i] = clamp(temp,0,255); imgUV[b8-4][pgImage->pix_c_y+blk_off_y+j][pgImage->pix_c_x+blk_off_x+i] = pgcurrMB->pred_residual[b8][b4][j][i]; #if TRACE MB_UV[b8-4][blk_off_y+j][blk_off_x+i] = pgcurrMB->pred_residual[b8][b4][j][i]; #endif } } } } /* ************************************************************************* * Function:Get predition residual. VLD * Input: * Output: * Return: * Attention:input curr_blk has to be [lines][pixels] ************************************************************************* */ void Get_residual( int b8,int b4) //zhangnan 2004-05-03 { int xx, yy; int mb_y = (b8 / 2) << 3; int mb_x = (b8 % 2) << 3; if (b8<=3) { for (yy=0; yy pred_residual[b8][b4][yy][xx] = pgImage->m7[mb_x+((b4 &1)<<2)+xx][mb_y+((b4>>1)<<2)+yy]; } else { for (yy=0; yy pred_residual[b8][b4][yy][xx] = pgImage->m8[b8-4][((b4 &1)<<2)+xx][((b4>>1)<<2)+yy]; } } //#ifdef AVS_ABT /************************************************************************* * Function: for abt 8x8 dequant. * Input: * Output: * Return: * Attention: *************************************************************************/ void abt_dequant_B8(int qp, int blk) { int val, shift, QPI; int subblk; int xx,yy; shift = IQ_SHIFT[qp]; QPI = IQ_TAB[qp]; for (yy=0; yy<8; yy++) for (xx=0; xx<8; xx++) { subblk=((yy>>2)<<1)+(xx>>2); val =pgcurrMB->pred_residual[blk][subblk][yy&3][xx&3]; pgcurrMB->pred_residual[blk][subblk][yy&3][xx&3]= (val*QPI+(1<<(shift-1)) )>>(shift); } } /******************************************************************** Function: for abt inverse transform 8x8 Created: Author : Input : Output : Function: *********************************************************************/ void abt_Itransform_B8(int blk) { short int xx, yy; short int tmp[8]; short int t; short int b[8]; int curr_blk[8][8]; int subblk; for(yy=0; yy<8; yy++) for(xx=0; xx<8; xx++) { subblk=((yy>>2)<<1)+(xx>>2); curr_blk[yy][xx] = pgcurrMB->pred_residual[blk][subblk][yy&3][xx&3]; } for(yy=0; yy<8; yy++) { // Horizontal inverse transform // Reorder tmp[0]=curr_blk[yy][0]; tmp[1]=curr_blk[yy][4]; tmp[2]=curr_blk[yy][2]; tmp[3]=curr_blk[yy][6]; tmp[4]=curr_blk[yy][1]; tmp[5]=curr_blk[yy][3]; tmp[6]=curr_blk[yy][5]; tmp[7]=curr_blk[yy][7]; // Downleft Butterfly /*Lou Change*/ b[0] = ((tmp[4] - tmp[7])<<1) + tmp[4]; b[1] = ((tmp[5] + tmp[6])<<1) + tmp[5]; b[2] = ((tmp[5] - tmp[6])<<1) - tmp[6]; b[3] = ((tmp[4] + tmp[7])<<1) + tmp[7]; b[4] = ((b[0] + b[1] + b[3])<<1) + b[1]; b[5] = ((b[0] - b[1] + b[2])<<1) + b[0]; b[6] = ((-b[1] - b[2] + b[3])<<1) + b[3]; b[7] = ((b[0] - b[2] - b[3])<<1) - b[2]; /*Lou End*/ // Upleft Butterfly /*Lou Change*/ t=((tmp[2]*10)+(tmp[3]<<2)); tmp[3]=((tmp[2]<<2)-(tmp[3]*10)); tmp[2]=t; t=(tmp[0]+tmp[1])<<3; tmp[1]=(tmp[0]-tmp[1])<<3; tmp[0]=t; /*Lou End*/ b[0]=tmp[0]+tmp[2]; b[1]=tmp[1]+tmp[3]; b[2]=tmp[1]-tmp[3]; b[3]=tmp[0]-tmp[2]; // Last Butterfly /*Lou Change*/ curr_blk[yy][0]=((b[0]+b[4])+(1<<2))>>3; curr_blk[yy][1]=((b[1]+b[5])+(1<<2))>>3; curr_blk[yy][2]=((b[2]+b[6])+(1<<2))>>3; curr_blk[yy][3]=((b[3]+b[7])+(1<<2))>>3; curr_blk[yy][7]=((b[0]-b[4])+(1<<2))>>3; curr_blk[yy][6]=((b[1]-b[5])+(1<<2))>>3; curr_blk[yy][5]=((b[2]-b[6])+(1<<2))>>3; curr_blk[yy][4]=((b[3]-b[7])+(1<<2))>>3; /*Lou End*/ } // Vertical inverse transform for(xx=0; xx<8; xx++) { // Reorder tmp[0]=curr_blk[0][xx]; tmp[1]=curr_blk[4][xx]; tmp[2]=curr_blk[2][xx]; tmp[3]=curr_blk[6][xx]; tmp[4]=curr_blk[1][xx]; tmp[5]=curr_blk[3][xx]; tmp[6]=curr_blk[5][xx]; tmp[7]=curr_blk[7][xx]; // Downleft Butterfly /*Lou Change*/ b[0] = ((tmp[4] - tmp[7])<<1) + tmp[4]; b[1] = ((tmp[5] + tmp[6])<<1) + tmp[5]; b[2] = ((tmp[5] - tmp[6])<<1) - tmp[6]; b[3] = ((tmp[4] + tmp[7])<<1) + tmp[7]; b[4] = ((b[0] + b[1] + b[3])<<1) + b[1]; b[5] = ((b[0] - b[1] + b[2])<<1) + b[0]; b[6] = ((-b[1] - b[2] + b[3])<<1) + b[3]; b[7] = ((b[0] - b[2] - b[3])<<1) - b[2]; /*Lou End*/ // Upleft Butterfly /*Lou Change*/ t=((tmp[2]*10)+(tmp[3]<<2)); tmp[3]=((tmp[2]<<2)-(tmp[3]*10)); tmp[2]=t; t=(tmp[0]+tmp[1])<<3; tmp[1]=(tmp[0]-tmp[1])<<3; tmp[0]=t; /*Lou End*/ b[0]=tmp[0]+tmp[2]; b[1]=tmp[1]+tmp[3]; b[2]=tmp[1]-tmp[3]; b[3]=tmp[0]-tmp[2]; // Last Butterfly curr_blk[0][xx]=(b[0]+b[4]+64)>>7; curr_blk[1][xx]=(b[1]+b[5]+64)>>7; curr_blk[2][xx]=(b[2]+b[6]+64)>>7; curr_blk[3][xx]=(b[3]+b[7]+64)>>7; curr_blk[7][xx]=(b[0]-b[4]+64)>>7; curr_blk[6][xx]=(b[1]-b[5]+64)>>7; curr_blk[5][xx]=(b[2]-b[6]+64)>>7; curr_blk[4][xx]=(b[3]-b[7]+64)>>7; } for(yy=0; yy<8; yy++) for(xx=0; xx<8; xx++) { subblk=((yy>>2)<<1)+(xx>>2); pgcurrMB->pred_residual[blk][subblk][yy&3][xx&3] = curr_blk[yy][xx]; } } //#endif