www.pudn.com > wm2.5.zip > intraprediction.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 "defines.h" #include "block.h" #include "intraprediction.h" // 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 * *********************************************************************** */ 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: // 8 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: * * * \return: * ************************************************************************* */ 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); //MZ /* int mb_nr = pgImage->current_mb_nr; int mb_available_up = ((mb_y == 0) ? 0 : (pgcurrMB->slice_nr == mb_data[mb_nr-pgImage->width/16].slice_nr)); int mb_available_left = ((mb_x == 0) ? 0 : (mb_data[mb_nr].slice_nr == mb_data[mb_nr-1].slice_nr)); int mb_available_up_left = ((mb_x == 0 || mb_y == 0) ? 0: (mb_data[mb_nr].slice_nr == mb_data[mb_nr-pgImage->width/16-1].slice_nr)); */ // 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 }