00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <math.h>
00013 #include <limits.h>
00014 #include <float.h>
00015
00016 #include "global.h"
00017 #include "rdopt_coding_state.h"
00018 #include "mb_access.h"
00019 #include "intrarefresh.h"
00020 #include "image.h"
00021 #include "transform8x8.h"
00022 #include "ratectl.h"
00023 #include "mode_decision.h"
00024 #include "fmo.h"
00025 #include "me_umhex.h"
00026 #include "me_umhexsmp.h"
00027 #include "macroblock.h"
00028 #include "rdoq.h"
00029 #include "errdo.h"
00030 #include "q_around.h"
00031
00032
00033 const int b8_mode_table[6] = {0, 4, 5, 6, 7};
00034 const int mb_mode_table[9] = {0, 1, 2, 3, P8x8, I16MB, I4MB, I8MB, IPCM};
00035 extern int luma_transform_size_8x8_flag;
00036
00037
00038
00039
00040
00041
00042
00043 void reset_valid_modes(RD_PARAMS *enc_mb)
00044 {
00045 memset(enc_mb->valid, 0, MAXMODE * sizeof(short));
00046 }
00047
00048
00049
00050
00051
00052
00053
00054
00055 void init_enc_mb_params(Macroblock* currMB, RD_PARAMS *enc_mb, int intra, int bslice)
00056 {
00057 int l,k;
00058
00059
00060 enc_mb->list_offset[LIST_0] = LIST_0 + currMB->list_offset;
00061 enc_mb->list_offset[LIST_1] = LIST_1 + currMB->list_offset;
00062
00063 enc_mb->curr_mb_field = ((img->MbaffFrameFlag)&&(currMB->mb_field));
00064
00065
00066 enc_mb->valid[I8MB] = (!params->DisableIntraInInter || intra )? params->Transform8x8Mode : 0;
00067 enc_mb->valid[I4MB] = (!params->DisableIntraInInter || intra )? ((params->Transform8x8Mode == 2) ? 0 : 1) : 0;
00068 enc_mb->valid[I4MB] = (!params->DisableIntra4x4 ) ? enc_mb->valid[I4MB] : 0;
00069 enc_mb->valid[I16MB] = (!params->DisableIntraInInter || intra )? 1 : 0;
00070 enc_mb->valid[I16MB] = (!params->DisableIntra16x16) ? enc_mb->valid[I16MB] : 0;
00071 enc_mb->valid[IPCM] = (!params->DisableIntraInInter || intra )? params->EnableIPCM : 0;
00072
00073 enc_mb->valid[0] = (!intra && params->InterSearch[bslice][0]);
00074 enc_mb->valid[1] = (!intra && params->InterSearch[bslice][1]);
00075 enc_mb->valid[2] = (!intra && params->InterSearch[bslice][2]);
00076 enc_mb->valid[3] = (!intra && params->InterSearch[bslice][3]);
00077 enc_mb->valid[4] = (!intra && params->InterSearch[bslice][4]);
00078 enc_mb->valid[5] = (!intra && params->InterSearch[bslice][5] && !(params->Transform8x8Mode==2));
00079 enc_mb->valid[6] = (!intra && params->InterSearch[bslice][6] && !(params->Transform8x8Mode==2));
00080 enc_mb->valid[7] = (!intra && params->InterSearch[bslice][7] && !(params->Transform8x8Mode==2));
00081 enc_mb->valid[P8x8] = (enc_mb->valid[4] || enc_mb->valid[5] || enc_mb->valid[6] || enc_mb->valid[7]);
00082 enc_mb->valid[12] = (img->type == SI_SLICE);
00083
00084 if (params->UseRDOQuant && params->RDOQ_CP_Mode && (img->qp != img->masterQP) )
00085 RDOQ_update_mode(enc_mb, bslice);
00086
00087 if(img->type==SP_SLICE)
00088 {
00089 if(si_frame_indicator)
00090 {
00091 reset_valid_modes(enc_mb);
00092 if(check_for_SI16())
00093 {
00094 enc_mb->valid[I16MB] = 1;
00095 }
00096 else
00097 {
00098 enc_mb->valid[I4MB] = 1;
00099 }
00100 }
00101
00102 if(sp2_frame_indicator)
00103 {
00104 if(check_for_SI16())
00105 {
00106 reset_valid_modes(enc_mb);
00107 enc_mb->valid[I16MB] = 1;
00108 }
00109 else
00110 {
00111 enc_mb->valid[I8MB] = 0;
00112 enc_mb->valid[IPCM] = 0;
00113 enc_mb->valid[0] = 0;
00114 enc_mb->valid[I16MB] = 0;
00115 }
00116 }
00117 }
00118
00119
00120
00121
00122 if (bslice && img->nal_reference_idc)
00123 {
00124 enc_mb->lambda_md = img->lambda_md[5][img->masterQP];
00125
00126 enc_mb->lambda_me[F_PEL] = img->lambda_me[5][img->masterQP][F_PEL];
00127 enc_mb->lambda_me[H_PEL] = img->lambda_me[5][img->masterQP][H_PEL];
00128 enc_mb->lambda_me[Q_PEL] = img->lambda_me[5][img->masterQP][Q_PEL];
00129
00130 enc_mb->lambda_mf[F_PEL] = img->lambda_mf[5][img->masterQP][F_PEL];
00131 enc_mb->lambda_mf[H_PEL] = img->lambda_mf[5][img->masterQP][H_PEL];
00132 enc_mb->lambda_mf[Q_PEL] = img->lambda_mf[5][img->masterQP][Q_PEL];
00133 }
00134 else
00135 {
00136 enc_mb->lambda_md = img->lambda_md[img->type][img->masterQP];
00137 enc_mb->lambda_me[F_PEL] = img->lambda_me[img->type][img->masterQP][F_PEL];
00138 enc_mb->lambda_me[H_PEL] = img->lambda_me[img->type][img->masterQP][H_PEL];
00139 enc_mb->lambda_me[Q_PEL] = img->lambda_me[img->type][img->masterQP][Q_PEL];
00140
00141 enc_mb->lambda_mf[F_PEL] = img->lambda_mf[img->type][img->masterQP][F_PEL];
00142 enc_mb->lambda_mf[H_PEL] = img->lambda_mf[img->type][img->masterQP][H_PEL];
00143 enc_mb->lambda_mf[Q_PEL] = img->lambda_mf[img->type][img->masterQP][Q_PEL];
00144 }
00145
00146 if (!img->MbaffFrameFlag)
00147 {
00148 for (l = LIST_0; l < BI_PRED; l++)
00149 {
00150 for(k = 0; k < listXsize[l]; k++)
00151 {
00152 if(img->structure != listX[l][k]->structure)
00153 {
00154 if (img->structure == TOP_FIELD)
00155 listX[l][k]->chroma_vector_adjustment = -2;
00156 else if (img->structure == BOTTOM_FIELD)
00157 listX[l][k]->chroma_vector_adjustment = 2;
00158 else
00159 listX[l][k]->chroma_vector_adjustment= 0;
00160 }
00161 else
00162 listX[l][k]->chroma_vector_adjustment= 0;
00163 }
00164 }
00165 }
00166 else
00167 {
00168 if (enc_mb->curr_mb_field)
00169 {
00170 for (l = enc_mb->list_offset[LIST_0]; l <= enc_mb->list_offset[LIST_1]; l++)
00171 {
00172 for(k = 0; k < listXsize[l]; k++)
00173 {
00174 listX[l][k]->chroma_vector_adjustment= 0;
00175 if((currMB->mb_nr & 0x01) == 0 && listX[l][k]->structure == BOTTOM_FIELD)
00176 listX[l][k]->chroma_vector_adjustment = -2;
00177 if((currMB->mb_nr & 0x01) == 1 && listX[l][k]->structure == TOP_FIELD)
00178 listX[l][k]->chroma_vector_adjustment = 2;
00179 }
00180 }
00181 }
00182 else
00183 {
00184 for (l = enc_mb->list_offset[LIST_0]; l <= enc_mb->list_offset[LIST_1]; l++)
00185 {
00186 for(k = 0; k < listXsize[l]; k++)
00187 listX[l][k]->chroma_vector_adjustment = 0;
00188 }
00189 }
00190 }
00191
00192
00193 currMB->c_ipred_mode = DC_PRED_8;
00194 }
00195
00196
00197
00198
00199
00200
00201
00202 void list_prediction_cost(Macroblock *currMB, int list, int block, int mode, RD_PARAMS *enc_mb, int bmcost[5], char best_ref[2])
00203 {
00204 short ref;
00205 int mcost;
00206 int cur_list = list < BI_PRED ? enc_mb->list_offset[list] : enc_mb->list_offset[LIST_0];
00207
00208
00209
00210 if (list < BI_PRED)
00211 {
00212 for (ref=0; ref < listXsize[cur_list]; ref++)
00213 {
00214 if (!img->checkref || list || ref==0 || (params->RestrictRef && CheckReliabilityOfRef (block, list, ref, mode)))
00215 {
00216
00217 if((!params->sp2_frame_indicator && !params->sp_output_indicator)||
00218 ((params->sp2_frame_indicator || params->sp_output_indicator) && (img->type != P_SLICE && img->type != SP_SLICE))||
00219 ((params->sp2_frame_indicator || params->sp_output_indicator) && ((img->type == P_SLICE || img->type == SP_SLICE) &&(ref==0))))
00220 {
00221 mcost = (params->rdopt
00222 ? REF_COST (enc_mb->lambda_mf[Q_PEL], ref, cur_list)
00223 : (int) (2 * enc_mb->lambda_me[Q_PEL] * imin(ref, 1)));
00224
00225 mcost += motion_cost[mode][list][ref][block];
00226 if (mcost < bmcost[list])
00227 {
00228 bmcost[list] = mcost;
00229 best_ref[list] = (char)ref;
00230 }
00231 }
00232 }
00233 }
00234 }
00235 else if (list == BI_PRED)
00236 {
00237 if (active_pps->weighted_bipred_idc == 1)
00238 {
00239 int weight_sum = wbp_weight[0][(int) best_ref[LIST_0]][(int) best_ref[LIST_1]][0] + wbp_weight[1][(int) best_ref[LIST_0]][(int) best_ref[LIST_1]][0];
00240
00241 if (weight_sum < -128 || weight_sum > 127)
00242 {
00243 bmcost[list] = INT_MAX;
00244 }
00245 else
00246 {
00247 bmcost[list] = (params->rdopt
00248 ? (REF_COST (enc_mb->lambda_mf[Q_PEL], (short)best_ref[LIST_0], cur_list)
00249 + REF_COST (enc_mb->lambda_mf[Q_PEL], (short)best_ref[LIST_1], cur_list + LIST_1))
00250 : (int) (2 * (enc_mb->lambda_me[Q_PEL] * (imin((short)best_ref[LIST_0], 1) + imin((short)best_ref[LIST_1], 1)))));
00251 bmcost[list] += BIDPartitionCost (currMB, mode, block, best_ref, enc_mb->lambda_mf[Q_PEL]);
00252 }
00253 }
00254 else
00255 {
00256 bmcost[list] = (params->rdopt
00257 ? (REF_COST (enc_mb->lambda_mf[Q_PEL], (short)best_ref[LIST_0], cur_list)
00258 + REF_COST (enc_mb->lambda_mf[Q_PEL], (short)best_ref[LIST_1], cur_list + LIST_1))
00259 : (int) (2 * (enc_mb->lambda_me[Q_PEL] * (imin((short)best_ref[LIST_0], 1) + imin((short)best_ref[LIST_1], 1)))));
00260 bmcost[list] += BIDPartitionCost (currMB, mode, block, best_ref, enc_mb->lambda_mf[Q_PEL]);
00261 }
00262 }
00263 else
00264 {
00265 bmcost[list] = (params->rdopt
00266 ? (REF_COST (enc_mb->lambda_mf[Q_PEL], 0, cur_list)
00267 + REF_COST (enc_mb->lambda_mf[Q_PEL], 0, cur_list + LIST_1))
00268 : (int) (4 * enc_mb->lambda_me[Q_PEL]));
00269 bmcost[list] += BPredPartitionCost(currMB, mode, block, 0, 0, enc_mb->lambda_mf[Q_PEL], !(list&1));
00270 }
00271 }
00272
00273 int compute_ref_cost(RD_PARAMS *enc_mb, int ref, int list)
00274 {
00275 return WEIGHTED_COST(enc_mb->lambda_mf[Q_PEL],((listXsize[enc_mb->list_offset[list]] <= 1)? 0:refbits[ref]));
00276 }
00277
00278
00279
00280
00281
00282
00283
00284 void determine_prediction_list(int mode, int bmcost[5], char best_ref[2], char *best_pdir, int *cost, short *bipred_me)
00285 {
00286 int bestlist;
00287
00288 *cost += iminarray ( bmcost, 5, &bestlist);
00289
00290 if (bestlist <= BI_PRED)
00291 {
00292 *best_pdir = bestlist;
00293 *bipred_me = 0;
00294 }
00295 else
00296 {
00297 *best_pdir = 2;
00298 *bipred_me = bestlist - 2;
00299 best_ref[LIST_0] = 0;
00300 best_ref[LIST_1] = 0;
00301 }
00302 }
00303
00304
00305
00306
00307
00308
00309
00310 void compute_mode_RD_cost(Slice *currSlice,
00311 Macroblock *currMB,
00312 RD_PARAMS *enc_mb,
00313 int mode,
00314 double *min_rdcost,
00315 double *min_dcost,
00316 double *min_rate,
00317 int i16mode,
00318 short bslice,
00319 short *inter_skip,
00320 int is_cavlc)
00321 {
00322 int terminate_16x16, terminate_trans, ctr16x16 = 0;
00323
00324 currMB->luma_transform_size_8x8_flag = params->Transform8x8Mode==2
00325 ? (mode >= 1 && mode <= 3)
00326 || (mode == 0 && bslice && active_sps->direct_8x8_inference_flag)
00327 || ((mode == P8x8) && (enc_mb->valid[4]))
00328 : 0;
00329
00330
00331 SetModesAndRefframeForBlocks (currMB, mode);
00332 memset( img->cofAC[0][0][0], 0, 4 * 4 * 2 * 65 * sizeof(int));
00333
00334
00335 img->NoResidueDirect = 0;
00336
00337 if ((params->FastCrIntraDecision )
00338 || (currMB->c_ipred_mode == DC_PRED_8 || (IS_INTRA(currMB) )))
00339 {
00340 do
00341 {
00342 terminate_16x16 = bslice_16x16_termination_control(img->b8x8info, &ctr16x16, mode, bslice);
00343 do
00344 {
00345 if (RDCost_for_macroblocks (currSlice, currMB, enc_mb->lambda_md, mode, min_rdcost, min_dcost, min_rate, i16mode, is_cavlc))
00346 {
00347
00348
00349 if (params->RCEnable)
00350 {
00351 if(mode == P8x8)
00352 rc_store_diff(img->opix_x, img->opix_y, currMB->luma_transform_size_8x8_flag == 1 ? tr8x8.mpr8x8 : tr4x4.mpr8x8);
00353 else
00354 rc_store_diff(img->opix_x, img->opix_y, pred);
00355 }
00356
00357 store_macroblock_parameters (currMB, mode);
00358
00359 if(params->rdopt == 2 && mode == 0 && params->EarlySkipEnable)
00360 {
00361
00362 if(currMB->cbp == 0)
00363 *inter_skip = 1;
00364 }
00365 }
00366 terminate_trans = transform_termination_control(currMB, mode, bslice);
00367 }while (!terminate_trans);
00368 }while (!terminate_16x16);
00369
00370
00371
00372 if (bslice && mode == 0 && (*inter_skip == 0) && enc_mb->valid[mode]
00373 && currMB->cbp && (currMB->cbp&15) != 15 && !params->nobskip
00374 && !(currMB->qp_scaled[0] == 0 && img->lossless_qpprime_flag==1) )
00375 {
00376 img->NoResidueDirect = 1;
00377
00378 if (RDCost_for_macroblocks (currSlice, currMB, enc_mb->lambda_md, mode, min_rdcost, min_dcost, min_rate, i16mode, is_cavlc))
00379 {
00380
00381 if (params->RCEnable)
00382 rc_store_diff(img->opix_x,img->opix_y,pred);
00383 if (img->AdaptiveRounding)
00384 reset_adaptive_rounding_direct();
00385 store_macroblock_parameters (currMB, mode);
00386 }
00387 }
00388
00389
00390 if (img->AdaptiveRounding && bslice && mode <= 1)
00391 {
00392 if (luma_transform_size_8x8_flag)
00393 update_adaptive_rounding_16x16( img, img->ARCofAdj8x8, mode);
00394 else
00395 update_adaptive_rounding_16x16( img, img->ARCofAdj4x4, mode);
00396 }
00397 }
00398 }
00399
00400
00401
00402
00403
00404
00405
00406
00407 void submacroblock_mode_decision(Slice *currSlice,
00408 RD_PARAMS *enc_mb,
00409 RD_8x8DATA *dataTr,
00410 Macroblock *currMB,
00411 int ****cofACtr,
00412 int *have_direct,
00413 short bslice,
00414 int block,
00415 int *cost_direct,
00416 int *cost,
00417 int *cost8x8_direct,
00418 int transform8x8,
00419 int is_cavlc)
00420 {
00421 int64 curr_cbp_blk;
00422 double min_rdcost, rdcost = 0.0;
00423 int j0, i0, j1, i1;
00424 int i,j, k;
00425 int min_cost8x8, index;
00426 int mode;
00427 int bmcost[5] = {INT_MAX};
00428 int cnt_nonz = 0;
00429 int best_cnt_nonz = 0;
00430 int maxindex = (transform8x8) ? 2 : 5;
00431 int block_x, block_y;
00432 int lambda_mf[3];
00433
00434 int ****fadjust = transform8x8? img->ARCofAdj8x8 : img->ARCofAdj4x4;
00435 short bipred_me = 0;
00436
00437 char best_pdir = 0;
00438 char best_ref[2] = {0, -1};
00439 imgpel **mb_pred = img->mb_pred[0];
00440 Boolean valid_8x8 = FALSE;
00441 Boolean stored_state_8x8 = FALSE;
00442
00443 #ifdef BEST_NZ_COEFF
00444 int best_nz_coeff[2][2];
00445 #endif
00446
00447
00448 j0 = ((block>>1)<<3);
00449 j1 = (j0>>2);
00450 i0 = ((block&0x01)<<3);
00451 i1 = (i0>>2);
00452
00453 #ifdef BEST_NZ_COEFF
00454 for(j = 0; j <= 1; j++)
00455 {
00456 for(i = 0; i <= 1; i++)
00457 best_nz_coeff[i][j] = img->nz_coeff[currMB->mb_nr][i1 + i][j1 + j] = 0;
00458 }
00459 #endif
00460
00461 if (transform8x8)
00462 currMB->luma_transform_size_8x8_flag = 1;
00463
00464
00465 store_coding_state (currSlice, currMB, cs_cm);
00466
00467
00468 for (min_cost8x8 = INT_MAX, min_rdcost = 1e20, index = (bslice?0:1); index < maxindex; index++)
00469 {
00470 mode = b8_mode_table[index];
00471 *cost = 0;
00472
00473 if (enc_mb->valid[mode] && (!(transform8x8 == 1 && mode > 4)) && (transform8x8 == 0 || mode != 0 || (mode == 0 && active_sps->direct_8x8_inference_flag)))
00474 {
00475 if (transform8x8)
00476 {
00477 currMB->valid_8x8 = TRUE;
00478 }
00479
00480 valid_8x8 = TRUE;
00481 curr_cbp_blk = 0;
00482
00483 if (mode==0)
00484 {
00485 block_x = img->block_x + (block & 0x01)*2;
00486 block_y = img->block_y + (block & 0x02);
00487 best_ref[LIST_0] = direct_ref_idx[LIST_0][block_y][block_x];
00488 best_ref[LIST_1] = direct_ref_idx[LIST_1][block_y][block_x];
00489 best_pdir = direct_pdir[block_y][block_x];
00490 }
00491 else
00492 {
00493 int64 ref_pic_num;
00494 char b_ref;
00495
00496
00497
00498 memcpy(lambda_mf, enc_mb->lambda_mf, 3 * sizeof(int));
00499 if (params->CtxAdptLagrangeMult == 1)
00500 {
00501 lambda_mf[F_PEL] = (int)(lambda_mf[F_PEL] * lambda_mf_factor);
00502 lambda_mf[H_PEL] = (int)(lambda_mf[H_PEL] * lambda_mf_factor);
00503 lambda_mf[Q_PEL] = (int)(lambda_mf[Q_PEL] * lambda_mf_factor);
00504 }
00505
00506 PartitionMotionSearch (currMB, mode, block, lambda_mf);
00507
00508
00509 bmcost[LIST_0] = INT_MAX;
00510 list_prediction_cost(currMB, LIST_0, block, mode, enc_mb, bmcost, best_ref);
00511
00512
00513 block_x = img->block_x + (block & 0x01)*2;
00514 block_y = img->block_y + (block & 0x02);
00515 b_ref = best_ref[LIST_0];
00516 ref_pic_num = enc_picture->ref_pic_num[enc_mb->list_offset[LIST_0]][(short) b_ref];
00517
00518 for (j = block_y; j< block_y + 2; j++)
00519 {
00520 memset(&enc_picture->motion.ref_idx [LIST_0][j][block_x], b_ref, 2 * sizeof(char));
00521 }
00522
00523 for (j = block_y; j< block_y + 2; j++)
00524 {
00525 for (i = block_x; i < block_x + 2; i++)
00526 {
00527 enc_picture->motion.ref_pic_id[LIST_0][j][i] = ref_pic_num;
00528 }
00529 }
00530
00531 for (j = 0; j< 2; j++)
00532 {
00533 memcpy(enc_picture->motion.mv[LIST_0][block_y + j][block_x], img->all_mv[LIST_0][(short) b_ref][mode][j1 + j][i1], 4 * sizeof(short));
00534 }
00535
00536
00537 if (bslice)
00538 {
00539
00540 bmcost[LIST_1] = INT_MAX;
00541 bmcost[BI_PRED] = INT_MAX;
00542 list_prediction_cost(currMB, LIST_1, block, mode, enc_mb, bmcost, best_ref);
00543
00544
00545 list_prediction_cost(currMB, BI_PRED, block, mode, enc_mb, bmcost, best_ref);
00546
00547
00548 if (is_bipred_enabled(mode))
00549 {
00550 list_prediction_cost(currMB, BI_PRED_L0, block, mode, enc_mb, bmcost, 0);
00551 list_prediction_cost(currMB, BI_PRED_L1, block, mode, enc_mb, bmcost, 0);
00552 }
00553 else
00554 {
00555 bmcost[BI_PRED_L0] = INT_MAX;
00556 bmcost[BI_PRED_L1] = INT_MAX;
00557 }
00558
00559
00560 determine_prediction_list(mode, bmcost, best_ref, &best_pdir, cost, &bipred_me);
00561
00562
00563 for (k = LIST_0; k <= LIST_1; k++)
00564 {
00565 for (j = block_y; j< block_y + 2; j++)
00566 {
00567 memset(&enc_picture->motion.ref_idx[k][j][block_x], best_ref[k], 2 * sizeof(char));
00568 }
00569 if (bipred_me)
00570 {
00571 for (j = 0; j< 2; j++)
00572 {
00573 memcpy(enc_picture->motion.mv[k][block_y + j][block_x], img->bipred_mv[bipred_me - 1][k][(short) best_ref[k]][mode][j1 + j][i1], 4 * sizeof(short));
00574 }
00575 }
00576 else
00577 {
00578 for (j = 0; j< 2; j++)
00579 {
00580 memcpy(enc_picture->motion.mv[k][block_y + j][block_x], img->all_mv[k][(short) best_ref[k]][mode][j1 + j][i1], 4 * sizeof(short));
00581 }
00582 }
00583 }
00584 }
00585 else
00586 {
00587 best_pdir = 0;
00588 *cost = bmcost[LIST_0];
00589 }
00590 }
00591
00592
00593 rdcost = RDCost_for_8x8blocks (currSlice, currMB, &cnt_nonz, &curr_cbp_blk, enc_mb->lambda_md,
00594 block, mode, best_pdir, best_ref[LIST_0], best_ref[LIST_1], bipred_me, is_cavlc);
00595
00596
00597 if (rdcost < min_rdcost)
00598 {
00599 min_cost8x8 = *cost;
00600 min_rdcost = rdcost;
00601 dataTr->part8x8mode [block] = mode;
00602 dataTr->part8x8pdir [block] = best_pdir;
00603 dataTr->part8x8l0ref [block] = best_ref[LIST_0];
00604 dataTr->part8x8l1ref [block] = best_ref[LIST_1];
00605 dataTr->part8x8bipred[block] = bipred_me;
00606
00607 currMB->b8mode[block] = mode;
00608
00609 #ifdef BEST_NZ_COEFF
00610 if (cnt_nonz)
00611 {
00612 for(i = 0; i <= 1; i++)
00613 {
00614 best_nz_coeff[i][0]= img->nz_coeff[currMB->mb_nr][i1 + i][j1 ];
00615 best_nz_coeff[i][1]= img->nz_coeff[currMB->mb_nr][i1 + i][j1 + 1];
00616 }
00617 }
00618 else
00619 {
00620 for(i = 0; i <= 1; i++)
00621 {
00622 best_nz_coeff[i][0]= 0;
00623 best_nz_coeff[i][1]= 0;
00624 }
00625 }
00626 #endif
00627
00628
00629 best_cnt_nonz = cnt_nonz;
00630
00631
00632 cbp_blk8x8 &= (~(0x33 << (((block>>1)<<3)+((block & 0x01)<<1))));
00633 cbp_blk8x8 |= curr_cbp_blk;
00634
00635
00636 memcpy(&cofACtr[0][0][0][0],&img->cofAC[block][0][0][0], 4 * 2 * 65 * sizeof(int));
00637
00638 if( img->P444_joined )
00639 {
00640
00641 memcpy(&cofACtr[1][0][0][0],&img->cofAC[block + 4][0][0][0], 4 * 2 * 65 * sizeof(int));
00642 memcpy(&cofACtr[2][0][0][0],&img->cofAC[block + 8][0][0][0], 4 * 2 * 65 * sizeof(int));
00643 }
00644
00645
00646 for (j = j0; j < j0 + BLOCK_SIZE_8x8; j++)
00647 {
00648 memcpy(&dataTr->rec_mbY8x8[j][i0],&enc_picture->imgY[img->pix_y + j][img->pix_x + i0], BLOCK_SIZE_8x8 * sizeof(imgpel));
00649 memcpy(&dataTr->mpr8x8[j][i0],&mb_pred[j][i0], BLOCK_SIZE_8x8 * sizeof(imgpel));
00650 }
00651
00652 if (params->rdopt == 3)
00653 {
00654 errdo_store_best_block(decs->dec_mbY_best8x8[transform8x8], enc_picture->p_dec_img[0], i0, j0, img->pix_x + i0, img->pix_y, BLOCK_SIZE_8x8);
00655 errdo_store_best_block(decs->dec_mb_pred_best8x8[transform8x8], decs->dec_mb_pred, i0, j0, i0, 0, BLOCK_SIZE_8x8);
00656 }
00657
00658 if(img->type==SP_SLICE && (!si_frame_indicator))
00659 {
00660 for (j = j0; j < j0 + BLOCK_SIZE_8x8; j++)
00661 {
00662 memcpy(&dataTr->lrec[j][i0],&lrec[img->pix_y + j][img->pix_x + i0], BLOCK_SIZE_8x8 * sizeof(int));
00663 }
00664 }
00665
00666 if(img->P444_joined)
00667 {
00668 for (j=j0; j<j0+8; j++)
00669 {
00670 memcpy(&dataTr->rec_mb8x8_cr[0][j][i0],&enc_picture->imgUV[0][img->pix_y + j][img->pix_x + i0], BLOCK_SIZE_8x8 * sizeof(imgpel));
00671 memcpy(&dataTr->rec_mb8x8_cr[1][j][i0],&enc_picture->imgUV[1][img->pix_y + j][img->pix_x + i0], BLOCK_SIZE_8x8 * sizeof(imgpel));
00672 memcpy(&dataTr->mpr8x8CbCr[0][j][i0],&img->mb_pred[1][j][i0], BLOCK_SIZE_8x8 * sizeof(imgpel));
00673 memcpy(&dataTr->mpr8x8CbCr[1][j][i0],&img->mb_pred[2][j][i0], BLOCK_SIZE_8x8 * sizeof(imgpel));
00674 }
00675 }
00676
00677
00678
00679 if (block < 3)
00680 {
00681 store_coding_state (currSlice, currMB, cs_b8);
00682 stored_state_8x8 = TRUE;
00683 }
00684 }
00685
00686
00687 reset_coding_state (currSlice, currMB, cs_cm);
00688 }
00689 }
00690
00691 if (valid_8x8 == TRUE)
00692 {
00693 #ifdef BEST_NZ_COEFF
00694 for(i = 0; i <= 1; i++)
00695 {
00696 for(j = 0; j <= 1; j++)
00697 img->nz_coeff[currMB->mb_nr][i1 + i][j1 + j] = best_nz_coeff[i][j];
00698 }
00699 #endif
00700
00701 if (!transform8x8)
00702 {
00703 if (min_cost8x8 != INT_MAX)
00704 dataTr->mb_p8x8_cost += min_cost8x8;
00705 else
00706 dataTr->mb_p8x8_cost = INT_MAX;
00707 }
00708
00709
00710 if (best_cnt_nonz)
00711 {
00712 cbp8x8 |= (1 << block);
00713 cnt_nonz_8x8 += best_cnt_nonz;
00714 }
00715
00716 if (!transform8x8)
00717 {
00718 if (block < 3)
00719 {
00720
00721 j0 = 8*(block >> 1);
00722 i0 = 8*(block & 0x01);
00723 for (j = j0; j < j0 + BLOCK_SIZE_8x8; j++)
00724 {
00725 memcpy(&enc_picture->imgY[img->pix_y + j][img->pix_x], dataTr->rec_mbY8x8[j], BLOCK_SIZE_8x8 * sizeof(imgpel));
00726 }
00727
00728 if (params->rdopt == 3)
00729 {
00730 errdo_get_best_block(img, enc_picture->p_dec_img[0], decs->dec_mbY_best8x8[transform8x8], j0, BLOCK_SIZE_8x8);
00731 }
00732
00733 if(img->type==SP_SLICE &&(!si_frame_indicator))
00734 {
00735 for (j = j0; j < j0 + BLOCK_SIZE_8x8; j++)
00736 {
00737 memcpy(&lrec[img->pix_y + j][img->pix_x], dataTr->lrec[j],2*BLOCK_SIZE*sizeof(imgpel));
00738 }
00739 }
00740
00741 if(img->P444_joined)
00742 {
00743 for (k=0; k<2; k++)
00744 {
00745 for (j = j0; j < j0 + BLOCK_SIZE_8x8; j++)
00746 {
00747 memcpy(&enc_picture->imgUV[k][img->pix_y + j][img->pix_x], dataTr->rec_mb8x8_cr[k][j], BLOCK_SIZE_8x8 * sizeof(imgpel));
00748 }
00749 }
00750 }
00751 }
00752 }
00753 else
00754 {
00755
00756 StoreNewMotionVectorsBlock8x8(0, block, dataTr->part8x8mode[block], dataTr->part8x8l0ref[block], dataTr->part8x8l1ref[block], dataTr->part8x8pdir[block], dataTr->part8x8bipred[block], bslice);
00757 }
00758
00759
00760 SetRefAndMotionVectors (&enc_picture->motion, currMB, block, dataTr->part8x8mode[block], dataTr->part8x8pdir[block], dataTr->part8x8l0ref[block], dataTr->part8x8l1ref[block], dataTr->part8x8bipred[block]);
00761
00762
00763
00764 if (stored_state_8x8 == TRUE)
00765 reset_coding_state (currSlice, currMB, cs_b8);
00766 else
00767 {
00768 update_adaptive_rounding_8x8(dataTr, fadjust);
00769 }
00770 }
00771 }
00772
00773
00774
00775
00776
00777
00778
00779 void submacroblock_mode_decision_low(Slice *currSlice,
00780 RD_PARAMS *enc_mb,
00781 RD_8x8DATA *dataTr,
00782 Macroblock *currMB,
00783 int ****cofACtr,
00784 int *have_direct,
00785 short bslice,
00786 int block,
00787 int *cost_direct,
00788 int *cost,
00789 int *cost8x8_direct,
00790 int transform8x8,
00791 int is_cavlc)
00792 {
00793 int64 curr_cbp_blk;
00794 double min_rdcost, rdcost = 0.0;
00795 int j0, i0, j1, i1;
00796 int i,j, k;
00797 int min_cost8x8, index;
00798 int mode;
00799 int direct4x4_tmp, direct8x8_tmp;
00800 int bmcost[5] = {INT_MAX};
00801 int cnt_nonz = 0;
00802 int dummy;
00803 int best_cnt_nonz = 0;
00804 int maxindex = (transform8x8) ? 2 : 5;
00805 int block_x, block_y;
00806 int lambda_mf[3];
00807
00808 int ****fadjust = transform8x8? img->ARCofAdj8x8 : img->ARCofAdj4x4;
00809 short pdir, bipred_me = 0;
00810
00811 char best_pdir = 0;
00812 char best_ref[2] = {0, -1};
00813 imgpel **mb_pred = img->mb_pred[0];
00814 Boolean valid_8x8 = FALSE;
00815 Boolean stored_state_8x8 = FALSE;
00816
00817 #ifdef BEST_NZ_COEFF
00818 int best_nz_coeff[2][2];
00819 #endif
00820
00821
00822 j0 = ((block>>1)<<3);
00823 j1 = (j0>>2);
00824 i0 = ((block&0x01)<<3);
00825 i1 = (i0>>2);
00826
00827 #ifdef BEST_NZ_COEFF
00828 for(j = 0; j <= 1; j++)
00829 {
00830 for(i = 0; i <= 1; i++)
00831 best_nz_coeff[i][j] = img->nz_coeff[currMB->mb_nr][i1 + i][j1 + j] = 0;
00832 }
00833 #endif
00834
00835 if (transform8x8)
00836 currMB->luma_transform_size_8x8_flag = 1;
00837
00838
00839 store_coding_state (currSlice, currMB, cs_cm);
00840
00841
00842 for (min_cost8x8 = INT_MAX, min_rdcost = 1e20, index = (bslice?0:1); index < maxindex; index++)
00843 {
00844 mode = b8_mode_table[index];
00845 *cost = 0;
00846
00847 if (enc_mb->valid[mode] && (!(transform8x8 == 1 && mode > 4)) && (transform8x8 == 0 || mode != 0 || (mode == 0 && active_sps->direct_8x8_inference_flag)))
00848 {
00849 if (transform8x8)
00850 {
00851 currMB->valid_8x8 = TRUE;
00852 }
00853
00854 valid_8x8 = TRUE;
00855 curr_cbp_blk = 0;
00856
00857 if (mode==0)
00858 {
00859
00860 direct4x4_tmp = 0;
00861 direct8x8_tmp = 0;
00862 direct4x4_tmp = GetDirectCost8x8 ( currMB, block, &direct8x8_tmp);
00863
00864 if ((direct4x4_tmp==INT_MAX)||(*cost_direct==INT_MAX))
00865 {
00866 *cost_direct = INT_MAX;
00867 if (transform8x8)
00868 *cost8x8_direct = INT_MAX;
00869 }
00870 else
00871 {
00872 *cost_direct += direct4x4_tmp;
00873 if (transform8x8)
00874 *cost8x8_direct += direct8x8_tmp;
00875 }
00876 (*have_direct) ++;
00877
00878 if (transform8x8)
00879 {
00880 switch(params->Transform8x8Mode)
00881 {
00882 case 1:
00883 if((direct8x8_tmp < direct4x4_tmp) || !(enc_mb->valid[5] && enc_mb->valid[6] && enc_mb->valid[7]))
00884 *cost = direct8x8_tmp;
00885 else
00886 *cost = direct4x4_tmp;
00887 break;
00888 case 2:
00889 *cost = direct8x8_tmp;
00890 break;
00891 default:
00892 *cost = direct4x4_tmp;
00893 break;
00894 }
00895 if (params->Transform8x8Mode==2)
00896 *cost = INT_MAX;
00897 }
00898 else
00899 {
00900 *cost = direct4x4_tmp;
00901 }
00902
00903 block_x = img->block_x + (block & 0x01)*2;
00904 block_y = img->block_y + (block & 0x02);
00905 best_ref[LIST_0] = direct_ref_idx[LIST_0][block_y][block_x];
00906 best_ref[LIST_1] = direct_ref_idx[LIST_1][block_y][block_x];
00907 best_pdir = direct_pdir[block_y][block_x];
00908 }
00909 else
00910 {
00911 int64 ref_pic_num;
00912 char b_ref;
00913
00914
00915
00916 memcpy(lambda_mf, enc_mb->lambda_mf, 3 * sizeof(int));
00917 if (params->CtxAdptLagrangeMult == 1)
00918 {
00919 lambda_mf[F_PEL] = (int)(lambda_mf[F_PEL] * lambda_mf_factor);
00920 lambda_mf[H_PEL] = (int)(lambda_mf[H_PEL] * lambda_mf_factor);
00921 lambda_mf[Q_PEL] = (int)(lambda_mf[Q_PEL] * lambda_mf_factor);
00922 }
00923
00924 PartitionMotionSearch (currMB, mode, block, lambda_mf);
00925
00926
00927 bmcost[LIST_0] = INT_MAX;
00928 list_prediction_cost(currMB, LIST_0, block, mode, enc_mb, bmcost, best_ref);
00929
00930
00931 block_x = img->block_x + (block & 0x01)*2;
00932 block_y = img->block_y + (block & 0x02);
00933 b_ref = best_ref[LIST_0];
00934 ref_pic_num = enc_picture->ref_pic_num[enc_mb->list_offset[LIST_0]][(short) b_ref];
00935
00936 for (j = block_y; j< block_y + 2; j++)
00937 {
00938 memset(&enc_picture->motion.ref_idx [LIST_0][j][block_x], b_ref, 2 * sizeof(char));
00939 }
00940
00941 for (j = block_y; j< block_y + 2; j++)
00942 {
00943 for (i = block_x; i < block_x + 2; i++)
00944 {
00945 enc_picture->motion.ref_pic_id[LIST_0][j][i] = ref_pic_num;
00946 }
00947 }
00948
00949 if (bslice)
00950 {
00951
00952 bmcost[LIST_1] = INT_MAX;
00953 bmcost[BI_PRED] = INT_MAX;
00954 list_prediction_cost(currMB, LIST_1, block, mode, enc_mb, bmcost, best_ref);
00955
00956
00957 list_prediction_cost(currMB, BI_PRED, block, mode, enc_mb, bmcost, best_ref);
00958
00959
00960 if (is_bipred_enabled(mode))
00961 {
00962 list_prediction_cost(currMB, BI_PRED_L0, block, mode, enc_mb, bmcost, 0);
00963 list_prediction_cost(currMB, BI_PRED_L1, block, mode, enc_mb, bmcost, 0);
00964 }
00965 else
00966 {
00967 bmcost[BI_PRED_L0] = INT_MAX;
00968 bmcost[BI_PRED_L1] = INT_MAX;
00969 }
00970
00971
00972 determine_prediction_list(mode, bmcost, best_ref, &best_pdir, cost, &bipred_me);
00973
00974
00975 for (k = LIST_0; k <= LIST_1; k++)
00976 {
00977 for (j = block_y; j< block_y + 2; j++)
00978 {
00979 memset(&enc_picture->motion.ref_idx[k][j][block_x], best_ref[k], 2 * sizeof(char));
00980 }
00981 }
00982 }
00983 else
00984 {
00985 best_pdir = 0;
00986 *cost = bmcost[LIST_0];
00987 }
00988 }
00989
00990 if (*cost!=INT_MAX)
00991 *cost += (REF_COST (enc_mb->lambda_mf[Q_PEL], B8Mode2Value (mode, best_pdir),
00992 enc_mb->list_offset[(best_pdir < 1 ? LIST_0 : LIST_1)]) - 1);
00993
00994
00995 if (*cost < min_cost8x8)
00996 {
00997 min_cost8x8 = *cost;
00998 min_rdcost = rdcost;
00999 dataTr->part8x8mode [block] = mode;
01000 dataTr->part8x8pdir [block] = best_pdir;
01001 dataTr->part8x8l0ref [block] = best_ref[LIST_0];
01002 dataTr->part8x8l1ref [block] = best_ref[LIST_1];
01003 dataTr->part8x8bipred[block] = bipred_me;
01004
01005 currMB->b8mode[block] = mode;
01006
01007 #ifdef BEST_NZ_COEFF
01008 if (cnt_nonz)
01009 {
01010 best_nz_coeff[0][0]= img->nz_coeff[currMB->mb_nr][i1 ][j1 ];
01011 best_nz_coeff[0][1]= img->nz_coeff[currMB->mb_nr][i1 ][j1 + 1];
01012 best_nz_coeff[1][0]= img->nz_coeff[currMB->mb_nr][i1 + 1][j1 ];
01013 best_nz_coeff[1][1]= img->nz_coeff[currMB->mb_nr][i1 + 1][j1 + 1];
01014 }
01015 else
01016 {
01017 best_nz_coeff[0][0]= 0;
01018 best_nz_coeff[0][1]= 0;
01019 best_nz_coeff[1][0]= 0;
01020 best_nz_coeff[1][1]= 0;
01021 }
01022 #endif
01023
01024
01025 best_cnt_nonz = cnt_nonz;
01026
01027
01028 if (block < 3)
01029 {
01030 store_coding_state (currSlice, currMB, cs_b8);
01031 stored_state_8x8 = TRUE;
01032 }
01033 }
01034
01035
01036 reset_coding_state (currSlice, currMB, cs_cm);
01037 }
01038 }
01039
01040 if (valid_8x8 == TRUE)
01041 {
01042 #ifdef BEST_NZ_COEFF
01043 for(i = 0; i <= 1; i++)
01044 {
01045 for(j = 0; j <= 1; j++)
01046 img->nz_coeff[currMB->mb_nr][i1 + i][j1 + j] = best_nz_coeff[i][j];
01047 }
01048 #endif
01049
01050 if (!transform8x8)
01051 {
01052 if (min_cost8x8 != INT_MAX)
01053 dataTr->mb_p8x8_cost += min_cost8x8;
01054 else
01055 dataTr->mb_p8x8_cost = INT_MAX;
01056 }
01057
01058
01059 if (transform8x8)
01060 {
01061 if (min_cost8x8 != INT_MAX)
01062 dataTr->mb_p8x8_cost += min_cost8x8;
01063 else
01064 dataTr->mb_p8x8_cost = INT_MAX;
01065
01066 mode = dataTr->part8x8mode[block];
01067 pdir = dataTr->part8x8pdir[block];
01068 }
01069 else
01070 {
01071 mode = dataTr->part8x8mode[block];
01072 pdir = dataTr->part8x8pdir[block];
01073 }
01074
01075 curr_cbp_blk = 0;
01076 currMB->bipred_me[block] = dataTr->part8x8bipred[block];
01077 currMB->ar_mode = (mode != 0)? mode: P8x8;
01078 best_cnt_nonz = LumaResidualCoding8x8 (currMB, &dummy, &curr_cbp_blk, block, pdir,
01079 (pdir == 0 || pdir == 2 ? mode : 0), (pdir == 1 || pdir == 2 ? mode : 0),
01080 dataTr->part8x8l0ref[block], dataTr->part8x8l1ref[block], is_cavlc);
01081
01082 if (img->P444_joined)
01083 best_cnt_nonz += coeff_cost_cr[1] + coeff_cost_cr[2];
01084
01085 cbp_blk8x8 &= (~(0x33 << (((block>>1)<<3)+((block & 0x01)<<1))));
01086 cbp_blk8x8 |= curr_cbp_blk;
01087
01088
01089 memcpy(cofACtr[0][0][0],img->cofAC[block][0][0], 4 * 2 * 65 * sizeof(int));
01090
01091 if(img->P444_joined)
01092 {
01093
01094 memcpy(cofACtr[1][0][0],img->cofAC[block + 4][0][0], 4 * 2 * 65 * sizeof(int));
01095 memcpy(cofACtr[2][0][0],img->cofAC[block + 8][0][0], 4 * 2 * 65 * sizeof(int));
01096 }
01097
01098
01099
01100 for (j = j0; j < j0 + BLOCK_SIZE_8x8; j++)
01101 {
01102 memcpy(&dataTr->rec_mbY8x8[j][i0], &enc_picture->imgY[img->pix_y + j][img->pix_x + i0], BLOCK_SIZE_8x8 * sizeof (imgpel));
01103 }
01104
01105 for (j = j0; j < j0 + BLOCK_SIZE_8x8; j++)
01106 {
01107 memcpy(&dataTr->mpr8x8[j][i0], &mb_pred[j][i0], BLOCK_SIZE_8x8 * sizeof (imgpel));
01108 }
01109
01110
01111
01112 if(img->type==SP_SLICE &&(!si_frame_indicator))
01113 {
01114 for (j=j0; j < j0 + BLOCK_SIZE_8x8; j++)
01115 {
01116 memcpy(&dataTr->lrec[j][i0],&lrec[img->pix_y+j][img->pix_x+i0],BLOCK_SIZE_8x8 * sizeof(int));
01117 }
01118 }
01119 if(img->P444_joined)
01120 {
01121 for (j=j0; j < j0 + BLOCK_SIZE_8x8; j++)
01122 {
01123 memcpy(&dataTr->rec_mb8x8_cr[0][j][i0], &enc_picture->imgUV[0][img->pix_y + j][img->pix_x + i0], BLOCK_SIZE_8x8 * sizeof (imgpel));
01124 memcpy(&dataTr->rec_mb8x8_cr[1][j][i0], &enc_picture->imgUV[1][img->pix_y + j][img->pix_x + i0], BLOCK_SIZE_8x8 * sizeof (imgpel));
01125 memcpy(&dataTr->mpr8x8CbCr[0][j][i0], &img->mb_pred[1][j][i0], BLOCK_SIZE_8x8 * sizeof (imgpel));
01126 memcpy(&dataTr->mpr8x8CbCr[1][j][i0], &img->mb_pred[2][j][i0], BLOCK_SIZE_8x8 * sizeof (imgpel));
01127 }
01128 }
01129
01130
01131
01132 if (best_cnt_nonz)
01133 {
01134 cbp8x8 |= (1 << block);
01135 cnt_nonz_8x8 += best_cnt_nonz;
01136 }
01137
01138 if (!transform8x8)
01139 {
01140 if (block < 3)
01141 {
01142
01143 j0 = 8*(block >> 1);
01144 i0 = 8*(block & 0x01);
01145 for (j = j0; j < j0 + BLOCK_SIZE_8x8; j++)
01146 {
01147 memcpy(&enc_picture->imgY[img->pix_y + j][img->pix_x], dataTr->rec_mbY8x8[j], BLOCK_SIZE_8x8 * sizeof(imgpel));
01148 }
01149
01150 if(img->type==SP_SLICE &&(!si_frame_indicator))
01151 {
01152 for (j = j0; j < j0 + BLOCK_SIZE_8x8; j++)
01153 {
01154 memcpy(&lrec[img->pix_y + j][img->pix_x], dataTr->lrec[j],2*BLOCK_SIZE*sizeof(imgpel));
01155 }
01156 }
01157
01158 if(img->P444_joined)
01159 {
01160 for (k=0; k<2; k++)
01161 {
01162 for (j = j0; j < j0 + BLOCK_SIZE_8x8; j++)
01163 {
01164 memcpy(&enc_picture->imgUV[k][img->pix_y + j][img->pix_x], dataTr->rec_mb8x8_cr[k][j], BLOCK_SIZE_8x8 * sizeof(imgpel));
01165 }
01166 }
01167 }
01168 }
01169 }
01170 else
01171 {
01172
01173 StoreNewMotionVectorsBlock8x8(0, block, dataTr->part8x8mode[block], dataTr->part8x8l0ref[block], dataTr->part8x8l1ref[block], dataTr->part8x8pdir[block], dataTr->part8x8bipred[block], bslice);
01174 }
01175
01176
01177 SetRefAndMotionVectors (&enc_picture->motion, currMB, block, dataTr->part8x8mode[block], dataTr->part8x8pdir[block], dataTr->part8x8l0ref[block], dataTr->part8x8l1ref[block], dataTr->part8x8bipred[block]);
01178
01179
01180
01181 if (stored_state_8x8 == TRUE)
01182 reset_coding_state (currSlice, currMB, cs_b8);
01183 else
01184 {
01185 update_adaptive_rounding_8x8(dataTr, fadjust);
01186 }
01187 }
01188 }
01189
01190
01191
01192
01193
01194
01195
01196 int check_for_SI16()
01197 {
01198 int i,j;
01199 for(i=img->pix_y;i<img->pix_y+MB_BLOCK_SIZE;i++)
01200 {
01201 for(j=img->pix_x;j<img->pix_x+MB_BLOCK_SIZE;j++)
01202 if(lrec[i][j]!=-16)
01203 return 0;
01204 }
01205 return 1;
01206 }
01207
01208 void get_initial_mb16x16_cost(Macroblock* currMB)
01209 {
01210 if (currMB->mb_available_left && currMB->mb_available_up)
01211 {
01212 mb16x16_cost = (mb16x16_cost_frame[currMB->mb_nr - 1] +
01213 mb16x16_cost_frame[currMB->mb_nr - (img->width>>4)] + 1)/2.0;
01214 }
01215 else if (currMB->mb_available_left)
01216 {
01217 mb16x16_cost = mb16x16_cost_frame[currMB->mb_nr - 1];
01218 }
01219 else if (currMB->mb_available_up)
01220 {
01221 mb16x16_cost = mb16x16_cost_frame[currMB->mb_nr - (img->width>>4)];
01222 }
01223 else
01224 {
01225 mb16x16_cost = CALM_MF_FACTOR_THRESHOLD;
01226 }
01227
01228 lambda_mf_factor = mb16x16_cost < CALM_MF_FACTOR_THRESHOLD ? 1.0 : sqrt(mb16x16_cost / (CALM_MF_FACTOR_THRESHOLD * img->lambda_mf_factor[img->type][img->qp]));
01229 }
01230
01231 void adjust_mb16x16_cost(int cost)
01232 {
01233 mb16x16_cost = (double) cost;
01234 mb16x16_cost_frame[img->current_mb_nr] = mb16x16_cost;
01235
01236 lambda_mf_factor = (mb16x16_cost < CALM_MF_FACTOR_THRESHOLD)
01237 ? 1.0
01238 : sqrt(mb16x16_cost / (CALM_MF_FACTOR_THRESHOLD * img->lambda_mf_factor[img->type][img->qp]));
01239 }
01240
01241 void update_lambda_costs(RD_PARAMS *enc_mb, int lambda_mf[3])
01242 {
01243 int MEPos;
01244 for (MEPos = 0; MEPos < 3; MEPos ++)
01245 {
01246 lambda_mf[MEPos] = params->CtxAdptLagrangeMult == 0 ? enc_mb->lambda_mf[MEPos] : (int)(enc_mb->lambda_mf[MEPos] * sqrt(lambda_mf_factor));
01247 }
01248 }
01249
01250
01251
01252
01253
01254
01255
01256 int iminarray ( int arr[], int size, int *minind )
01257 {
01258 int i;
01259 int mincand = arr[0];
01260 *minind = 0;
01261 for ( i = 1; i < size; i++ )
01262 {
01263 if (arr[i] < mincand)
01264 {
01265 mincand = arr[i];
01266 *minind = i;
01267 }
01268 }
01269 return mincand;
01270 }
01271
01272
01273
01274
01275
01276
01277
01278 int is_bipred_enabled(int mode)
01279 {
01280 int enabled = 0;
01281 mode = (mode == P8x8) ? 4: mode;
01282
01283 if (params->BiPredMotionEstimation)
01284 {
01285 if (mode > 0 && mode < 5)
01286 {
01287 enabled = (params->BiPredSearch[mode - 1]) ? 1: 0;
01288 }
01289 else
01290 {
01291 enabled = 0;
01292 }
01293 }
01294 else
01295 {
01296 enabled = 0;
01297 }
01298 return enabled;
01299 }
01300
01301
01302
01303
01304
01305
01306
01307
01308 int transform_termination_control(Macroblock* currMB, int mode, int bslice)
01309 {
01310
01311
01312
01313
01314 if (params->Transform8x8Mode == 1)
01315 {
01316
01317 if (currMB->luma_transform_size_8x8_flag == 0 &&
01318 ((mode >= 1 && mode <= 3) || (bslice && mode == 0 && active_sps->direct_8x8_inference_flag) || (mode == P8x8)))
01319 {
01320
01321 currMB->luma_transform_size_8x8_flag = 1;
01322 return 0;
01323 }
01324 else
01325 {
01326 currMB->luma_transform_size_8x8_flag = 0;
01327 return 1;
01328 }
01329 }
01330 else
01331 {
01332 return 1;
01333 }
01334 }
01335
01336
01337
01338
01339
01340
01341
01342 int bslice_16x16_termination_control(Block8x8Info *b8x8info, int *ctr16x16, int mode, int bslice)
01343 {
01344 char pdir = 0;
01345 short i, bipred_me = 0;
01346 int lastcheck = 1;
01347
01348 if (mode == 1 && bslice)
01349 {
01350 switch (*ctr16x16)
01351 {
01352 case 0:
01353 pdir = 0;
01354 lastcheck = 0;
01355 break;
01356 case 1:
01357 pdir = 1;
01358 lastcheck = 0;
01359 break;
01360 case 2:
01361 pdir = 2;
01362 if (params->BiPredMotionEstimation)
01363 {
01364 lastcheck = 0;
01365 }
01366 break;
01367 case 3:
01368 pdir = 2;
01369 bipred_me = 1;
01370 lastcheck = 0;
01371 break;
01372 case 4:
01373 pdir = 2;
01374 bipred_me = 2;
01375 break;
01376 default:
01377 error("invalid 'ctr16x16' value", -1);
01378 break;
01379 }
01380 for (i = 0; i< 4; i++)
01381 {
01382 b8x8info->bipred8x8me[1][i] = bipred_me;
01383 b8x8info->best8x8pdir[1][i] = pdir;
01384 }
01385 (*ctr16x16)++;
01386 }
01387 return lastcheck;
01388 }
01389