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_highloss (Macroblock *currMB)
00038 {
00039 Slice *currSlice = currMB->p_slice;
00040 RDOPTStructure *p_RDO = currSlice->p_RDO;
00041 ImageParameters *p_Img = currMB->p_Img;
00042 InputParameters *p_Inp = currMB->p_Inp;
00043 PicMotionParams *motion = &p_Img->enc_picture->motion;
00044
00045 int max_index = 9;
00046 int rerun, 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, cost_direct=0;
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 short runs = (short) ((p_Inp->RestrictRef==1 && (pslice || (bslice && p_Img->nal_reference_idc>0))) ? 2 : 1);
00059
00060 imgpel **mb_pred = currSlice->mb_pred[0];
00061 Block8x8Info *b8x8info = p_Img->b8x8info;
00062
00063 char chroma_pred_mode_range[2];
00064 short inter_skip = 0;
00065 BestMode md_best;
00066 Info8x8 best;
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
00081
00082 for (rerun=0; rerun<runs; rerun++)
00083 {
00084 if (runs==2)
00085 p_Inp->rdopt= (rerun==0) ? 1 : 3;
00086
00087 if (p_Inp->AdaptiveRounding)
00088 {
00089 reset_adaptive_rounding(p_Img);
00090 }
00091
00092 if (currSlice->MbaffFrameFlag)
00093 {
00094 reset_mb_nz_coeff(p_Img, currMB->mbAddrX);
00095 }
00096
00097
00098 currMB->c_ipred_mode = DC_PRED_8;
00099 min_cost = INT_MAX;
00100
00101
00102
00103 currSlice->store_coding_state (currMB, currSlice->p_RDO->cs_cm);
00104
00105 if (!intra)
00106 {
00107
00108 if (enc_mb.valid[0])
00109 {
00110 if (bslice)
00111 currSlice->Get_Direct_Motion_Vectors (currMB);
00112 else
00113 FindSkipModeMotionVector (currMB);
00114 }
00115 if (p_Inp->CtxAdptLagrangeMult == 1)
00116 {
00117 get_initial_mb16x16_cost(currMB);
00118 }
00119
00120
00121 for (mode = 1; mode < 4; mode++)
00122 {
00123 best.mode = (byte) mode;
00124 best.bipred = 0;
00125 b8x8info->best[mode][0].bipred = 0;
00126 if (enc_mb.valid[mode])
00127 {
00128 for (cost=0, block=0; block<(mode==1?1:2); block++)
00129 {
00130 update_lambda_costs(currMB, &enc_mb, lambda_mf);
00131 PartitionMotionSearch (currMB, mode, block, lambda_mf);
00132
00133
00134 j = (block==1 && mode==2 ? 2 : 0);
00135 i = (block==1 && mode==3 ? 2 : 0);
00136
00137
00138 bmcost[LIST_0] = INT_MAX;
00139 list_prediction_cost(currMB, LIST_0, block, mode, &enc_mb, bmcost, best.ref);
00140
00141 if (bslice)
00142 {
00143
00144 bmcost[LIST_1] = INT_MAX;
00145 list_prediction_cost(currMB, LIST_1, block, mode, &enc_mb, bmcost, best.ref);
00146
00147
00148 list_prediction_cost(currMB, BI_PRED, block, mode, &enc_mb, bmcost, best.ref);
00149
00150
00151 if (is_bipred_enabled(p_Inp, mode))
00152 {
00153 get_bipred_cost(currMB, mode, block, i, j, &best, &enc_mb, bmcost);
00154 }
00155 else
00156 {
00157 bmcost[BI_PRED_L0] = INT_MAX;
00158 bmcost[BI_PRED_L1] = INT_MAX;
00159 }
00160
00161
00162 determine_prediction_list(bmcost, &best, &cost);
00163 }
00164 else
00165 {
00166 best.pdir = 0;
00167 cost += bmcost[LIST_0];
00168 }
00169
00170 assign_enc_picture_params(currMB, mode, &best, 2 * block);
00171
00172
00173 set_block8x8_info(b8x8info, mode, block, &best);
00174
00175
00176 if (mode>1 && block==0)
00177 currSlice->set_ref_and_motion_vectors (currMB, motion, &best, block);
00178 }
00179
00180 if (cost < min_cost)
00181 {
00182 md_best.mode = (byte) mode;
00183 md_best.cost = cost;
00184 currMB->best_mode = (short) mode;
00185 min_cost = cost;
00186 if (p_Inp->CtxAdptLagrangeMult == 1)
00187 {
00188 adjust_mb16x16_cost(currMB, cost);
00189 }
00190 }
00191 }
00192 }
00193
00194 if (enc_mb.valid[P8x8])
00195 {
00196 currMB->valid_8x8 = FALSE;
00197
00198 if (p_Inp->Transform8x8Mode)
00199 {
00200 ResetRD8x8Data(p_Img, p_RDO->tr8x8);
00201 currMB->luma_transform_size_8x8_flag = TRUE;
00202
00203
00204
00205
00206 for (cost_direct = 0, block=0; block<4; block++)
00207 {
00208 submacroblock_mode_decision(currMB, &enc_mb, p_RDO->tr8x8, p_RDO->cofAC8x8ts[block], block, &cost);
00209
00210 set_subblock8x8_info(b8x8info, P8x8, block, p_RDO->tr8x8);
00211 }
00212
00213 }
00214
00215
00216 if (p_Inp->Transform8x8Mode != 2)
00217 {
00218 currMB->luma_transform_size_8x8_flag = FALSE;
00219 ResetRD8x8Data(p_Img, p_RDO->tr4x4);
00220
00221
00222
00223
00224 for (cost_direct = 0, block=0; block<4; block++)
00225 {
00226 submacroblock_mode_decision(currMB, &enc_mb, p_RDO->tr4x4, p_RDO->coefAC8x8[block], block, &cost);
00227
00228 set_subblock8x8_info(b8x8info, P8x8, block, p_RDO->tr4x4);
00229 }
00230 }
00231
00232 if (p_Inp->RCEnable)
00233 rc_store_diff(currSlice->diffy, &p_Img->pCurImg[currMB->opix_y], currMB->pix_x, mb_pred);
00234
00235 p_Img->giRDOpt_B8OnlyFlag = FALSE;
00236 }
00237 }
00238 else
00239 {
00240 min_cost = INT_MAX;
00241 }
00242
00243
00244 SetChromaPredMode(currMB, enc_mb, mb_available, chroma_pred_mode_range);
00245
00246
00247
00248
00249 for (currMB->c_ipred_mode = chroma_pred_mode_range[0]; currMB->c_ipred_mode<=chroma_pred_mode_range[1]; currMB->c_ipred_mode++)
00250 {
00251
00252 if ( (p_Img->yuv_format != YUV400) &&
00253 ( ((!intra || !p_Inp->IntraDisableInterOnly) && p_Inp->ChromaIntraDisable == 1 && currMB->c_ipred_mode!=DC_PRED_8)
00254 || (currMB->c_ipred_mode == VERT_PRED_8 && !mb_available[0])
00255 || (currMB->c_ipred_mode == HOR_PRED_8 && !mb_available[1])
00256 || (currMB->c_ipred_mode == PLANE_8 && (!mb_available[1] || !mb_available[0] || !mb_available[2]))))
00257 continue;
00258
00259
00260 for (index=0; index < max_index; index++)
00261 {
00262 mode = mb_mode_table[index];
00263 if (enc_mb.valid[mode])
00264 {
00265 if (p_Img->yuv_format != YUV400)
00266 {
00267 currMB->i16mode = 0;
00268 }
00269
00270
00271 if (currSlice->P444_joined)
00272 {
00273 if (p_Inp->SkipIntraInInterSlices && !intra && mode >= I16MB
00274 && 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))
00275 continue;
00276 }
00277 else
00278 {
00279 if (p_Inp->SkipIntraInInterSlices && !intra && mode >= I4MB && currMB->best_mode <=3 && currMB->best_cbp == 0 && (currMB->min_rdcost < enc_mb.lambda_md * 5.0))
00280 continue;
00281 }
00282
00283 compute_mode_RD_cost(currMB, &enc_mb, (short) mode, &inter_skip);
00284 }
00285 }
00286 }
00287
00288
00289 restore_nz_coeff(currMB);
00290
00291 if (rerun==0)
00292 intra1 = IS_INTRA(currMB);
00293 }
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 if (p_Inp->RestrictRef)
00306 update_refresh_map(currMB, intra, intra1);
00307 }