www.pudn.com > avs-m3.rar > block.c
/*! ************************************************************************************* * \file * block.c * \brief * block based action such as transform, quantization, re-constructions * * \date: updating* ************************************************************************************* */ #include #include #include "block.h" #include "global.h" #include "defines.h" //#include "compensation.h" //!< Global Tables for Inverse Quantization const 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 }; const 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 }; const unsigned char QP_SCALE_CR[64]= { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15,16,17,18,19, 20,21,22,23,24,25,26,27,28,29, 30,31,32,33,34,35,36,37,38,39, 40,41,42,42,43,43,44,44,45,45, 46,46,47,47,48,48,48,49,49,49, 50,50,50,51 }; /*! ************************************************************************************* * \brief : Dequantization of 4x4 block. ************************************************************************************* */ void Dequant_B4(int qp, int b8, int b4) { int i, j; int val; int shift, QPI; assert((b8 >= 0) && (b8 <= 5)); if(b8 >= 4) qp = QP_SCALE_CR[qp]; for (j=0; j<4; j++) for (i=0; i<4; i++) { CheckQCoeffValid(pgImage->current_mb_nr,b8,b4,pgcurrMB->pred_residual[b8][b4][j][i]); /* check quantized coefficient */ 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 CheckDCTCoeffValid(pgImage->current_mb_nr,b8,b4,pgcurrMB->pred_residual[b8][b4][j][i]); /* Inverse Quantization DCT coefficient Check */ #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 } } /*! ************************************************************************************* * \brief : Inverse transform 4x4 block. ************************************************************************************* */ 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]; tmp_blk[j1][i]= tmp[j]-tmp[j1]; // //tmp_blk[j][i] =(tmp[j]+tmp[j1]+16)>>5; //tmp_blk[j1][i]=(tmp[j]-tmp[j1]+16)>>5; // } } //added by zhan ma for(j=0; j<4; j++) for(i=0; i<4; i++) { CheckHCoeffValid(pgImage->current_mb_nr,b8,b4,tmp_blk[j][i]); /* IDCT coefficient check */ #if TRACE if(b8<4) MB_H_coeff_Y[((b8>>1)<<3)+((b4>>1)<<2)+j][((b8 &1)<<3)+((b4 &1)<<2)+i] = tmp_blk[j][i]; else MB_H_coeff_UV[b8-4][((b4>>1)<<2)+j][((b4 &1)<<2)+i] = tmp_blk[j][i]; #endif tmp_blk[j][i] = (tmp_blk[j][i] +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 } } /*! ************************************************************************************* * \brief : Reconstruction of a 4x4 block. ************************************************************************************* */ void Recon_B4(int b8, int b4) { 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 } } } } /*! ************************************************************************************* * \brief : * Get predition residual. VLD ************************************************************************************* */ void Get_residual(int b8,int b4) { int xx, yy; int mb_y = (b8 / 2) << 3; int mb_x = (b8 % 2) << 3; assert(b8<=5&&b8>=0); 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]; } } // Notation for comments regarding prediction and predictors. // The pels of the 4x4 block are labelled a..p. The predictor pels above // are labelled A..H, from the left I..P, and from above left X, as follows: // // X A B C D E F G H // I a b c d // J e f g h // K i j k l // L m n o p // M // N // O // P // // Predictor array index definitions #define P_X (PredPel[0]) #define P_A (PredPel[1]) #define P_B (PredPel[2]) #define P_C (PredPel[3]) #define P_D (PredPel[4]) #define P_E (PredPel[5]) #define P_F (PredPel[6]) #define P_G (PredPel[7]) #define P_H (PredPel[8]) #define P_I (PredPel[9]) #define P_J (PredPel[10]) #define P_K (PredPel[11]) #define P_L (PredPel[12]) #define P_M (PredPel[13]) #define P_N (PredPel[14]) #define P_O (PredPel[15]) #define P_P (PredPel[16]) /*! *********************************************************************** * \brief * makes and returns 4x4 blocks with all 5 intra prediction modes * * \return * DECODING_OK decoding of intraprediction mode was sucessfull * SEARCH_SYNC search next sync element as errors while decoding occured * \notes checke by Zhan MA June 20th 2005 *********************************************************************** */ int intrapred(int b8, int b4, int ioff, //!< pixel offset X within MB int joff, //!< pixel offset Y within MB int img_block_x, //!< location of block X, multiples of 4 int img_block_y) //!< location of block Y, multiples of 4 { int i,j; int s0; int img_y,img_x; int PredPel[17]; // array of predictor pels int block_available_up; int block_available_up_right; int block_available_left; int block_available_left_down; int block_available_up_left; //one 4x4 block one mode byte predmode = pgImage->ipredmode[img_block_x+1][img_block_y+1]; //accordinate based on this img_x=img_block_x*4; img_y=img_block_y*4; block_available_up = (pgImage->ipredmode[img_block_x+1][img_block_y] >=0); /// can use frm block_available_left = (pgImage->ipredmode[img_block_x][img_block_y+1] >=0); /// can use frm block_available_up_left = (pgImage->ipredmode[img_block_x][img_block_y] >=0); block_available_left_down = 0; // undecoded block_available_up_right = 0; // undecoded // end i = (img_x & 15); j = (img_y & 15); // form predictor pels if (block_available_up) { P_A = imgY[img_y-1][img_x+0]; P_B = imgY[img_y-1][img_x+1]; P_C = imgY[img_y-1][img_x+2]; P_D = imgY[img_y-1][img_x+3]; P_E = P_F = P_G = P_H = P_D; //last 5 pixels is equivalent. } else P_A = P_B = P_C = P_D = P_E = P_F = P_G = P_H = 128; // if (block_available_left) { P_I = imgY[img_y+0][img_x-1]; P_J = imgY[img_y+1][img_x-1]; P_K = imgY[img_y+2][img_x-1]; P_L = imgY[img_y+3][img_x-1]; P_M = P_N = P_O = P_P = P_L; } else P_I = P_J = P_K = P_L = P_M = P_N = P_O = P_P = 128; //luma r0 picking up if (block_available_up_left) P_X = imgY[img_y-1][img_x-1]; else P_X = 128; //predmode selection // 9 modes proposed by HUST in AVS_Mxxxx switch (predmode) { case DC_PRED: // DC prediction s0 = 0; if (block_available_up && block_available_left) { // no edge s0 = (P_A + P_B + P_C + P_D + P_I + P_J + P_K + P_L + 4)/(2*BLOCK_SIZE); } else if (!block_available_up && block_available_left) { // upper edge s0 = (P_I + P_J + P_K + P_L + 2)/BLOCK_SIZE; } else if (block_available_up && !block_available_left) { // left edge s0 = (P_A + P_B + P_C + P_D + 2)/BLOCK_SIZE; } else //if (!block_available_up && !block_available_left) { // top left corner, nothing to predict from s0 = 128; } for (j=0; j < BLOCK_SIZE; j++) for (i=0; i < BLOCK_SIZE; i++) pgcurrMB->pred_sample[b8][b4][i][j] = s0; // store DC prediction break; case VERT_PRED: // vertical prediction from block above for(j=0;j pred_sample[b8][b4][i][j]=imgY[img_y-1][img_x+i];// store predicted 4x4 block break; case HOR_PRED: // horisontal prediction from left block for(j=0;j pred_sample[b8][b4][i][j]=imgY[img_y+j][img_x-1]; // store predicted 4x4 block break; case DOWN_RIGHT_PRED: pgcurrMB->pred_sample[b8][b4][0][3] = (P_L + 2*P_K + P_J + 2) / 4; pgcurrMB->pred_sample[b8][b4][0][2] = pgcurrMB->pred_sample[b8][b4][1][3] = (P_K + 2*P_J + P_I + 2) / 4; pgcurrMB->pred_sample[b8][b4][0][1] = pgcurrMB->pred_sample[b8][b4][1][2] = pgcurrMB->pred_sample[b8][b4][2][3] = (P_J + 2*P_I + P_X + 2) / 4; pgcurrMB->pred_sample[b8][b4][0][0] = pgcurrMB->pred_sample[b8][b4][1][1] = pgcurrMB->pred_sample[b8][b4][2][2] = pgcurrMB->pred_sample[b8][b4][3][3] = (P_I + 2*P_X + P_A + 2) / 4; pgcurrMB->pred_sample[b8][b4][1][0] = pgcurrMB->pred_sample[b8][b4][2][1] = pgcurrMB->pred_sample[b8][b4][3][2] = (P_X + 2*P_A + P_B + 2) / 4; pgcurrMB->pred_sample[b8][b4][2][0] = pgcurrMB->pred_sample[b8][b4][3][1] = (P_A + 2*P_B + P_C + 2) / 4; pgcurrMB->pred_sample[b8][b4][3][0] = (P_B + 2*P_C + P_D + 2) / 4; break; case DOWN_LEFT_PRED: pgcurrMB->pred_sample[b8][b4][0][0] = (P_A + P_C + P_I + P_K + 2*(P_B + P_J) + 4) / 8; pgcurrMB->pred_sample[b8][b4][1][0] = pgcurrMB->pred_sample[b8][b4][0][1] = (P_B + P_D + P_J + P_L + 2*(P_C + P_K) + 4) / 8; pgcurrMB->pred_sample[b8][b4][2][0] = pgcurrMB->pred_sample[b8][b4][1][1] = pgcurrMB->pred_sample[b8][b4][0][2] = (P_C + P_E + P_K + P_M + 2*(P_D + P_L) + 4) / 8; pgcurrMB->pred_sample[b8][b4][3][0] = pgcurrMB->pred_sample[b8][b4][2][1] = pgcurrMB->pred_sample[b8][b4][1][2] = pgcurrMB->pred_sample[b8][b4][0][3] = (P_D + P_F + P_L + P_N + 2*(P_E + P_M) + 4) / 8; pgcurrMB->pred_sample[b8][b4][3][1] = pgcurrMB->pred_sample[b8][b4][2][2] = pgcurrMB->pred_sample[b8][b4][1][3] = (P_E + P_G + P_M + P_O + 2*(P_F + P_N) + 4) / 8; pgcurrMB->pred_sample[b8][b4][3][2] = pgcurrMB->pred_sample[b8][b4][2][3] = (P_F + P_H + P_N + P_P + 2*(P_G + P_O) + 4) / 8; pgcurrMB->pred_sample[b8][b4][3][3] = (P_G + P_O + P_H + P_P + 2) / 4; break; case VERT_RIGHT_PRED: // 5 make VERT_RIGHT_PRED Prediction pgcurrMB->pred_sample[b8][b4][0][0] = pgcurrMB->pred_sample[b8][b4][1][2] = (P_X + P_A + 1) / 2; pgcurrMB->pred_sample[b8][b4][1][0] = pgcurrMB->pred_sample[b8][b4][2][2] = (P_A + P_B + 1) / 2; pgcurrMB->pred_sample[b8][b4][2][0] = pgcurrMB->pred_sample[b8][b4][3][2] = (P_B + P_C + 1) / 2; pgcurrMB->pred_sample[b8][b4][3][0] = (P_C + P_D + 1) / 2; pgcurrMB->pred_sample[b8][b4][0][1] = pgcurrMB->pred_sample[b8][b4][1][3] = (P_I + 2*P_X + P_A + 2) / 4; pgcurrMB->pred_sample[b8][b4][1][1] = pgcurrMB->pred_sample[b8][b4][2][3] = (P_X + 2*P_A + P_B + 2) / 4; pgcurrMB->pred_sample[b8][b4][2][1] = pgcurrMB->pred_sample[b8][b4][3][3] = (P_A + 2*P_B + P_C + 2) / 4; pgcurrMB->pred_sample[b8][b4][3][1] = (P_B + 2*P_C + P_D + 2) / 4; pgcurrMB->pred_sample[b8][b4][0][2] = (P_X + 2*P_I + P_J + 2) / 4; pgcurrMB->pred_sample[b8][b4][0][3] = (P_I + 2*P_J + P_K + 2) / 4; break; case HOR_DOWN_PRED: // 6 make HOR_DOWN_PRED Prediction pgcurrMB->pred_sample[b8][b4][0][0] = pgcurrMB->pred_sample[b8][b4][2][1] = (P_X + P_I + 1) / 2; pgcurrMB->pred_sample[b8][b4][1][0] = pgcurrMB->pred_sample[b8][b4][3][1] = (P_I + 2*P_X + P_A + 2) / 4; pgcurrMB->pred_sample[b8][b4][2][0] = (P_X + 2*P_A + P_B + 2) / 4; pgcurrMB->pred_sample[b8][b4][3][0] = (P_A + 2*P_B + P_C + 2) / 4; pgcurrMB->pred_sample[b8][b4][0][1] = pgcurrMB->pred_sample[b8][b4][2][2] = (P_I + P_J + 1) / 2; pgcurrMB->pred_sample[b8][b4][1][1] = pgcurrMB->pred_sample[b8][b4][3][2] = (P_X + 2*P_I + P_J + 2) / 4; pgcurrMB->pred_sample[b8][b4][0][2] = pgcurrMB->pred_sample[b8][b4][2][3] = (P_J + P_K + 1) / 2; pgcurrMB->pred_sample[b8][b4][1][2] = pgcurrMB->pred_sample[b8][b4][3][3] = (P_I + 2*P_J + P_K + 2) / 4; pgcurrMB->pred_sample[b8][b4][0][3] = (P_K + P_L + 1) / 2; pgcurrMB->pred_sample[b8][b4][1][3] = (P_J + 2*P_K + P_L + 2) / 4; break; // end HOR_DOWN_PRED case VERT_LEFT_PRED: // 7 make VERT_LEFT_PRED Prediction pgcurrMB->pred_sample[b8][b4][0][0] = (P_A + P_B + 1) / 2; pgcurrMB->pred_sample[b8][b4][1][0] = pgcurrMB->pred_sample[b8][b4][0][2] = (P_B + P_C + 1) / 2; pgcurrMB->pred_sample[b8][b4][2][0] = pgcurrMB->pred_sample[b8][b4][1][2] = (P_C + P_D + 1) / 2; pgcurrMB->pred_sample[b8][b4][3][0] = pgcurrMB->pred_sample[b8][b4][2][2] = (P_D + P_E + 1) / 2; pgcurrMB->pred_sample[b8][b4][3][2] = (P_E + P_F + 1) / 2; pgcurrMB->pred_sample[b8][b4][0][1] = (P_A + 2*P_B + P_C + 2) / 4; pgcurrMB->pred_sample[b8][b4][1][1] = pgcurrMB->pred_sample[b8][b4][0][3] = (P_B + 2*P_C + P_D + 2) / 4; pgcurrMB->pred_sample[b8][b4][2][1] = pgcurrMB->pred_sample[b8][b4][1][3] = (P_C + 2*P_D + P_E + 2) / 4; pgcurrMB->pred_sample[b8][b4][3][1] = pgcurrMB->pred_sample[b8][b4][2][3] = (P_D + 2*P_E + P_F + 2) / 4; pgcurrMB->pred_sample[b8][b4][3][3] = (P_E + 2*P_F + P_G + 2) / 4; break; // end VERT_LEFT_PRED case HOR_UP_PRED: // 7 make HOR_UP_PRED Prediction pgcurrMB->pred_sample[b8][b4][0][0] = (P_I + P_J + 1) / 2; pgcurrMB->pred_sample[b8][b4][1][0] = (P_I + 2*P_J + P_K + 2) / 4; pgcurrMB->pred_sample[b8][b4][2][0] = pgcurrMB->pred_sample[b8][b4][0][1] = (P_J + P_K + 1) / 2; pgcurrMB->pred_sample[b8][b4][3][0] = pgcurrMB->pred_sample[b8][b4][1][1] = (P_J + 2*P_K + P_L + 2) / 4; pgcurrMB->pred_sample[b8][b4][2][1] = pgcurrMB->pred_sample[b8][b4][0][2] = (P_K + P_L + 1) / 2; pgcurrMB->pred_sample[b8][b4][3][1] = pgcurrMB->pred_sample[b8][b4][1][2] = (P_K + 2*P_L + P_M + 2) / 4; pgcurrMB->pred_sample[b8][b4][0][3] = pgcurrMB->pred_sample[b8][b4][2][2] = pgcurrMB->pred_sample[b8][b4][3][2] = pgcurrMB->pred_sample[b8][b4][1][3] = pgcurrMB->pred_sample[b8][b4][2][3] = pgcurrMB->pred_sample[b8][b4][3][3] = P_L; break; // end HOR_UP_PRED default: printf("Error: illegal prediction mode input: %d\n",predmode); return SEARCH_SYNC; break; } #if TRACE for(j=0;j<4;j++) for(i=0;i<4;i++) MB_intrapred_Y[((b8>>1)<<3)+((b4>>1)<<2)+j][((b8 &1)<<3)+((b4 &1)<<2)+i] = pgcurrMB->pred_sample[b8][b4][i][j]; #endif return DECODING_OK; } /*! ************************************************************************* * \brief: * intra chroma prediction based on 4x4 block ************************************************************************* */ void intrapred_chroma_4x4(int mb_x, int mb_y, int b4, int mode) { #define CBS 4 // chroma block size unsigned char edgepixu[20]; #define EU (edgepixu + 10) unsigned char edgepixv[20]; #define EV (edgepixv + 10) int hlineU[CBS],vlineU[CBS]; int hlineV[CBS],vlineV[CBS]; int x,y; int uv; int u0,v0; int bx = (b4 &1)<<2; int by = (b4>>1)<<2; int img_cx = (mb_x << 3) + bx; // block pel x int img_cy = (mb_y << 3) + by; // block pel y //MZ int mb_available_up = (pgImage->ipredmode[(mb_x<<2)+1][(mb_y<<2)]>=0); int mb_available_left = (pgImage->ipredmode[(mb_x<<2)][(mb_y<<2)+1] >=0); /// can use frm int mb_available_up_left = (pgImage->ipredmode[(mb_x<<2)][(mb_y<<2)] >=0); // int block_available_up = (b4 ==0||b4==1)?mb_available_up:1; int block_available_left = (b4 ==0||b4==2)?mb_available_left:1; int block_available_up_left = (b4==0) ? mb_available_up_left : ((b4==1) ? mb_available_up : ((b4==2) ? mb_available_left : 1 )); assert(b4>=0 && b4 <=3); uv = 0; if (block_available_up) { for(x=0;x pred_sample[4][b4][x][y] = u0; pgcurrMB->pred_sample[5][b4][x][y] = v0; } } break; case HOR_PRED_8: if (!block_available_left) error("unexpected HOR_PRED_8 chroma intra prediction mode",-1); for (y=0;y pred_sample[4][b4][x][y] = vlineU[y]; pgcurrMB->pred_sample[5][b4][x][y] = vlineV[y]; } } break; case VERT_PRED_8: if (!block_available_up) error("unexpected VERT_PRED_8 chroma intra prediction mode",-1); for (x=0;x pred_sample[4][b4][x][y] = hlineU[x]; pgcurrMB->pred_sample[5][b4][x][y] = hlineV[x]; } } break; default: error("intrapred_chroma_4x4:illegal chroma intra prediction mode", 600); break; } #if TRACE for(y=0;y >1)<<2)+y][((b4 &1)<<2)+x] = pgcurrMB->pred_sample[4][b4][x][y]; MB_intrapred_UV[1][((b4>>1)<<2)+y][((b4 &1)<<2)+x] = pgcurrMB->pred_sample[5][b4][x][y]; } #endif } /*! ************************************************************************ * \brief * Set motion vector predictor ************************************************************************ */ void SetMotionVectorPredictor(int *pmv_x, int *pmv_y, int ref_frame, int block_x, int block_y, int blockshape_x, int blockshape_y, int ref) { int mb_x = 4*block_x; int mb_y = 4*block_y; int pic_block_x = pgImage->block4_x + block_x; int pic_block_y = pgImage->block4_y + block_y; int mb_width = pgImage->width/16; //WJP FOR SLICE int mb_available_up = (pgImage->mb_y == 0) ? 0 : (pgcurrMB->slice_nr == mb_data[pgImage->current_mb_nr-mb_width].slice_nr); int mb_available_left = (pgImage->mb_x == 0) ? 0 : (pgcurrMB->slice_nr == mb_data[pgImage->current_mb_nr-1].slice_nr); int mb_available_upleft = (pgImage->mb_x == 0 || pgImage->mb_y == 0) ? 0 : (pgcurrMB->slice_nr == mb_data[pgImage->current_mb_nr-mb_width-1].slice_nr); int mb_available_upright = (pgImage->mb_x >= mb_width-1 || pgImage->mb_y == 0) ? 0 : (pgcurrMB->slice_nr == mb_data[pgImage->current_mb_nr-mb_width+1].slice_nr); //WJP END int block_available_up, block_available_left, block_available_upright, block_available_upleft; int mv_a, mv_b, mv_c, mv_d, pred_vec[2]; int mvPredType, rFrameL, rFrameU, rFrameUR; int hv; int ***tmp_mv = pgImage->mv; int a_c, b_c, a_b;//qhg int ABC;//qhg int a[2],b[2],c[2];//qhg /* D B C */ /* A X */ /* 1 A, B, D are set to 0 if unavailable */ /* 2 If C is not available it is replaced by D */ block_available_up = mb_available_up || (mb_y > 0); block_available_left = mb_available_left || (mb_x > 0); if (mb_y > 0) { if (mb_x < 8) // first column of 8x8 blocks { if (mb_y==8) { if (blockshape_x == 16) block_available_upright = 0; else block_available_upright = 1; } else { if (mb_x+blockshape_x != 8) block_available_upright = 1; else block_available_upright = 0; } } else { if (mb_x+blockshape_x != 16) block_available_upright = 1; else block_available_upright = 0; } } else if (mb_x+blockshape_x != MB_BLOCK_SIZE) { block_available_upright = block_available_up; } else { block_available_upright = mb_available_upright; } if (mb_x > 0) { block_available_upleft = (mb_y > 0 ? 1 : mb_available_up); } else if (mb_y > 0) { block_available_upleft = mb_available_left; } else { block_available_upleft = mb_available_upleft; } mvPredType = MVPRED_MEDIAN; // rFrameL = block_available_left ? refFrArr[pic_block_y] [pic_block_x-1 ] : -1; rFrameL = block_available_left ? refFrArr[pic_block_y+blockshape_y/4 -1] [pic_block_x-1] : -1; //JX 05-4-1 rFrameU = block_available_up ? refFrArr[pic_block_y-1][pic_block_x] : -1; //added by MZ if(block_available_upright) block_available_upright = block_available_upright && (refFrArr[pic_block_y-1][pic_block_x+blockshape_x/4]!=-1); if(block_available_upleft) block_available_upleft = block_available_upleft && (refFrArr[pic_block_y-1][pic_block_x-1 ]!=-1); rFrameUR = block_available_upright ? refFrArr[pic_block_y-1][pic_block_x+blockshape_x/4] : block_available_upleft ? refFrArr[pic_block_y-1][pic_block_x-1] : -1; /* Prediction if only one of the neighbors uses the reference frame * we are checking */ if(rFrameL == ref_frame && rFrameU != ref_frame && rFrameUR != ref_frame) mvPredType = MVPRED_L; else if(rFrameL != ref_frame && rFrameU == ref_frame && rFrameUR != ref_frame) mvPredType = MVPRED_U; else if(rFrameL != ref_frame && rFrameU != ref_frame && rFrameUR == ref_frame) mvPredType = MVPRED_UR; // Directional predictions else if(blockshape_x == 8 && blockshape_y == 16) { if(mb_x == 0) { if(rFrameL == ref_frame) mvPredType = MVPRED_L; } else { if(rFrameUR == ref_frame) mvPredType = MVPRED_UR; } } else if(blockshape_x == 16 && blockshape_y == 8) { if(mb_y == 0) { if(rFrameU == ref_frame) mvPredType = MVPRED_U; } else { if(rFrameL == ref_frame) mvPredType = MVPRED_L; } } //#define MIN(a,b,c) (ab?a>c?a:c:b>c?b:c)//WJP FOR MV prediction 050320 a_b=a_c=b_c=0; //printf("%d \n" , pgImage->current_mb_nr); for (hv=0; hv < 2; hv++) { //mv_a = block_available_left ? tmp_mv[4+pic_block_x-1 ][pic_block_y ][hv] : 0; mv_a = block_available_left ? tmp_mv[4+pic_block_x-1][pic_block_y + (blockshape_y/4) -1 ][hv]: 0; mv_b = block_available_up ? tmp_mv[4+pic_block_x ][pic_block_y-1][hv] : 0; mv_d = block_available_upleft ? tmp_mv[4+pic_block_x-1 ][pic_block_y-1][hv] : 0; mv_c = block_available_upright ? tmp_mv[4+pic_block_x+blockshape_x/4][pic_block_y-1][hv] : mv_d; //qhg a[hv] = mv_a; b[hv] = mv_b; c[hv] = mv_c; a_b+= abs(mv_a-mv_b); a_c+= abs(mv_a-mv_c); b_c+= abs(mv_b-mv_c); switch (mvPredType) { case MVPRED_MEDIAN: if(hv == 1) { ABC = MAX(a_b,a_c,b_c); if(ABC == a_b) { pred_vec[0] = c[0]; pred_vec[1] = c[1]; } else if(ABC == b_c) { pred_vec[0] = a[0]; pred_vec[1] = a[1]; } else { pred_vec[0] = b[0]; pred_vec[1] = b[1]; } } //WJP END break; case MVPRED_L: pred_vec[hv] = mv_a; break; case MVPRED_U: pred_vec[hv] = mv_b; break; case MVPRED_UR: pred_vec[hv] = mv_c; break; default: break; } } /* MV predictor */ *pmv_x = pred_vec[0]; *pmv_y = pred_vec[1]; } /*! *********************************************************************** * \brief * Find Skip Motion Vector for SKIP_MB *********************************************************************** */ void FindSkipMVandRef() { int i, j, iii, jjj, pmv[2]; int ***tmp_mv = pgImage->mv; int mb_available_up = (pgImage->mb_y == 0) ? 0 : (pgcurrMB->slice_nr == mb_data[pgImage->current_mb_nr-pgImage->width/16].slice_nr); int mb_available_left = (pgImage->mb_x == 0) ? 0 : (pgcurrMB->slice_nr == mb_data[pgImage->current_mb_nr-1].slice_nr); int zeroMotionAbove = !mb_available_up ? 1 : refFrArr[pgImage->block4_y-1][pgImage->block4_x] == 0 && tmp_mv[4+pgImage->block4_x ][pgImage->block4_y-1][0] == 0 && tmp_mv[4+pgImage->block4_x ][pgImage->block4_y-1][1] == 0 ? 1 : 0; //int zeroMotionLeft = !mb_available_left? 1 : refFrArr[pgImage->block4_y][pgImage->block4_x-1] == 0 && tmp_mv[4+pgImage->block4_x-1][pgImage->block4_y][0] == 0 && tmp_mv[4+pgImage->block4_x-1][pgImage->block4_y][1] == 0 ? 1 : 0; //MZ 050403 int zeroMotionLeft = !mb_available_left? 1 : refFrArr[pgImage->block4_y+4-1][pgImage->block4_x-1] == 0 && tmp_mv[4+pgImage->block4_x-1][pgImage->block4_y+4-1][0] == 0 && tmp_mv[4+pgImage->block4_x-1][pgImage->block4_y+4-1][1] == 0 ? 1 : 0; int img_block_y; pgcurrMB->cbp = 0; for (i=0;i cof[i][j][iii][jjj]=0; } for (j=4;j<6;j++) { // reset chroma coeffs for (i=0;i<4;i++) for (iii=0;iii<4;iii++) for (jjj=0;jjj<4;jjj++) pgImage->cof[i][j][iii][jjj]=0; } img_block_y = pgImage->block4_y; if (zeroMotionAbove || zeroMotionLeft) { for(i=0;i<4;i++) for(j=0;j<4;j++) { pgImage->mv[pgImage->block4_x+i+BLOCK_SIZE][pgImage->block4_y+j][0] = 0; pgImage->mv[pgImage->block4_x+i+BLOCK_SIZE][pgImage->block4_y+j][1] = 0; } } else { SetMotionVectorPredictor (pmv, pmv+1, 0, 0, 0, 16, 16, 0);//Lou 1016 for(i=0;i<4;i++) for(j=0;j<4;j++) { pgImage->mv[pgImage->block4_x+i+BLOCK_SIZE][img_block_y+j][0] = pmv[0]; pgImage->mv[pgImage->block4_x+i+BLOCK_SIZE][img_block_y+j][1] = pmv[1]; } } for (j=0; j<4;j++) for (i=0; i<4;i++) { refFrArr[pgImage->block4_y+j][pgImage->block4_x+i] = 0; } }