00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "contributors.h"
00016
00017 #include <stdlib.h>
00018 #include <assert.h>
00019 #include <limits.h>
00020 #include <math.h>
00021
00022 #include "block.h"
00023 #include "global.h"
00024
00025 #include "macroblock.h"
00026 #include "mc_prediction.h"
00027 #include "refbuf.h"
00028 #include "image.h"
00029 #include "mb_access.h"
00030 #include "me_distortion.h"
00031
00032
00033
00034
00035
00036
00037
00038 static inline void MCWeightedBiPrediction(imgpel** mb_pred, imgpel* l0pred, imgpel *l1pred,
00039 int block_size_y, int block_x, int block_size_x,
00040 int max_imgpel_value,
00041 short wbp0, short wbp1, short offset, short wp_round, short weight_denom)
00042 {
00043 int i, j;
00044 int block_x4 = block_x + block_size_x;
00045
00046 for (j = 0; j< block_size_y; j++)
00047 {
00048 for (i=block_x; i<block_x4; i++)
00049 mb_pred[j][i] = (imgpel) iClip1( max_imgpel_value,
00050 ((wbp0 * *l0pred++ + wbp1 * *l1pred++ + wp_round) >> (weight_denom)) + offset);
00051 }
00052 }
00053
00054
00055
00056
00057
00058
00059
00060 static inline void MCWeightedPrediction(imgpel** mb_pred, imgpel* lpred,
00061 int block_size_y, int block_x, int block_size_x,
00062 int max_imgpel_value,
00063 short wp, short offset, short wp_round, short weight_denom)
00064 {
00065 int i, j;
00066 int block_x4 = block_x + block_size_x;
00067
00068 for (j = 0; j < block_size_y; j++)
00069 {
00070 for (i=block_x; i<block_x4; i++)
00071 mb_pred[j][i] = (imgpel) iClip1( max_imgpel_value,
00072 ((wp * *lpred++ + wp_round) >> weight_denom) + offset);
00073 }
00074 }
00075
00076
00077
00078
00079
00080
00081
00082 static inline void MCBiPrediction(imgpel** mb_pred, imgpel* l0pred, imgpel *l1pred,
00083 int block_size_y, int block_x, int block_size_x)
00084 {
00085 int i, j;
00086 int block_x4 = block_x + block_size_x;
00087
00088 for (j = 0; j < block_size_y; j++)
00089 {
00090 for (i=block_x; i<block_x4; i++)
00091 mb_pred[j][i] = (*l0pred++ + *l1pred++ + 1) >> 1;
00092 }
00093 }
00094
00095
00096
00097
00098
00099
00100
00101 static inline void MCPrediction(imgpel** mb_pred, imgpel* lpred, int block_size_y, int block_x, int block_size_x)
00102 {
00103 int j;
00104 for (j = 0; j < block_size_y; j++)
00105 {
00106 memcpy(&(mb_pred[j][block_x]), lpred, block_size_x * sizeof(imgpel));
00107 lpred += block_size_x;
00108 }
00109 }
00110
00111
00112
00113
00114
00115
00116
00117 static inline void OneComponentLumaPrediction ( ImageParameters *p_Img,
00118 imgpel* mpred,
00119 int pic_pix_x,
00120 int pic_pix_y,
00121 int block_size_x,
00122 int block_size_y,
00123 StorablePicture *list
00124 )
00125 {
00126 int j;
00127 imgpel *ref_line = UMVLine4X (list, pic_pix_y, pic_pix_x);
00128
00129 for (j = 0; j < block_size_y; j++)
00130 {
00131 memcpy(mpred, ref_line, block_size_x * sizeof(imgpel));
00132 ref_line += p_Img->padded_size_x;
00133 mpred += block_size_x;
00134 }
00135 }
00136
00137
00138
00139
00140
00141
00142
00143
00144 void luma_prediction (Macroblock* currMB,
00145 int block_x,
00146 int block_y,
00147 int block_size_x,
00148 int block_size_y,
00149 int p_dir,
00150 int list_mode[2],
00151 char *ref_idx,
00152 short bipred_me
00153 )
00154 {
00155 ImageParameters *p_Img = currMB->p_Img;
00156 InputParameters *p_Inp = currMB->p_Inp;
00157 Slice *currSlice = currMB->p_slice;
00158 imgpel l0_pred[MB_PIXELS];
00159 imgpel l1_pred[MB_PIXELS];
00160
00161 #if (PAD_AFTER)
00162 int pic_opix_x = ((currMB->pix_x + block_x) << 2);
00163 int pic_opix_y = ((currMB->opix_y + block_y) << 2);
00164 #else
00165 int pic_opix_x = ((currMB->pix_x + block_x) << 2) + IMG_PAD_SIZE_TIMES4;
00166 int pic_opix_y = ((currMB->opix_y + block_y) << 2) + IMG_PAD_SIZE_TIMES4;
00167 #endif
00168 int bx = block_x >> 2;
00169 int by = block_y >> 2;
00170 short****** mv_array = currSlice->all_mv;
00171 short *curr_mv = NULL;
00172 imgpel **mb_pred = currSlice->mb_pred[0];
00173
00174 int apply_weights = ( currSlice->weighted_prediction != 0 );
00175
00176 if (bipred_me && ref_idx[0] == 0 && ref_idx[1] == 0 && p_dir == 2 && is_bipred_enabled(p_Inp, list_mode[0]) && is_bipred_enabled(p_Inp, list_mode[1]))
00177 mv_array = currSlice->bipred_mv[bipred_me - 1];
00178
00179 switch (p_dir)
00180 {
00181 case 0:
00182 curr_mv = mv_array[LIST_0][(short) ref_idx[0]][list_mode[0]][by][bx];
00183 OneComponentLumaPrediction (p_Img, l0_pred, pic_opix_x + curr_mv[0], pic_opix_y + curr_mv[1], block_size_x, block_size_y, p_Img->listX[LIST_0 + currMB->list_offset][(short) ref_idx[0]]);
00184 break;
00185 case 1:
00186 curr_mv = mv_array[LIST_1][(short) ref_idx[1]][list_mode[1]][by][bx];
00187 OneComponentLumaPrediction (p_Img, l1_pred, pic_opix_x + curr_mv[0], pic_opix_y + curr_mv[1], block_size_x, block_size_y, p_Img->listX[LIST_1 + currMB->list_offset][(short)ref_idx[1]]);
00188 break;
00189 case 2:
00190 curr_mv = mv_array[LIST_0][(short) ref_idx[0]][list_mode[0]][by][bx];
00191 OneComponentLumaPrediction (p_Img, l0_pred, pic_opix_x + curr_mv[0], pic_opix_y + curr_mv[1], block_size_x, block_size_y, p_Img->listX[LIST_0 + currMB->list_offset][(short)ref_idx[0]]);
00192 curr_mv = mv_array[LIST_1][(short) ref_idx[1]][list_mode[1]][by][bx];
00193 OneComponentLumaPrediction (p_Img, l1_pred, pic_opix_x + curr_mv[0], pic_opix_y + curr_mv[1], block_size_x, block_size_y, p_Img->listX[LIST_1 + currMB->list_offset][(short)ref_idx[1]]);
00194 break;
00195 default:
00196 break;
00197 }
00198
00199 if (apply_weights)
00200 {
00201 if (p_dir==2)
00202 {
00203 MCWeightedBiPrediction(&mb_pred[block_y], l0_pred, l1_pred, block_size_y, block_x, block_size_x,
00204 p_Img->max_imgpel_value,
00205 currSlice->wbp_weight[0][(short)ref_idx[0]][(short)ref_idx[1]][0], currSlice->wbp_weight[1][(short)ref_idx[0]][(short)ref_idx[1]][0],
00206 (currSlice->wp_offset[0][(short)ref_idx[0]][0] + currSlice->wp_offset[1][(short)ref_idx[1]][0] + 1)>>1,
00207 (currSlice->wp_luma_round << 1), currSlice->luma_log_weight_denom + 1);
00208 }
00209 else if (p_dir==0)
00210 {
00211 MCWeightedPrediction(&mb_pred[block_y], l0_pred, block_size_y, block_x, block_size_x,
00212 p_Img->max_imgpel_value,
00213 currSlice->wp_weight[0][(short)ref_idx[0]][0], currSlice->wp_offset[0][(short)ref_idx[0]][0], currSlice->wp_luma_round, currSlice->luma_log_weight_denom);
00214 }
00215 else
00216 {
00217 MCWeightedPrediction(&mb_pred[block_y], l1_pred, block_size_y, block_x, block_size_x,
00218 p_Img->max_imgpel_value,
00219 currSlice->wp_weight[1][(short)ref_idx[1]][0], currSlice->wp_offset[1][(short)ref_idx[1]][0], currSlice->wp_luma_round, currSlice->luma_log_weight_denom);
00220 }
00221 }
00222 else
00223 {
00224 if (p_dir==2)
00225 {
00226 MCBiPrediction(&mb_pred[block_y], l0_pred, l1_pred, block_size_y, block_x, block_size_x);
00227 }
00228 else if (p_dir==0)
00229 {
00230 MCPrediction(&mb_pred[block_y], l0_pred, block_size_y, block_x, block_size_x);
00231 }
00232 else
00233 {
00234 MCPrediction(&mb_pred[block_y], l1_pred, block_size_y, block_x, block_size_x);
00235 }
00236 }
00237 }
00238
00239
00240
00241
00242
00243
00244
00245 void luma_prediction_bi (Macroblock* currMB,
00246 int block_x,
00247 int block_y,
00248 int block_size_x,
00249 int block_size_y,
00250 int l0_mode,
00251 int l1_mode,
00252 short l0_ref_idx,
00253 short l1_ref_idx,
00254 int list
00255 )
00256 {
00257 ImageParameters *p_Img = currMB->p_Img;
00258 Slice *currSlice = currMB->p_slice;
00259
00260 imgpel l0_pred[MB_PIXELS];
00261 imgpel l1_pred[MB_PIXELS];
00262 #if (PAD_AFTER)
00263 int pic_opix_x = ((currMB->pix_x + block_x) << 2);
00264 int pic_opix_y = ((currMB->opix_y + block_y) << 2);
00265 #else
00266 int pic_opix_x = ((currMB->pix_x + block_x) << 2) + IMG_PAD_SIZE_TIMES4;
00267 int pic_opix_y = ((currMB->opix_y + block_y) << 2) + IMG_PAD_SIZE_TIMES4;
00268 #endif
00269 int bx = block_x >> 2;
00270 int by = block_y >> 2;
00271
00272 int apply_weights = ( currSlice->weighted_prediction != 0 );
00273
00274 short ******mv_array = currSlice->bipred_mv[list];
00275 short *mv_arrayl0 = mv_array[LIST_0][l0_ref_idx][l0_mode][by][bx];
00276 short *mv_arrayl1 = mv_array[LIST_1][l1_ref_idx][l1_mode][by][bx];
00277 imgpel **mb_pred = currSlice->mb_pred[0];
00278
00279 OneComponentLumaPrediction (p_Img, l0_pred, pic_opix_x + mv_arrayl0[0], pic_opix_y + mv_arrayl0[1], block_size_x, block_size_y, p_Img->listX[0+currMB->list_offset][l0_ref_idx]);
00280 OneComponentLumaPrediction (p_Img, l1_pred, pic_opix_x + mv_arrayl1[0], pic_opix_y + mv_arrayl1[1], block_size_x, block_size_y, p_Img->listX[1+currMB->list_offset][l1_ref_idx]);
00281
00282 if (apply_weights)
00283 {
00284 MCWeightedBiPrediction(&mb_pred[block_y], l0_pred, l1_pred, block_size_y, block_x, block_size_x,
00285 p_Img->max_imgpel_value,
00286 currSlice->wbp_weight[0][l0_ref_idx][l1_ref_idx][0], currSlice->wbp_weight[1][l0_ref_idx][l1_ref_idx][0],
00287 (currSlice->wp_offset[0][l0_ref_idx][0] + currSlice->wp_offset[1][l1_ref_idx][0] + 1)>>1,
00288 (currSlice->wp_luma_round << 1), currSlice->luma_log_weight_denom + 1);
00289 }
00290 else
00291 {
00292 MCBiPrediction(&mb_pred[block_y], l0_pred, l1_pred, block_size_y, block_x, block_size_x);
00293 }
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303 void OneComponentChromaPrediction4x4_regenerate (
00304 Macroblock *currMB,
00305 imgpel* mpred,
00306 int block_c_x,
00307 int block_c_y,
00308 short*** mv,
00309 StorablePicture *list,
00310 int uv)
00311 {
00312 ImageParameters *p_Img = currMB->p_Img;
00313 int i, j, ii, jj, ii0, jj0, ii1, jj1, if0, if1, jf0, jf1;
00314 short* mvb;
00315
00316 int f1_x = 64/p_Img->mb_cr_size_x;
00317 int f2_x=f1_x-1;
00318
00319 int f1_y = 64/p_Img->mb_cr_size_y;
00320 int f2_y=f1_y-1;
00321
00322 int f3=f1_x*f1_y, f4=f3>>1;
00323 int list_offset = p_Img->mb_data[currMB->mbAddrX].list_offset;
00324 int max_y_cr = (int) (list_offset ? (p_Img->height_cr >> 1) - 1 : p_Img->height_cr - 1);
00325 int max_x_cr = (int) (p_Img->width_cr - 1);
00326 int jjx, iix;
00327 int mb_cr_y_div4 = p_Img->mb_cr_size_y>>2;
00328 int mb_cr_x_div4 = p_Img->mb_cr_size_x>>2;
00329 int jpos;
00330
00331 imgpel** refimage = list->imgUV[uv];
00332
00333 for (j=block_c_y; j < block_c_y + BLOCK_SIZE; j++)
00334 {
00335 jjx = j/mb_cr_y_div4;
00336 jpos = (j + currMB->opix_c_y)*f1_y;
00337
00338 for (i=block_c_x; i < block_c_x + BLOCK_SIZE; i++)
00339 {
00340 iix = i/mb_cr_x_div4;
00341 mvb = mv [jjx][iix];
00342
00343 ii = (i + currMB->pix_c_x)*f1_x + mvb[0];
00344 jj = jpos + mvb[1];
00345
00346 if (p_Img->active_sps->chroma_format_idc == 1)
00347 jj += list->chroma_vector_adjustment;
00348
00349 ii0 = iClip3 (0, max_x_cr, ii/f1_x);
00350 jj0 = iClip3 (0, max_y_cr, jj/f1_y);
00351 ii1 = iClip3 (0, max_x_cr, (ii+f2_x)/f1_x);
00352 jj1 = iClip3 (0, max_y_cr, (jj+f2_y)/f1_y);
00353
00354 if1 = (ii&f2_x); if0 = f1_x-if1;
00355 jf1 = (jj&f2_y); jf0 = f1_y-jf1;
00356
00357 *mpred++ = (imgpel) (
00358 (if0 * jf0 * refimage[jj0][ii0] +
00359 if1 * jf0 * refimage[jj0][ii1] +
00360 if0 * jf1 * refimage[jj1][ii0] +
00361 if1 * jf1 * refimage[jj1][ii1] + f4) / f3);
00362 }
00363 }
00364 }
00365
00366
00367
00368
00369
00370
00371
00372 void OneComponentChromaPrediction4x4_retrieve (
00373 Macroblock *currMB,
00374 imgpel* mpred,
00375 int block_c_x,
00376 int block_c_y,
00377 short*** mv,
00378 StorablePicture *list,
00379 int uv)
00380 {
00381 ImageParameters *p_Img = currMB->p_Img;
00382 int j, ii, jj;
00383 short* mvb;
00384
00385 int jjx;
00386 int right_shift_x = 4 - p_Img->chroma_shift_x;
00387 int right_shift_y = 4 - p_Img->chroma_shift_y;
00388 int jpos;
00389
00390 int pos_x1 = block_c_x >> right_shift_x;
00391 int pos_x2 = (block_c_x + 2) >> right_shift_x;
00392
00393 #if (PAD_AFTER)
00394 int ipos1 = ((block_c_x + currMB->pix_c_x ) << p_Img->chroma_shift_x);
00395 int ipos2 = ((block_c_x + currMB->pix_c_x + 2) << p_Img->chroma_shift_x);
00396 int jj_chroma = ((p_Img->active_sps->chroma_format_idc == 1) ? list->chroma_vector_adjustment : 0);
00397 #else
00398 int ipos1 = ((block_c_x + currMB->pix_c_x ) << p_Img->chroma_shift_x) + IMG_PAD_SIZE_TIMES4;
00399 int ipos2 = ((block_c_x + currMB->pix_c_x + 2) << p_Img->chroma_shift_x) + IMG_PAD_SIZE_TIMES4;
00400 int jj_chroma = ((p_Img->active_sps->chroma_format_idc == 1) ? list->chroma_vector_adjustment : 0) + IMG_PAD_SIZE_TIMES4;
00401 #endif
00402
00403 imgpel *line_ptr;
00404
00405 for (j=block_c_y; j < block_c_y + BLOCK_SIZE; j++)
00406 {
00407 jjx = j >> right_shift_y;
00408
00409 jpos = ( (j + currMB->opix_c_y) << p_Img->chroma_shift_y ) + jj_chroma;
00410
00411 mvb = mv [jjx][pos_x1];
00412
00413 ii = ipos1 + mvb[0];
00414 jj = jpos + mvb[1];
00415
00416 line_ptr = UMVLine8X_chroma ( list, uv + 1, jj, ii);
00417 *mpred++ = *line_ptr++;
00418 *mpred++ = *line_ptr;
00419
00420 mvb = mv [jjx][pos_x2];
00421
00422 ii = ipos2 + mvb[0];
00423 jj = jpos + mvb[1];
00424
00425 line_ptr = UMVLine8X_chroma ( list, uv + 1, jj, ii);
00426 *mpred++ = *line_ptr++;
00427 *mpred++ = *line_ptr;
00428 }
00429 }
00430
00431
00432
00433
00434
00435
00436
00437
00438 static inline
00439 void OneComponentChromaPrediction (ImageParameters *p_Img,
00440 imgpel* mpred,
00441 int pic_pix_x,
00442 int pic_pix_y,
00443 int block_size_x,
00444 int block_size_y,
00445 StorablePicture *list,
00446 int uv)
00447 {
00448 int j;
00449 imgpel *ref_line = UMVLine4Xcr (list, uv + 1, pic_pix_y, pic_pix_x);
00450
00451 for (j = 0; j < block_size_y; j++)
00452 {
00453 memcpy(mpred, ref_line, block_size_x * sizeof(imgpel));
00454 ref_line += p_Img->cr_padded_size_x;
00455 mpred += block_size_x;
00456 }
00457 }
00458
00459
00460
00461
00462
00463
00464
00465 static inline
00466 void IntraChromaPrediction4x4 (Macroblock* currMB,
00467 int uv,
00468 int block_x,
00469 int block_y)
00470 {
00471 int j;
00472 Slice *currSlice = currMB->p_slice;
00473 imgpel **mb_pred = currSlice->mb_pred[ uv ];
00474 imgpel **curr_mpr_16x16 = currSlice->mpr_16x16[uv][ (short) currMB->c_ipred_mode];
00475
00476
00477 for (j=block_y; j<block_y + BLOCK_SIZE; j++)
00478 memcpy(&mb_pred[j][block_x],&curr_mpr_16x16[j][block_x], BLOCK_SIZE * sizeof(imgpel));
00479 }
00480
00481
00482
00483
00484
00485
00486
00487 void chroma_prediction (Macroblock* currMB,
00488 int uv,
00489 int block_x,
00490 int block_y,
00491 int block_size_x,
00492 int block_size_y,
00493 int p_dir,
00494 int l0_mode,
00495 int l1_mode,
00496 short l0_ref_idx,
00497 short l1_ref_idx,
00498 short bipred_me
00499 )
00500 {
00501 ImageParameters *p_Img = currMB->p_Img;
00502 InputParameters *p_Inp = currMB->p_Inp;
00503 Slice *currSlice = currMB->p_slice;
00504
00505 imgpel l0_pred[MB_PIXELS];
00506 imgpel l1_pred[MB_PIXELS];
00507
00508 #if (PAD_AFTER)
00509 int pic_opix_x = ((currMB->pix_c_x + block_x) << 2);
00510 int pic_opix_y = ((currMB->opix_c_y + block_y) << 2);
00511 #else
00512 int pic_opix_x = ((currMB->pix_c_x + block_x) << 2) + IMG_PAD_SIZE_TIMES4;
00513 int pic_opix_y = ((currMB->opix_c_y + block_y) << 2) + IMG_PAD_SIZE_TIMES4;
00514 #endif
00515 int bx = block_x >> 2;
00516 int by = block_y >> 2;
00517 short****** mv_array = currSlice->all_mv;
00518 int uv_comp = uv + 1;
00519 imgpel **mb_pred = currSlice->mb_pred[ uv_comp];
00520
00521 int apply_weights = ( currSlice->weighted_prediction != 0 );
00522
00523 if (bipred_me && l0_ref_idx == 0 && l1_ref_idx == 0 && p_dir == 2 && is_bipred_enabled(p_Inp, l0_mode) && is_bipred_enabled(p_Inp, l1_mode))
00524 mv_array = currSlice->bipred_mv[bipred_me - 1];
00525
00526
00527 if (p_dir==-1)
00528 {
00529 IntraChromaPrediction4x4 (currMB, uv_comp, block_x, block_y);
00530 return;
00531 }
00532
00533
00534 switch (p_dir)
00535 {
00536 case 0:
00537 OneComponentChromaPrediction (p_Img, l0_pred, pic_opix_x + mv_array[LIST_0][l0_ref_idx][l0_mode][by][bx][0], pic_opix_y + mv_array[LIST_0][l0_ref_idx][l0_mode][by][bx][1], block_size_x, block_size_y, p_Img->listX[0+currMB->list_offset][l0_ref_idx], uv);
00538 break;
00539 case 1:
00540 OneComponentChromaPrediction (p_Img, l1_pred, pic_opix_x + mv_array[LIST_1][l1_ref_idx][l1_mode][by][bx][0], pic_opix_y + mv_array[LIST_1][l1_ref_idx][l1_mode][by][bx][1], block_size_x, block_size_y, p_Img->listX[1+currMB->list_offset][l1_ref_idx], uv);
00541 break;
00542 case 2:
00543 OneComponentChromaPrediction (p_Img, l0_pred, pic_opix_x + mv_array[LIST_0][l0_ref_idx][l0_mode][by][bx][0], pic_opix_y + mv_array[LIST_0][l0_ref_idx][l0_mode][by][bx][1], block_size_x, block_size_y, p_Img->listX[0+currMB->list_offset][l0_ref_idx], uv);
00544 OneComponentChromaPrediction (p_Img, l1_pred, pic_opix_x + mv_array[LIST_1][l1_ref_idx][l1_mode][by][bx][0], pic_opix_y + mv_array[LIST_1][l1_ref_idx][l1_mode][by][bx][1], block_size_x, block_size_y, p_Img->listX[1+currMB->list_offset][l1_ref_idx], uv);
00545 break;
00546 default:
00547 break;
00548 }
00549
00550 if (apply_weights)
00551 {
00552 if (p_dir==2)
00553 {
00554 MCWeightedBiPrediction(&mb_pred[block_y], l0_pred, l1_pred, block_size_y, block_x, block_size_x,
00555 p_Img->max_pel_value_comp[1],
00556 currSlice->wbp_weight[0][l0_ref_idx][l1_ref_idx][uv_comp], currSlice->wbp_weight[1][l0_ref_idx][l1_ref_idx][uv_comp],
00557 (currSlice->wp_offset[0][l0_ref_idx][uv_comp] + currSlice->wp_offset[1][l1_ref_idx][uv_comp] + 1)>>1,
00558 (currSlice->wp_chroma_round << 1), currSlice->chroma_log_weight_denom + 1);
00559 }
00560 else if (p_dir==0)
00561 {
00562 MCWeightedPrediction(&mb_pred[block_y], l0_pred, block_size_y, block_x, block_size_x,
00563 p_Img->max_pel_value_comp[1],
00564 currSlice->wp_weight[0][l0_ref_idx][uv_comp], currSlice->wp_offset[0][l0_ref_idx][uv_comp], currSlice->wp_chroma_round, currSlice->chroma_log_weight_denom );
00565 }
00566 else
00567 {
00568 MCWeightedPrediction(&mb_pred[block_y], l1_pred, block_size_y, block_x, block_size_x,
00569 p_Img->max_pel_value_comp[1],
00570 currSlice->wp_weight[1][l1_ref_idx][uv_comp], currSlice->wp_offset[1][l1_ref_idx][uv_comp], currSlice->wp_chroma_round, currSlice->chroma_log_weight_denom );
00571 }
00572 }
00573 else
00574 {
00575 if (p_dir==2)
00576 {
00577 MCBiPrediction(&mb_pred[block_y], l0_pred, l1_pred, block_size_y, block_x, block_size_x);
00578 }
00579 else if (p_dir==0)
00580 {
00581 MCPrediction(&mb_pred[block_y], l0_pred, block_size_y, block_x, block_size_x);
00582 }
00583 else
00584 {
00585 MCPrediction(&mb_pred[block_y], l1_pred, block_size_y, block_x, block_size_x);
00586 }
00587 }
00588 }
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598 void chroma_prediction_4x4 (Macroblock* currMB,
00599 int uv,
00600 int block_x,
00601 int block_y,
00602 int p_dir,
00603 int l0_mode,
00604 int l1_mode,
00605 short l0_ref_idx,
00606 short l1_ref_idx,
00607 short bipred_me
00608 )
00609 {
00610 ImageParameters *p_Img = currMB->p_Img;
00611 InputParameters *p_Inp = currMB->p_Inp;
00612 Slice *currSlice = currMB->p_slice;
00613
00614 imgpel l0_pred[MB_PIXELS];
00615 imgpel l1_pred[MB_PIXELS];
00616
00617 short****** mv_array = currSlice->all_mv;
00618 int uv_comp = uv + 1;
00619 imgpel **mb_pred = currSlice->mb_pred[uv_comp];
00620 int list_offset = currMB->list_offset;
00621
00622 int apply_weights = ( currSlice->weighted_prediction != 0 );
00623
00624 if (bipred_me && l0_ref_idx == 0 && l1_ref_idx == 0 && p_dir == 2 && is_bipred_enabled(p_Inp, l0_mode) && is_bipred_enabled(p_Inp, l1_mode) )
00625 mv_array = currSlice->bipred_mv[bipred_me - 1];
00626
00627 if (p_dir==-1)
00628 {
00629 IntraChromaPrediction4x4 (currMB, uv_comp, block_x, block_y);
00630 return;
00631 }
00632
00633
00634 switch (p_dir)
00635 {
00636 case 0:
00637 p_Img->OneComponentChromaPrediction4x4 (currMB, l0_pred, block_x, block_y, mv_array[LIST_0][l0_ref_idx][l0_mode], p_Img->listX[LIST_0 + list_offset][l0_ref_idx], uv);
00638 break;
00639 case 1:
00640 p_Img->OneComponentChromaPrediction4x4 (currMB, l1_pred, block_x, block_y, mv_array[LIST_1][l1_ref_idx][l1_mode], p_Img->listX[LIST_1 + list_offset][l1_ref_idx], uv);
00641 break;
00642 case 2:
00643 p_Img->OneComponentChromaPrediction4x4 (currMB, l0_pred, block_x, block_y, mv_array[LIST_0][l0_ref_idx][l0_mode], p_Img->listX[LIST_0 + list_offset][l0_ref_idx], uv);
00644 p_Img->OneComponentChromaPrediction4x4 (currMB, l1_pred, block_x, block_y, mv_array[LIST_1][l1_ref_idx][l1_mode], p_Img->listX[LIST_1 + list_offset][l1_ref_idx], uv);
00645 break;
00646 default:
00647 break;
00648 }
00649
00650 if (apply_weights)
00651 {
00652 if (p_dir==2)
00653 {
00654 MCWeightedBiPrediction(&mb_pred[block_y], l0_pred, l1_pred, BLOCK_SIZE, block_x, BLOCK_SIZE,
00655 p_Img->max_pel_value_comp[1],
00656 currSlice->wbp_weight[0][l0_ref_idx][l1_ref_idx][uv_comp], currSlice->wbp_weight[1][l0_ref_idx][l1_ref_idx][uv_comp],
00657 (currSlice->wp_offset[0][l0_ref_idx][uv_comp] + currSlice->wp_offset[1][l1_ref_idx][uv_comp] + 1)>>1,
00658 (currSlice->wp_chroma_round << 1), currSlice->chroma_log_weight_denom + 1);
00659
00660 }
00661 else if (p_dir==0)
00662 {
00663 MCWeightedPrediction(&mb_pred[block_y], l0_pred, BLOCK_SIZE, block_x, BLOCK_SIZE,
00664 p_Img->max_pel_value_comp[1],
00665 currSlice->wp_weight[0][l0_ref_idx][uv_comp], currSlice->wp_offset[0][l0_ref_idx][uv_comp], currSlice->wp_chroma_round, currSlice->chroma_log_weight_denom );
00666 }
00667 else
00668 {
00669 MCWeightedPrediction(&mb_pred[block_y], l1_pred, BLOCK_SIZE, block_x, BLOCK_SIZE,
00670 p_Img->max_pel_value_comp[1],
00671 currSlice->wp_weight[1][l1_ref_idx][uv_comp], currSlice->wp_offset[1][l1_ref_idx][uv_comp], currSlice->wp_chroma_round, currSlice->chroma_log_weight_denom );
00672 }
00673 }
00674 else
00675 {
00676 if (p_dir==2)
00677 {
00678 MCBiPrediction(&mb_pred[block_y], l0_pred, l1_pred, BLOCK_SIZE, block_x, BLOCK_SIZE);
00679 }
00680 else if (p_dir==0)
00681 {
00682 MCPrediction(&mb_pred[block_y], l0_pred, BLOCK_SIZE, block_x, BLOCK_SIZE);
00683 }
00684 else
00685 {
00686 MCPrediction(&mb_pred[block_y], l1_pred, BLOCK_SIZE, block_x, BLOCK_SIZE);
00687 }
00688 }
00689 }
00690
00691
00692
00693
00694
00695
00696
00697
00698 void intra_chroma_prediction (Macroblock *currMB, int *mb_up, int *mb_left, int*mb_up_left)
00699 {
00700 int s, s0, s1, s2, s3, i, j, k;
00701 int ih,iv, ib, ic, iaa;
00702 int uv;
00703 int blk_x, blk_y;
00704 int b8,b4;
00705 imgpel** image;
00706 imgpel vline[16];
00707 int block_x, block_y;
00708 int mb_available_up;
00709 int mb_available_left[2];
00710 int mb_available_up_left;
00711
00712 int mode;
00713 int best_mode = DC_PRED_8;
00714 int cost;
00715 int min_cost;
00716 PixelPos up;
00717 PixelPos left[17];
00718 int diff [16];
00719
00720 Slice *currSlice = currMB->p_slice;
00721 ImageParameters *p_Img = currSlice->p_Img;
00722 InputParameters *p_Inp = currSlice->p_Inp;
00723 int cr_MB_x = p_Img->mb_cr_size_x;
00724 int cr_MB_y = p_Img->mb_cr_size_y;
00725 imgpel **cur_pred = NULL;
00726 imgpel ***curr_mpr_16x16 = NULL;
00727 imgpel *hline = NULL;
00728 imgpel *img_org = NULL, *img_prd = NULL;
00729
00730 int yuv = p_Img->yuv_format - 1;
00731 int dc_pred_value_chroma = p_Img->dc_pred_value_comp[1];
00732 int max_imgpel_value_uv = p_Img->max_pel_value_comp[1];
00733
00734 static const int block_pos[3][4][4]=
00735 {
00736 { {0, 1, 2, 3},{0, 0, 0, 0},{0, 0, 0, 0},{0, 0, 0, 0}},
00737 { {0, 1, 2, 3},{2, 3, 2, 3},{0, 0, 0, 0},{0, 0, 0, 0}},
00738 { {0, 1, 2, 3},{1, 1, 3, 3},{2, 3, 2, 3},{3, 3, 3, 3}}
00739 };
00740
00741 for (i=0;i<cr_MB_y+1;i++)
00742 {
00743 p_Img->getNeighbour(currMB, -1 , i-1 , p_Img->mb_size[IS_CHROMA], &left[i]);
00744 }
00745 p_Img->getNeighbour(currMB, 0 , -1 , p_Img->mb_size[IS_CHROMA], &up);
00746
00747 mb_available_up = up.available;
00748 mb_available_up_left = left[0].available;
00749 mb_available_left[0] = mb_available_left[1] = left[1].available;
00750
00751 if(p_Inp->UseConstrainedIntraPred)
00752 {
00753 mb_available_up = up.available ? p_Img->intra_block[up.mb_addr] : 0;
00754 for (i=0, mb_available_left[0]=1; i<(cr_MB_y>>1);i++)
00755 mb_available_left[0] &= left[i+1].available ? p_Img->intra_block[left[i+1].mb_addr]: 0;
00756 for (i=(cr_MB_y>>1), mb_available_left[1]=1; i<cr_MB_y;i++)
00757 mb_available_left[1] &= left[i+1].available ? p_Img->intra_block[left[i+1].mb_addr]: 0;
00758 mb_available_up_left = left[0].available ? p_Img->intra_block[left[0].mb_addr]: 0;
00759 }
00760
00761 if (mb_up)
00762 *mb_up = mb_available_up;
00763 if (mb_left)
00764 *mb_left = mb_available_left[0] && mb_available_left[1];
00765 if (mb_up_left)
00766 *mb_up_left = mb_available_up_left;
00767
00768
00769
00770 for (uv=0; uv<2; uv++)
00771 {
00772 image = p_Img->enc_picture->imgUV[uv];
00773 curr_mpr_16x16 = currSlice->mpr_16x16[uv + 1];
00774
00775
00776 for(b8=0; b8<p_Img->num_blk8x8_uv >> 1;b8++)
00777 {
00778 for (b4 = 0; b4 < 4; b4++)
00779 {
00780 block_y = subblk_offset_y[yuv][b8][b4];
00781 block_x = subblk_offset_x[yuv][b8][b4];
00782 blk_x = block_x;
00783 blk_y = block_y + 1;
00784
00785 s = dc_pred_value_chroma;
00786 s0 = s1 = s2 = s3 = 0;
00787
00788
00789 switch (block_pos[yuv][b8][b4])
00790 {
00791 case 0:
00792 if (mb_available_up)
00793 for (i = blk_x; i < (blk_x + 4); i++)
00794 s0 += image[up.pos_y][up.pos_x + i];
00795 if (mb_available_left[0])
00796 for (i = blk_y; i < (blk_y + 4);i++)
00797 s2 += image[left[i].pos_y][left[i].pos_x];
00798 if (mb_available_up && mb_available_left[0])
00799 s = (s0 + s2 + 4) >> 3;
00800 else if (mb_available_up)
00801 s = (s0 + 2) >> 2;
00802 else if (mb_available_left[0])
00803 s = (s2 +2) >> 2;
00804 break;
00805 case 1:
00806 if (mb_available_up)
00807 for (i=blk_x;i<(blk_x+4);i++)
00808 s1 += image[up.pos_y][up.pos_x + i];
00809 else if (mb_available_left[0])
00810 for (i=blk_y;i<(blk_y+4);i++)
00811 s2 += image[left[i].pos_y][left[i].pos_x];
00812 if (mb_available_up)
00813 s = (s1 +2) >> 2;
00814 else if (mb_available_left[0])
00815 s = (s2 +2) >> 2;
00816 break;
00817 case 2:
00818 if (mb_available_left[1])
00819 for (i=blk_y;i<(blk_y+4);i++)
00820 s3 += image[left[i].pos_y][left[i].pos_x];
00821 else if (mb_available_up)
00822 for (i=blk_x;i<(blk_x+4);i++)
00823 s0 += image[up.pos_y][up.pos_x + i];
00824 if (mb_available_left[1])
00825 s = (s3 +2) >> 2;
00826 else if (mb_available_up)
00827 s = (s0 +2) >> 2;
00828 break;
00829 case 3:
00830 if (mb_available_up)
00831 for (i=blk_x;i<(blk_x+4);i++)
00832 s1 += image[up.pos_y][up.pos_x + i];
00833 if (mb_available_left[1])
00834 for (i=blk_y;i<(blk_y+4);i++)
00835 s3 += image[left[i].pos_y][left[i].pos_x];
00836 if (mb_available_up && mb_available_left[1])
00837 s = (s1+s3+4) >> 3;
00838 else if (mb_available_up)
00839 s = (s1 +2) >> 2;
00840 else if (mb_available_left[1])
00841 s = (s3 +2) >> 2;
00842 break;
00843 }
00844
00845
00846 cur_pred = curr_mpr_16x16[DC_PRED_8];
00847 for (j=block_y; j<block_y+4; j++)
00848 for (i=block_x; i<block_x+4; i++)
00849 {
00850 cur_pred[j][i] = (imgpel) s;
00851 }
00852 }
00853 }
00854
00855
00856 if (mb_available_up)
00857 {
00858 cur_pred = curr_mpr_16x16[VERT_PRED_8];
00859
00860 hline = &image[up.pos_y][up.pos_x];
00861 for (j=0; j<cr_MB_y; j++)
00862 memcpy(cur_pred[j], hline, cr_MB_x * sizeof(imgpel));
00863 }
00864
00865
00866 if (mb_available_left[0] && mb_available_left[1])
00867 {
00868 cur_pred = curr_mpr_16x16[HOR_PRED_8];
00869 for (i=0; i<cr_MB_y; i++)
00870 vline[i] = image[left[i+1].pos_y][left[i+1].pos_x];
00871 for (j=0; j<cr_MB_y; j++)
00872 {
00873 int predictor = vline[j];
00874 for (i=0; i<cr_MB_x; i++)
00875 cur_pred[j][i] = (imgpel) predictor;
00876 }
00877 }
00878
00879
00880 if (mb_available_left[0] && mb_available_left[1] && mb_available_up && mb_available_up_left)
00881 {
00882 ih = (cr_MB_x>>1)*(hline[cr_MB_x-1] - image[left[0].pos_y][left[0].pos_x]);
00883 for (i=0;i<(cr_MB_x>>1)-1;i++)
00884 ih += (i+1)*(hline[(cr_MB_x>>1)+i] - hline[(cr_MB_x>>1)-2-i]);
00885
00886 iv = (cr_MB_y>>1)*(vline[cr_MB_y-1] - image[left[0].pos_y][left[0].pos_x]);
00887 for (i=0;i<(cr_MB_y>>1)-1;i++)
00888 iv += (i+1)*(vline[(cr_MB_y>>1)+i] - vline[(cr_MB_y>>1)-2-i]);
00889
00890 ib= ((cr_MB_x == 8?17:5)*ih+2*cr_MB_x)>>(cr_MB_x == 8?5:6);
00891 ic= ((cr_MB_y == 8?17:5)*iv+2*cr_MB_y)>>(cr_MB_y == 8?5:6);
00892
00893 iaa=16*(hline[cr_MB_x-1] + vline[cr_MB_y-1]);
00894 cur_pred = curr_mpr_16x16[PLANE_8];
00895 for (j=0; j<cr_MB_y; j++)
00896 for (i=0; i<cr_MB_x; i++)
00897 cur_pred[j][i]= (imgpel) iClip1( max_imgpel_value_uv, (iaa+(i-(cr_MB_x>>1)+1)*ib+(j-(cr_MB_y>>1)+1)*ic+16)>>5);
00898 }
00899 }
00900
00901 if (!p_Inp->rdopt)
00902 {
00903
00904 min_cost = INT_MAX;
00905 for (i=0;i<cr_MB_y;i++)
00906 {
00907 p_Img->getNeighbour(currMB, 0 , i, p_Img->mb_size[IS_CHROMA], &left[i]);
00908 }
00909
00910 if ( p_Img->MbaffFrameFlag && p_Img->field_mode )
00911 {
00912 for (i=0;i<cr_MB_y;i++)
00913 {
00914 left[i].pos_y = left[i].pos_y >> 1;
00915 }
00916 }
00917
00918 for (mode=DC_PRED_8; mode<=PLANE_8; mode++)
00919 {
00920 if ((currSlice->slice_type != I_SLICE || !p_Inp->IntraDisableInterOnly) && p_Inp->ChromaIntraDisable == 1 && mode!=DC_PRED_8)
00921 continue;
00922
00923 if ((mode==VERT_PRED_8 && !mb_available_up) ||
00924 (mode==HOR_PRED_8 && (!mb_available_left[0] || !mb_available_left[1])) ||
00925 (mode==PLANE_8 && (!mb_available_left[0] || !mb_available_left[1] || !mb_available_up || !mb_available_up_left)))
00926 continue;
00927
00928 cost = 0;
00929 for (uv = 1; uv < 3; uv++)
00930 {
00931 image = p_Img->pImgOrg[uv];
00932 curr_mpr_16x16 = currSlice->mpr_16x16[uv];
00933 for (block_y=0; block_y<cr_MB_y; block_y+=4)
00934 for (block_x = 0; block_x < cr_MB_x; block_x += 4)
00935 {
00936 for (k=0, j = block_y; j < block_y + 4; j++)
00937 {
00938 img_prd = curr_mpr_16x16[mode][j];
00939 img_org = &image[left[j].pos_y][left[j].pos_x];
00940 for (i = block_x; i < block_x + 4; i++)
00941 diff[k++] = img_org[i] - img_prd[i];
00942 }
00943 cost += p_Img->distortion4x4(diff, min_cost);
00944 }
00945 }
00946 if (cost < min_cost)
00947 {
00948 best_mode = mode;
00949 min_cost = cost;
00950 }
00951 }
00952 currMB->c_ipred_mode = (char) best_mode;
00953 }
00954 }
00955
00956 void compute_residue (imgpel **curImg, imgpel **mpr, int **mb_rres, int mb_x, int opix_x, int width, int height)
00957 {
00958 imgpel *imgOrg, *imgPred;
00959 int *m7;
00960 int i, j;
00961
00962 for (j = 0; j < height; j++)
00963 {
00964 imgOrg = &curImg[j][opix_x];
00965 imgPred = &mpr[j][mb_x];
00966 m7 = &mb_rres[j][mb_x];
00967 for (i = 0; i < width; i++)
00968 {
00969 *m7++ = *imgOrg++ - *imgPred++;
00970 }
00971 }
00972 }
00973
00974 void sample_reconstruct (imgpel **curImg, imgpel **mpr, int **mb_rres, int mb_x, int opix_x, int width, int height, int max_imgpel_value, int dq_bits)
00975 {
00976 imgpel *imgOrg, *imgPred;
00977 int *m7;
00978 int i, j;
00979
00980 for (j = 0; j < height; j++)
00981 {
00982 imgOrg = &curImg[j][opix_x];
00983 imgPred = &mpr[j][mb_x];
00984 m7 = &mb_rres[j][mb_x];
00985 for (i=0;i<width;i++)
00986 *imgOrg++ = (imgpel) iClip1( max_imgpel_value, rshift_rnd_sf(*m7++, dq_bits) + *imgPred++);
00987 }
00988 }
00989
00990