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