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 "intrarefresh.h"
00018 #include "image.h"
00019 #include "ratectl.h"
00020 #include "mode_decision.h"
00021 #include "fmo.h"
00022 #include "me_umhex.h"
00023 #include "me_umhexsmp.h"
00024 #include "macroblock.h"
00025 #include "md_common.h"
00026 #include "conformance.h"
00027 #include "vlc.h"
00028 #include "rdopt.h"
00029 #include "mv_search.h"
00030
00031
00032
00033
00034
00035
00036
00037 void encode_one_macroblock_high (Macroblock *currMB)
00038 {
00039 Slice *currSlice = currMB->p_slice;
00040 ImageParameters *p_Img = currMB->p_Img;
00041 InputParameters *p_Inp = currMB->p_Inp;
00042 PicMotionParams *motion = &p_Img->enc_picture->motion;
00043 RDOPTStructure *p_RDO = currSlice->p_RDO;
00044
00045 int max_index = 9;
00046 int block, index, mode, i, j;
00047 RD_PARAMS enc_mb;
00048 int bmcost[5] = {INT_MAX};
00049 int cost=0;
00050 int min_cost = INT_MAX;
00051 int intra1 = 0;
00052 int mb_available[3];
00053
00054 short bslice = (short) (currSlice->slice_type == B_SLICE);
00055 short pslice = (short) ((currSlice->slice_type == P_SLICE) || (currSlice->slice_type == SP_SLICE));
00056 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));
00057 int lambda_mf[3];
00058
00059 imgpel **mb_pred = currSlice->mb_pred[0];
00060 Block8x8Info *b8x8info = p_Img->b8x8info;
00061
00062 char chroma_pred_mode_range[2];
00063 short inter_skip = 0;
00064 BestMode md_best;
00065 Info8x8 best;
00066
00067
00068 init_md_best(&md_best);
00069
00070
00071 best.pdir = 0;
00072 best.bipred = 0;
00073 best.ref[LIST_0] = 0;
00074 best.ref[LIST_1] = -1;
00075
00076 intra |= RandomIntra (p_Img, currMB->mbAddrX);
00077
00078
00079 init_enc_mb_params(currMB, &enc_mb, intra);
00080 if (p_Inp->AdaptiveRounding)
00081 {
00082 reset_adaptive_rounding(p_Img);
00083 }
00084
00085 if (currSlice->MbaffFrameFlag)
00086 {
00087 reset_mb_nz_coeff(p_Img, currMB->mbAddrX);
00088 }
00089
00090
00091
00092 currSlice->store_coding_state (currMB, currSlice->p_RDO->cs_cm);
00093
00094 if (!intra)
00095 {
00096
00097 if (enc_mb.valid[0])
00098 {
00099 if (bslice)
00100 currSlice->Get_Direct_Motion_Vectors (currMB);
00101 else
00102 FindSkipModeMotionVector (currMB);
00103 }
00104 if (p_Inp->CtxAdptLagrangeMult == 1)
00105 {
00106 get_initial_mb16x16_cost(currMB);
00107 }
00108
00109
00110 for (mode = 1; mode < 4; mode++)
00111 {
00112 best.mode = (char) mode;
00113 best.bipred = 0;
00114 b8x8info->best[mode][0].bipred = 0;
00115
00116 if (enc_mb.valid[mode])
00117 {
00118 for (cost=0, block=0; block<(mode==1?1:2); block++)
00119 {
00120 update_lambda_costs(currMB, &enc_mb, lambda_mf);
00121 PartitionMotionSearch (currMB, mode, block, lambda_mf);
00122
00123
00124 j = (block==1 && mode==2 ? 2 : 0);
00125 i = (block==1 && mode==3 ? 2 : 0);
00126
00127
00128 bmcost[LIST_0] = INT_MAX;
00129 list_prediction_cost(currMB, LIST_0, block, mode, &enc_mb, bmcost, best.ref);
00130
00131 if (bslice)
00132 {
00133
00134 bmcost[LIST_1] = INT_MAX;
00135 list_prediction_cost(currMB, LIST_1, block, mode, &enc_mb, bmcost, best.ref);
00136
00137
00138 list_prediction_cost(currMB, BI_PRED, block, mode, &enc_mb, bmcost, best.ref);
00139
00140
00141 if (is_bipred_enabled(p_Inp, mode))
00142 {
00143 get_bipred_cost(currMB, mode, block, i, j, &best, &enc_mb, bmcost);
00144 }
00145 else
00146 {
00147 bmcost[BI_PRED_L0] = INT_MAX;
00148 bmcost[BI_PRED_L1] = INT_MAX;
00149 }
00150
00151
00152 determine_prediction_list(bmcost, &best, &cost);
00153 }
00154 else
00155 {
00156 best.pdir = 0;
00157 cost += bmcost[LIST_0];
00158 }
00159
00160 assign_enc_picture_params(currMB, mode, &best, 2 * block);
00161
00162
00163 set_block8x8_info(b8x8info, mode, block, &best);
00164
00165
00166 if (mode>1 && block == 0)
00167 currSlice->set_ref_and_motion_vectors (currMB, motion, &best, block);
00168 }
00169
00170 if (cost < min_cost)
00171 {
00172 md_best.mode = (byte) mode;
00173 md_best.cost = cost;
00174 currMB->best_mode = (short) mode;
00175 min_cost = cost;
00176 if (p_Inp->CtxAdptLagrangeMult == 1)
00177 {
00178 adjust_mb16x16_cost(currMB, cost);
00179 }
00180 }
00181 }
00182 }
00183
00184 if (enc_mb.valid[P8x8])
00185 {
00186 currMB->valid_8x8 = FALSE;
00187
00188 if (p_Inp->Transform8x8Mode)
00189 {
00190 ResetRD8x8Data(p_Img, p_RDO->tr8x8);
00191 currMB->luma_transform_size_8x8_flag = TRUE;
00192
00193
00194
00195
00196 for (block = 0; block < 4; block++)
00197 {
00198 submacroblock_mode_decision(currMB, &enc_mb, p_RDO->tr8x8, p_RDO->cofAC8x8ts[block], block, &cost);
00199
00200 set_subblock8x8_info(b8x8info, P8x8, block, p_RDO->tr8x8);
00201 }
00202 }
00203
00204
00205 if (p_Inp->Transform8x8Mode != 2)
00206 {
00207 currMB->luma_transform_size_8x8_flag = FALSE;
00208 ResetRD8x8Data(p_Img, p_RDO->tr4x4);
00209
00210
00211
00212
00213 for (block = 0; block < 4; block++)
00214 {
00215 submacroblock_mode_decision(currMB, &enc_mb, p_RDO->tr4x4, p_RDO->coefAC8x8[block], block, &cost);
00216
00217 set_subblock8x8_info(b8x8info, P8x8, block, p_RDO->tr4x4);
00218 }
00219 }
00220
00221 if (p_Inp->RCEnable)
00222 rc_store_diff(currSlice->diffy, &p_Img->pCurImg[currMB->opix_y], currMB->pix_x, mb_pred);
00223
00224 p_Img->giRDOpt_B8OnlyFlag = FALSE;
00225 }
00226 }
00227 else
00228 {
00229 min_cost = INT_MAX;
00230 }
00231
00232
00233 SetChromaPredMode(currMB, enc_mb, mb_available, chroma_pred_mode_range);
00234
00235
00236
00237
00238 for (currMB->c_ipred_mode = chroma_pred_mode_range[0]; currMB->c_ipred_mode<=chroma_pred_mode_range[1]; currMB->c_ipred_mode++)
00239 {
00240
00241 if ( (p_Img->yuv_format != YUV400) &&
00242 ( ((!intra || !p_Inp->IntraDisableInterOnly) && p_Inp->ChromaIntraDisable == 1 && currMB->c_ipred_mode!=DC_PRED_8)
00243 || (currMB->c_ipred_mode == VERT_PRED_8 && !mb_available[0])
00244 || (currMB->c_ipred_mode == HOR_PRED_8 && !mb_available[1])
00245 || (currMB->c_ipred_mode == PLANE_8 && (!mb_available[1] || !mb_available[0] || !mb_available[2]))))
00246 continue;
00247
00248
00249 for (index=0; index < max_index; index++)
00250 {
00251 mode = mb_mode_table[index];
00252 if (enc_mb.valid[mode])
00253 {
00254 if (p_Img->yuv_format != YUV400)
00255 {
00256 currMB->i16mode = 0;
00257 }
00258
00259
00260 if (currSlice->P444_joined)
00261 {
00262 if (p_Inp->SkipIntraInInterSlices && !intra && mode >= I16MB
00263 && 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))
00264 continue;
00265 }
00266 else
00267 {
00268 if (p_Inp->SkipIntraInInterSlices)
00269 {
00270 if (!intra && mode >= I4MB)
00271 {
00272 if (currMB->best_mode <=3 && currMB->best_cbp == 0 && (currMB->min_rdcost < enc_mb.lambda_md * 5.0))
00273 {
00274 continue;
00275 }
00276 else if (currMB->best_mode == 0 && (currMB->min_rdcost < enc_mb.lambda_md * 6.0))
00277 {
00278 continue;
00279 }
00280 }
00281 }
00282
00283 }
00284
00285 compute_mode_RD_cost(currMB, &enc_mb, (short) mode, &inter_skip);
00286
00287 }
00288 }
00289 }
00290
00291 restore_nz_coeff(currMB);
00292
00293 intra1 = IS_INTRA(currMB);
00294
00295
00296
00297 update_qp_cbp_tmp(currMB, p_RDO->cbp);
00298 currSlice->set_stored_mb_parameters (currMB);
00299
00300
00301 if(p_Inp->RCEnable && p_Inp->RCUpdateMode <= MAX_RC_MODE)
00302 rc_store_mad(currMB);
00303
00304
00305
00306 if (p_Inp->RestrictRef)
00307 update_refresh_map(currMB, intra, intra1);
00308
00309 }
00310
00311