00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "contributors.h"
00016
00017 #include "global.h"
00018 #include "image.h"
00019 #include "mb_access.h"
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #define P_X (PredPel[0])
00034 #define P_A (PredPel[1])
00035 #define P_B (PredPel[2])
00036 #define P_C (PredPel[3])
00037 #define P_D (PredPel[4])
00038 #define P_E (PredPel[5])
00039 #define P_F (PredPel[6])
00040 #define P_G (PredPel[7])
00041 #define P_H (PredPel[8])
00042 #define P_I (PredPel[9])
00043 #define P_J (PredPel[10])
00044 #define P_K (PredPel[11])
00045 #define P_L (PredPel[12])
00046
00047
00048
00049
00050
00051
00052
00053 static inline void get_i4x4_vertical(imgpel **cur_pred, imgpel *PredPel)
00054 {
00055 memcpy(cur_pred[0], &PredPel[1], BLOCK_SIZE * sizeof(imgpel));
00056 memcpy(cur_pred[1], &PredPel[1], BLOCK_SIZE * sizeof(imgpel));
00057 memcpy(cur_pred[2], &PredPel[1], BLOCK_SIZE * sizeof(imgpel));
00058 memcpy(cur_pred[3], &PredPel[1], BLOCK_SIZE * sizeof(imgpel));
00059 }
00060
00061
00062
00063
00064
00065
00066
00067
00068 static inline void get_i4x4_horizontal(imgpel **cur_pred, imgpel *PredPel)
00069 {
00070 int i;
00071
00072 for (i=0; i < BLOCK_SIZE; i++)
00073 {
00074 cur_pred[i][0] =
00075 cur_pred[i][1] =
00076 cur_pred[i][2] =
00077 cur_pred[i][3] = (imgpel) (&P_I)[i];
00078 }
00079 }
00080
00081
00082
00083
00084
00085
00086
00087 static inline void get_i4x4_dc(imgpel **cur_pred, imgpel *PredPel, int left_available, int up_available)
00088 {
00089 int i, j, s0 = 0;
00090 if (up_available && left_available)
00091 {
00092
00093 s0 = (P_A + P_B + P_C + P_D + P_I + P_J + P_K + P_L + 4) >> (BLOCK_SHIFT + 1);
00094 }
00095 else if (!up_available && left_available)
00096 {
00097
00098 s0 = (P_I + P_J + P_K + P_L + 2) >> BLOCK_SHIFT;;
00099 }
00100 else if (up_available && !left_available)
00101 {
00102
00103 s0 = (P_A + P_B + P_C + P_D + 2) >> BLOCK_SHIFT;
00104 }
00105 else
00106 {
00107
00108 s0 = P_A;
00109 }
00110
00111 for (j=0; j < BLOCK_SIZE; j++)
00112 {
00113 for (i=0; i < BLOCK_SIZE; i++)
00114 cur_pred[j][i] = (imgpel) s0;
00115 }
00116 }
00117
00118
00119
00120
00121
00122
00123
00124 static inline void get_i4x4_downleft(imgpel **cur_pred, imgpel *PredPel)
00125 {
00126 cur_pred[0][0] = (imgpel) ((P_A + P_C + ((P_B) << 1) + 2) >> 2);
00127 cur_pred[0][1] =
00128 cur_pred[1][0] = (imgpel) ((P_B + P_D + ((P_C) << 1) + 2) >> 2);
00129 cur_pred[0][2] =
00130 cur_pred[1][1] =
00131 cur_pred[2][0] = (imgpel) ((P_C + P_E + ((P_D) << 1) + 2) >> 2);
00132 cur_pred[0][3] =
00133 cur_pred[1][2] =
00134 cur_pred[2][1] =
00135 cur_pred[3][0] = (imgpel) ((P_D + P_F + ((P_E) << 1) + 2) >> 2);
00136 cur_pred[1][3] =
00137 cur_pred[2][2] =
00138 cur_pred[3][1] = (imgpel) ((P_E + P_G + ((P_F)<<1) + 2) >> 2);
00139 cur_pred[2][3] =
00140 cur_pred[3][2] = (imgpel) ((P_F + P_H + ((P_G)<<1) + 2) >> 2);
00141 cur_pred[3][3] = (imgpel) ((P_G + 3*(P_H) + 2) >> 2);
00142 }
00143
00144
00145
00146
00147
00148
00149
00150 static inline void get_i4x4_downright(imgpel **cur_pred, imgpel *PredPel)
00151 {
00152 cur_pred[3][0] = (imgpel) ((P_L + 2*P_K + P_J + 2) >> 2);
00153 cur_pred[2][0] =
00154 cur_pred[3][1] = (imgpel) ((P_K + 2*P_J + P_I + 2) >> 2);
00155 cur_pred[1][0] =
00156 cur_pred[2][1] =
00157 cur_pred[3][2] = (imgpel) ((P_J + 2*P_I + P_X + 2) >> 2);
00158 cur_pred[0][0] =
00159 cur_pred[1][1] =
00160 cur_pred[2][2] =
00161 cur_pred[3][3] = (imgpel) ((P_I + 2*P_X + P_A + 2) >> 2);
00162 cur_pred[0][1] =
00163 cur_pred[1][2] =
00164 cur_pred[2][3] = (imgpel) ((P_X + 2*P_A + P_B + 2) >> 2);
00165 cur_pred[0][2] =
00166 cur_pred[1][3] = (imgpel) ((P_A + 2*P_B + P_C + 2) >> 2);
00167 cur_pred[0][3] = (imgpel) ((P_B + 2*P_C + P_D + 2) >> 2);
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177 static inline void get_i4x4_vertleft(imgpel **cur_pred, imgpel *PredPel)
00178 {
00179 cur_pred[0][0] = (imgpel) ((P_A + P_B + 1) >> 1);
00180 cur_pred[0][1] =
00181 cur_pred[2][0] = (imgpel) ((P_B + P_C + 1) >> 1);
00182 cur_pred[0][2] =
00183 cur_pred[2][1] = (imgpel) ((P_C + P_D + 1) >> 1);
00184 cur_pred[0][3] =
00185 cur_pred[2][2] = (imgpel) ((P_D + P_E + 1) >> 1);
00186 cur_pred[2][3] = (imgpel) ((P_E + P_F + 1) >> 1);
00187 cur_pred[1][0] = (imgpel) ((P_A + ((P_B)<<1) + P_C + 2) >> 2);
00188 cur_pred[1][1] =
00189 cur_pred[3][0] = (imgpel) ((P_B + ((P_C)<<1) + P_D + 2) >> 2);
00190 cur_pred[1][2] =
00191 cur_pred[3][1] = (imgpel) ((P_C + ((P_D)<<1) + P_E + 2) >> 2);
00192 cur_pred[1][3] =
00193 cur_pred[3][2] = (imgpel) ((P_D + ((P_E)<<1) + P_F + 2) >> 2);
00194 cur_pred[3][3] = (imgpel) ((P_E + ((P_F)<<1) + P_G + 2) >> 2);
00195 }
00196
00197
00198
00199
00200
00201
00202
00203 static inline void get_i4x4_vertright(imgpel **cur_pred, imgpel *PredPel)
00204 {
00205 cur_pred[0][0] =
00206 cur_pred[2][1] = (imgpel) ((P_X + P_A + 1) >> 1);
00207 cur_pred[0][1] =
00208 cur_pred[2][2] = (imgpel) ((P_A + P_B + 1) >> 1);
00209 cur_pred[0][2] =
00210 cur_pred[2][3] = (imgpel) ((P_B + P_C + 1) >> 1);
00211 cur_pred[0][3] = (imgpel) ((P_C + P_D + 1) >> 1);
00212 cur_pred[1][0] =
00213 cur_pred[3][1] = (imgpel) ((P_I + 2*P_X + P_A + 2) >> 2);
00214 cur_pred[1][1] =
00215 cur_pred[3][2] = (imgpel) ((P_X + 2*P_A + P_B + 2) >> 2);
00216 cur_pred[1][2] =
00217 cur_pred[3][3] = (imgpel) ((P_A + 2*P_B + P_C + 2) >> 2);
00218 cur_pred[1][3] = (imgpel) ((P_B + 2*P_C + P_D + 2) >> 2);
00219 cur_pred[2][0] = (imgpel) ((P_X + 2*P_I + P_J + 2) >> 2);
00220 cur_pred[3][0] = (imgpel) ((P_I + 2*P_J + P_K + 2) >> 2);
00221 }
00222
00223
00224
00225
00226
00227
00228
00229 static inline void get_i4x4_hordown(imgpel **cur_pred, imgpel *PredPel)
00230 {
00231 cur_pred[0][0] =
00232 cur_pred[1][2] = (imgpel) ((P_X + P_I + 1) >> 1);
00233 cur_pred[0][1] =
00234 cur_pred[1][3] = (imgpel) ((P_I + 2*P_X + P_A + 2) >> 2);
00235 cur_pred[0][2] = (imgpel) ((P_X + 2*P_A + P_B + 2) >> 2);
00236 cur_pred[0][3] = (imgpel) ((P_A + 2*P_B + P_C + 2) >> 2);
00237 cur_pred[1][0] =
00238 cur_pred[2][2] = (imgpel) ((P_I + P_J + 1) >> 1);
00239 cur_pred[1][1] =
00240 cur_pred[2][3] = (imgpel) ((P_X + 2*P_I + P_J + 2) >> 2);
00241 cur_pred[2][0] =
00242 cur_pred[3][2] = (imgpel) ((P_J + P_K + 1) >> 1);
00243 cur_pred[2][1] =
00244 cur_pred[3][3] = (imgpel) ((P_I + 2*P_J + P_K + 2) >> 2);
00245 cur_pred[3][0] = (imgpel) ((P_K + P_L + 1) >> 1);
00246 cur_pred[3][1] = (imgpel) ((P_J + 2*P_K + P_L + 2) >> 2);
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256 static inline void get_i4x4_horup(imgpel **cur_pred, imgpel *PredPel)
00257 {
00258 cur_pred[0][0] = (imgpel) ((P_I + P_J + 1) >> 1);
00259 cur_pred[0][1] = (imgpel) ((P_I + 2*P_J + P_K + 2) >> 2);
00260 cur_pred[0][2] =
00261 cur_pred[1][0] = (imgpel) ((P_J + P_K + 1) >> 1);
00262 cur_pred[0][3] =
00263 cur_pred[1][1] = (imgpel) ((P_J + 2*P_K + P_L + 2) >> 2);
00264 cur_pred[1][2] =
00265 cur_pred[2][0] = (imgpel) ((P_K + P_L + 1) >> 1);
00266 cur_pred[1][3] =
00267 cur_pred[2][1] = (imgpel) ((P_K + 2*P_L + P_L + 2) >> 2);
00268 cur_pred[3][0] =
00269 cur_pred[2][2] =
00270 cur_pred[2][3] =
00271 cur_pred[3][1] =
00272 cur_pred[3][2] =
00273 cur_pred[3][3] = (imgpel) P_L;
00274 }
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 void set_intrapred_4x4(Macroblock *currMB, ColorPlane pl, int img_x,int img_y, int *left_available, int *up_available, int *all_available)
00293 {
00294 ImageParameters *p_Img = currMB->p_Img;
00295 InputParameters *p_Inp = currMB->p_Inp;
00296
00297 int i;
00298 imgpel *PredPel = currMB->intra4x4_pred[pl];
00299 imgpel **img_enc = p_Img->enc_picture->p_curr_img;
00300 imgpel *img_pel;
00301
00302 int ioff = (img_x & 15);
00303 int joff = (img_y & 15);
00304
00305 PixelPos pix_a[4];
00306 PixelPos pix_b, pix_c, pix_d;
00307
00308 int block_available_up;
00309 int block_available_left;
00310 int block_available_up_left;
00311 int block_available_up_right;
00312 int *mb_size = p_Img->mb_size[IS_LUMA];
00313
00314 for (i=0;i<4;i++)
00315 {
00316 p_Img->getNeighbour(currMB, ioff -1 , joff +i , mb_size, &pix_a[i]);
00317 }
00318
00319 p_Img->getNeighbour(currMB, ioff , joff -1 , mb_size, &pix_b);
00320 p_Img->getNeighbour(currMB, ioff +4 , joff -1 , mb_size, &pix_c);
00321 p_Img->getNeighbour(currMB, ioff -1 , joff -1 , mb_size, &pix_d);
00322
00323 pix_c.available = pix_c.available && !((ioff==4) && ((joff==4)||(joff==12)));
00324
00325 if (p_Inp->UseConstrainedIntraPred)
00326 {
00327 for (i=0, block_available_left=1; i<4;i++)
00328 block_available_left &= pix_a[i].available ? p_Img->intra_block[pix_a[i].mb_addr]: 0;
00329 block_available_up = pix_b.available ? p_Img->intra_block [pix_b.mb_addr] : 0;
00330 block_available_up_right = pix_c.available ? p_Img->intra_block [pix_c.mb_addr] : 0;
00331 block_available_up_left = pix_d.available ? p_Img->intra_block [pix_d.mb_addr] : 0;
00332 }
00333 else
00334 {
00335 block_available_left = pix_a[0].available;
00336 block_available_up = pix_b.available;
00337 block_available_up_right = pix_c.available;
00338 block_available_up_left = pix_d.available;
00339 }
00340
00341 *left_available = block_available_left;
00342 *up_available = block_available_up;
00343 *all_available = block_available_up && block_available_left && block_available_up_left;
00344
00345 i = (img_x & 15);
00346
00347
00348
00349 if (block_available_up)
00350 {
00351 img_pel = &img_enc[pix_b.pos_y][pix_b.pos_x];
00352 P_A = *(img_pel++);
00353 P_B = *(img_pel++);
00354 P_C = *(img_pel++);
00355 P_D = *(img_pel);
00356
00357 }
00358 else
00359 {
00360 P_A = P_B = P_C = P_D = (imgpel) p_Img->dc_pred_value;
00361 }
00362
00363 if (block_available_up_right)
00364 {
00365 img_pel = &img_enc[pix_c.pos_y][pix_c.pos_x];
00366 P_E = *(img_pel++);
00367 P_F = *(img_pel++);
00368 P_G = *(img_pel++);
00369 P_H = *(img_pel);
00370 }
00371 else
00372 {
00373 P_E = P_F = P_G = P_H = P_D;
00374 }
00375
00376 if (block_available_left)
00377 {
00378 P_I = img_enc[pix_a[0].pos_y][pix_a[0].pos_x];
00379 P_J = img_enc[pix_a[1].pos_y][pix_a[1].pos_x];
00380 P_K = img_enc[pix_a[2].pos_y][pix_a[2].pos_x];
00381 P_L = img_enc[pix_a[3].pos_y][pix_a[3].pos_x];
00382 }
00383 else
00384 {
00385 P_I = P_J = P_K = P_L = p_Img->dc_pred_value;
00386 }
00387
00388 if (block_available_up_left)
00389 {
00390 P_X = img_enc[pix_d.pos_y][pix_d.pos_x];
00391 }
00392 else
00393 {
00394 P_X = p_Img->dc_pred_value;
00395 }
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 void get_intrapred_4x4(Macroblock *currMB, ColorPlane pl, int i4x4_mode, int img_x, int img_y, int left_available, int up_available)
00411 {
00412 imgpel *PredPel = currMB->intra4x4_pred[pl];
00413 imgpel ***curr_mpr_4x4 = currMB->p_slice->mpr_4x4[pl];
00414
00415
00416
00417 switch (i4x4_mode)
00418 {
00419 case VERT_PRED :
00420 get_i4x4_vertical(curr_mpr_4x4[VERT_PRED], PredPel);
00421 break;
00422 case HOR_PRED :
00423 get_i4x4_horizontal(curr_mpr_4x4[HOR_PRED], PredPel);
00424 break;
00425 case DC_PRED :
00426 get_i4x4_dc(curr_mpr_4x4[DC_PRED], PredPel, left_available, up_available);
00427 break;
00428 case DIAG_DOWN_LEFT_PRED :
00429 get_i4x4_downleft(curr_mpr_4x4[DIAG_DOWN_LEFT_PRED], PredPel);
00430 break;
00431 case DIAG_DOWN_RIGHT_PRED :
00432 get_i4x4_downright(curr_mpr_4x4[DIAG_DOWN_RIGHT_PRED], PredPel);
00433 break;
00434 case VERT_RIGHT_PRED :
00435 get_i4x4_vertright(curr_mpr_4x4[VERT_RIGHT_PRED], PredPel);
00436 break;
00437 case HOR_DOWN_PRED :
00438 get_i4x4_hordown(curr_mpr_4x4[HOR_DOWN_PRED], PredPel);
00439 break;
00440 case VERT_LEFT_PRED :
00441 get_i4x4_vertleft(curr_mpr_4x4[VERT_LEFT_PRED], PredPel);
00442 break;
00443 case HOR_UP_PRED :
00444 get_i4x4_horup(curr_mpr_4x4[HOR_UP_PRED], PredPel);
00445 break;
00446 default:
00447 printf("invalid prediction mode \n");
00448 break;
00449 }
00450 }