00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <math.h>
00012 #include <limits.h>
00013 #include <float.h>
00014
00015 #include "global.h"
00016 #include "rdopt_coding_state.h"
00017 #include "mb_access.h"
00018 #include "intrarefresh.h"
00019 #include "image.h"
00020 #include "ratectl.h"
00021 #include "mode_decision.h"
00022 #include "fmo.h"
00023 #include "me_umhex.h"
00024 #include "me_umhexsmp.h"
00025 #include "macroblock.h"
00026 #include "md_common.h"
00027 #include "conformance.h"
00028 #include "vlc.h"
00029 #include "rdopt.h"
00030 #include "mv_search.h"
00031
00032
00033
00034
00035
00036
00037
00038
00039 static void fast_mode_intra_decision(Macroblock *currMB, short *intra_skip)
00040 {
00041 ImageParameters *p_Img = currMB->p_Img;
00042 int i;
00043 int mb_available_up, mb_available_left;
00044 long SBE;
00045 double AR = 0, ABE = 0;
00046 PixelPos up;
00047 PixelPos left[2];
00048
00049 p_Img->getNeighbour(currMB, 0 , -1 , p_Img->mb_size[IS_LUMA], &up);
00050 p_Img->getNeighbour(currMB, -1 , -1 , p_Img->mb_size[IS_LUMA], &left[0]);
00051 p_Img->getNeighbour(currMB, -1 , 0 , p_Img->mb_size[IS_LUMA], &left[1]);
00052
00053 mb_available_up = up.available;
00054 mb_available_left = left[1].available;
00055
00056 AR=(1.0/384)*currMB->min_rate;
00057
00058 SBE = 0;
00059
00060 if( (currMB->mb_y != (int)p_Img->FrameHeightInMbs-1) && (currMB->mb_x != (int)p_Img->PicWidthInMbs-1) && mb_available_left && mb_available_up)
00061 {
00062 for(i = 0; i < MB_BLOCK_SIZE; i++)
00063 {
00064 SBE += iabs(p_Img->pCurImg[currMB->opix_y][currMB->pix_x + i] - p_Img->enc_picture->imgY[currMB->pix_y - 1][currMB->pix_x + i]);
00065 SBE += iabs(p_Img->pCurImg[currMB->opix_y + i][currMB->pix_x] - p_Img->enc_picture->imgY[currMB->pix_y + i][currMB->pix_x - 1]);
00066 }
00067
00068 for(i = 0; i < 8; i++)
00069 {
00070 SBE += iabs(p_Img->pImgOrg[1][currMB->opix_c_y][currMB->pix_c_x + i] - p_Img->enc_picture->imgUV[0][currMB->pix_c_y - 1][currMB->pix_c_x + i]);
00071 SBE += iabs(p_Img->pImgOrg[1][currMB->opix_c_y+i][currMB->pix_c_x] - p_Img->enc_picture->imgUV[0][currMB->pix_c_y + i][currMB->pix_c_x - 1]);
00072 SBE += iabs(p_Img->pImgOrg[2][currMB->opix_c_y][currMB->pix_c_x + i] - p_Img->enc_picture->imgUV[1][currMB->pix_c_y - 1][currMB->pix_c_x + i]);
00073 SBE += iabs(p_Img->pImgOrg[2][currMB->opix_c_y+i][currMB->pix_c_x] - p_Img->enc_picture->imgUV[1][currMB->pix_c_y + i][currMB->pix_c_x - 1]);
00074 }
00075 ABE = 1.0/64 * SBE;
00076 }
00077 else
00078 {
00079 ABE = 0;
00080 }
00081
00082 if(AR <= ABE)
00083 {
00084 *intra_skip = 1;
00085 }
00086 }
00087
00088
00089
00090
00091
00092
00093
00094 void encode_one_macroblock_highfast (Macroblock *currMB)
00095 {
00096 Slice *currSlice = currMB->p_slice;
00097 ImageParameters *p_Img = currMB->p_Img;
00098 InputParameters *p_Inp = currMB->p_Inp;
00099 PicMotionParams *motion = &p_Img->enc_picture->motion;
00100 RDOPTStructure *p_RDO = currSlice->p_RDO;
00101
00102 int max_index;
00103 int block, index, mode, i, j;
00104 RD_PARAMS enc_mb;
00105 double max_rdcost = 1e30;
00106 int bmcost[5] = {INT_MAX};
00107 int cost=0;
00108 int min_cost = INT_MAX;
00109 int intra1 = 0;
00110 int mb_available[3];
00111
00112 short islice = (short) (currSlice->slice_type == I_SLICE);
00113 short bslice = (short) (currSlice->slice_type == B_SLICE);
00114 short pslice = (short) ((currSlice->slice_type == P_SLICE) || (currSlice->slice_type == SP_SLICE));
00115 short intra = (short) ((currSlice->slice_type == I_SLICE) || (pslice && currMB->mb_y == p_Img->mb_y_upd && p_Img->mb_y_upd != p_Img->mb_y_intra));
00116 int lambda_mf[3];
00117
00118 imgpel **mb_pred = currSlice->mb_pred[0];
00119 Block8x8Info *b8x8info = p_Img->b8x8info;
00120
00121 char chroma_pred_mode_range[2];
00122
00123
00124 short *allmvs = (currSlice->slice_type == I_SLICE) ? NULL: currSlice->all_mv[0][0][0][0][0];
00125
00126
00127 short inter_skip = 0, intra_skip = 0;
00128 int mode16 = 0;
00129 double RDCost16 = DBL_MAX;
00130
00131 BestMode md_best;
00132 Info8x8 best;
00133
00134 init_md_best(&md_best);
00135
00136
00137 best.pdir = 0;
00138 best.bipred = 0;
00139 best.ref[LIST_0] = 0;
00140 best.ref[LIST_1] = -1;
00141
00142 intra |= RandomIntra (p_Img, currMB->mbAddrX);
00143
00144
00145 init_enc_mb_params(currMB, &enc_mb, intra);
00146 if (p_Inp->AdaptiveRounding)
00147 {
00148 reset_adaptive_rounding(p_Img);
00149 }
00150
00151 if (currSlice->MbaffFrameFlag)
00152 {
00153 reset_mb_nz_coeff(p_Img, currMB->mbAddrX);
00154 }
00155
00156
00157
00158 currSlice->store_coding_state (currMB, currSlice->p_RDO->cs_cm);
00159
00160 if (!intra)
00161 {
00162
00163 if (bslice && enc_mb.valid[0])
00164 {
00165 currSlice->Get_Direct_Motion_Vectors (currMB);
00166 currMB->best_mode = 0;
00167 currMB->c_ipred_mode=DC_PRED_8;
00168 currMB->min_rdcost = max_rdcost;
00169 compute_mode_RD_cost(currMB, &enc_mb, 0, &inter_skip);
00170 }
00171 if (p_Inp->CtxAdptLagrangeMult == 1)
00172 {
00173 get_initial_mb16x16_cost(currMB);
00174 }
00175
00176
00177 for (mode = 1; mode < 4; mode++)
00178 {
00179 best.mode = (char) mode;
00180 best.bipred = 0;
00181 b8x8info->best[mode][0].bipred = 0;
00182
00183 if (enc_mb.valid[mode] && !inter_skip)
00184 {
00185 for (cost=0, block=0; block<(mode==1?1:2); block++)
00186 {
00187 update_lambda_costs(currMB, &enc_mb, lambda_mf);
00188 PartitionMotionSearch (currMB, mode, block, lambda_mf);
00189
00190
00191 j = (block==1 && mode==2 ? 2 : 0);
00192 i = (block==1 && mode==3 ? 2 : 0);
00193
00194
00195 bmcost[LIST_0] = INT_MAX;
00196 list_prediction_cost(currMB, LIST_0, block, mode, &enc_mb, bmcost, best.ref);
00197
00198 if (bslice)
00199 {
00200
00201 bmcost[LIST_1] = INT_MAX;
00202 list_prediction_cost(currMB, LIST_1, block, mode, &enc_mb, bmcost, best.ref);
00203
00204
00205 list_prediction_cost(currMB, BI_PRED, block, mode, &enc_mb, bmcost, best.ref);
00206
00207
00208 if (is_bipred_enabled(p_Inp, mode))
00209 {
00210 get_bipred_cost(currMB, mode, block, i, j, &best, &enc_mb, bmcost);
00211 }
00212 else
00213 {
00214 bmcost[BI_PRED_L0] = INT_MAX;
00215 bmcost[BI_PRED_L1] = INT_MAX;
00216 }
00217
00218
00219 determine_prediction_list(bmcost, &best, &cost);
00220 }
00221 else
00222 {
00223 best.pdir = 0;
00224 cost += bmcost[LIST_0];
00225 }
00226
00227 assign_enc_picture_params(currMB, mode, &best, 2 * block);
00228
00229
00230 set_block8x8_info(b8x8info, mode, block, &best);
00231
00232
00233 if (mode>1 && block == 0)
00234 currSlice->set_ref_and_motion_vectors (currMB, motion, &best, block);
00235 }
00236
00237
00238 if(mode == 1)
00239 {
00240 if(pslice)
00241 currMB->min_rdcost = max_rdcost;
00242
00243 currMB->c_ipred_mode=DC_PRED_8;
00244 compute_mode_RD_cost(currMB, &enc_mb, (short) mode, &inter_skip);
00245
00246 if(pslice)
00247 {
00248
00249 FindSkipModeMotionVector (currMB);
00250
00251 if(p_Inp->EarlySkipEnable)
00252 {
00253
00254 if ( currMB->cbp==0 && motion->ref_idx[LIST_0][currMB->block_y][currMB->block_x]==0 &&
00255 motion->mv[LIST_0][currMB->block_y][currMB->block_x][0]==allmvs[0] &&
00256 motion->mv[LIST_0][currMB->block_y][currMB->block_x][1]==allmvs[1] )
00257 {
00258 inter_skip = 1;
00259 currMB->best_mode = 0;
00260 }
00261 }
00262 }
00263
00264
00265 RDCost16 = currMB->min_rdcost;
00266 mode16 = currMB->best_mode;
00267 }
00268
00269 if ((!inter_skip) && (cost < min_cost))
00270 {
00271 md_best.mode = (byte) mode;
00272 md_best.cost = cost;
00273 currMB->best_mode = (short) mode;
00274 min_cost = cost;
00275 if (p_Inp->CtxAdptLagrangeMult == 1)
00276 {
00277 adjust_mb16x16_cost(currMB, cost);
00278 }
00279 }
00280 }
00281 }
00282
00283 if ((!inter_skip) && enc_mb.valid[P8x8])
00284 {
00285 currMB->valid_8x8 = FALSE;
00286
00287 if (p_Inp->Transform8x8Mode)
00288 {
00289 ResetRD8x8Data(p_Img, p_RDO->tr8x8);
00290 currMB->luma_transform_size_8x8_flag = TRUE;
00291
00292
00293
00294
00295 for (block = 0; block < 4; block++)
00296 {
00297 submacroblock_mode_decision(currMB, &enc_mb, p_RDO->tr8x8, p_RDO->cofAC8x8ts[block], block, &cost);
00298
00299 set_subblock8x8_info(b8x8info, P8x8, block, p_RDO->tr8x8);
00300 }
00301 }
00302
00303
00304 if (p_Inp->Transform8x8Mode != 2)
00305 {
00306 currMB->luma_transform_size_8x8_flag = FALSE;
00307 ResetRD8x8Data(p_Img, p_RDO->tr4x4);
00308
00309
00310
00311
00312 for (block = 0; block < 4; block++)
00313 {
00314 submacroblock_mode_decision(currMB, &enc_mb, p_RDO->tr4x4, p_RDO->coefAC8x8[block], block, &cost);
00315
00316 set_subblock8x8_info(b8x8info, P8x8, block, p_RDO->tr4x4);
00317 }
00318 }
00319
00320 if (p_Inp->RCEnable)
00321 rc_store_diff(currSlice->diffy, &p_Img->pCurImg[currMB->opix_y], currMB->pix_x, mb_pred);
00322
00323 p_Img->giRDOpt_B8OnlyFlag = FALSE;
00324 }
00325 }
00326 else
00327 {
00328 min_cost = INT_MAX;
00329 }
00330
00331
00332
00333 {
00334 if (!inter_skip)
00335 {
00336 if(currSlice->slice_type != I_SLICE)
00337 {
00338 currMB->min_rdcost = RDCost16;
00339 currMB->best_mode = (short) mode16;
00340 }
00341 else
00342 currMB->min_rdcost = max_rdcost;
00343
00344
00345 max_index = ((!intra && p_Inp->SelectiveIntraEnable ) ? 5 : 9);
00346
00347
00348 SetChromaPredMode(currMB, enc_mb, mb_available, chroma_pred_mode_range);
00349
00350
00351
00352
00353 for (currMB->c_ipred_mode = chroma_pred_mode_range[0]; currMB->c_ipred_mode<=chroma_pred_mode_range[1]; currMB->c_ipred_mode++)
00354 {
00355
00356 if ( (p_Img->yuv_format != YUV400) &&
00357 ( ((!intra || !p_Inp->IntraDisableInterOnly) && p_Inp->ChromaIntraDisable == 1 && currMB->c_ipred_mode!=DC_PRED_8)
00358 || (currMB->c_ipred_mode == VERT_PRED_8 && !mb_available[0])
00359 || (currMB->c_ipred_mode == HOR_PRED_8 && !mb_available[1])
00360 || (currMB->c_ipred_mode == PLANE_8 && (!mb_available[1] || !mb_available[0] || !mb_available[2]))))
00361 continue;
00362
00363
00364 for (index=0; index < max_index; index++)
00365 {
00366 mode = mb_mode_table[index];
00367 if (enc_mb.valid[mode])
00368 {
00369 if (p_Img->yuv_format != YUV400)
00370 {
00371 currMB->i16mode = 0;
00372 }
00373
00374
00375 if (currSlice->P444_joined)
00376 {
00377 if (p_Inp->SkipIntraInInterSlices && !intra && mode >= I16MB
00378 && currMB->best_mode <=3 && currMB->best_cbp == 0 && currSlice->cmp_cbp[1] == 0 && currSlice->cmp_cbp[2] == 0 && (currMB->min_rdcost < enc_mb.lambda_md * 5.0))
00379 continue;
00380 }
00381 else
00382 {
00383 if (p_Inp->SkipIntraInInterSlices && !intra && mode >= I4MB && currMB->best_mode <=3 && currMB->best_cbp == 0 && (currMB->min_rdcost < enc_mb.lambda_md * 5.0))
00384 continue;
00385 }
00386
00387 compute_mode_RD_cost(currMB, &enc_mb, (short) mode, &inter_skip);
00388
00389 }
00390 }
00391 }
00392
00393
00394 if(currSlice->slice_type != I_SLICE && p_Inp->SelectiveIntraEnable && !IS_FREXT_PROFILE(p_Inp->ProfileIDC))
00395 {
00396 fast_mode_intra_decision(currMB, &intra_skip);
00397
00398 if(!intra_skip)
00399 {
00400
00401 SetChromaPredMode(currMB, enc_mb, mb_available, chroma_pred_mode_range);
00402
00403 max_index = 9;
00404
00405 for (currMB->c_ipred_mode=chroma_pred_mode_range[0]; currMB->c_ipred_mode<=chroma_pred_mode_range[1]; currMB->c_ipred_mode++)
00406 {
00407
00408
00409 if ( (p_Img->yuv_format != YUV400) &&
00410 ( ((!intra || !p_Inp->IntraDisableInterOnly) && p_Inp->ChromaIntraDisable == 1 && currMB->c_ipred_mode!=DC_PRED_8)
00411 || (currMB->c_ipred_mode == VERT_PRED_8 && !mb_available[0])
00412 || (currMB->c_ipred_mode == HOR_PRED_8 && !mb_available[1])
00413 || (currMB->c_ipred_mode == PLANE_8 && (!mb_available[0] || !mb_available[1]|| !mb_available[2]))))
00414 continue;
00415
00416
00417 for (index = 5; index < max_index; index++)
00418 {
00419 mode = mb_mode_table[index];
00420
00421
00422 if (p_Inp->SkipIntraInInterSlices && !intra && mode >= I4MB && currMB->best_mode <=3 && currMB->best_cbp == 0)
00423 continue;
00424
00425 if (p_Img->yuv_format != YUV400)
00426 {
00427 currMB->i16mode = 0;
00428
00429 if(((bslice && mode == 0) || (!islice && mode == 1)))
00430 continue;
00431 }
00432
00433 if (enc_mb.valid[mode])
00434 compute_mode_RD_cost(currMB, &enc_mb, (short) mode, &inter_skip);
00435 }
00436 }
00437 }
00438 }
00439 }
00440 restore_nz_coeff(currMB);
00441
00442 }
00443
00444 intra1 = IS_INTRA(currMB);
00445
00446
00447
00448 update_qp_cbp_tmp(currMB, p_RDO->cbp);
00449 currSlice->set_stored_mb_parameters (currMB);
00450
00451
00452 if(p_Inp->RCEnable && p_Inp->RCUpdateMode <= MAX_RC_MODE)
00453 rc_store_mad(currMB);
00454
00455
00456 if (p_Inp->RestrictRef)
00457 update_refresh_map(currMB, intra, intra1);
00458
00459 }
00460
00461