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