Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* |
michael@0 | 2 | * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
michael@0 | 3 | * |
michael@0 | 4 | * Use of this source code is governed by a BSD-style license |
michael@0 | 5 | * that can be found in the LICENSE file in the root of the source |
michael@0 | 6 | * tree. An additional intellectual property rights grant can be found |
michael@0 | 7 | * in the file PATENTS. All contributing project authors may |
michael@0 | 8 | * be found in the AUTHORS file in the root of the source tree. |
michael@0 | 9 | */ |
michael@0 | 10 | |
michael@0 | 11 | #include <stdio.h> |
michael@0 | 12 | #include <math.h> |
michael@0 | 13 | #include <limits.h> |
michael@0 | 14 | #include <assert.h> |
michael@0 | 15 | |
michael@0 | 16 | #include "vp9/common/vp9_pragmas.h" |
michael@0 | 17 | #include "vp9/encoder/vp9_tokenize.h" |
michael@0 | 18 | #include "vp9/encoder/vp9_treewriter.h" |
michael@0 | 19 | #include "vp9/encoder/vp9_onyx_int.h" |
michael@0 | 20 | #include "vp9/encoder/vp9_modecosts.h" |
michael@0 | 21 | #include "vp9/encoder/vp9_encodeintra.h" |
michael@0 | 22 | #include "vp9/common/vp9_entropymode.h" |
michael@0 | 23 | #include "vp9/common/vp9_reconinter.h" |
michael@0 | 24 | #include "vp9/common/vp9_reconintra.h" |
michael@0 | 25 | #include "vp9/common/vp9_findnearmv.h" |
michael@0 | 26 | #include "vp9/common/vp9_quant_common.h" |
michael@0 | 27 | #include "vp9/encoder/vp9_encodemb.h" |
michael@0 | 28 | #include "vp9/encoder/vp9_quantize.h" |
michael@0 | 29 | #include "vp9/encoder/vp9_variance.h" |
michael@0 | 30 | #include "vp9/encoder/vp9_mcomp.h" |
michael@0 | 31 | #include "vp9/encoder/vp9_rdopt.h" |
michael@0 | 32 | #include "vp9/encoder/vp9_ratectrl.h" |
michael@0 | 33 | #include "vpx_mem/vpx_mem.h" |
michael@0 | 34 | #include "vp9/common/vp9_systemdependent.h" |
michael@0 | 35 | #include "vp9/encoder/vp9_encodemv.h" |
michael@0 | 36 | #include "vp9/common/vp9_seg_common.h" |
michael@0 | 37 | #include "vp9/common/vp9_pred_common.h" |
michael@0 | 38 | #include "vp9/common/vp9_entropy.h" |
michael@0 | 39 | #include "./vp9_rtcd.h" |
michael@0 | 40 | #include "vp9/common/vp9_mvref_common.h" |
michael@0 | 41 | #include "vp9/common/vp9_common.h" |
michael@0 | 42 | |
michael@0 | 43 | #define INVALID_MV 0x80008000 |
michael@0 | 44 | |
michael@0 | 45 | /* Factor to weigh the rate for switchable interp filters */ |
michael@0 | 46 | #define SWITCHABLE_INTERP_RATE_FACTOR 1 |
michael@0 | 47 | |
michael@0 | 48 | #define LAST_FRAME_MODE_MASK 0xFFEDCD60 |
michael@0 | 49 | #define GOLDEN_FRAME_MODE_MASK 0xFFDA3BB0 |
michael@0 | 50 | #define ALT_REF_MODE_MASK 0xFFC648D0 |
michael@0 | 51 | |
michael@0 | 52 | #define MIN_EARLY_TERM_INDEX 3 |
michael@0 | 53 | |
michael@0 | 54 | const MODE_DEFINITION vp9_mode_order[MAX_MODES] = { |
michael@0 | 55 | {NEARESTMV, LAST_FRAME, NONE}, |
michael@0 | 56 | {NEARESTMV, ALTREF_FRAME, NONE}, |
michael@0 | 57 | {NEARESTMV, GOLDEN_FRAME, NONE}, |
michael@0 | 58 | |
michael@0 | 59 | {DC_PRED, INTRA_FRAME, NONE}, |
michael@0 | 60 | |
michael@0 | 61 | {NEWMV, LAST_FRAME, NONE}, |
michael@0 | 62 | {NEWMV, ALTREF_FRAME, NONE}, |
michael@0 | 63 | {NEWMV, GOLDEN_FRAME, NONE}, |
michael@0 | 64 | |
michael@0 | 65 | {NEARMV, LAST_FRAME, NONE}, |
michael@0 | 66 | {NEARMV, ALTREF_FRAME, NONE}, |
michael@0 | 67 | {NEARESTMV, LAST_FRAME, ALTREF_FRAME}, |
michael@0 | 68 | {NEARESTMV, GOLDEN_FRAME, ALTREF_FRAME}, |
michael@0 | 69 | |
michael@0 | 70 | {TM_PRED, INTRA_FRAME, NONE}, |
michael@0 | 71 | |
michael@0 | 72 | {NEARMV, LAST_FRAME, ALTREF_FRAME}, |
michael@0 | 73 | {NEWMV, LAST_FRAME, ALTREF_FRAME}, |
michael@0 | 74 | {NEARMV, GOLDEN_FRAME, NONE}, |
michael@0 | 75 | {NEARMV, GOLDEN_FRAME, ALTREF_FRAME}, |
michael@0 | 76 | {NEWMV, GOLDEN_FRAME, ALTREF_FRAME}, |
michael@0 | 77 | |
michael@0 | 78 | {ZEROMV, LAST_FRAME, NONE}, |
michael@0 | 79 | {ZEROMV, GOLDEN_FRAME, NONE}, |
michael@0 | 80 | {ZEROMV, ALTREF_FRAME, NONE}, |
michael@0 | 81 | {ZEROMV, LAST_FRAME, ALTREF_FRAME}, |
michael@0 | 82 | {ZEROMV, GOLDEN_FRAME, ALTREF_FRAME}, |
michael@0 | 83 | |
michael@0 | 84 | {H_PRED, INTRA_FRAME, NONE}, |
michael@0 | 85 | {V_PRED, INTRA_FRAME, NONE}, |
michael@0 | 86 | {D135_PRED, INTRA_FRAME, NONE}, |
michael@0 | 87 | {D207_PRED, INTRA_FRAME, NONE}, |
michael@0 | 88 | {D153_PRED, INTRA_FRAME, NONE}, |
michael@0 | 89 | {D63_PRED, INTRA_FRAME, NONE}, |
michael@0 | 90 | {D117_PRED, INTRA_FRAME, NONE}, |
michael@0 | 91 | {D45_PRED, INTRA_FRAME, NONE}, |
michael@0 | 92 | }; |
michael@0 | 93 | |
michael@0 | 94 | const REF_DEFINITION vp9_ref_order[MAX_REFS] = { |
michael@0 | 95 | {LAST_FRAME, NONE}, |
michael@0 | 96 | {GOLDEN_FRAME, NONE}, |
michael@0 | 97 | {ALTREF_FRAME, NONE}, |
michael@0 | 98 | {LAST_FRAME, ALTREF_FRAME}, |
michael@0 | 99 | {GOLDEN_FRAME, ALTREF_FRAME}, |
michael@0 | 100 | {INTRA_FRAME, NONE}, |
michael@0 | 101 | }; |
michael@0 | 102 | |
michael@0 | 103 | // The baseline rd thresholds for breaking out of the rd loop for |
michael@0 | 104 | // certain modes are assumed to be based on 8x8 blocks. |
michael@0 | 105 | // This table is used to correct for blocks size. |
michael@0 | 106 | // The factors here are << 2 (2 = x0.5, 32 = x8 etc). |
michael@0 | 107 | static int rd_thresh_block_size_factor[BLOCK_SIZES] = |
michael@0 | 108 | {2, 3, 3, 4, 6, 6, 8, 12, 12, 16, 24, 24, 32}; |
michael@0 | 109 | |
michael@0 | 110 | #define RD_THRESH_MAX_FACT 64 |
michael@0 | 111 | #define RD_THRESH_INC 1 |
michael@0 | 112 | #define RD_THRESH_POW 1.25 |
michael@0 | 113 | #define RD_MULT_EPB_RATIO 64 |
michael@0 | 114 | |
michael@0 | 115 | #define MV_COST_WEIGHT 108 |
michael@0 | 116 | #define MV_COST_WEIGHT_SUB 120 |
michael@0 | 117 | |
michael@0 | 118 | static void fill_token_costs(vp9_coeff_cost *c, |
michael@0 | 119 | vp9_coeff_probs_model (*p)[BLOCK_TYPES]) { |
michael@0 | 120 | int i, j, k, l; |
michael@0 | 121 | TX_SIZE t; |
michael@0 | 122 | for (t = TX_4X4; t <= TX_32X32; t++) |
michael@0 | 123 | for (i = 0; i < BLOCK_TYPES; i++) |
michael@0 | 124 | for (j = 0; j < REF_TYPES; j++) |
michael@0 | 125 | for (k = 0; k < COEF_BANDS; k++) |
michael@0 | 126 | for (l = 0; l < PREV_COEF_CONTEXTS; l++) { |
michael@0 | 127 | vp9_prob probs[ENTROPY_NODES]; |
michael@0 | 128 | vp9_model_to_full_probs(p[t][i][j][k][l], probs); |
michael@0 | 129 | vp9_cost_tokens((int *)c[t][i][j][k][0][l], probs, |
michael@0 | 130 | vp9_coef_tree); |
michael@0 | 131 | vp9_cost_tokens_skip((int *)c[t][i][j][k][1][l], probs, |
michael@0 | 132 | vp9_coef_tree); |
michael@0 | 133 | assert(c[t][i][j][k][0][l][DCT_EOB_TOKEN] == |
michael@0 | 134 | c[t][i][j][k][1][l][DCT_EOB_TOKEN]); |
michael@0 | 135 | } |
michael@0 | 136 | } |
michael@0 | 137 | |
michael@0 | 138 | static const int rd_iifactor[32] = { |
michael@0 | 139 | 4, 4, 3, 2, 1, 0, 0, 0, |
michael@0 | 140 | 0, 0, 0, 0, 0, 0, 0, 0, |
michael@0 | 141 | 0, 0, 0, 0, 0, 0, 0, 0, |
michael@0 | 142 | 0, 0, 0, 0, 0, 0, 0, 0, |
michael@0 | 143 | }; |
michael@0 | 144 | |
michael@0 | 145 | // 3* dc_qlookup[Q]*dc_qlookup[Q]; |
michael@0 | 146 | |
michael@0 | 147 | /* values are now correlated to quantizer */ |
michael@0 | 148 | static int sad_per_bit16lut[QINDEX_RANGE]; |
michael@0 | 149 | static int sad_per_bit4lut[QINDEX_RANGE]; |
michael@0 | 150 | |
michael@0 | 151 | void vp9_init_me_luts() { |
michael@0 | 152 | int i; |
michael@0 | 153 | |
michael@0 | 154 | // Initialize the sad lut tables using a formulaic calculation for now |
michael@0 | 155 | // This is to make it easier to resolve the impact of experimental changes |
michael@0 | 156 | // to the quantizer tables. |
michael@0 | 157 | for (i = 0; i < QINDEX_RANGE; i++) { |
michael@0 | 158 | sad_per_bit16lut[i] = |
michael@0 | 159 | (int)((0.0418 * vp9_convert_qindex_to_q(i)) + 2.4107); |
michael@0 | 160 | sad_per_bit4lut[i] = (int)(0.063 * vp9_convert_qindex_to_q(i) + 2.742); |
michael@0 | 161 | } |
michael@0 | 162 | } |
michael@0 | 163 | |
michael@0 | 164 | int vp9_compute_rd_mult(VP9_COMP *cpi, int qindex) { |
michael@0 | 165 | const int q = vp9_dc_quant(qindex, 0); |
michael@0 | 166 | // TODO(debargha): Adjust the function below |
michael@0 | 167 | int rdmult = 88 * q * q / 25; |
michael@0 | 168 | if (cpi->pass == 2 && (cpi->common.frame_type != KEY_FRAME)) { |
michael@0 | 169 | if (cpi->twopass.next_iiratio > 31) |
michael@0 | 170 | rdmult += (rdmult * rd_iifactor[31]) >> 4; |
michael@0 | 171 | else |
michael@0 | 172 | rdmult += (rdmult * rd_iifactor[cpi->twopass.next_iiratio]) >> 4; |
michael@0 | 173 | } |
michael@0 | 174 | return rdmult; |
michael@0 | 175 | } |
michael@0 | 176 | |
michael@0 | 177 | static int compute_rd_thresh_factor(int qindex) { |
michael@0 | 178 | int q; |
michael@0 | 179 | // TODO(debargha): Adjust the function below |
michael@0 | 180 | q = (int)(pow(vp9_dc_quant(qindex, 0) / 4.0, RD_THRESH_POW) * 5.12); |
michael@0 | 181 | if (q < 8) |
michael@0 | 182 | q = 8; |
michael@0 | 183 | return q; |
michael@0 | 184 | } |
michael@0 | 185 | |
michael@0 | 186 | void vp9_initialize_me_consts(VP9_COMP *cpi, int qindex) { |
michael@0 | 187 | cpi->mb.sadperbit16 = sad_per_bit16lut[qindex]; |
michael@0 | 188 | cpi->mb.sadperbit4 = sad_per_bit4lut[qindex]; |
michael@0 | 189 | } |
michael@0 | 190 | |
michael@0 | 191 | static void set_block_thresholds(VP9_COMP *cpi) { |
michael@0 | 192 | int i, bsize, segment_id; |
michael@0 | 193 | VP9_COMMON *cm = &cpi->common; |
michael@0 | 194 | |
michael@0 | 195 | for (segment_id = 0; segment_id < MAX_SEGMENTS; ++segment_id) { |
michael@0 | 196 | int q; |
michael@0 | 197 | int segment_qindex = vp9_get_qindex(&cm->seg, segment_id, cm->base_qindex); |
michael@0 | 198 | segment_qindex = clamp(segment_qindex + cm->y_dc_delta_q, 0, MAXQ); |
michael@0 | 199 | q = compute_rd_thresh_factor(segment_qindex); |
michael@0 | 200 | |
michael@0 | 201 | for (bsize = 0; bsize < BLOCK_SIZES; ++bsize) { |
michael@0 | 202 | // Threshold here seem unecessarily harsh but fine given actual |
michael@0 | 203 | // range of values used for cpi->sf.thresh_mult[] |
michael@0 | 204 | int thresh_max = INT_MAX / (q * rd_thresh_block_size_factor[bsize]); |
michael@0 | 205 | |
michael@0 | 206 | for (i = 0; i < MAX_MODES; ++i) { |
michael@0 | 207 | if (cpi->sf.thresh_mult[i] < thresh_max) { |
michael@0 | 208 | cpi->rd_threshes[segment_id][bsize][i] = |
michael@0 | 209 | cpi->sf.thresh_mult[i] * q * |
michael@0 | 210 | rd_thresh_block_size_factor[bsize] / 4; |
michael@0 | 211 | } else { |
michael@0 | 212 | cpi->rd_threshes[segment_id][bsize][i] = INT_MAX; |
michael@0 | 213 | } |
michael@0 | 214 | } |
michael@0 | 215 | |
michael@0 | 216 | for (i = 0; i < MAX_REFS; ++i) { |
michael@0 | 217 | if (cpi->sf.thresh_mult_sub8x8[i] < thresh_max) { |
michael@0 | 218 | cpi->rd_thresh_sub8x8[segment_id][bsize][i] = |
michael@0 | 219 | cpi->sf.thresh_mult_sub8x8[i] * q * |
michael@0 | 220 | rd_thresh_block_size_factor[bsize] / 4; |
michael@0 | 221 | } else { |
michael@0 | 222 | cpi->rd_thresh_sub8x8[segment_id][bsize][i] = INT_MAX; |
michael@0 | 223 | } |
michael@0 | 224 | } |
michael@0 | 225 | } |
michael@0 | 226 | } |
michael@0 | 227 | } |
michael@0 | 228 | |
michael@0 | 229 | void vp9_initialize_rd_consts(VP9_COMP *cpi) { |
michael@0 | 230 | VP9_COMMON *cm = &cpi->common; |
michael@0 | 231 | int qindex, i; |
michael@0 | 232 | |
michael@0 | 233 | vp9_clear_system_state(); // __asm emms; |
michael@0 | 234 | |
michael@0 | 235 | // Further tests required to see if optimum is different |
michael@0 | 236 | // for key frames, golden frames and arf frames. |
michael@0 | 237 | // if (cpi->common.refresh_golden_frame || |
michael@0 | 238 | // cpi->common.refresh_alt_ref_frame) |
michael@0 | 239 | qindex = clamp(cm->base_qindex + cm->y_dc_delta_q, 0, MAXQ); |
michael@0 | 240 | |
michael@0 | 241 | cpi->RDDIV = RDDIV_BITS; // in bits (to multiply D by 128) |
michael@0 | 242 | cpi->RDMULT = vp9_compute_rd_mult(cpi, qindex); |
michael@0 | 243 | |
michael@0 | 244 | cpi->mb.errorperbit = cpi->RDMULT / RD_MULT_EPB_RATIO; |
michael@0 | 245 | cpi->mb.errorperbit += (cpi->mb.errorperbit == 0); |
michael@0 | 246 | |
michael@0 | 247 | vp9_set_speed_features(cpi); |
michael@0 | 248 | |
michael@0 | 249 | cpi->mb.select_txfm_size = (cpi->sf.tx_size_search_method == USE_LARGESTALL && |
michael@0 | 250 | cm->frame_type != KEY_FRAME) ? |
michael@0 | 251 | 0 : 1; |
michael@0 | 252 | |
michael@0 | 253 | set_block_thresholds(cpi); |
michael@0 | 254 | |
michael@0 | 255 | fill_token_costs(cpi->mb.token_costs, cm->fc.coef_probs); |
michael@0 | 256 | |
michael@0 | 257 | for (i = 0; i < PARTITION_CONTEXTS; i++) |
michael@0 | 258 | vp9_cost_tokens(cpi->mb.partition_cost[i], get_partition_probs(cm, i), |
michael@0 | 259 | vp9_partition_tree); |
michael@0 | 260 | |
michael@0 | 261 | /*rough estimate for costing*/ |
michael@0 | 262 | vp9_init_mode_costs(cpi); |
michael@0 | 263 | |
michael@0 | 264 | if (!frame_is_intra_only(cm)) { |
michael@0 | 265 | vp9_build_nmv_cost_table( |
michael@0 | 266 | cpi->mb.nmvjointcost, |
michael@0 | 267 | cm->allow_high_precision_mv ? cpi->mb.nmvcost_hp : cpi->mb.nmvcost, |
michael@0 | 268 | &cm->fc.nmvc, |
michael@0 | 269 | cm->allow_high_precision_mv, 1, 1); |
michael@0 | 270 | |
michael@0 | 271 | for (i = 0; i < INTER_MODE_CONTEXTS; i++) { |
michael@0 | 272 | MB_PREDICTION_MODE m; |
michael@0 | 273 | |
michael@0 | 274 | for (m = NEARESTMV; m < MB_MODE_COUNT; m++) |
michael@0 | 275 | cpi->mb.inter_mode_cost[i][INTER_OFFSET(m)] = |
michael@0 | 276 | cost_token(vp9_inter_mode_tree, |
michael@0 | 277 | cm->fc.inter_mode_probs[i], |
michael@0 | 278 | &vp9_inter_mode_encodings[INTER_OFFSET(m)]); |
michael@0 | 279 | } |
michael@0 | 280 | } |
michael@0 | 281 | } |
michael@0 | 282 | |
michael@0 | 283 | static INLINE void linear_interpolate2(double x, int ntab, int inv_step, |
michael@0 | 284 | const double *tab1, const double *tab2, |
michael@0 | 285 | double *v1, double *v2) { |
michael@0 | 286 | double y = x * inv_step; |
michael@0 | 287 | int d = (int) y; |
michael@0 | 288 | if (d >= ntab - 1) { |
michael@0 | 289 | *v1 = tab1[ntab - 1]; |
michael@0 | 290 | *v2 = tab2[ntab - 1]; |
michael@0 | 291 | } else { |
michael@0 | 292 | double a = y - d; |
michael@0 | 293 | *v1 = tab1[d] * (1 - a) + tab1[d + 1] * a; |
michael@0 | 294 | *v2 = tab2[d] * (1 - a) + tab2[d + 1] * a; |
michael@0 | 295 | } |
michael@0 | 296 | } |
michael@0 | 297 | |
michael@0 | 298 | static void model_rd_norm(double x, double *R, double *D) { |
michael@0 | 299 | static const int inv_tab_step = 8; |
michael@0 | 300 | static const int tab_size = 120; |
michael@0 | 301 | // NOTE: The tables below must be of the same size |
michael@0 | 302 | // |
michael@0 | 303 | // Normalized rate |
michael@0 | 304 | // This table models the rate for a Laplacian source |
michael@0 | 305 | // source with given variance when quantized with a uniform quantizer |
michael@0 | 306 | // with given stepsize. The closed form expression is: |
michael@0 | 307 | // Rn(x) = H(sqrt(r)) + sqrt(r)*[1 + H(r)/(1 - r)], |
michael@0 | 308 | // where r = exp(-sqrt(2) * x) and x = qpstep / sqrt(variance), |
michael@0 | 309 | // and H(x) is the binary entropy function. |
michael@0 | 310 | static const double rate_tab[] = { |
michael@0 | 311 | 64.00, 4.944, 3.949, 3.372, 2.966, 2.655, 2.403, 2.194, |
michael@0 | 312 | 2.014, 1.858, 1.720, 1.596, 1.485, 1.384, 1.291, 1.206, |
michael@0 | 313 | 1.127, 1.054, 0.986, 0.923, 0.863, 0.808, 0.756, 0.708, |
michael@0 | 314 | 0.662, 0.619, 0.579, 0.541, 0.506, 0.473, 0.442, 0.412, |
michael@0 | 315 | 0.385, 0.359, 0.335, 0.313, 0.291, 0.272, 0.253, 0.236, |
michael@0 | 316 | 0.220, 0.204, 0.190, 0.177, 0.165, 0.153, 0.142, 0.132, |
michael@0 | 317 | 0.123, 0.114, 0.106, 0.099, 0.091, 0.085, 0.079, 0.073, |
michael@0 | 318 | 0.068, 0.063, 0.058, 0.054, 0.050, 0.047, 0.043, 0.040, |
michael@0 | 319 | 0.037, 0.034, 0.032, 0.029, 0.027, 0.025, 0.023, 0.022, |
michael@0 | 320 | 0.020, 0.019, 0.017, 0.016, 0.015, 0.014, 0.013, 0.012, |
michael@0 | 321 | 0.011, 0.010, 0.009, 0.008, 0.008, 0.007, 0.007, 0.006, |
michael@0 | 322 | 0.006, 0.005, 0.005, 0.005, 0.004, 0.004, 0.004, 0.003, |
michael@0 | 323 | 0.003, 0.003, 0.003, 0.002, 0.002, 0.002, 0.002, 0.002, |
michael@0 | 324 | 0.002, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, |
michael@0 | 325 | 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.000, |
michael@0 | 326 | }; |
michael@0 | 327 | // Normalized distortion |
michael@0 | 328 | // This table models the normalized distortion for a Laplacian source |
michael@0 | 329 | // source with given variance when quantized with a uniform quantizer |
michael@0 | 330 | // with given stepsize. The closed form expression is: |
michael@0 | 331 | // Dn(x) = 1 - 1/sqrt(2) * x / sinh(x/sqrt(2)) |
michael@0 | 332 | // where x = qpstep / sqrt(variance) |
michael@0 | 333 | // Note the actual distortion is Dn * variance. |
michael@0 | 334 | static const double dist_tab[] = { |
michael@0 | 335 | 0.000, 0.001, 0.005, 0.012, 0.021, 0.032, 0.045, 0.061, |
michael@0 | 336 | 0.079, 0.098, 0.119, 0.142, 0.166, 0.190, 0.216, 0.242, |
michael@0 | 337 | 0.269, 0.296, 0.324, 0.351, 0.378, 0.405, 0.432, 0.458, |
michael@0 | 338 | 0.484, 0.509, 0.534, 0.557, 0.580, 0.603, 0.624, 0.645, |
michael@0 | 339 | 0.664, 0.683, 0.702, 0.719, 0.735, 0.751, 0.766, 0.780, |
michael@0 | 340 | 0.794, 0.807, 0.819, 0.830, 0.841, 0.851, 0.861, 0.870, |
michael@0 | 341 | 0.878, 0.886, 0.894, 0.901, 0.907, 0.913, 0.919, 0.925, |
michael@0 | 342 | 0.930, 0.935, 0.939, 0.943, 0.947, 0.951, 0.954, 0.957, |
michael@0 | 343 | 0.960, 0.963, 0.966, 0.968, 0.971, 0.973, 0.975, 0.976, |
michael@0 | 344 | 0.978, 0.980, 0.981, 0.982, 0.984, 0.985, 0.986, 0.987, |
michael@0 | 345 | 0.988, 0.989, 0.990, 0.990, 0.991, 0.992, 0.992, 0.993, |
michael@0 | 346 | 0.993, 0.994, 0.994, 0.995, 0.995, 0.996, 0.996, 0.996, |
michael@0 | 347 | 0.996, 0.997, 0.997, 0.997, 0.997, 0.998, 0.998, 0.998, |
michael@0 | 348 | 0.998, 0.998, 0.998, 0.999, 0.999, 0.999, 0.999, 0.999, |
michael@0 | 349 | 0.999, 0.999, 0.999, 0.999, 0.999, 0.999, 0.999, 1.000, |
michael@0 | 350 | }; |
michael@0 | 351 | /* |
michael@0 | 352 | assert(sizeof(rate_tab) == tab_size * sizeof(rate_tab[0]); |
michael@0 | 353 | assert(sizeof(dist_tab) == tab_size * sizeof(dist_tab[0]); |
michael@0 | 354 | assert(sizeof(rate_tab) == sizeof(dist_tab)); |
michael@0 | 355 | */ |
michael@0 | 356 | assert(x >= 0.0); |
michael@0 | 357 | linear_interpolate2(x, tab_size, inv_tab_step, |
michael@0 | 358 | rate_tab, dist_tab, R, D); |
michael@0 | 359 | } |
michael@0 | 360 | |
michael@0 | 361 | static void model_rd_from_var_lapndz(int var, int n, int qstep, |
michael@0 | 362 | int *rate, int64_t *dist) { |
michael@0 | 363 | // This function models the rate and distortion for a Laplacian |
michael@0 | 364 | // source with given variance when quantized with a uniform quantizer |
michael@0 | 365 | // with given stepsize. The closed form expressions are in: |
michael@0 | 366 | // Hang and Chen, "Source Model for transform video coder and its |
michael@0 | 367 | // application - Part I: Fundamental Theory", IEEE Trans. Circ. |
michael@0 | 368 | // Sys. for Video Tech., April 1997. |
michael@0 | 369 | vp9_clear_system_state(); |
michael@0 | 370 | if (var == 0 || n == 0) { |
michael@0 | 371 | *rate = 0; |
michael@0 | 372 | *dist = 0; |
michael@0 | 373 | } else { |
michael@0 | 374 | double D, R; |
michael@0 | 375 | double s2 = (double) var / n; |
michael@0 | 376 | double x = qstep / sqrt(s2); |
michael@0 | 377 | model_rd_norm(x, &R, &D); |
michael@0 | 378 | *rate = (int)((n << 8) * R + 0.5); |
michael@0 | 379 | *dist = (int)(var * D + 0.5); |
michael@0 | 380 | } |
michael@0 | 381 | vp9_clear_system_state(); |
michael@0 | 382 | } |
michael@0 | 383 | |
michael@0 | 384 | static void model_rd_for_sb(VP9_COMP *cpi, BLOCK_SIZE bsize, |
michael@0 | 385 | MACROBLOCK *x, MACROBLOCKD *xd, |
michael@0 | 386 | int *out_rate_sum, int64_t *out_dist_sum) { |
michael@0 | 387 | // Note our transform coeffs are 8 times an orthogonal transform. |
michael@0 | 388 | // Hence quantizer step is also 8 times. To get effective quantizer |
michael@0 | 389 | // we need to divide by 8 before sending to modeling function. |
michael@0 | 390 | int i, rate_sum = 0, dist_sum = 0; |
michael@0 | 391 | |
michael@0 | 392 | for (i = 0; i < MAX_MB_PLANE; ++i) { |
michael@0 | 393 | struct macroblock_plane *const p = &x->plane[i]; |
michael@0 | 394 | struct macroblockd_plane *const pd = &xd->plane[i]; |
michael@0 | 395 | const BLOCK_SIZE bs = get_plane_block_size(bsize, pd); |
michael@0 | 396 | unsigned int sse; |
michael@0 | 397 | int rate; |
michael@0 | 398 | int64_t dist; |
michael@0 | 399 | (void) cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride, |
michael@0 | 400 | pd->dst.buf, pd->dst.stride, &sse); |
michael@0 | 401 | // sse works better than var, since there is no dc prediction used |
michael@0 | 402 | model_rd_from_var_lapndz(sse, 1 << num_pels_log2_lookup[bs], |
michael@0 | 403 | pd->dequant[1] >> 3, &rate, &dist); |
michael@0 | 404 | |
michael@0 | 405 | rate_sum += rate; |
michael@0 | 406 | dist_sum += (int)dist; |
michael@0 | 407 | } |
michael@0 | 408 | |
michael@0 | 409 | *out_rate_sum = rate_sum; |
michael@0 | 410 | *out_dist_sum = dist_sum << 4; |
michael@0 | 411 | } |
michael@0 | 412 | |
michael@0 | 413 | static void model_rd_for_sb_y_tx(VP9_COMP *cpi, BLOCK_SIZE bsize, |
michael@0 | 414 | TX_SIZE tx_size, |
michael@0 | 415 | MACROBLOCK *x, MACROBLOCKD *xd, |
michael@0 | 416 | int *out_rate_sum, int64_t *out_dist_sum, |
michael@0 | 417 | int *out_skip) { |
michael@0 | 418 | int j, k; |
michael@0 | 419 | BLOCK_SIZE bs; |
michael@0 | 420 | struct macroblock_plane *const p = &x->plane[0]; |
michael@0 | 421 | struct macroblockd_plane *const pd = &xd->plane[0]; |
michael@0 | 422 | const int width = 4 << num_4x4_blocks_wide_lookup[bsize]; |
michael@0 | 423 | const int height = 4 << num_4x4_blocks_high_lookup[bsize]; |
michael@0 | 424 | int rate_sum = 0; |
michael@0 | 425 | int64_t dist_sum = 0; |
michael@0 | 426 | const int t = 4 << tx_size; |
michael@0 | 427 | |
michael@0 | 428 | if (tx_size == TX_4X4) { |
michael@0 | 429 | bs = BLOCK_4X4; |
michael@0 | 430 | } else if (tx_size == TX_8X8) { |
michael@0 | 431 | bs = BLOCK_8X8; |
michael@0 | 432 | } else if (tx_size == TX_16X16) { |
michael@0 | 433 | bs = BLOCK_16X16; |
michael@0 | 434 | } else if (tx_size == TX_32X32) { |
michael@0 | 435 | bs = BLOCK_32X32; |
michael@0 | 436 | } else { |
michael@0 | 437 | assert(0); |
michael@0 | 438 | } |
michael@0 | 439 | |
michael@0 | 440 | *out_skip = 1; |
michael@0 | 441 | for (j = 0; j < height; j += t) { |
michael@0 | 442 | for (k = 0; k < width; k += t) { |
michael@0 | 443 | int rate; |
michael@0 | 444 | int64_t dist; |
michael@0 | 445 | unsigned int sse; |
michael@0 | 446 | cpi->fn_ptr[bs].vf(&p->src.buf[j * p->src.stride + k], p->src.stride, |
michael@0 | 447 | &pd->dst.buf[j * pd->dst.stride + k], pd->dst.stride, |
michael@0 | 448 | &sse); |
michael@0 | 449 | // sse works better than var, since there is no dc prediction used |
michael@0 | 450 | model_rd_from_var_lapndz(sse, t * t, pd->dequant[1] >> 3, &rate, &dist); |
michael@0 | 451 | rate_sum += rate; |
michael@0 | 452 | dist_sum += dist; |
michael@0 | 453 | *out_skip &= (rate < 1024); |
michael@0 | 454 | } |
michael@0 | 455 | } |
michael@0 | 456 | |
michael@0 | 457 | *out_rate_sum = rate_sum; |
michael@0 | 458 | *out_dist_sum = dist_sum << 4; |
michael@0 | 459 | } |
michael@0 | 460 | |
michael@0 | 461 | int64_t vp9_block_error_c(int16_t *coeff, int16_t *dqcoeff, |
michael@0 | 462 | intptr_t block_size, int64_t *ssz) { |
michael@0 | 463 | int i; |
michael@0 | 464 | int64_t error = 0, sqcoeff = 0; |
michael@0 | 465 | |
michael@0 | 466 | for (i = 0; i < block_size; i++) { |
michael@0 | 467 | int this_diff = coeff[i] - dqcoeff[i]; |
michael@0 | 468 | error += (unsigned)this_diff * this_diff; |
michael@0 | 469 | sqcoeff += (unsigned) coeff[i] * coeff[i]; |
michael@0 | 470 | } |
michael@0 | 471 | |
michael@0 | 472 | *ssz = sqcoeff; |
michael@0 | 473 | return error; |
michael@0 | 474 | } |
michael@0 | 475 | |
michael@0 | 476 | /* The trailing '0' is a terminator which is used inside cost_coeffs() to |
michael@0 | 477 | * decide whether to include cost of a trailing EOB node or not (i.e. we |
michael@0 | 478 | * can skip this if the last coefficient in this transform block, e.g. the |
michael@0 | 479 | * 16th coefficient in a 4x4 block or the 64th coefficient in a 8x8 block, |
michael@0 | 480 | * were non-zero). */ |
michael@0 | 481 | static const int16_t band_counts[TX_SIZES][8] = { |
michael@0 | 482 | { 1, 2, 3, 4, 3, 16 - 13, 0 }, |
michael@0 | 483 | { 1, 2, 3, 4, 11, 64 - 21, 0 }, |
michael@0 | 484 | { 1, 2, 3, 4, 11, 256 - 21, 0 }, |
michael@0 | 485 | { 1, 2, 3, 4, 11, 1024 - 21, 0 }, |
michael@0 | 486 | }; |
michael@0 | 487 | |
michael@0 | 488 | static INLINE int cost_coeffs(MACROBLOCK *x, |
michael@0 | 489 | int plane, int block, |
michael@0 | 490 | ENTROPY_CONTEXT *A, ENTROPY_CONTEXT *L, |
michael@0 | 491 | TX_SIZE tx_size, |
michael@0 | 492 | const int16_t *scan, const int16_t *nb) { |
michael@0 | 493 | MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 494 | MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; |
michael@0 | 495 | struct macroblockd_plane *pd = &xd->plane[plane]; |
michael@0 | 496 | const PLANE_TYPE type = pd->plane_type; |
michael@0 | 497 | const int16_t *band_count = &band_counts[tx_size][1]; |
michael@0 | 498 | const int eob = pd->eobs[block]; |
michael@0 | 499 | const int16_t *const qcoeff_ptr = BLOCK_OFFSET(pd->qcoeff, block); |
michael@0 | 500 | const int ref = mbmi->ref_frame[0] != INTRA_FRAME; |
michael@0 | 501 | unsigned int (*token_costs)[2][PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS] = |
michael@0 | 502 | x->token_costs[tx_size][type][ref]; |
michael@0 | 503 | const ENTROPY_CONTEXT above_ec = !!*A, left_ec = !!*L; |
michael@0 | 504 | uint8_t *p_tok = x->token_cache; |
michael@0 | 505 | int pt = combine_entropy_contexts(above_ec, left_ec); |
michael@0 | 506 | int c, cost; |
michael@0 | 507 | |
michael@0 | 508 | // Check for consistency of tx_size with mode info |
michael@0 | 509 | assert(type == PLANE_TYPE_Y_WITH_DC ? mbmi->tx_size == tx_size |
michael@0 | 510 | : get_uv_tx_size(mbmi) == tx_size); |
michael@0 | 511 | |
michael@0 | 512 | if (eob == 0) { |
michael@0 | 513 | // single eob token |
michael@0 | 514 | cost = token_costs[0][0][pt][DCT_EOB_TOKEN]; |
michael@0 | 515 | c = 0; |
michael@0 | 516 | } else { |
michael@0 | 517 | int band_left = *band_count++; |
michael@0 | 518 | |
michael@0 | 519 | // dc token |
michael@0 | 520 | int v = qcoeff_ptr[0]; |
michael@0 | 521 | int prev_t = vp9_dct_value_tokens_ptr[v].token; |
michael@0 | 522 | cost = (*token_costs)[0][pt][prev_t] + vp9_dct_value_cost_ptr[v]; |
michael@0 | 523 | p_tok[0] = vp9_pt_energy_class[prev_t]; |
michael@0 | 524 | ++token_costs; |
michael@0 | 525 | |
michael@0 | 526 | // ac tokens |
michael@0 | 527 | for (c = 1; c < eob; c++) { |
michael@0 | 528 | const int rc = scan[c]; |
michael@0 | 529 | int t; |
michael@0 | 530 | |
michael@0 | 531 | v = qcoeff_ptr[rc]; |
michael@0 | 532 | t = vp9_dct_value_tokens_ptr[v].token; |
michael@0 | 533 | pt = get_coef_context(nb, p_tok, c); |
michael@0 | 534 | cost += (*token_costs)[!prev_t][pt][t] + vp9_dct_value_cost_ptr[v]; |
michael@0 | 535 | p_tok[rc] = vp9_pt_energy_class[t]; |
michael@0 | 536 | prev_t = t; |
michael@0 | 537 | if (!--band_left) { |
michael@0 | 538 | band_left = *band_count++; |
michael@0 | 539 | ++token_costs; |
michael@0 | 540 | } |
michael@0 | 541 | } |
michael@0 | 542 | |
michael@0 | 543 | // eob token |
michael@0 | 544 | if (band_left) { |
michael@0 | 545 | pt = get_coef_context(nb, p_tok, c); |
michael@0 | 546 | cost += (*token_costs)[0][pt][DCT_EOB_TOKEN]; |
michael@0 | 547 | } |
michael@0 | 548 | } |
michael@0 | 549 | |
michael@0 | 550 | // is eob first coefficient; |
michael@0 | 551 | *A = *L = (c > 0); |
michael@0 | 552 | |
michael@0 | 553 | return cost; |
michael@0 | 554 | } |
michael@0 | 555 | |
michael@0 | 556 | static void dist_block(int plane, int block, TX_SIZE tx_size, void *arg) { |
michael@0 | 557 | const int ss_txfrm_size = tx_size << 1; |
michael@0 | 558 | struct rdcost_block_args* args = arg; |
michael@0 | 559 | MACROBLOCK* const x = args->x; |
michael@0 | 560 | MACROBLOCKD* const xd = &x->e_mbd; |
michael@0 | 561 | struct macroblock_plane *const p = &x->plane[plane]; |
michael@0 | 562 | struct macroblockd_plane *const pd = &xd->plane[plane]; |
michael@0 | 563 | int64_t this_sse; |
michael@0 | 564 | int shift = args->tx_size == TX_32X32 ? 0 : 2; |
michael@0 | 565 | int16_t *const coeff = BLOCK_OFFSET(p->coeff, block); |
michael@0 | 566 | int16_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block); |
michael@0 | 567 | args->dist = vp9_block_error(coeff, dqcoeff, 16 << ss_txfrm_size, |
michael@0 | 568 | &this_sse) >> shift; |
michael@0 | 569 | args->sse = this_sse >> shift; |
michael@0 | 570 | |
michael@0 | 571 | if (x->skip_encode && |
michael@0 | 572 | xd->mi_8x8[0]->mbmi.ref_frame[0] == INTRA_FRAME) { |
michael@0 | 573 | // TODO(jingning): tune the model to better capture the distortion. |
michael@0 | 574 | int64_t p = (pd->dequant[1] * pd->dequant[1] * |
michael@0 | 575 | (1 << ss_txfrm_size)) >> (shift + 2); |
michael@0 | 576 | args->dist += (p >> 4); |
michael@0 | 577 | args->sse += p; |
michael@0 | 578 | } |
michael@0 | 579 | } |
michael@0 | 580 | |
michael@0 | 581 | static void rate_block(int plane, int block, BLOCK_SIZE plane_bsize, |
michael@0 | 582 | TX_SIZE tx_size, void *arg) { |
michael@0 | 583 | struct rdcost_block_args* args = arg; |
michael@0 | 584 | |
michael@0 | 585 | int x_idx, y_idx; |
michael@0 | 586 | txfrm_block_to_raster_xy(plane_bsize, args->tx_size, block, &x_idx, &y_idx); |
michael@0 | 587 | |
michael@0 | 588 | args->rate = cost_coeffs(args->x, plane, block, args->t_above + x_idx, |
michael@0 | 589 | args->t_left + y_idx, args->tx_size, |
michael@0 | 590 | args->scan, args->nb); |
michael@0 | 591 | } |
michael@0 | 592 | |
michael@0 | 593 | static void block_yrd_txfm(int plane, int block, BLOCK_SIZE plane_bsize, |
michael@0 | 594 | TX_SIZE tx_size, void *arg) { |
michael@0 | 595 | struct rdcost_block_args *args = arg; |
michael@0 | 596 | MACROBLOCK *const x = args->x; |
michael@0 | 597 | MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 598 | struct encode_b_args encode_args = {x, NULL}; |
michael@0 | 599 | int64_t rd1, rd2, rd; |
michael@0 | 600 | |
michael@0 | 601 | if (args->skip) |
michael@0 | 602 | return; |
michael@0 | 603 | |
michael@0 | 604 | if (!is_inter_block(&xd->mi_8x8[0]->mbmi)) |
michael@0 | 605 | vp9_encode_block_intra(plane, block, plane_bsize, tx_size, &encode_args); |
michael@0 | 606 | else |
michael@0 | 607 | vp9_xform_quant(plane, block, plane_bsize, tx_size, &encode_args); |
michael@0 | 608 | |
michael@0 | 609 | dist_block(plane, block, tx_size, args); |
michael@0 | 610 | rate_block(plane, block, plane_bsize, tx_size, args); |
michael@0 | 611 | rd1 = RDCOST(x->rdmult, x->rddiv, args->rate, args->dist); |
michael@0 | 612 | rd2 = RDCOST(x->rdmult, x->rddiv, 0, args->sse); |
michael@0 | 613 | |
michael@0 | 614 | // TODO(jingning): temporarily enabled only for luma component |
michael@0 | 615 | rd = MIN(rd1, rd2); |
michael@0 | 616 | if (!xd->lossless && plane == 0) |
michael@0 | 617 | x->zcoeff_blk[tx_size][block] = rd1 > rd2 || !xd->plane[plane].eobs[block]; |
michael@0 | 618 | |
michael@0 | 619 | args->this_rate += args->rate; |
michael@0 | 620 | args->this_dist += args->dist; |
michael@0 | 621 | args->this_sse += args->sse; |
michael@0 | 622 | args->this_rd += rd; |
michael@0 | 623 | |
michael@0 | 624 | if (args->this_rd > args->best_rd) { |
michael@0 | 625 | args->skip = 1; |
michael@0 | 626 | return; |
michael@0 | 627 | } |
michael@0 | 628 | } |
michael@0 | 629 | |
michael@0 | 630 | void vp9_get_entropy_contexts(TX_SIZE tx_size, |
michael@0 | 631 | ENTROPY_CONTEXT t_above[16], ENTROPY_CONTEXT t_left[16], |
michael@0 | 632 | const ENTROPY_CONTEXT *above, const ENTROPY_CONTEXT *left, |
michael@0 | 633 | int num_4x4_w, int num_4x4_h) { |
michael@0 | 634 | int i; |
michael@0 | 635 | switch (tx_size) { |
michael@0 | 636 | case TX_4X4: |
michael@0 | 637 | vpx_memcpy(t_above, above, sizeof(ENTROPY_CONTEXT) * num_4x4_w); |
michael@0 | 638 | vpx_memcpy(t_left, left, sizeof(ENTROPY_CONTEXT) * num_4x4_h); |
michael@0 | 639 | break; |
michael@0 | 640 | case TX_8X8: |
michael@0 | 641 | for (i = 0; i < num_4x4_w; i += 2) |
michael@0 | 642 | t_above[i] = !!*(const uint16_t *)&above[i]; |
michael@0 | 643 | for (i = 0; i < num_4x4_h; i += 2) |
michael@0 | 644 | t_left[i] = !!*(const uint16_t *)&left[i]; |
michael@0 | 645 | break; |
michael@0 | 646 | case TX_16X16: |
michael@0 | 647 | for (i = 0; i < num_4x4_w; i += 4) |
michael@0 | 648 | t_above[i] = !!*(const uint32_t *)&above[i]; |
michael@0 | 649 | for (i = 0; i < num_4x4_h; i += 4) |
michael@0 | 650 | t_left[i] = !!*(const uint32_t *)&left[i]; |
michael@0 | 651 | break; |
michael@0 | 652 | case TX_32X32: |
michael@0 | 653 | for (i = 0; i < num_4x4_w; i += 8) |
michael@0 | 654 | t_above[i] = !!*(const uint64_t *)&above[i]; |
michael@0 | 655 | for (i = 0; i < num_4x4_h; i += 8) |
michael@0 | 656 | t_left[i] = !!*(const uint64_t *)&left[i]; |
michael@0 | 657 | break; |
michael@0 | 658 | default: |
michael@0 | 659 | assert(!"Invalid transform size."); |
michael@0 | 660 | } |
michael@0 | 661 | } |
michael@0 | 662 | |
michael@0 | 663 | static void init_rdcost_stack(MACROBLOCK *x, TX_SIZE tx_size, |
michael@0 | 664 | const int num_4x4_w, const int num_4x4_h, |
michael@0 | 665 | const int64_t ref_rdcost, |
michael@0 | 666 | struct rdcost_block_args *arg) { |
michael@0 | 667 | vpx_memset(arg, 0, sizeof(struct rdcost_block_args)); |
michael@0 | 668 | arg->x = x; |
michael@0 | 669 | arg->tx_size = tx_size; |
michael@0 | 670 | arg->bw = num_4x4_w; |
michael@0 | 671 | arg->bh = num_4x4_h; |
michael@0 | 672 | arg->best_rd = ref_rdcost; |
michael@0 | 673 | } |
michael@0 | 674 | |
michael@0 | 675 | static void txfm_rd_in_plane(MACROBLOCK *x, |
michael@0 | 676 | struct rdcost_block_args *rd_stack, |
michael@0 | 677 | int *rate, int64_t *distortion, |
michael@0 | 678 | int *skippable, int64_t *sse, |
michael@0 | 679 | int64_t ref_best_rd, int plane, |
michael@0 | 680 | BLOCK_SIZE bsize, TX_SIZE tx_size) { |
michael@0 | 681 | MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 682 | struct macroblockd_plane *const pd = &xd->plane[plane]; |
michael@0 | 683 | const BLOCK_SIZE bs = get_plane_block_size(bsize, pd); |
michael@0 | 684 | const int num_4x4_w = num_4x4_blocks_wide_lookup[bs]; |
michael@0 | 685 | const int num_4x4_h = num_4x4_blocks_high_lookup[bs]; |
michael@0 | 686 | |
michael@0 | 687 | init_rdcost_stack(x, tx_size, num_4x4_w, num_4x4_h, |
michael@0 | 688 | ref_best_rd, rd_stack); |
michael@0 | 689 | if (plane == 0) |
michael@0 | 690 | xd->mi_8x8[0]->mbmi.tx_size = tx_size; |
michael@0 | 691 | |
michael@0 | 692 | vp9_get_entropy_contexts(tx_size, rd_stack->t_above, rd_stack->t_left, |
michael@0 | 693 | pd->above_context, pd->left_context, |
michael@0 | 694 | num_4x4_w, num_4x4_h); |
michael@0 | 695 | |
michael@0 | 696 | get_scan(xd, tx_size, pd->plane_type, 0, &rd_stack->scan, &rd_stack->nb); |
michael@0 | 697 | |
michael@0 | 698 | foreach_transformed_block_in_plane(xd, bsize, plane, |
michael@0 | 699 | block_yrd_txfm, rd_stack); |
michael@0 | 700 | if (rd_stack->skip) { |
michael@0 | 701 | *rate = INT_MAX; |
michael@0 | 702 | *distortion = INT64_MAX; |
michael@0 | 703 | *sse = INT64_MAX; |
michael@0 | 704 | *skippable = 0; |
michael@0 | 705 | } else { |
michael@0 | 706 | *distortion = rd_stack->this_dist; |
michael@0 | 707 | *rate = rd_stack->this_rate; |
michael@0 | 708 | *sse = rd_stack->this_sse; |
michael@0 | 709 | *skippable = vp9_is_skippable_in_plane(xd, bsize, plane); |
michael@0 | 710 | } |
michael@0 | 711 | } |
michael@0 | 712 | |
michael@0 | 713 | static void choose_largest_txfm_size(VP9_COMP *cpi, MACROBLOCK *x, |
michael@0 | 714 | int *rate, int64_t *distortion, |
michael@0 | 715 | int *skip, int64_t *sse, |
michael@0 | 716 | int64_t ref_best_rd, |
michael@0 | 717 | BLOCK_SIZE bs) { |
michael@0 | 718 | const TX_SIZE max_tx_size = max_txsize_lookup[bs]; |
michael@0 | 719 | VP9_COMMON *const cm = &cpi->common; |
michael@0 | 720 | const TX_SIZE largest_tx_size = tx_mode_to_biggest_tx_size[cm->tx_mode]; |
michael@0 | 721 | MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 722 | MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; |
michael@0 | 723 | |
michael@0 | 724 | mbmi->tx_size = MIN(max_tx_size, largest_tx_size); |
michael@0 | 725 | |
michael@0 | 726 | txfm_rd_in_plane(x, &cpi->rdcost_stack, rate, distortion, skip, |
michael@0 | 727 | &sse[mbmi->tx_size], ref_best_rd, 0, bs, |
michael@0 | 728 | mbmi->tx_size); |
michael@0 | 729 | cpi->tx_stepdown_count[0]++; |
michael@0 | 730 | } |
michael@0 | 731 | |
michael@0 | 732 | static void choose_txfm_size_from_rd(VP9_COMP *cpi, MACROBLOCK *x, |
michael@0 | 733 | int (*r)[2], int *rate, |
michael@0 | 734 | int64_t *d, int64_t *distortion, |
michael@0 | 735 | int *s, int *skip, |
michael@0 | 736 | int64_t tx_cache[TX_MODES], |
michael@0 | 737 | BLOCK_SIZE bs) { |
michael@0 | 738 | const TX_SIZE max_tx_size = max_txsize_lookup[bs]; |
michael@0 | 739 | VP9_COMMON *const cm = &cpi->common; |
michael@0 | 740 | MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 741 | MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; |
michael@0 | 742 | vp9_prob skip_prob = vp9_get_pred_prob_mbskip(cm, xd); |
michael@0 | 743 | int64_t rd[TX_SIZES][2]; |
michael@0 | 744 | int n, m; |
michael@0 | 745 | int s0, s1; |
michael@0 | 746 | |
michael@0 | 747 | const vp9_prob *tx_probs = get_tx_probs2(max_tx_size, xd, &cm->fc.tx_probs); |
michael@0 | 748 | |
michael@0 | 749 | for (n = TX_4X4; n <= max_tx_size; n++) { |
michael@0 | 750 | r[n][1] = r[n][0]; |
michael@0 | 751 | if (r[n][0] == INT_MAX) |
michael@0 | 752 | continue; |
michael@0 | 753 | for (m = 0; m <= n - (n == max_tx_size); m++) { |
michael@0 | 754 | if (m == n) |
michael@0 | 755 | r[n][1] += vp9_cost_zero(tx_probs[m]); |
michael@0 | 756 | else |
michael@0 | 757 | r[n][1] += vp9_cost_one(tx_probs[m]); |
michael@0 | 758 | } |
michael@0 | 759 | } |
michael@0 | 760 | |
michael@0 | 761 | assert(skip_prob > 0); |
michael@0 | 762 | s0 = vp9_cost_bit(skip_prob, 0); |
michael@0 | 763 | s1 = vp9_cost_bit(skip_prob, 1); |
michael@0 | 764 | |
michael@0 | 765 | for (n = TX_4X4; n <= max_tx_size; n++) { |
michael@0 | 766 | if (d[n] == INT64_MAX) { |
michael@0 | 767 | rd[n][0] = rd[n][1] = INT64_MAX; |
michael@0 | 768 | continue; |
michael@0 | 769 | } |
michael@0 | 770 | if (s[n]) { |
michael@0 | 771 | rd[n][0] = rd[n][1] = RDCOST(x->rdmult, x->rddiv, s1, d[n]); |
michael@0 | 772 | } else { |
michael@0 | 773 | rd[n][0] = RDCOST(x->rdmult, x->rddiv, r[n][0] + s0, d[n]); |
michael@0 | 774 | rd[n][1] = RDCOST(x->rdmult, x->rddiv, r[n][1] + s0, d[n]); |
michael@0 | 775 | } |
michael@0 | 776 | } |
michael@0 | 777 | |
michael@0 | 778 | if (max_tx_size == TX_32X32 && |
michael@0 | 779 | (cm->tx_mode == ALLOW_32X32 || |
michael@0 | 780 | (cm->tx_mode == TX_MODE_SELECT && |
michael@0 | 781 | rd[TX_32X32][1] < rd[TX_16X16][1] && rd[TX_32X32][1] < rd[TX_8X8][1] && |
michael@0 | 782 | rd[TX_32X32][1] < rd[TX_4X4][1]))) { |
michael@0 | 783 | mbmi->tx_size = TX_32X32; |
michael@0 | 784 | } else if (max_tx_size >= TX_16X16 && |
michael@0 | 785 | (cm->tx_mode == ALLOW_16X16 || |
michael@0 | 786 | cm->tx_mode == ALLOW_32X32 || |
michael@0 | 787 | (cm->tx_mode == TX_MODE_SELECT && |
michael@0 | 788 | rd[TX_16X16][1] < rd[TX_8X8][1] && |
michael@0 | 789 | rd[TX_16X16][1] < rd[TX_4X4][1]))) { |
michael@0 | 790 | mbmi->tx_size = TX_16X16; |
michael@0 | 791 | } else if (cm->tx_mode == ALLOW_8X8 || |
michael@0 | 792 | cm->tx_mode == ALLOW_16X16 || |
michael@0 | 793 | cm->tx_mode == ALLOW_32X32 || |
michael@0 | 794 | (cm->tx_mode == TX_MODE_SELECT && rd[TX_8X8][1] < rd[TX_4X4][1])) { |
michael@0 | 795 | mbmi->tx_size = TX_8X8; |
michael@0 | 796 | } else { |
michael@0 | 797 | mbmi->tx_size = TX_4X4; |
michael@0 | 798 | } |
michael@0 | 799 | |
michael@0 | 800 | *distortion = d[mbmi->tx_size]; |
michael@0 | 801 | *rate = r[mbmi->tx_size][cm->tx_mode == TX_MODE_SELECT]; |
michael@0 | 802 | *skip = s[mbmi->tx_size]; |
michael@0 | 803 | |
michael@0 | 804 | tx_cache[ONLY_4X4] = rd[TX_4X4][0]; |
michael@0 | 805 | tx_cache[ALLOW_8X8] = rd[TX_8X8][0]; |
michael@0 | 806 | tx_cache[ALLOW_16X16] = rd[MIN(max_tx_size, TX_16X16)][0]; |
michael@0 | 807 | tx_cache[ALLOW_32X32] = rd[MIN(max_tx_size, TX_32X32)][0]; |
michael@0 | 808 | if (max_tx_size == TX_32X32 && |
michael@0 | 809 | rd[TX_32X32][1] < rd[TX_16X16][1] && rd[TX_32X32][1] < rd[TX_8X8][1] && |
michael@0 | 810 | rd[TX_32X32][1] < rd[TX_4X4][1]) |
michael@0 | 811 | tx_cache[TX_MODE_SELECT] = rd[TX_32X32][1]; |
michael@0 | 812 | else if (max_tx_size >= TX_16X16 && |
michael@0 | 813 | rd[TX_16X16][1] < rd[TX_8X8][1] && rd[TX_16X16][1] < rd[TX_4X4][1]) |
michael@0 | 814 | tx_cache[TX_MODE_SELECT] = rd[TX_16X16][1]; |
michael@0 | 815 | else |
michael@0 | 816 | tx_cache[TX_MODE_SELECT] = rd[TX_4X4][1] < rd[TX_8X8][1] ? |
michael@0 | 817 | rd[TX_4X4][1] : rd[TX_8X8][1]; |
michael@0 | 818 | |
michael@0 | 819 | if (max_tx_size == TX_32X32 && |
michael@0 | 820 | rd[TX_32X32][1] < rd[TX_16X16][1] && |
michael@0 | 821 | rd[TX_32X32][1] < rd[TX_8X8][1] && |
michael@0 | 822 | rd[TX_32X32][1] < rd[TX_4X4][1]) { |
michael@0 | 823 | cpi->tx_stepdown_count[0]++; |
michael@0 | 824 | } else if (max_tx_size >= TX_16X16 && |
michael@0 | 825 | rd[TX_16X16][1] < rd[TX_8X8][1] && |
michael@0 | 826 | rd[TX_16X16][1] < rd[TX_4X4][1]) { |
michael@0 | 827 | cpi->tx_stepdown_count[max_tx_size - TX_16X16]++; |
michael@0 | 828 | } else if (rd[TX_8X8][1] < rd[TX_4X4][1]) { |
michael@0 | 829 | cpi->tx_stepdown_count[max_tx_size - TX_8X8]++; |
michael@0 | 830 | } else { |
michael@0 | 831 | cpi->tx_stepdown_count[max_tx_size - TX_4X4]++; |
michael@0 | 832 | } |
michael@0 | 833 | } |
michael@0 | 834 | |
michael@0 | 835 | static void choose_txfm_size_from_modelrd(VP9_COMP *cpi, MACROBLOCK *x, |
michael@0 | 836 | int (*r)[2], int *rate, |
michael@0 | 837 | int64_t *d, int64_t *distortion, |
michael@0 | 838 | int *s, int *skip, int64_t *sse, |
michael@0 | 839 | int64_t ref_best_rd, |
michael@0 | 840 | BLOCK_SIZE bs) { |
michael@0 | 841 | const TX_SIZE max_tx_size = max_txsize_lookup[bs]; |
michael@0 | 842 | VP9_COMMON *const cm = &cpi->common; |
michael@0 | 843 | MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 844 | MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; |
michael@0 | 845 | vp9_prob skip_prob = vp9_get_pred_prob_mbskip(cm, xd); |
michael@0 | 846 | int64_t rd[TX_SIZES][2]; |
michael@0 | 847 | int n, m; |
michael@0 | 848 | int s0, s1; |
michael@0 | 849 | double scale_rd[TX_SIZES] = {1.73, 1.44, 1.20, 1.00}; |
michael@0 | 850 | // double scale_r[TX_SIZES] = {2.82, 2.00, 1.41, 1.00}; |
michael@0 | 851 | |
michael@0 | 852 | const vp9_prob *tx_probs = get_tx_probs2(max_tx_size, xd, &cm->fc.tx_probs); |
michael@0 | 853 | |
michael@0 | 854 | // for (n = TX_4X4; n <= max_txfm_size; n++) |
michael@0 | 855 | // r[n][0] = (r[n][0] * scale_r[n]); |
michael@0 | 856 | |
michael@0 | 857 | for (n = TX_4X4; n <= max_tx_size; n++) { |
michael@0 | 858 | r[n][1] = r[n][0]; |
michael@0 | 859 | for (m = 0; m <= n - (n == max_tx_size); m++) { |
michael@0 | 860 | if (m == n) |
michael@0 | 861 | r[n][1] += vp9_cost_zero(tx_probs[m]); |
michael@0 | 862 | else |
michael@0 | 863 | r[n][1] += vp9_cost_one(tx_probs[m]); |
michael@0 | 864 | } |
michael@0 | 865 | } |
michael@0 | 866 | |
michael@0 | 867 | assert(skip_prob > 0); |
michael@0 | 868 | s0 = vp9_cost_bit(skip_prob, 0); |
michael@0 | 869 | s1 = vp9_cost_bit(skip_prob, 1); |
michael@0 | 870 | |
michael@0 | 871 | for (n = TX_4X4; n <= max_tx_size; n++) { |
michael@0 | 872 | if (s[n]) { |
michael@0 | 873 | rd[n][0] = rd[n][1] = RDCOST(x->rdmult, x->rddiv, s1, d[n]); |
michael@0 | 874 | } else { |
michael@0 | 875 | rd[n][0] = RDCOST(x->rdmult, x->rddiv, r[n][0] + s0, d[n]); |
michael@0 | 876 | rd[n][1] = RDCOST(x->rdmult, x->rddiv, r[n][1] + s0, d[n]); |
michael@0 | 877 | } |
michael@0 | 878 | } |
michael@0 | 879 | for (n = TX_4X4; n <= max_tx_size; n++) { |
michael@0 | 880 | rd[n][0] = (int64_t)(scale_rd[n] * rd[n][0]); |
michael@0 | 881 | rd[n][1] = (int64_t)(scale_rd[n] * rd[n][1]); |
michael@0 | 882 | } |
michael@0 | 883 | |
michael@0 | 884 | if (max_tx_size == TX_32X32 && |
michael@0 | 885 | (cm->tx_mode == ALLOW_32X32 || |
michael@0 | 886 | (cm->tx_mode == TX_MODE_SELECT && |
michael@0 | 887 | rd[TX_32X32][1] <= rd[TX_16X16][1] && |
michael@0 | 888 | rd[TX_32X32][1] <= rd[TX_8X8][1] && |
michael@0 | 889 | rd[TX_32X32][1] <= rd[TX_4X4][1]))) { |
michael@0 | 890 | mbmi->tx_size = TX_32X32; |
michael@0 | 891 | } else if (max_tx_size >= TX_16X16 && |
michael@0 | 892 | (cm->tx_mode == ALLOW_16X16 || |
michael@0 | 893 | cm->tx_mode == ALLOW_32X32 || |
michael@0 | 894 | (cm->tx_mode == TX_MODE_SELECT && |
michael@0 | 895 | rd[TX_16X16][1] <= rd[TX_8X8][1] && |
michael@0 | 896 | rd[TX_16X16][1] <= rd[TX_4X4][1]))) { |
michael@0 | 897 | mbmi->tx_size = TX_16X16; |
michael@0 | 898 | } else if (cm->tx_mode == ALLOW_8X8 || |
michael@0 | 899 | cm->tx_mode == ALLOW_16X16 || |
michael@0 | 900 | cm->tx_mode == ALLOW_32X32 || |
michael@0 | 901 | (cm->tx_mode == TX_MODE_SELECT && |
michael@0 | 902 | rd[TX_8X8][1] <= rd[TX_4X4][1])) { |
michael@0 | 903 | mbmi->tx_size = TX_8X8; |
michael@0 | 904 | } else { |
michael@0 | 905 | mbmi->tx_size = TX_4X4; |
michael@0 | 906 | } |
michael@0 | 907 | |
michael@0 | 908 | // Actually encode using the chosen mode if a model was used, but do not |
michael@0 | 909 | // update the r, d costs |
michael@0 | 910 | txfm_rd_in_plane(x, &cpi->rdcost_stack, rate, distortion, skip, |
michael@0 | 911 | &sse[mbmi->tx_size], ref_best_rd, 0, bs, mbmi->tx_size); |
michael@0 | 912 | |
michael@0 | 913 | if (max_tx_size == TX_32X32 && |
michael@0 | 914 | rd[TX_32X32][1] <= rd[TX_16X16][1] && |
michael@0 | 915 | rd[TX_32X32][1] <= rd[TX_8X8][1] && |
michael@0 | 916 | rd[TX_32X32][1] <= rd[TX_4X4][1]) { |
michael@0 | 917 | cpi->tx_stepdown_count[0]++; |
michael@0 | 918 | } else if (max_tx_size >= TX_16X16 && |
michael@0 | 919 | rd[TX_16X16][1] <= rd[TX_8X8][1] && |
michael@0 | 920 | rd[TX_16X16][1] <= rd[TX_4X4][1]) { |
michael@0 | 921 | cpi->tx_stepdown_count[max_tx_size - TX_16X16]++; |
michael@0 | 922 | } else if (rd[TX_8X8][1] <= rd[TX_4X4][1]) { |
michael@0 | 923 | cpi->tx_stepdown_count[max_tx_size - TX_8X8]++; |
michael@0 | 924 | } else { |
michael@0 | 925 | cpi->tx_stepdown_count[max_tx_size - TX_4X4]++; |
michael@0 | 926 | } |
michael@0 | 927 | } |
michael@0 | 928 | |
michael@0 | 929 | static void super_block_yrd(VP9_COMP *cpi, |
michael@0 | 930 | MACROBLOCK *x, int *rate, int64_t *distortion, |
michael@0 | 931 | int *skip, int64_t *psse, BLOCK_SIZE bs, |
michael@0 | 932 | int64_t txfm_cache[TX_MODES], |
michael@0 | 933 | int64_t ref_best_rd) { |
michael@0 | 934 | int r[TX_SIZES][2], s[TX_SIZES]; |
michael@0 | 935 | int64_t d[TX_SIZES], sse[TX_SIZES]; |
michael@0 | 936 | MACROBLOCKD *xd = &x->e_mbd; |
michael@0 | 937 | MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; |
michael@0 | 938 | struct rdcost_block_args *rdcost_stack = &cpi->rdcost_stack; |
michael@0 | 939 | const int b_inter_mode = is_inter_block(mbmi); |
michael@0 | 940 | |
michael@0 | 941 | assert(bs == mbmi->sb_type); |
michael@0 | 942 | if (b_inter_mode) |
michael@0 | 943 | vp9_subtract_sby(x, bs); |
michael@0 | 944 | |
michael@0 | 945 | if (cpi->sf.tx_size_search_method == USE_LARGESTALL || |
michael@0 | 946 | (cpi->sf.tx_size_search_method != USE_FULL_RD && |
michael@0 | 947 | !b_inter_mode)) { |
michael@0 | 948 | vpx_memset(txfm_cache, 0, TX_MODES * sizeof(int64_t)); |
michael@0 | 949 | choose_largest_txfm_size(cpi, x, rate, distortion, skip, sse, |
michael@0 | 950 | ref_best_rd, bs); |
michael@0 | 951 | if (psse) |
michael@0 | 952 | *psse = sse[mbmi->tx_size]; |
michael@0 | 953 | return; |
michael@0 | 954 | } |
michael@0 | 955 | |
michael@0 | 956 | if (cpi->sf.tx_size_search_method == USE_LARGESTINTRA_MODELINTER && |
michael@0 | 957 | b_inter_mode) { |
michael@0 | 958 | if (bs >= BLOCK_32X32) |
michael@0 | 959 | model_rd_for_sb_y_tx(cpi, bs, TX_32X32, x, xd, |
michael@0 | 960 | &r[TX_32X32][0], &d[TX_32X32], &s[TX_32X32]); |
michael@0 | 961 | if (bs >= BLOCK_16X16) |
michael@0 | 962 | model_rd_for_sb_y_tx(cpi, bs, TX_16X16, x, xd, |
michael@0 | 963 | &r[TX_16X16][0], &d[TX_16X16], &s[TX_16X16]); |
michael@0 | 964 | |
michael@0 | 965 | model_rd_for_sb_y_tx(cpi, bs, TX_8X8, x, xd, |
michael@0 | 966 | &r[TX_8X8][0], &d[TX_8X8], &s[TX_8X8]); |
michael@0 | 967 | |
michael@0 | 968 | model_rd_for_sb_y_tx(cpi, bs, TX_4X4, x, xd, |
michael@0 | 969 | &r[TX_4X4][0], &d[TX_4X4], &s[TX_4X4]); |
michael@0 | 970 | |
michael@0 | 971 | choose_txfm_size_from_modelrd(cpi, x, r, rate, d, distortion, s, |
michael@0 | 972 | skip, sse, ref_best_rd, bs); |
michael@0 | 973 | } else { |
michael@0 | 974 | if (bs >= BLOCK_32X32) |
michael@0 | 975 | txfm_rd_in_plane(x, rdcost_stack, &r[TX_32X32][0], &d[TX_32X32], |
michael@0 | 976 | &s[TX_32X32], &sse[TX_32X32], |
michael@0 | 977 | ref_best_rd, 0, bs, TX_32X32); |
michael@0 | 978 | if (bs >= BLOCK_16X16) |
michael@0 | 979 | txfm_rd_in_plane(x, rdcost_stack, &r[TX_16X16][0], &d[TX_16X16], |
michael@0 | 980 | &s[TX_16X16], &sse[TX_16X16], |
michael@0 | 981 | ref_best_rd, 0, bs, TX_16X16); |
michael@0 | 982 | txfm_rd_in_plane(x, rdcost_stack, &r[TX_8X8][0], &d[TX_8X8], &s[TX_8X8], |
michael@0 | 983 | &sse[TX_8X8], ref_best_rd, 0, bs, TX_8X8); |
michael@0 | 984 | txfm_rd_in_plane(x, rdcost_stack, &r[TX_4X4][0], &d[TX_4X4], &s[TX_4X4], |
michael@0 | 985 | &sse[TX_4X4], ref_best_rd, 0, bs, TX_4X4); |
michael@0 | 986 | choose_txfm_size_from_rd(cpi, x, r, rate, d, distortion, s, |
michael@0 | 987 | skip, txfm_cache, bs); |
michael@0 | 988 | } |
michael@0 | 989 | if (psse) |
michael@0 | 990 | *psse = sse[mbmi->tx_size]; |
michael@0 | 991 | } |
michael@0 | 992 | |
michael@0 | 993 | static int conditional_skipintra(MB_PREDICTION_MODE mode, |
michael@0 | 994 | MB_PREDICTION_MODE best_intra_mode) { |
michael@0 | 995 | if (mode == D117_PRED && |
michael@0 | 996 | best_intra_mode != V_PRED && |
michael@0 | 997 | best_intra_mode != D135_PRED) |
michael@0 | 998 | return 1; |
michael@0 | 999 | if (mode == D63_PRED && |
michael@0 | 1000 | best_intra_mode != V_PRED && |
michael@0 | 1001 | best_intra_mode != D45_PRED) |
michael@0 | 1002 | return 1; |
michael@0 | 1003 | if (mode == D207_PRED && |
michael@0 | 1004 | best_intra_mode != H_PRED && |
michael@0 | 1005 | best_intra_mode != D45_PRED) |
michael@0 | 1006 | return 1; |
michael@0 | 1007 | if (mode == D153_PRED && |
michael@0 | 1008 | best_intra_mode != H_PRED && |
michael@0 | 1009 | best_intra_mode != D135_PRED) |
michael@0 | 1010 | return 1; |
michael@0 | 1011 | return 0; |
michael@0 | 1012 | } |
michael@0 | 1013 | |
michael@0 | 1014 | static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib, |
michael@0 | 1015 | MB_PREDICTION_MODE *best_mode, |
michael@0 | 1016 | int *bmode_costs, |
michael@0 | 1017 | ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l, |
michael@0 | 1018 | int *bestrate, int *bestratey, |
michael@0 | 1019 | int64_t *bestdistortion, |
michael@0 | 1020 | BLOCK_SIZE bsize, int64_t rd_thresh) { |
michael@0 | 1021 | MB_PREDICTION_MODE mode; |
michael@0 | 1022 | MACROBLOCKD *xd = &x->e_mbd; |
michael@0 | 1023 | int64_t best_rd = rd_thresh; |
michael@0 | 1024 | int rate = 0; |
michael@0 | 1025 | int64_t distortion; |
michael@0 | 1026 | struct macroblock_plane *p = &x->plane[0]; |
michael@0 | 1027 | struct macroblockd_plane *pd = &xd->plane[0]; |
michael@0 | 1028 | const int src_stride = p->src.stride; |
michael@0 | 1029 | const int dst_stride = pd->dst.stride; |
michael@0 | 1030 | uint8_t *src_init = raster_block_offset_uint8(BLOCK_8X8, ib, |
michael@0 | 1031 | p->src.buf, src_stride); |
michael@0 | 1032 | uint8_t *dst_init = raster_block_offset_uint8(BLOCK_8X8, ib, |
michael@0 | 1033 | pd->dst.buf, dst_stride); |
michael@0 | 1034 | int16_t *src_diff, *coeff; |
michael@0 | 1035 | |
michael@0 | 1036 | ENTROPY_CONTEXT ta[2], tempa[2]; |
michael@0 | 1037 | ENTROPY_CONTEXT tl[2], templ[2]; |
michael@0 | 1038 | |
michael@0 | 1039 | const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize]; |
michael@0 | 1040 | const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize]; |
michael@0 | 1041 | int idx, idy; |
michael@0 | 1042 | uint8_t best_dst[8 * 8]; |
michael@0 | 1043 | |
michael@0 | 1044 | assert(ib < 4); |
michael@0 | 1045 | |
michael@0 | 1046 | vpx_memcpy(ta, a, sizeof(ta)); |
michael@0 | 1047 | vpx_memcpy(tl, l, sizeof(tl)); |
michael@0 | 1048 | xd->mi_8x8[0]->mbmi.tx_size = TX_4X4; |
michael@0 | 1049 | |
michael@0 | 1050 | for (mode = DC_PRED; mode <= TM_PRED; ++mode) { |
michael@0 | 1051 | int64_t this_rd; |
michael@0 | 1052 | int ratey = 0; |
michael@0 | 1053 | |
michael@0 | 1054 | if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode))) |
michael@0 | 1055 | continue; |
michael@0 | 1056 | |
michael@0 | 1057 | // Only do the oblique modes if the best so far is |
michael@0 | 1058 | // one of the neighboring directional modes |
michael@0 | 1059 | if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) { |
michael@0 | 1060 | if (conditional_skipintra(mode, *best_mode)) |
michael@0 | 1061 | continue; |
michael@0 | 1062 | } |
michael@0 | 1063 | |
michael@0 | 1064 | rate = bmode_costs[mode]; |
michael@0 | 1065 | distortion = 0; |
michael@0 | 1066 | |
michael@0 | 1067 | vpx_memcpy(tempa, ta, sizeof(ta)); |
michael@0 | 1068 | vpx_memcpy(templ, tl, sizeof(tl)); |
michael@0 | 1069 | |
michael@0 | 1070 | for (idy = 0; idy < num_4x4_blocks_high; ++idy) { |
michael@0 | 1071 | for (idx = 0; idx < num_4x4_blocks_wide; ++idx) { |
michael@0 | 1072 | int64_t ssz; |
michael@0 | 1073 | const int16_t *scan; |
michael@0 | 1074 | const int16_t *nb; |
michael@0 | 1075 | uint8_t *src = src_init + idx * 4 + idy * 4 * src_stride; |
michael@0 | 1076 | uint8_t *dst = dst_init + idx * 4 + idy * 4 * dst_stride; |
michael@0 | 1077 | const int block = ib + idy * 2 + idx; |
michael@0 | 1078 | TX_TYPE tx_type; |
michael@0 | 1079 | xd->mi_8x8[0]->bmi[block].as_mode = mode; |
michael@0 | 1080 | src_diff = raster_block_offset_int16(BLOCK_8X8, block, p->src_diff); |
michael@0 | 1081 | coeff = BLOCK_OFFSET(x->plane[0].coeff, block); |
michael@0 | 1082 | vp9_predict_intra_block(xd, block, 1, |
michael@0 | 1083 | TX_4X4, mode, |
michael@0 | 1084 | x->skip_encode ? src : dst, |
michael@0 | 1085 | x->skip_encode ? src_stride : dst_stride, |
michael@0 | 1086 | dst, dst_stride); |
michael@0 | 1087 | vp9_subtract_block(4, 4, src_diff, 8, |
michael@0 | 1088 | src, src_stride, |
michael@0 | 1089 | dst, dst_stride); |
michael@0 | 1090 | |
michael@0 | 1091 | tx_type = get_tx_type_4x4(PLANE_TYPE_Y_WITH_DC, xd, block); |
michael@0 | 1092 | get_scan_nb_4x4(tx_type, &scan, &nb); |
michael@0 | 1093 | |
michael@0 | 1094 | if (tx_type != DCT_DCT) |
michael@0 | 1095 | vp9_short_fht4x4(src_diff, coeff, 8, tx_type); |
michael@0 | 1096 | else |
michael@0 | 1097 | x->fwd_txm4x4(src_diff, coeff, 8); |
michael@0 | 1098 | |
michael@0 | 1099 | vp9_regular_quantize_b_4x4(x, 4, block, scan, get_iscan_4x4(tx_type)); |
michael@0 | 1100 | |
michael@0 | 1101 | ratey += cost_coeffs(x, 0, block, |
michael@0 | 1102 | tempa + idx, templ + idy, TX_4X4, scan, nb); |
michael@0 | 1103 | distortion += vp9_block_error(coeff, BLOCK_OFFSET(pd->dqcoeff, block), |
michael@0 | 1104 | 16, &ssz) >> 2; |
michael@0 | 1105 | if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd) |
michael@0 | 1106 | goto next; |
michael@0 | 1107 | |
michael@0 | 1108 | if (tx_type != DCT_DCT) |
michael@0 | 1109 | vp9_iht4x4_16_add(BLOCK_OFFSET(pd->dqcoeff, block), |
michael@0 | 1110 | dst, pd->dst.stride, tx_type); |
michael@0 | 1111 | else |
michael@0 | 1112 | xd->itxm_add(BLOCK_OFFSET(pd->dqcoeff, block), dst, pd->dst.stride, |
michael@0 | 1113 | 16); |
michael@0 | 1114 | } |
michael@0 | 1115 | } |
michael@0 | 1116 | |
michael@0 | 1117 | rate += ratey; |
michael@0 | 1118 | this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion); |
michael@0 | 1119 | |
michael@0 | 1120 | if (this_rd < best_rd) { |
michael@0 | 1121 | *bestrate = rate; |
michael@0 | 1122 | *bestratey = ratey; |
michael@0 | 1123 | *bestdistortion = distortion; |
michael@0 | 1124 | best_rd = this_rd; |
michael@0 | 1125 | *best_mode = mode; |
michael@0 | 1126 | vpx_memcpy(a, tempa, sizeof(tempa)); |
michael@0 | 1127 | vpx_memcpy(l, templ, sizeof(templ)); |
michael@0 | 1128 | for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) |
michael@0 | 1129 | vpx_memcpy(best_dst + idy * 8, dst_init + idy * dst_stride, |
michael@0 | 1130 | num_4x4_blocks_wide * 4); |
michael@0 | 1131 | } |
michael@0 | 1132 | next: |
michael@0 | 1133 | {} |
michael@0 | 1134 | } |
michael@0 | 1135 | |
michael@0 | 1136 | if (best_rd >= rd_thresh || x->skip_encode) |
michael@0 | 1137 | return best_rd; |
michael@0 | 1138 | |
michael@0 | 1139 | for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) |
michael@0 | 1140 | vpx_memcpy(dst_init + idy * dst_stride, best_dst + idy * 8, |
michael@0 | 1141 | num_4x4_blocks_wide * 4); |
michael@0 | 1142 | |
michael@0 | 1143 | return best_rd; |
michael@0 | 1144 | } |
michael@0 | 1145 | |
michael@0 | 1146 | static int64_t rd_pick_intra_sub_8x8_y_mode(VP9_COMP * const cpi, |
michael@0 | 1147 | MACROBLOCK * const mb, |
michael@0 | 1148 | int * const rate, |
michael@0 | 1149 | int * const rate_y, |
michael@0 | 1150 | int64_t * const distortion, |
michael@0 | 1151 | int64_t best_rd) { |
michael@0 | 1152 | int i, j; |
michael@0 | 1153 | MACROBLOCKD *const xd = &mb->e_mbd; |
michael@0 | 1154 | MODE_INFO *const mic = xd->mi_8x8[0]; |
michael@0 | 1155 | const MODE_INFO *above_mi = xd->mi_8x8[-xd->mode_info_stride]; |
michael@0 | 1156 | const MODE_INFO *left_mi = xd->left_available ? xd->mi_8x8[-1] : NULL; |
michael@0 | 1157 | const BLOCK_SIZE bsize = xd->mi_8x8[0]->mbmi.sb_type; |
michael@0 | 1158 | const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize]; |
michael@0 | 1159 | const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize]; |
michael@0 | 1160 | int idx, idy; |
michael@0 | 1161 | int cost = 0; |
michael@0 | 1162 | int64_t total_distortion = 0; |
michael@0 | 1163 | int tot_rate_y = 0; |
michael@0 | 1164 | int64_t total_rd = 0; |
michael@0 | 1165 | ENTROPY_CONTEXT t_above[4], t_left[4]; |
michael@0 | 1166 | int *bmode_costs; |
michael@0 | 1167 | |
michael@0 | 1168 | vpx_memcpy(t_above, xd->plane[0].above_context, sizeof(t_above)); |
michael@0 | 1169 | vpx_memcpy(t_left, xd->plane[0].left_context, sizeof(t_left)); |
michael@0 | 1170 | |
michael@0 | 1171 | bmode_costs = mb->mbmode_cost; |
michael@0 | 1172 | |
michael@0 | 1173 | // Pick modes for each sub-block (of size 4x4, 4x8, or 8x4) in an 8x8 block. |
michael@0 | 1174 | for (idy = 0; idy < 2; idy += num_4x4_blocks_high) { |
michael@0 | 1175 | for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) { |
michael@0 | 1176 | MB_PREDICTION_MODE best_mode = DC_PRED; |
michael@0 | 1177 | int r = INT_MAX, ry = INT_MAX; |
michael@0 | 1178 | int64_t d = INT64_MAX, this_rd = INT64_MAX; |
michael@0 | 1179 | i = idy * 2 + idx; |
michael@0 | 1180 | if (cpi->common.frame_type == KEY_FRAME) { |
michael@0 | 1181 | const MB_PREDICTION_MODE A = above_block_mode(mic, above_mi, i); |
michael@0 | 1182 | const MB_PREDICTION_MODE L = left_block_mode(mic, left_mi, i); |
michael@0 | 1183 | |
michael@0 | 1184 | bmode_costs = mb->y_mode_costs[A][L]; |
michael@0 | 1185 | } |
michael@0 | 1186 | |
michael@0 | 1187 | this_rd = rd_pick_intra4x4block(cpi, mb, i, &best_mode, bmode_costs, |
michael@0 | 1188 | t_above + idx, t_left + idy, &r, &ry, &d, |
michael@0 | 1189 | bsize, best_rd - total_rd); |
michael@0 | 1190 | if (this_rd >= best_rd - total_rd) |
michael@0 | 1191 | return INT64_MAX; |
michael@0 | 1192 | |
michael@0 | 1193 | total_rd += this_rd; |
michael@0 | 1194 | cost += r; |
michael@0 | 1195 | total_distortion += d; |
michael@0 | 1196 | tot_rate_y += ry; |
michael@0 | 1197 | |
michael@0 | 1198 | mic->bmi[i].as_mode = best_mode; |
michael@0 | 1199 | for (j = 1; j < num_4x4_blocks_high; ++j) |
michael@0 | 1200 | mic->bmi[i + j * 2].as_mode = best_mode; |
michael@0 | 1201 | for (j = 1; j < num_4x4_blocks_wide; ++j) |
michael@0 | 1202 | mic->bmi[i + j].as_mode = best_mode; |
michael@0 | 1203 | |
michael@0 | 1204 | if (total_rd >= best_rd) |
michael@0 | 1205 | return INT64_MAX; |
michael@0 | 1206 | } |
michael@0 | 1207 | } |
michael@0 | 1208 | |
michael@0 | 1209 | *rate = cost; |
michael@0 | 1210 | *rate_y = tot_rate_y; |
michael@0 | 1211 | *distortion = total_distortion; |
michael@0 | 1212 | mic->mbmi.mode = mic->bmi[3].as_mode; |
michael@0 | 1213 | |
michael@0 | 1214 | return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion); |
michael@0 | 1215 | } |
michael@0 | 1216 | |
michael@0 | 1217 | static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x, |
michael@0 | 1218 | int *rate, int *rate_tokenonly, |
michael@0 | 1219 | int64_t *distortion, int *skippable, |
michael@0 | 1220 | BLOCK_SIZE bsize, |
michael@0 | 1221 | int64_t tx_cache[TX_MODES], |
michael@0 | 1222 | int64_t best_rd) { |
michael@0 | 1223 | MB_PREDICTION_MODE mode; |
michael@0 | 1224 | MB_PREDICTION_MODE mode_selected = DC_PRED; |
michael@0 | 1225 | MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 1226 | MODE_INFO *const mic = xd->mi_8x8[0]; |
michael@0 | 1227 | int this_rate, this_rate_tokenonly, s; |
michael@0 | 1228 | int64_t this_distortion, this_rd; |
michael@0 | 1229 | TX_SIZE best_tx = TX_4X4; |
michael@0 | 1230 | int i; |
michael@0 | 1231 | int *bmode_costs = x->mbmode_cost; |
michael@0 | 1232 | |
michael@0 | 1233 | if (cpi->sf.tx_size_search_method == USE_FULL_RD) |
michael@0 | 1234 | for (i = 0; i < TX_MODES; i++) |
michael@0 | 1235 | tx_cache[i] = INT64_MAX; |
michael@0 | 1236 | |
michael@0 | 1237 | /* Y Search for intra prediction mode */ |
michael@0 | 1238 | for (mode = DC_PRED; mode <= TM_PRED; mode++) { |
michael@0 | 1239 | int64_t local_tx_cache[TX_MODES]; |
michael@0 | 1240 | MODE_INFO *above_mi = xd->mi_8x8[-xd->mode_info_stride]; |
michael@0 | 1241 | MODE_INFO *left_mi = xd->left_available ? xd->mi_8x8[-1] : NULL; |
michael@0 | 1242 | |
michael@0 | 1243 | if (!(cpi->sf.intra_y_mode_mask[max_txsize_lookup[bsize]] & (1 << mode))) |
michael@0 | 1244 | continue; |
michael@0 | 1245 | |
michael@0 | 1246 | if (cpi->common.frame_type == KEY_FRAME) { |
michael@0 | 1247 | const MB_PREDICTION_MODE A = above_block_mode(mic, above_mi, 0); |
michael@0 | 1248 | const MB_PREDICTION_MODE L = left_block_mode(mic, left_mi, 0); |
michael@0 | 1249 | |
michael@0 | 1250 | bmode_costs = x->y_mode_costs[A][L]; |
michael@0 | 1251 | } |
michael@0 | 1252 | mic->mbmi.mode = mode; |
michael@0 | 1253 | |
michael@0 | 1254 | super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s, NULL, |
michael@0 | 1255 | bsize, local_tx_cache, best_rd); |
michael@0 | 1256 | |
michael@0 | 1257 | if (this_rate_tokenonly == INT_MAX) |
michael@0 | 1258 | continue; |
michael@0 | 1259 | |
michael@0 | 1260 | this_rate = this_rate_tokenonly + bmode_costs[mode]; |
michael@0 | 1261 | this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion); |
michael@0 | 1262 | |
michael@0 | 1263 | if (this_rd < best_rd) { |
michael@0 | 1264 | mode_selected = mode; |
michael@0 | 1265 | best_rd = this_rd; |
michael@0 | 1266 | best_tx = mic->mbmi.tx_size; |
michael@0 | 1267 | *rate = this_rate; |
michael@0 | 1268 | *rate_tokenonly = this_rate_tokenonly; |
michael@0 | 1269 | *distortion = this_distortion; |
michael@0 | 1270 | *skippable = s; |
michael@0 | 1271 | } |
michael@0 | 1272 | |
michael@0 | 1273 | if (cpi->sf.tx_size_search_method == USE_FULL_RD && this_rd < INT64_MAX) { |
michael@0 | 1274 | for (i = 0; i < TX_MODES && local_tx_cache[i] < INT64_MAX; i++) { |
michael@0 | 1275 | const int64_t adj_rd = this_rd + local_tx_cache[i] - |
michael@0 | 1276 | local_tx_cache[cpi->common.tx_mode]; |
michael@0 | 1277 | if (adj_rd < tx_cache[i]) { |
michael@0 | 1278 | tx_cache[i] = adj_rd; |
michael@0 | 1279 | } |
michael@0 | 1280 | } |
michael@0 | 1281 | } |
michael@0 | 1282 | } |
michael@0 | 1283 | |
michael@0 | 1284 | mic->mbmi.mode = mode_selected; |
michael@0 | 1285 | mic->mbmi.tx_size = best_tx; |
michael@0 | 1286 | |
michael@0 | 1287 | return best_rd; |
michael@0 | 1288 | } |
michael@0 | 1289 | |
michael@0 | 1290 | static void super_block_uvrd(VP9_COMP *const cpi, MACROBLOCK *x, |
michael@0 | 1291 | int *rate, int64_t *distortion, int *skippable, |
michael@0 | 1292 | int64_t *sse, BLOCK_SIZE bsize, |
michael@0 | 1293 | int64_t ref_best_rd) { |
michael@0 | 1294 | MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 1295 | MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; |
michael@0 | 1296 | TX_SIZE uv_txfm_size = get_uv_tx_size(mbmi); |
michael@0 | 1297 | int plane; |
michael@0 | 1298 | int pnrate = 0, pnskip = 1; |
michael@0 | 1299 | int64_t pndist = 0, pnsse = 0; |
michael@0 | 1300 | |
michael@0 | 1301 | if (ref_best_rd < 0) |
michael@0 | 1302 | goto term; |
michael@0 | 1303 | |
michael@0 | 1304 | if (is_inter_block(mbmi)) |
michael@0 | 1305 | vp9_subtract_sbuv(x, bsize); |
michael@0 | 1306 | |
michael@0 | 1307 | *rate = 0; |
michael@0 | 1308 | *distortion = 0; |
michael@0 | 1309 | *sse = 0; |
michael@0 | 1310 | *skippable = 1; |
michael@0 | 1311 | |
michael@0 | 1312 | for (plane = 1; plane < MAX_MB_PLANE; ++plane) { |
michael@0 | 1313 | txfm_rd_in_plane(x, &cpi->rdcost_stack, &pnrate, &pndist, &pnskip, &pnsse, |
michael@0 | 1314 | ref_best_rd, plane, bsize, uv_txfm_size); |
michael@0 | 1315 | if (pnrate == INT_MAX) |
michael@0 | 1316 | goto term; |
michael@0 | 1317 | *rate += pnrate; |
michael@0 | 1318 | *distortion += pndist; |
michael@0 | 1319 | *sse += pnsse; |
michael@0 | 1320 | *skippable &= pnskip; |
michael@0 | 1321 | } |
michael@0 | 1322 | return; |
michael@0 | 1323 | |
michael@0 | 1324 | term: |
michael@0 | 1325 | *rate = INT_MAX; |
michael@0 | 1326 | *distortion = INT64_MAX; |
michael@0 | 1327 | *sse = INT64_MAX; |
michael@0 | 1328 | *skippable = 0; |
michael@0 | 1329 | return; |
michael@0 | 1330 | } |
michael@0 | 1331 | |
michael@0 | 1332 | static int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x, |
michael@0 | 1333 | PICK_MODE_CONTEXT *ctx, |
michael@0 | 1334 | int *rate, int *rate_tokenonly, |
michael@0 | 1335 | int64_t *distortion, int *skippable, |
michael@0 | 1336 | BLOCK_SIZE bsize) { |
michael@0 | 1337 | MB_PREDICTION_MODE mode; |
michael@0 | 1338 | MB_PREDICTION_MODE mode_selected = DC_PRED; |
michael@0 | 1339 | int64_t best_rd = INT64_MAX, this_rd; |
michael@0 | 1340 | int this_rate_tokenonly, this_rate, s; |
michael@0 | 1341 | int64_t this_distortion, this_sse; |
michael@0 | 1342 | |
michael@0 | 1343 | // int mode_mask = (bsize <= BLOCK_8X8) |
michael@0 | 1344 | // ? ALL_INTRA_MODES : cpi->sf.intra_uv_mode_mask; |
michael@0 | 1345 | |
michael@0 | 1346 | for (mode = DC_PRED; mode <= TM_PRED; mode ++) { |
michael@0 | 1347 | // if (!(mode_mask & (1 << mode))) |
michael@0 | 1348 | if (!(cpi->sf.intra_uv_mode_mask[max_uv_txsize_lookup[bsize]] |
michael@0 | 1349 | & (1 << mode))) |
michael@0 | 1350 | continue; |
michael@0 | 1351 | |
michael@0 | 1352 | x->e_mbd.mi_8x8[0]->mbmi.uv_mode = mode; |
michael@0 | 1353 | |
michael@0 | 1354 | super_block_uvrd(cpi, x, &this_rate_tokenonly, |
michael@0 | 1355 | &this_distortion, &s, &this_sse, bsize, best_rd); |
michael@0 | 1356 | if (this_rate_tokenonly == INT_MAX) |
michael@0 | 1357 | continue; |
michael@0 | 1358 | this_rate = this_rate_tokenonly + |
michael@0 | 1359 | x->intra_uv_mode_cost[cpi->common.frame_type][mode]; |
michael@0 | 1360 | this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion); |
michael@0 | 1361 | |
michael@0 | 1362 | if (this_rd < best_rd) { |
michael@0 | 1363 | mode_selected = mode; |
michael@0 | 1364 | best_rd = this_rd; |
michael@0 | 1365 | *rate = this_rate; |
michael@0 | 1366 | *rate_tokenonly = this_rate_tokenonly; |
michael@0 | 1367 | *distortion = this_distortion; |
michael@0 | 1368 | *skippable = s; |
michael@0 | 1369 | if (!x->select_txfm_size) { |
michael@0 | 1370 | int i; |
michael@0 | 1371 | struct macroblock_plane *const p = x->plane; |
michael@0 | 1372 | struct macroblockd_plane *const pd = x->e_mbd.plane; |
michael@0 | 1373 | for (i = 1; i < MAX_MB_PLANE; ++i) { |
michael@0 | 1374 | p[i].coeff = ctx->coeff_pbuf[i][2]; |
michael@0 | 1375 | pd[i].qcoeff = ctx->qcoeff_pbuf[i][2]; |
michael@0 | 1376 | pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][2]; |
michael@0 | 1377 | pd[i].eobs = ctx->eobs_pbuf[i][2]; |
michael@0 | 1378 | |
michael@0 | 1379 | ctx->coeff_pbuf[i][2] = ctx->coeff_pbuf[i][0]; |
michael@0 | 1380 | ctx->qcoeff_pbuf[i][2] = ctx->qcoeff_pbuf[i][0]; |
michael@0 | 1381 | ctx->dqcoeff_pbuf[i][2] = ctx->dqcoeff_pbuf[i][0]; |
michael@0 | 1382 | ctx->eobs_pbuf[i][2] = ctx->eobs_pbuf[i][0]; |
michael@0 | 1383 | |
michael@0 | 1384 | ctx->coeff_pbuf[i][0] = p[i].coeff; |
michael@0 | 1385 | ctx->qcoeff_pbuf[i][0] = pd[i].qcoeff; |
michael@0 | 1386 | ctx->dqcoeff_pbuf[i][0] = pd[i].dqcoeff; |
michael@0 | 1387 | ctx->eobs_pbuf[i][0] = pd[i].eobs; |
michael@0 | 1388 | } |
michael@0 | 1389 | } |
michael@0 | 1390 | } |
michael@0 | 1391 | } |
michael@0 | 1392 | |
michael@0 | 1393 | x->e_mbd.mi_8x8[0]->mbmi.uv_mode = mode_selected; |
michael@0 | 1394 | |
michael@0 | 1395 | return best_rd; |
michael@0 | 1396 | } |
michael@0 | 1397 | |
michael@0 | 1398 | static int64_t rd_sbuv_dcpred(VP9_COMP *cpi, MACROBLOCK *x, |
michael@0 | 1399 | int *rate, int *rate_tokenonly, |
michael@0 | 1400 | int64_t *distortion, int *skippable, |
michael@0 | 1401 | BLOCK_SIZE bsize) { |
michael@0 | 1402 | int64_t this_rd; |
michael@0 | 1403 | int64_t this_sse; |
michael@0 | 1404 | |
michael@0 | 1405 | x->e_mbd.mi_8x8[0]->mbmi.uv_mode = DC_PRED; |
michael@0 | 1406 | super_block_uvrd(cpi, x, rate_tokenonly, distortion, |
michael@0 | 1407 | skippable, &this_sse, bsize, INT64_MAX); |
michael@0 | 1408 | *rate = *rate_tokenonly + |
michael@0 | 1409 | x->intra_uv_mode_cost[cpi->common.frame_type][DC_PRED]; |
michael@0 | 1410 | this_rd = RDCOST(x->rdmult, x->rddiv, *rate, *distortion); |
michael@0 | 1411 | |
michael@0 | 1412 | return this_rd; |
michael@0 | 1413 | } |
michael@0 | 1414 | |
michael@0 | 1415 | static void choose_intra_uv_mode(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx, |
michael@0 | 1416 | BLOCK_SIZE bsize, int *rate_uv, |
michael@0 | 1417 | int *rate_uv_tokenonly, |
michael@0 | 1418 | int64_t *dist_uv, int *skip_uv, |
michael@0 | 1419 | MB_PREDICTION_MODE *mode_uv) { |
michael@0 | 1420 | MACROBLOCK *const x = &cpi->mb; |
michael@0 | 1421 | |
michael@0 | 1422 | // Use an estimated rd for uv_intra based on DC_PRED if the |
michael@0 | 1423 | // appropriate speed flag is set. |
michael@0 | 1424 | if (cpi->sf.use_uv_intra_rd_estimate) { |
michael@0 | 1425 | rd_sbuv_dcpred(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv, |
michael@0 | 1426 | bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize); |
michael@0 | 1427 | // Else do a proper rd search for each possible transform size that may |
michael@0 | 1428 | // be considered in the main rd loop. |
michael@0 | 1429 | } else { |
michael@0 | 1430 | rd_pick_intra_sbuv_mode(cpi, x, ctx, |
michael@0 | 1431 | rate_uv, rate_uv_tokenonly, dist_uv, skip_uv, |
michael@0 | 1432 | bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize); |
michael@0 | 1433 | } |
michael@0 | 1434 | *mode_uv = x->e_mbd.mi_8x8[0]->mbmi.uv_mode; |
michael@0 | 1435 | } |
michael@0 | 1436 | |
michael@0 | 1437 | static int cost_mv_ref(VP9_COMP *cpi, MB_PREDICTION_MODE mode, |
michael@0 | 1438 | int mode_context) { |
michael@0 | 1439 | MACROBLOCK *const x = &cpi->mb; |
michael@0 | 1440 | MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 1441 | const int segment_id = xd->mi_8x8[0]->mbmi.segment_id; |
michael@0 | 1442 | |
michael@0 | 1443 | // Don't account for mode here if segment skip is enabled. |
michael@0 | 1444 | if (!vp9_segfeature_active(&cpi->common.seg, segment_id, SEG_LVL_SKIP)) { |
michael@0 | 1445 | assert(is_inter_mode(mode)); |
michael@0 | 1446 | return x->inter_mode_cost[mode_context][INTER_OFFSET(mode)]; |
michael@0 | 1447 | } else { |
michael@0 | 1448 | return 0; |
michael@0 | 1449 | } |
michael@0 | 1450 | } |
michael@0 | 1451 | |
michael@0 | 1452 | void vp9_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, int_mv *mv) { |
michael@0 | 1453 | x->e_mbd.mi_8x8[0]->mbmi.mode = mb; |
michael@0 | 1454 | x->e_mbd.mi_8x8[0]->mbmi.mv[0].as_int = mv->as_int; |
michael@0 | 1455 | } |
michael@0 | 1456 | |
michael@0 | 1457 | static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x, |
michael@0 | 1458 | BLOCK_SIZE bsize, |
michael@0 | 1459 | int_mv *frame_mv, |
michael@0 | 1460 | int mi_row, int mi_col, |
michael@0 | 1461 | int_mv single_newmv[MAX_REF_FRAMES], |
michael@0 | 1462 | int *rate_mv); |
michael@0 | 1463 | |
michael@0 | 1464 | static int labels2mode(MACROBLOCK *x, int i, |
michael@0 | 1465 | MB_PREDICTION_MODE this_mode, |
michael@0 | 1466 | int_mv *this_mv, int_mv *this_second_mv, |
michael@0 | 1467 | int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES], |
michael@0 | 1468 | int_mv seg_mvs[MAX_REF_FRAMES], |
michael@0 | 1469 | int_mv *best_ref_mv, |
michael@0 | 1470 | int_mv *second_best_ref_mv, |
michael@0 | 1471 | int *mvjcost, int *mvcost[2], VP9_COMP *cpi) { |
michael@0 | 1472 | MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 1473 | MODE_INFO *const mic = xd->mi_8x8[0]; |
michael@0 | 1474 | MB_MODE_INFO *mbmi = &mic->mbmi; |
michael@0 | 1475 | int cost = 0, thismvcost = 0; |
michael@0 | 1476 | int idx, idy; |
michael@0 | 1477 | const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type]; |
michael@0 | 1478 | const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type]; |
michael@0 | 1479 | const int has_second_rf = has_second_ref(mbmi); |
michael@0 | 1480 | |
michael@0 | 1481 | /* We have to be careful retrieving previously-encoded motion vectors. |
michael@0 | 1482 | Ones from this macroblock have to be pulled from the BLOCKD array |
michael@0 | 1483 | as they have not yet made it to the bmi array in our MB_MODE_INFO. */ |
michael@0 | 1484 | MB_PREDICTION_MODE m; |
michael@0 | 1485 | |
michael@0 | 1486 | // the only time we should do costing for new motion vector or mode |
michael@0 | 1487 | // is when we are on a new label (jbb May 08, 2007) |
michael@0 | 1488 | switch (m = this_mode) { |
michael@0 | 1489 | case NEWMV: |
michael@0 | 1490 | this_mv->as_int = seg_mvs[mbmi->ref_frame[0]].as_int; |
michael@0 | 1491 | thismvcost = vp9_mv_bit_cost(&this_mv->as_mv, &best_ref_mv->as_mv, |
michael@0 | 1492 | mvjcost, mvcost, MV_COST_WEIGHT_SUB); |
michael@0 | 1493 | if (has_second_rf) { |
michael@0 | 1494 | this_second_mv->as_int = seg_mvs[mbmi->ref_frame[1]].as_int; |
michael@0 | 1495 | thismvcost += vp9_mv_bit_cost(&this_second_mv->as_mv, |
michael@0 | 1496 | &second_best_ref_mv->as_mv, |
michael@0 | 1497 | mvjcost, mvcost, MV_COST_WEIGHT_SUB); |
michael@0 | 1498 | } |
michael@0 | 1499 | break; |
michael@0 | 1500 | case NEARESTMV: |
michael@0 | 1501 | this_mv->as_int = frame_mv[NEARESTMV][mbmi->ref_frame[0]].as_int; |
michael@0 | 1502 | if (has_second_rf) |
michael@0 | 1503 | this_second_mv->as_int = |
michael@0 | 1504 | frame_mv[NEARESTMV][mbmi->ref_frame[1]].as_int; |
michael@0 | 1505 | break; |
michael@0 | 1506 | case NEARMV: |
michael@0 | 1507 | this_mv->as_int = frame_mv[NEARMV][mbmi->ref_frame[0]].as_int; |
michael@0 | 1508 | if (has_second_rf) |
michael@0 | 1509 | this_second_mv->as_int = |
michael@0 | 1510 | frame_mv[NEARMV][mbmi->ref_frame[1]].as_int; |
michael@0 | 1511 | break; |
michael@0 | 1512 | case ZEROMV: |
michael@0 | 1513 | this_mv->as_int = 0; |
michael@0 | 1514 | if (has_second_rf) |
michael@0 | 1515 | this_second_mv->as_int = 0; |
michael@0 | 1516 | break; |
michael@0 | 1517 | default: |
michael@0 | 1518 | break; |
michael@0 | 1519 | } |
michael@0 | 1520 | |
michael@0 | 1521 | cost = cost_mv_ref(cpi, this_mode, |
michael@0 | 1522 | mbmi->mode_context[mbmi->ref_frame[0]]); |
michael@0 | 1523 | |
michael@0 | 1524 | mic->bmi[i].as_mv[0].as_int = this_mv->as_int; |
michael@0 | 1525 | if (has_second_rf) |
michael@0 | 1526 | mic->bmi[i].as_mv[1].as_int = this_second_mv->as_int; |
michael@0 | 1527 | |
michael@0 | 1528 | mic->bmi[i].as_mode = m; |
michael@0 | 1529 | |
michael@0 | 1530 | for (idy = 0; idy < num_4x4_blocks_high; ++idy) |
michael@0 | 1531 | for (idx = 0; idx < num_4x4_blocks_wide; ++idx) |
michael@0 | 1532 | vpx_memcpy(&mic->bmi[i + idy * 2 + idx], |
michael@0 | 1533 | &mic->bmi[i], sizeof(mic->bmi[i])); |
michael@0 | 1534 | |
michael@0 | 1535 | cost += thismvcost; |
michael@0 | 1536 | return cost; |
michael@0 | 1537 | } |
michael@0 | 1538 | |
michael@0 | 1539 | static int64_t encode_inter_mb_segment(VP9_COMP *cpi, |
michael@0 | 1540 | MACROBLOCK *x, |
michael@0 | 1541 | int64_t best_yrd, |
michael@0 | 1542 | int i, |
michael@0 | 1543 | int *labelyrate, |
michael@0 | 1544 | int64_t *distortion, int64_t *sse, |
michael@0 | 1545 | ENTROPY_CONTEXT *ta, |
michael@0 | 1546 | ENTROPY_CONTEXT *tl) { |
michael@0 | 1547 | int k; |
michael@0 | 1548 | MACROBLOCKD *xd = &x->e_mbd; |
michael@0 | 1549 | struct macroblockd_plane *const pd = &xd->plane[0]; |
michael@0 | 1550 | struct macroblock_plane *const p = &x->plane[0]; |
michael@0 | 1551 | MODE_INFO *const mi = xd->mi_8x8[0]; |
michael@0 | 1552 | const BLOCK_SIZE bsize = mi->mbmi.sb_type; |
michael@0 | 1553 | const int width = plane_block_width(bsize, pd); |
michael@0 | 1554 | const int height = plane_block_height(bsize, pd); |
michael@0 | 1555 | int idx, idy; |
michael@0 | 1556 | |
michael@0 | 1557 | uint8_t *const src = raster_block_offset_uint8(BLOCK_8X8, i, |
michael@0 | 1558 | p->src.buf, p->src.stride); |
michael@0 | 1559 | uint8_t *const dst = raster_block_offset_uint8(BLOCK_8X8, i, |
michael@0 | 1560 | pd->dst.buf, pd->dst.stride); |
michael@0 | 1561 | int64_t thisdistortion = 0, thissse = 0; |
michael@0 | 1562 | int thisrate = 0, ref; |
michael@0 | 1563 | const int is_compound = has_second_ref(&mi->mbmi); |
michael@0 | 1564 | for (ref = 0; ref < 1 + is_compound; ++ref) { |
michael@0 | 1565 | const uint8_t *pre = raster_block_offset_uint8(BLOCK_8X8, i, |
michael@0 | 1566 | pd->pre[ref].buf, pd->pre[ref].stride); |
michael@0 | 1567 | vp9_build_inter_predictor(pre, pd->pre[ref].stride, |
michael@0 | 1568 | dst, pd->dst.stride, |
michael@0 | 1569 | &mi->bmi[i].as_mv[ref].as_mv, |
michael@0 | 1570 | &xd->scale_factor[ref], |
michael@0 | 1571 | width, height, ref, &xd->subpix, MV_PRECISION_Q3); |
michael@0 | 1572 | } |
michael@0 | 1573 | |
michael@0 | 1574 | vp9_subtract_block(height, width, |
michael@0 | 1575 | raster_block_offset_int16(BLOCK_8X8, i, p->src_diff), 8, |
michael@0 | 1576 | src, p->src.stride, |
michael@0 | 1577 | dst, pd->dst.stride); |
michael@0 | 1578 | |
michael@0 | 1579 | k = i; |
michael@0 | 1580 | for (idy = 0; idy < height / 4; ++idy) { |
michael@0 | 1581 | for (idx = 0; idx < width / 4; ++idx) { |
michael@0 | 1582 | int64_t ssz, rd, rd1, rd2; |
michael@0 | 1583 | int16_t* coeff; |
michael@0 | 1584 | |
michael@0 | 1585 | k += (idy * 2 + idx); |
michael@0 | 1586 | coeff = BLOCK_OFFSET(p->coeff, k); |
michael@0 | 1587 | x->fwd_txm4x4(raster_block_offset_int16(BLOCK_8X8, k, p->src_diff), |
michael@0 | 1588 | coeff, 8); |
michael@0 | 1589 | vp9_regular_quantize_b_4x4(x, 4, k, get_scan_4x4(DCT_DCT), |
michael@0 | 1590 | get_iscan_4x4(DCT_DCT)); |
michael@0 | 1591 | thisdistortion += vp9_block_error(coeff, BLOCK_OFFSET(pd->dqcoeff, k), |
michael@0 | 1592 | 16, &ssz); |
michael@0 | 1593 | thissse += ssz; |
michael@0 | 1594 | thisrate += cost_coeffs(x, 0, k, |
michael@0 | 1595 | ta + (k & 1), |
michael@0 | 1596 | tl + (k >> 1), TX_4X4, |
michael@0 | 1597 | vp9_default_scan_4x4, |
michael@0 | 1598 | vp9_default_scan_4x4_neighbors); |
michael@0 | 1599 | rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion >> 2); |
michael@0 | 1600 | rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse >> 2); |
michael@0 | 1601 | rd = MIN(rd1, rd2); |
michael@0 | 1602 | if (rd >= best_yrd) |
michael@0 | 1603 | return INT64_MAX; |
michael@0 | 1604 | } |
michael@0 | 1605 | } |
michael@0 | 1606 | |
michael@0 | 1607 | *distortion = thisdistortion >> 2; |
michael@0 | 1608 | *labelyrate = thisrate; |
michael@0 | 1609 | *sse = thissse >> 2; |
michael@0 | 1610 | |
michael@0 | 1611 | return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion); |
michael@0 | 1612 | } |
michael@0 | 1613 | |
michael@0 | 1614 | typedef struct { |
michael@0 | 1615 | int eobs; |
michael@0 | 1616 | int brate; |
michael@0 | 1617 | int byrate; |
michael@0 | 1618 | int64_t bdist; |
michael@0 | 1619 | int64_t bsse; |
michael@0 | 1620 | int64_t brdcost; |
michael@0 | 1621 | int_mv mvs[2]; |
michael@0 | 1622 | ENTROPY_CONTEXT ta[2]; |
michael@0 | 1623 | ENTROPY_CONTEXT tl[2]; |
michael@0 | 1624 | } SEG_RDSTAT; |
michael@0 | 1625 | |
michael@0 | 1626 | typedef struct { |
michael@0 | 1627 | int_mv *ref_mv, *second_ref_mv; |
michael@0 | 1628 | int_mv mvp; |
michael@0 | 1629 | |
michael@0 | 1630 | int64_t segment_rd; |
michael@0 | 1631 | int r; |
michael@0 | 1632 | int64_t d; |
michael@0 | 1633 | int64_t sse; |
michael@0 | 1634 | int segment_yrate; |
michael@0 | 1635 | MB_PREDICTION_MODE modes[4]; |
michael@0 | 1636 | SEG_RDSTAT rdstat[4][INTER_MODES]; |
michael@0 | 1637 | int mvthresh; |
michael@0 | 1638 | } BEST_SEG_INFO; |
michael@0 | 1639 | |
michael@0 | 1640 | static INLINE int mv_check_bounds(MACROBLOCK *x, int_mv *mv) { |
michael@0 | 1641 | int r = 0; |
michael@0 | 1642 | r |= (mv->as_mv.row >> 3) < x->mv_row_min; |
michael@0 | 1643 | r |= (mv->as_mv.row >> 3) > x->mv_row_max; |
michael@0 | 1644 | r |= (mv->as_mv.col >> 3) < x->mv_col_min; |
michael@0 | 1645 | r |= (mv->as_mv.col >> 3) > x->mv_col_max; |
michael@0 | 1646 | return r; |
michael@0 | 1647 | } |
michael@0 | 1648 | |
michael@0 | 1649 | static INLINE void mi_buf_shift(MACROBLOCK *x, int i) { |
michael@0 | 1650 | MB_MODE_INFO *const mbmi = &x->e_mbd.mi_8x8[0]->mbmi; |
michael@0 | 1651 | struct macroblock_plane *const p = &x->plane[0]; |
michael@0 | 1652 | struct macroblockd_plane *const pd = &x->e_mbd.plane[0]; |
michael@0 | 1653 | |
michael@0 | 1654 | p->src.buf = raster_block_offset_uint8(BLOCK_8X8, i, p->src.buf, |
michael@0 | 1655 | p->src.stride); |
michael@0 | 1656 | assert(((intptr_t)pd->pre[0].buf & 0x7) == 0); |
michael@0 | 1657 | pd->pre[0].buf = raster_block_offset_uint8(BLOCK_8X8, i, pd->pre[0].buf, |
michael@0 | 1658 | pd->pre[0].stride); |
michael@0 | 1659 | if (has_second_ref(mbmi)) |
michael@0 | 1660 | pd->pre[1].buf = raster_block_offset_uint8(BLOCK_8X8, i, pd->pre[1].buf, |
michael@0 | 1661 | pd->pre[1].stride); |
michael@0 | 1662 | } |
michael@0 | 1663 | |
michael@0 | 1664 | static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src, |
michael@0 | 1665 | struct buf_2d orig_pre[2]) { |
michael@0 | 1666 | MB_MODE_INFO *mbmi = &x->e_mbd.mi_8x8[0]->mbmi; |
michael@0 | 1667 | x->plane[0].src = orig_src; |
michael@0 | 1668 | x->e_mbd.plane[0].pre[0] = orig_pre[0]; |
michael@0 | 1669 | if (has_second_ref(mbmi)) |
michael@0 | 1670 | x->e_mbd.plane[0].pre[1] = orig_pre[1]; |
michael@0 | 1671 | } |
michael@0 | 1672 | |
michael@0 | 1673 | static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, |
michael@0 | 1674 | const TileInfo *const tile, |
michael@0 | 1675 | BEST_SEG_INFO *bsi_buf, int filter_idx, |
michael@0 | 1676 | int_mv seg_mvs[4][MAX_REF_FRAMES], |
michael@0 | 1677 | int mi_row, int mi_col) { |
michael@0 | 1678 | int i, br = 0, idx, idy; |
michael@0 | 1679 | int64_t bd = 0, block_sse = 0; |
michael@0 | 1680 | MB_PREDICTION_MODE this_mode; |
michael@0 | 1681 | MODE_INFO *mi = x->e_mbd.mi_8x8[0]; |
michael@0 | 1682 | MB_MODE_INFO *const mbmi = &mi->mbmi; |
michael@0 | 1683 | struct macroblockd_plane *const pd = &x->e_mbd.plane[0]; |
michael@0 | 1684 | const int label_count = 4; |
michael@0 | 1685 | int64_t this_segment_rd = 0; |
michael@0 | 1686 | int label_mv_thresh; |
michael@0 | 1687 | int segmentyrate = 0; |
michael@0 | 1688 | const BLOCK_SIZE bsize = mbmi->sb_type; |
michael@0 | 1689 | const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize]; |
michael@0 | 1690 | const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize]; |
michael@0 | 1691 | vp9_variance_fn_ptr_t *v_fn_ptr; |
michael@0 | 1692 | ENTROPY_CONTEXT t_above[2], t_left[2]; |
michael@0 | 1693 | BEST_SEG_INFO *bsi = bsi_buf + filter_idx; |
michael@0 | 1694 | int mode_idx; |
michael@0 | 1695 | int subpelmv = 1, have_ref = 0; |
michael@0 | 1696 | const int has_second_rf = has_second_ref(mbmi); |
michael@0 | 1697 | |
michael@0 | 1698 | vpx_memcpy(t_above, pd->above_context, sizeof(t_above)); |
michael@0 | 1699 | vpx_memcpy(t_left, pd->left_context, sizeof(t_left)); |
michael@0 | 1700 | |
michael@0 | 1701 | v_fn_ptr = &cpi->fn_ptr[bsize]; |
michael@0 | 1702 | |
michael@0 | 1703 | // 64 makes this threshold really big effectively |
michael@0 | 1704 | // making it so that we very rarely check mvs on |
michael@0 | 1705 | // segments. setting this to 1 would make mv thresh |
michael@0 | 1706 | // roughly equal to what it is for macroblocks |
michael@0 | 1707 | label_mv_thresh = 1 * bsi->mvthresh / label_count; |
michael@0 | 1708 | |
michael@0 | 1709 | // Segmentation method overheads |
michael@0 | 1710 | for (idy = 0; idy < 2; idy += num_4x4_blocks_high) { |
michael@0 | 1711 | for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) { |
michael@0 | 1712 | // TODO(jingning,rbultje): rewrite the rate-distortion optimization |
michael@0 | 1713 | // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop |
michael@0 | 1714 | int_mv mode_mv[MB_MODE_COUNT], second_mode_mv[MB_MODE_COUNT]; |
michael@0 | 1715 | int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES]; |
michael@0 | 1716 | MB_PREDICTION_MODE mode_selected = ZEROMV; |
michael@0 | 1717 | int64_t best_rd = INT64_MAX; |
michael@0 | 1718 | i = idy * 2 + idx; |
michael@0 | 1719 | |
michael@0 | 1720 | frame_mv[ZEROMV][mbmi->ref_frame[0]].as_int = 0; |
michael@0 | 1721 | vp9_append_sub8x8_mvs_for_idx(&cpi->common, &x->e_mbd, tile, |
michael@0 | 1722 | &frame_mv[NEARESTMV][mbmi->ref_frame[0]], |
michael@0 | 1723 | &frame_mv[NEARMV][mbmi->ref_frame[0]], |
michael@0 | 1724 | i, 0, mi_row, mi_col); |
michael@0 | 1725 | if (has_second_rf) { |
michael@0 | 1726 | frame_mv[ZEROMV][mbmi->ref_frame[1]].as_int = 0; |
michael@0 | 1727 | vp9_append_sub8x8_mvs_for_idx(&cpi->common, &x->e_mbd, tile, |
michael@0 | 1728 | &frame_mv[NEARESTMV][mbmi->ref_frame[1]], |
michael@0 | 1729 | &frame_mv[NEARMV][mbmi->ref_frame[1]], |
michael@0 | 1730 | i, 1, mi_row, mi_col); |
michael@0 | 1731 | } |
michael@0 | 1732 | // search for the best motion vector on this segment |
michael@0 | 1733 | for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) { |
michael@0 | 1734 | const struct buf_2d orig_src = x->plane[0].src; |
michael@0 | 1735 | struct buf_2d orig_pre[2]; |
michael@0 | 1736 | |
michael@0 | 1737 | mode_idx = INTER_OFFSET(this_mode); |
michael@0 | 1738 | bsi->rdstat[i][mode_idx].brdcost = INT64_MAX; |
michael@0 | 1739 | |
michael@0 | 1740 | // if we're near/nearest and mv == 0,0, compare to zeromv |
michael@0 | 1741 | if ((this_mode == NEARMV || this_mode == NEARESTMV || |
michael@0 | 1742 | this_mode == ZEROMV) && |
michael@0 | 1743 | frame_mv[this_mode][mbmi->ref_frame[0]].as_int == 0 && |
michael@0 | 1744 | (!has_second_rf || |
michael@0 | 1745 | frame_mv[this_mode][mbmi->ref_frame[1]].as_int == 0)) { |
michael@0 | 1746 | int rfc = mbmi->mode_context[mbmi->ref_frame[0]]; |
michael@0 | 1747 | int c1 = cost_mv_ref(cpi, NEARMV, rfc); |
michael@0 | 1748 | int c2 = cost_mv_ref(cpi, NEARESTMV, rfc); |
michael@0 | 1749 | int c3 = cost_mv_ref(cpi, ZEROMV, rfc); |
michael@0 | 1750 | |
michael@0 | 1751 | if (this_mode == NEARMV) { |
michael@0 | 1752 | if (c1 > c3) |
michael@0 | 1753 | continue; |
michael@0 | 1754 | } else if (this_mode == NEARESTMV) { |
michael@0 | 1755 | if (c2 > c3) |
michael@0 | 1756 | continue; |
michael@0 | 1757 | } else { |
michael@0 | 1758 | assert(this_mode == ZEROMV); |
michael@0 | 1759 | if (!has_second_rf) { |
michael@0 | 1760 | if ((c3 >= c2 && |
michael@0 | 1761 | frame_mv[NEARESTMV][mbmi->ref_frame[0]].as_int == 0) || |
michael@0 | 1762 | (c3 >= c1 && |
michael@0 | 1763 | frame_mv[NEARMV][mbmi->ref_frame[0]].as_int == 0)) |
michael@0 | 1764 | continue; |
michael@0 | 1765 | } else { |
michael@0 | 1766 | if ((c3 >= c2 && |
michael@0 | 1767 | frame_mv[NEARESTMV][mbmi->ref_frame[0]].as_int == 0 && |
michael@0 | 1768 | frame_mv[NEARESTMV][mbmi->ref_frame[1]].as_int == 0) || |
michael@0 | 1769 | (c3 >= c1 && |
michael@0 | 1770 | frame_mv[NEARMV][mbmi->ref_frame[0]].as_int == 0 && |
michael@0 | 1771 | frame_mv[NEARMV][mbmi->ref_frame[1]].as_int == 0)) |
michael@0 | 1772 | continue; |
michael@0 | 1773 | } |
michael@0 | 1774 | } |
michael@0 | 1775 | } |
michael@0 | 1776 | |
michael@0 | 1777 | vpx_memcpy(orig_pre, pd->pre, sizeof(orig_pre)); |
michael@0 | 1778 | vpx_memcpy(bsi->rdstat[i][mode_idx].ta, t_above, |
michael@0 | 1779 | sizeof(bsi->rdstat[i][mode_idx].ta)); |
michael@0 | 1780 | vpx_memcpy(bsi->rdstat[i][mode_idx].tl, t_left, |
michael@0 | 1781 | sizeof(bsi->rdstat[i][mode_idx].tl)); |
michael@0 | 1782 | |
michael@0 | 1783 | // motion search for newmv (single predictor case only) |
michael@0 | 1784 | if (!has_second_rf && this_mode == NEWMV && |
michael@0 | 1785 | seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV) { |
michael@0 | 1786 | int step_param = 0; |
michael@0 | 1787 | int further_steps; |
michael@0 | 1788 | int thissme, bestsme = INT_MAX; |
michael@0 | 1789 | int sadpb = x->sadperbit4; |
michael@0 | 1790 | int_mv mvp_full; |
michael@0 | 1791 | int max_mv; |
michael@0 | 1792 | |
michael@0 | 1793 | /* Is the best so far sufficiently good that we cant justify doing |
michael@0 | 1794 | * and new motion search. */ |
michael@0 | 1795 | if (best_rd < label_mv_thresh) |
michael@0 | 1796 | break; |
michael@0 | 1797 | |
michael@0 | 1798 | if (cpi->compressor_speed) { |
michael@0 | 1799 | // use previous block's result as next block's MV predictor. |
michael@0 | 1800 | if (i > 0) { |
michael@0 | 1801 | bsi->mvp.as_int = mi->bmi[i - 1].as_mv[0].as_int; |
michael@0 | 1802 | if (i == 2) |
michael@0 | 1803 | bsi->mvp.as_int = mi->bmi[i - 2].as_mv[0].as_int; |
michael@0 | 1804 | } |
michael@0 | 1805 | } |
michael@0 | 1806 | if (i == 0) |
michael@0 | 1807 | max_mv = x->max_mv_context[mbmi->ref_frame[0]]; |
michael@0 | 1808 | else |
michael@0 | 1809 | max_mv = MAX(abs(bsi->mvp.as_mv.row), abs(bsi->mvp.as_mv.col)) >> 3; |
michael@0 | 1810 | |
michael@0 | 1811 | if (cpi->sf.auto_mv_step_size && cpi->common.show_frame) { |
michael@0 | 1812 | // Take wtd average of the step_params based on the last frame's |
michael@0 | 1813 | // max mv magnitude and the best ref mvs of the current block for |
michael@0 | 1814 | // the given reference. |
michael@0 | 1815 | step_param = (vp9_init_search_range(cpi, max_mv) + |
michael@0 | 1816 | cpi->mv_step_param) >> 1; |
michael@0 | 1817 | } else { |
michael@0 | 1818 | step_param = cpi->mv_step_param; |
michael@0 | 1819 | } |
michael@0 | 1820 | |
michael@0 | 1821 | mvp_full.as_mv.row = bsi->mvp.as_mv.row >> 3; |
michael@0 | 1822 | mvp_full.as_mv.col = bsi->mvp.as_mv.col >> 3; |
michael@0 | 1823 | |
michael@0 | 1824 | if (cpi->sf.adaptive_motion_search && cpi->common.show_frame) { |
michael@0 | 1825 | mvp_full.as_mv.row = x->pred_mv[mbmi->ref_frame[0]].as_mv.row >> 3; |
michael@0 | 1826 | mvp_full.as_mv.col = x->pred_mv[mbmi->ref_frame[0]].as_mv.col >> 3; |
michael@0 | 1827 | step_param = MAX(step_param, 8); |
michael@0 | 1828 | } |
michael@0 | 1829 | |
michael@0 | 1830 | further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param; |
michael@0 | 1831 | // adjust src pointer for this block |
michael@0 | 1832 | mi_buf_shift(x, i); |
michael@0 | 1833 | if (cpi->sf.search_method == HEX) { |
michael@0 | 1834 | bestsme = vp9_hex_search(x, &mvp_full.as_mv, |
michael@0 | 1835 | step_param, |
michael@0 | 1836 | sadpb, 1, v_fn_ptr, 1, |
michael@0 | 1837 | &bsi->ref_mv->as_mv, |
michael@0 | 1838 | &mode_mv[NEWMV].as_mv); |
michael@0 | 1839 | } else if (cpi->sf.search_method == SQUARE) { |
michael@0 | 1840 | bestsme = vp9_square_search(x, &mvp_full.as_mv, |
michael@0 | 1841 | step_param, |
michael@0 | 1842 | sadpb, 1, v_fn_ptr, 1, |
michael@0 | 1843 | &bsi->ref_mv->as_mv, |
michael@0 | 1844 | &mode_mv[NEWMV].as_mv); |
michael@0 | 1845 | } else if (cpi->sf.search_method == BIGDIA) { |
michael@0 | 1846 | bestsme = vp9_bigdia_search(x, &mvp_full.as_mv, |
michael@0 | 1847 | step_param, |
michael@0 | 1848 | sadpb, 1, v_fn_ptr, 1, |
michael@0 | 1849 | &bsi->ref_mv->as_mv, |
michael@0 | 1850 | &mode_mv[NEWMV].as_mv); |
michael@0 | 1851 | } else { |
michael@0 | 1852 | bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param, |
michael@0 | 1853 | sadpb, further_steps, 0, v_fn_ptr, |
michael@0 | 1854 | bsi->ref_mv, &mode_mv[NEWMV]); |
michael@0 | 1855 | } |
michael@0 | 1856 | |
michael@0 | 1857 | // Should we do a full search (best quality only) |
michael@0 | 1858 | if (cpi->compressor_speed == 0) { |
michael@0 | 1859 | /* Check if mvp_full is within the range. */ |
michael@0 | 1860 | clamp_mv(&mvp_full.as_mv, x->mv_col_min, x->mv_col_max, |
michael@0 | 1861 | x->mv_row_min, x->mv_row_max); |
michael@0 | 1862 | |
michael@0 | 1863 | thissme = cpi->full_search_sad(x, &mvp_full, |
michael@0 | 1864 | sadpb, 16, v_fn_ptr, |
michael@0 | 1865 | x->nmvjointcost, x->mvcost, |
michael@0 | 1866 | bsi->ref_mv, i); |
michael@0 | 1867 | |
michael@0 | 1868 | if (thissme < bestsme) { |
michael@0 | 1869 | bestsme = thissme; |
michael@0 | 1870 | mode_mv[NEWMV].as_int = mi->bmi[i].as_mv[0].as_int; |
michael@0 | 1871 | } else { |
michael@0 | 1872 | /* The full search result is actually worse so re-instate the |
michael@0 | 1873 | * previous best vector */ |
michael@0 | 1874 | mi->bmi[i].as_mv[0].as_int = mode_mv[NEWMV].as_int; |
michael@0 | 1875 | } |
michael@0 | 1876 | } |
michael@0 | 1877 | |
michael@0 | 1878 | if (bestsme < INT_MAX) { |
michael@0 | 1879 | int distortion; |
michael@0 | 1880 | unsigned int sse; |
michael@0 | 1881 | cpi->find_fractional_mv_step(x, |
michael@0 | 1882 | &mode_mv[NEWMV].as_mv, |
michael@0 | 1883 | &bsi->ref_mv->as_mv, |
michael@0 | 1884 | cpi->common.allow_high_precision_mv, |
michael@0 | 1885 | x->errorperbit, v_fn_ptr, |
michael@0 | 1886 | 0, cpi->sf.subpel_iters_per_step, |
michael@0 | 1887 | x->nmvjointcost, x->mvcost, |
michael@0 | 1888 | &distortion, &sse); |
michael@0 | 1889 | |
michael@0 | 1890 | // save motion search result for use in compound prediction |
michael@0 | 1891 | seg_mvs[i][mbmi->ref_frame[0]].as_int = mode_mv[NEWMV].as_int; |
michael@0 | 1892 | } |
michael@0 | 1893 | |
michael@0 | 1894 | if (cpi->sf.adaptive_motion_search) |
michael@0 | 1895 | x->pred_mv[mbmi->ref_frame[0]].as_int = mode_mv[NEWMV].as_int; |
michael@0 | 1896 | |
michael@0 | 1897 | // restore src pointers |
michael@0 | 1898 | mi_buf_restore(x, orig_src, orig_pre); |
michael@0 | 1899 | } |
michael@0 | 1900 | |
michael@0 | 1901 | if (has_second_rf) { |
michael@0 | 1902 | if (seg_mvs[i][mbmi->ref_frame[1]].as_int == INVALID_MV || |
michael@0 | 1903 | seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV) |
michael@0 | 1904 | continue; |
michael@0 | 1905 | } |
michael@0 | 1906 | |
michael@0 | 1907 | if (has_second_rf && this_mode == NEWMV && |
michael@0 | 1908 | mbmi->interp_filter == EIGHTTAP) { |
michael@0 | 1909 | // adjust src pointers |
michael@0 | 1910 | mi_buf_shift(x, i); |
michael@0 | 1911 | if (cpi->sf.comp_inter_joint_search_thresh <= bsize) { |
michael@0 | 1912 | int rate_mv; |
michael@0 | 1913 | joint_motion_search(cpi, x, bsize, frame_mv[this_mode], |
michael@0 | 1914 | mi_row, mi_col, seg_mvs[i], |
michael@0 | 1915 | &rate_mv); |
michael@0 | 1916 | seg_mvs[i][mbmi->ref_frame[0]].as_int = |
michael@0 | 1917 | frame_mv[this_mode][mbmi->ref_frame[0]].as_int; |
michael@0 | 1918 | seg_mvs[i][mbmi->ref_frame[1]].as_int = |
michael@0 | 1919 | frame_mv[this_mode][mbmi->ref_frame[1]].as_int; |
michael@0 | 1920 | } |
michael@0 | 1921 | // restore src pointers |
michael@0 | 1922 | mi_buf_restore(x, orig_src, orig_pre); |
michael@0 | 1923 | } |
michael@0 | 1924 | |
michael@0 | 1925 | bsi->rdstat[i][mode_idx].brate = |
michael@0 | 1926 | labels2mode(x, i, this_mode, &mode_mv[this_mode], |
michael@0 | 1927 | &second_mode_mv[this_mode], frame_mv, seg_mvs[i], |
michael@0 | 1928 | bsi->ref_mv, bsi->second_ref_mv, x->nmvjointcost, |
michael@0 | 1929 | x->mvcost, cpi); |
michael@0 | 1930 | |
michael@0 | 1931 | |
michael@0 | 1932 | bsi->rdstat[i][mode_idx].mvs[0].as_int = mode_mv[this_mode].as_int; |
michael@0 | 1933 | if (num_4x4_blocks_wide > 1) |
michael@0 | 1934 | bsi->rdstat[i + 1][mode_idx].mvs[0].as_int = |
michael@0 | 1935 | mode_mv[this_mode].as_int; |
michael@0 | 1936 | if (num_4x4_blocks_high > 1) |
michael@0 | 1937 | bsi->rdstat[i + 2][mode_idx].mvs[0].as_int = |
michael@0 | 1938 | mode_mv[this_mode].as_int; |
michael@0 | 1939 | if (has_second_rf) { |
michael@0 | 1940 | bsi->rdstat[i][mode_idx].mvs[1].as_int = |
michael@0 | 1941 | second_mode_mv[this_mode].as_int; |
michael@0 | 1942 | if (num_4x4_blocks_wide > 1) |
michael@0 | 1943 | bsi->rdstat[i + 1][mode_idx].mvs[1].as_int = |
michael@0 | 1944 | second_mode_mv[this_mode].as_int; |
michael@0 | 1945 | if (num_4x4_blocks_high > 1) |
michael@0 | 1946 | bsi->rdstat[i + 2][mode_idx].mvs[1].as_int = |
michael@0 | 1947 | second_mode_mv[this_mode].as_int; |
michael@0 | 1948 | } |
michael@0 | 1949 | |
michael@0 | 1950 | // Trap vectors that reach beyond the UMV borders |
michael@0 | 1951 | if (mv_check_bounds(x, &mode_mv[this_mode])) |
michael@0 | 1952 | continue; |
michael@0 | 1953 | if (has_second_rf && |
michael@0 | 1954 | mv_check_bounds(x, &second_mode_mv[this_mode])) |
michael@0 | 1955 | continue; |
michael@0 | 1956 | |
michael@0 | 1957 | if (filter_idx > 0) { |
michael@0 | 1958 | BEST_SEG_INFO *ref_bsi = bsi_buf; |
michael@0 | 1959 | subpelmv = (mode_mv[this_mode].as_mv.row & 0x0f) || |
michael@0 | 1960 | (mode_mv[this_mode].as_mv.col & 0x0f); |
michael@0 | 1961 | have_ref = mode_mv[this_mode].as_int == |
michael@0 | 1962 | ref_bsi->rdstat[i][mode_idx].mvs[0].as_int; |
michael@0 | 1963 | if (has_second_rf) { |
michael@0 | 1964 | subpelmv |= (second_mode_mv[this_mode].as_mv.row & 0x0f) || |
michael@0 | 1965 | (second_mode_mv[this_mode].as_mv.col & 0x0f); |
michael@0 | 1966 | have_ref &= second_mode_mv[this_mode].as_int == |
michael@0 | 1967 | ref_bsi->rdstat[i][mode_idx].mvs[1].as_int; |
michael@0 | 1968 | } |
michael@0 | 1969 | |
michael@0 | 1970 | if (filter_idx > 1 && !subpelmv && !have_ref) { |
michael@0 | 1971 | ref_bsi = bsi_buf + 1; |
michael@0 | 1972 | have_ref = mode_mv[this_mode].as_int == |
michael@0 | 1973 | ref_bsi->rdstat[i][mode_idx].mvs[0].as_int; |
michael@0 | 1974 | if (has_second_rf) { |
michael@0 | 1975 | have_ref &= second_mode_mv[this_mode].as_int == |
michael@0 | 1976 | ref_bsi->rdstat[i][mode_idx].mvs[1].as_int; |
michael@0 | 1977 | } |
michael@0 | 1978 | } |
michael@0 | 1979 | |
michael@0 | 1980 | if (!subpelmv && have_ref && |
michael@0 | 1981 | ref_bsi->rdstat[i][mode_idx].brdcost < INT64_MAX) { |
michael@0 | 1982 | vpx_memcpy(&bsi->rdstat[i][mode_idx], &ref_bsi->rdstat[i][mode_idx], |
michael@0 | 1983 | sizeof(SEG_RDSTAT)); |
michael@0 | 1984 | if (num_4x4_blocks_wide > 1) |
michael@0 | 1985 | bsi->rdstat[i + 1][mode_idx].eobs = |
michael@0 | 1986 | ref_bsi->rdstat[i + 1][mode_idx].eobs; |
michael@0 | 1987 | if (num_4x4_blocks_high > 1) |
michael@0 | 1988 | bsi->rdstat[i + 2][mode_idx].eobs = |
michael@0 | 1989 | ref_bsi->rdstat[i + 2][mode_idx].eobs; |
michael@0 | 1990 | |
michael@0 | 1991 | if (bsi->rdstat[i][mode_idx].brdcost < best_rd) { |
michael@0 | 1992 | mode_selected = this_mode; |
michael@0 | 1993 | best_rd = bsi->rdstat[i][mode_idx].brdcost; |
michael@0 | 1994 | } |
michael@0 | 1995 | continue; |
michael@0 | 1996 | } |
michael@0 | 1997 | } |
michael@0 | 1998 | |
michael@0 | 1999 | bsi->rdstat[i][mode_idx].brdcost = |
michael@0 | 2000 | encode_inter_mb_segment(cpi, x, |
michael@0 | 2001 | bsi->segment_rd - this_segment_rd, i, |
michael@0 | 2002 | &bsi->rdstat[i][mode_idx].byrate, |
michael@0 | 2003 | &bsi->rdstat[i][mode_idx].bdist, |
michael@0 | 2004 | &bsi->rdstat[i][mode_idx].bsse, |
michael@0 | 2005 | bsi->rdstat[i][mode_idx].ta, |
michael@0 | 2006 | bsi->rdstat[i][mode_idx].tl); |
michael@0 | 2007 | if (bsi->rdstat[i][mode_idx].brdcost < INT64_MAX) { |
michael@0 | 2008 | bsi->rdstat[i][mode_idx].brdcost += RDCOST(x->rdmult, x->rddiv, |
michael@0 | 2009 | bsi->rdstat[i][mode_idx].brate, 0); |
michael@0 | 2010 | bsi->rdstat[i][mode_idx].brate += bsi->rdstat[i][mode_idx].byrate; |
michael@0 | 2011 | bsi->rdstat[i][mode_idx].eobs = pd->eobs[i]; |
michael@0 | 2012 | if (num_4x4_blocks_wide > 1) |
michael@0 | 2013 | bsi->rdstat[i + 1][mode_idx].eobs = pd->eobs[i + 1]; |
michael@0 | 2014 | if (num_4x4_blocks_high > 1) |
michael@0 | 2015 | bsi->rdstat[i + 2][mode_idx].eobs = pd->eobs[i + 2]; |
michael@0 | 2016 | } |
michael@0 | 2017 | |
michael@0 | 2018 | if (bsi->rdstat[i][mode_idx].brdcost < best_rd) { |
michael@0 | 2019 | mode_selected = this_mode; |
michael@0 | 2020 | best_rd = bsi->rdstat[i][mode_idx].brdcost; |
michael@0 | 2021 | } |
michael@0 | 2022 | } /*for each 4x4 mode*/ |
michael@0 | 2023 | |
michael@0 | 2024 | if (best_rd == INT64_MAX) { |
michael@0 | 2025 | int iy, midx; |
michael@0 | 2026 | for (iy = i + 1; iy < 4; ++iy) |
michael@0 | 2027 | for (midx = 0; midx < INTER_MODES; ++midx) |
michael@0 | 2028 | bsi->rdstat[iy][midx].brdcost = INT64_MAX; |
michael@0 | 2029 | bsi->segment_rd = INT64_MAX; |
michael@0 | 2030 | return; |
michael@0 | 2031 | } |
michael@0 | 2032 | |
michael@0 | 2033 | mode_idx = INTER_OFFSET(mode_selected); |
michael@0 | 2034 | vpx_memcpy(t_above, bsi->rdstat[i][mode_idx].ta, sizeof(t_above)); |
michael@0 | 2035 | vpx_memcpy(t_left, bsi->rdstat[i][mode_idx].tl, sizeof(t_left)); |
michael@0 | 2036 | |
michael@0 | 2037 | labels2mode(x, i, mode_selected, &mode_mv[mode_selected], |
michael@0 | 2038 | &second_mode_mv[mode_selected], frame_mv, seg_mvs[i], |
michael@0 | 2039 | bsi->ref_mv, bsi->second_ref_mv, x->nmvjointcost, |
michael@0 | 2040 | x->mvcost, cpi); |
michael@0 | 2041 | |
michael@0 | 2042 | br += bsi->rdstat[i][mode_idx].brate; |
michael@0 | 2043 | bd += bsi->rdstat[i][mode_idx].bdist; |
michael@0 | 2044 | block_sse += bsi->rdstat[i][mode_idx].bsse; |
michael@0 | 2045 | segmentyrate += bsi->rdstat[i][mode_idx].byrate; |
michael@0 | 2046 | this_segment_rd += bsi->rdstat[i][mode_idx].brdcost; |
michael@0 | 2047 | |
michael@0 | 2048 | if (this_segment_rd > bsi->segment_rd) { |
michael@0 | 2049 | int iy, midx; |
michael@0 | 2050 | for (iy = i + 1; iy < 4; ++iy) |
michael@0 | 2051 | for (midx = 0; midx < INTER_MODES; ++midx) |
michael@0 | 2052 | bsi->rdstat[iy][midx].brdcost = INT64_MAX; |
michael@0 | 2053 | bsi->segment_rd = INT64_MAX; |
michael@0 | 2054 | return; |
michael@0 | 2055 | } |
michael@0 | 2056 | } |
michael@0 | 2057 | } /* for each label */ |
michael@0 | 2058 | |
michael@0 | 2059 | bsi->r = br; |
michael@0 | 2060 | bsi->d = bd; |
michael@0 | 2061 | bsi->segment_yrate = segmentyrate; |
michael@0 | 2062 | bsi->segment_rd = this_segment_rd; |
michael@0 | 2063 | bsi->sse = block_sse; |
michael@0 | 2064 | |
michael@0 | 2065 | // update the coding decisions |
michael@0 | 2066 | for (i = 0; i < 4; ++i) |
michael@0 | 2067 | bsi->modes[i] = mi->bmi[i].as_mode; |
michael@0 | 2068 | } |
michael@0 | 2069 | |
michael@0 | 2070 | static int64_t rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x, |
michael@0 | 2071 | const TileInfo *const tile, |
michael@0 | 2072 | int_mv *best_ref_mv, |
michael@0 | 2073 | int_mv *second_best_ref_mv, |
michael@0 | 2074 | int64_t best_rd, |
michael@0 | 2075 | int *returntotrate, |
michael@0 | 2076 | int *returnyrate, |
michael@0 | 2077 | int64_t *returndistortion, |
michael@0 | 2078 | int *skippable, int64_t *psse, |
michael@0 | 2079 | int mvthresh, |
michael@0 | 2080 | int_mv seg_mvs[4][MAX_REF_FRAMES], |
michael@0 | 2081 | BEST_SEG_INFO *bsi_buf, |
michael@0 | 2082 | int filter_idx, |
michael@0 | 2083 | int mi_row, int mi_col) { |
michael@0 | 2084 | int i; |
michael@0 | 2085 | BEST_SEG_INFO *bsi = bsi_buf + filter_idx; |
michael@0 | 2086 | MACROBLOCKD *xd = &x->e_mbd; |
michael@0 | 2087 | MODE_INFO *mi = xd->mi_8x8[0]; |
michael@0 | 2088 | MB_MODE_INFO *mbmi = &mi->mbmi; |
michael@0 | 2089 | int mode_idx; |
michael@0 | 2090 | |
michael@0 | 2091 | vp9_zero(*bsi); |
michael@0 | 2092 | |
michael@0 | 2093 | bsi->segment_rd = best_rd; |
michael@0 | 2094 | bsi->ref_mv = best_ref_mv; |
michael@0 | 2095 | bsi->second_ref_mv = second_best_ref_mv; |
michael@0 | 2096 | bsi->mvp.as_int = best_ref_mv->as_int; |
michael@0 | 2097 | bsi->mvthresh = mvthresh; |
michael@0 | 2098 | |
michael@0 | 2099 | for (i = 0; i < 4; i++) |
michael@0 | 2100 | bsi->modes[i] = ZEROMV; |
michael@0 | 2101 | |
michael@0 | 2102 | rd_check_segment_txsize(cpi, x, tile, bsi_buf, filter_idx, seg_mvs, |
michael@0 | 2103 | mi_row, mi_col); |
michael@0 | 2104 | |
michael@0 | 2105 | if (bsi->segment_rd > best_rd) |
michael@0 | 2106 | return INT64_MAX; |
michael@0 | 2107 | /* set it to the best */ |
michael@0 | 2108 | for (i = 0; i < 4; i++) { |
michael@0 | 2109 | mode_idx = INTER_OFFSET(bsi->modes[i]); |
michael@0 | 2110 | mi->bmi[i].as_mv[0].as_int = bsi->rdstat[i][mode_idx].mvs[0].as_int; |
michael@0 | 2111 | if (has_second_ref(mbmi)) |
michael@0 | 2112 | mi->bmi[i].as_mv[1].as_int = bsi->rdstat[i][mode_idx].mvs[1].as_int; |
michael@0 | 2113 | xd->plane[0].eobs[i] = bsi->rdstat[i][mode_idx].eobs; |
michael@0 | 2114 | mi->bmi[i].as_mode = bsi->modes[i]; |
michael@0 | 2115 | } |
michael@0 | 2116 | |
michael@0 | 2117 | /* |
michael@0 | 2118 | * used to set mbmi->mv.as_int |
michael@0 | 2119 | */ |
michael@0 | 2120 | *returntotrate = bsi->r; |
michael@0 | 2121 | *returndistortion = bsi->d; |
michael@0 | 2122 | *returnyrate = bsi->segment_yrate; |
michael@0 | 2123 | *skippable = vp9_is_skippable_in_plane(&x->e_mbd, BLOCK_8X8, 0); |
michael@0 | 2124 | *psse = bsi->sse; |
michael@0 | 2125 | mbmi->mode = bsi->modes[3]; |
michael@0 | 2126 | |
michael@0 | 2127 | return bsi->segment_rd; |
michael@0 | 2128 | } |
michael@0 | 2129 | |
michael@0 | 2130 | static void mv_pred(VP9_COMP *cpi, MACROBLOCK *x, |
michael@0 | 2131 | uint8_t *ref_y_buffer, int ref_y_stride, |
michael@0 | 2132 | int ref_frame, BLOCK_SIZE block_size ) { |
michael@0 | 2133 | MACROBLOCKD *xd = &x->e_mbd; |
michael@0 | 2134 | MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; |
michael@0 | 2135 | int_mv this_mv; |
michael@0 | 2136 | int i; |
michael@0 | 2137 | int zero_seen = 0; |
michael@0 | 2138 | int best_index = 0; |
michael@0 | 2139 | int best_sad = INT_MAX; |
michael@0 | 2140 | int this_sad = INT_MAX; |
michael@0 | 2141 | unsigned int max_mv = 0; |
michael@0 | 2142 | |
michael@0 | 2143 | uint8_t *src_y_ptr = x->plane[0].src.buf; |
michael@0 | 2144 | uint8_t *ref_y_ptr; |
michael@0 | 2145 | int row_offset, col_offset; |
michael@0 | 2146 | int num_mv_refs = MAX_MV_REF_CANDIDATES + |
michael@0 | 2147 | (cpi->sf.adaptive_motion_search && |
michael@0 | 2148 | cpi->common.show_frame && |
michael@0 | 2149 | block_size < cpi->sf.max_partition_size); |
michael@0 | 2150 | |
michael@0 | 2151 | // Get the sad for each candidate reference mv |
michael@0 | 2152 | for (i = 0; i < num_mv_refs; i++) { |
michael@0 | 2153 | this_mv.as_int = (i < MAX_MV_REF_CANDIDATES) ? |
michael@0 | 2154 | mbmi->ref_mvs[ref_frame][i].as_int : x->pred_mv[ref_frame].as_int; |
michael@0 | 2155 | |
michael@0 | 2156 | max_mv = MAX(max_mv, |
michael@0 | 2157 | MAX(abs(this_mv.as_mv.row), abs(this_mv.as_mv.col)) >> 3); |
michael@0 | 2158 | // The list is at an end if we see 0 for a second time. |
michael@0 | 2159 | if (!this_mv.as_int && zero_seen) |
michael@0 | 2160 | break; |
michael@0 | 2161 | zero_seen = zero_seen || !this_mv.as_int; |
michael@0 | 2162 | |
michael@0 | 2163 | row_offset = this_mv.as_mv.row >> 3; |
michael@0 | 2164 | col_offset = this_mv.as_mv.col >> 3; |
michael@0 | 2165 | ref_y_ptr = ref_y_buffer + (ref_y_stride * row_offset) + col_offset; |
michael@0 | 2166 | |
michael@0 | 2167 | // Find sad for current vector. |
michael@0 | 2168 | this_sad = cpi->fn_ptr[block_size].sdf(src_y_ptr, x->plane[0].src.stride, |
michael@0 | 2169 | ref_y_ptr, ref_y_stride, |
michael@0 | 2170 | 0x7fffffff); |
michael@0 | 2171 | |
michael@0 | 2172 | // Note if it is the best so far. |
michael@0 | 2173 | if (this_sad < best_sad) { |
michael@0 | 2174 | best_sad = this_sad; |
michael@0 | 2175 | best_index = i; |
michael@0 | 2176 | } |
michael@0 | 2177 | } |
michael@0 | 2178 | |
michael@0 | 2179 | // Note the index of the mv that worked best in the reference list. |
michael@0 | 2180 | x->mv_best_ref_index[ref_frame] = best_index; |
michael@0 | 2181 | x->max_mv_context[ref_frame] = max_mv; |
michael@0 | 2182 | } |
michael@0 | 2183 | |
michael@0 | 2184 | static void estimate_ref_frame_costs(VP9_COMP *cpi, int segment_id, |
michael@0 | 2185 | unsigned int *ref_costs_single, |
michael@0 | 2186 | unsigned int *ref_costs_comp, |
michael@0 | 2187 | vp9_prob *comp_mode_p) { |
michael@0 | 2188 | VP9_COMMON *const cm = &cpi->common; |
michael@0 | 2189 | MACROBLOCKD *const xd = &cpi->mb.e_mbd; |
michael@0 | 2190 | int seg_ref_active = vp9_segfeature_active(&cm->seg, segment_id, |
michael@0 | 2191 | SEG_LVL_REF_FRAME); |
michael@0 | 2192 | if (seg_ref_active) { |
michael@0 | 2193 | vpx_memset(ref_costs_single, 0, MAX_REF_FRAMES * sizeof(*ref_costs_single)); |
michael@0 | 2194 | vpx_memset(ref_costs_comp, 0, MAX_REF_FRAMES * sizeof(*ref_costs_comp)); |
michael@0 | 2195 | *comp_mode_p = 128; |
michael@0 | 2196 | } else { |
michael@0 | 2197 | vp9_prob intra_inter_p = vp9_get_pred_prob_intra_inter(cm, xd); |
michael@0 | 2198 | vp9_prob comp_inter_p = 128; |
michael@0 | 2199 | |
michael@0 | 2200 | if (cm->comp_pred_mode == HYBRID_PREDICTION) { |
michael@0 | 2201 | comp_inter_p = vp9_get_pred_prob_comp_inter_inter(cm, xd); |
michael@0 | 2202 | *comp_mode_p = comp_inter_p; |
michael@0 | 2203 | } else { |
michael@0 | 2204 | *comp_mode_p = 128; |
michael@0 | 2205 | } |
michael@0 | 2206 | |
michael@0 | 2207 | ref_costs_single[INTRA_FRAME] = vp9_cost_bit(intra_inter_p, 0); |
michael@0 | 2208 | |
michael@0 | 2209 | if (cm->comp_pred_mode != COMP_PREDICTION_ONLY) { |
michael@0 | 2210 | vp9_prob ref_single_p1 = vp9_get_pred_prob_single_ref_p1(cm, xd); |
michael@0 | 2211 | vp9_prob ref_single_p2 = vp9_get_pred_prob_single_ref_p2(cm, xd); |
michael@0 | 2212 | unsigned int base_cost = vp9_cost_bit(intra_inter_p, 1); |
michael@0 | 2213 | |
michael@0 | 2214 | if (cm->comp_pred_mode == HYBRID_PREDICTION) |
michael@0 | 2215 | base_cost += vp9_cost_bit(comp_inter_p, 0); |
michael@0 | 2216 | |
michael@0 | 2217 | ref_costs_single[LAST_FRAME] = ref_costs_single[GOLDEN_FRAME] = |
michael@0 | 2218 | ref_costs_single[ALTREF_FRAME] = base_cost; |
michael@0 | 2219 | ref_costs_single[LAST_FRAME] += vp9_cost_bit(ref_single_p1, 0); |
michael@0 | 2220 | ref_costs_single[GOLDEN_FRAME] += vp9_cost_bit(ref_single_p1, 1); |
michael@0 | 2221 | ref_costs_single[ALTREF_FRAME] += vp9_cost_bit(ref_single_p1, 1); |
michael@0 | 2222 | ref_costs_single[GOLDEN_FRAME] += vp9_cost_bit(ref_single_p2, 0); |
michael@0 | 2223 | ref_costs_single[ALTREF_FRAME] += vp9_cost_bit(ref_single_p2, 1); |
michael@0 | 2224 | } else { |
michael@0 | 2225 | ref_costs_single[LAST_FRAME] = 512; |
michael@0 | 2226 | ref_costs_single[GOLDEN_FRAME] = 512; |
michael@0 | 2227 | ref_costs_single[ALTREF_FRAME] = 512; |
michael@0 | 2228 | } |
michael@0 | 2229 | if (cm->comp_pred_mode != SINGLE_PREDICTION_ONLY) { |
michael@0 | 2230 | vp9_prob ref_comp_p = vp9_get_pred_prob_comp_ref_p(cm, xd); |
michael@0 | 2231 | unsigned int base_cost = vp9_cost_bit(intra_inter_p, 1); |
michael@0 | 2232 | |
michael@0 | 2233 | if (cm->comp_pred_mode == HYBRID_PREDICTION) |
michael@0 | 2234 | base_cost += vp9_cost_bit(comp_inter_p, 1); |
michael@0 | 2235 | |
michael@0 | 2236 | ref_costs_comp[LAST_FRAME] = base_cost + vp9_cost_bit(ref_comp_p, 0); |
michael@0 | 2237 | ref_costs_comp[GOLDEN_FRAME] = base_cost + vp9_cost_bit(ref_comp_p, 1); |
michael@0 | 2238 | } else { |
michael@0 | 2239 | ref_costs_comp[LAST_FRAME] = 512; |
michael@0 | 2240 | ref_costs_comp[GOLDEN_FRAME] = 512; |
michael@0 | 2241 | } |
michael@0 | 2242 | } |
michael@0 | 2243 | } |
michael@0 | 2244 | |
michael@0 | 2245 | static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx, |
michael@0 | 2246 | int mode_index, |
michael@0 | 2247 | int_mv *ref_mv, |
michael@0 | 2248 | int_mv *second_ref_mv, |
michael@0 | 2249 | int64_t comp_pred_diff[NB_PREDICTION_TYPES], |
michael@0 | 2250 | int64_t tx_size_diff[TX_MODES], |
michael@0 | 2251 | int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS]) { |
michael@0 | 2252 | MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 2253 | |
michael@0 | 2254 | // Take a snapshot of the coding context so it can be |
michael@0 | 2255 | // restored if we decide to encode this way |
michael@0 | 2256 | ctx->skip = x->skip; |
michael@0 | 2257 | ctx->best_mode_index = mode_index; |
michael@0 | 2258 | ctx->mic = *xd->mi_8x8[0]; |
michael@0 | 2259 | |
michael@0 | 2260 | ctx->best_ref_mv.as_int = ref_mv->as_int; |
michael@0 | 2261 | ctx->second_best_ref_mv.as_int = second_ref_mv->as_int; |
michael@0 | 2262 | |
michael@0 | 2263 | ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_PREDICTION_ONLY]; |
michael@0 | 2264 | ctx->comp_pred_diff = (int)comp_pred_diff[COMP_PREDICTION_ONLY]; |
michael@0 | 2265 | ctx->hybrid_pred_diff = (int)comp_pred_diff[HYBRID_PREDICTION]; |
michael@0 | 2266 | |
michael@0 | 2267 | vpx_memcpy(ctx->tx_rd_diff, tx_size_diff, sizeof(ctx->tx_rd_diff)); |
michael@0 | 2268 | vpx_memcpy(ctx->best_filter_diff, best_filter_diff, |
michael@0 | 2269 | sizeof(*best_filter_diff) * SWITCHABLE_FILTER_CONTEXTS); |
michael@0 | 2270 | } |
michael@0 | 2271 | |
michael@0 | 2272 | static void setup_pred_block(const MACROBLOCKD *xd, |
michael@0 | 2273 | struct buf_2d dst[MAX_MB_PLANE], |
michael@0 | 2274 | const YV12_BUFFER_CONFIG *src, |
michael@0 | 2275 | int mi_row, int mi_col, |
michael@0 | 2276 | const struct scale_factors *scale, |
michael@0 | 2277 | const struct scale_factors *scale_uv) { |
michael@0 | 2278 | int i; |
michael@0 | 2279 | |
michael@0 | 2280 | dst[0].buf = src->y_buffer; |
michael@0 | 2281 | dst[0].stride = src->y_stride; |
michael@0 | 2282 | dst[1].buf = src->u_buffer; |
michael@0 | 2283 | dst[2].buf = src->v_buffer; |
michael@0 | 2284 | dst[1].stride = dst[2].stride = src->uv_stride; |
michael@0 | 2285 | #if CONFIG_ALPHA |
michael@0 | 2286 | dst[3].buf = src->alpha_buffer; |
michael@0 | 2287 | dst[3].stride = src->alpha_stride; |
michael@0 | 2288 | #endif |
michael@0 | 2289 | |
michael@0 | 2290 | // TODO(jkoleszar): Make scale factors per-plane data |
michael@0 | 2291 | for (i = 0; i < MAX_MB_PLANE; i++) { |
michael@0 | 2292 | setup_pred_plane(dst + i, dst[i].buf, dst[i].stride, mi_row, mi_col, |
michael@0 | 2293 | i ? scale_uv : scale, |
michael@0 | 2294 | xd->plane[i].subsampling_x, xd->plane[i].subsampling_y); |
michael@0 | 2295 | } |
michael@0 | 2296 | } |
michael@0 | 2297 | |
michael@0 | 2298 | static void setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x, |
michael@0 | 2299 | const TileInfo *const tile, |
michael@0 | 2300 | int idx, MV_REFERENCE_FRAME frame_type, |
michael@0 | 2301 | BLOCK_SIZE block_size, |
michael@0 | 2302 | int mi_row, int mi_col, |
michael@0 | 2303 | int_mv frame_nearest_mv[MAX_REF_FRAMES], |
michael@0 | 2304 | int_mv frame_near_mv[MAX_REF_FRAMES], |
michael@0 | 2305 | struct buf_2d yv12_mb[4][MAX_MB_PLANE], |
michael@0 | 2306 | struct scale_factors scale[MAX_REF_FRAMES]) { |
michael@0 | 2307 | VP9_COMMON *cm = &cpi->common; |
michael@0 | 2308 | YV12_BUFFER_CONFIG *yv12 = &cm->yv12_fb[cpi->common.ref_frame_map[idx]]; |
michael@0 | 2309 | MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 2310 | MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; |
michael@0 | 2311 | |
michael@0 | 2312 | // set up scaling factors |
michael@0 | 2313 | scale[frame_type] = cpi->common.active_ref_scale[frame_type - 1]; |
michael@0 | 2314 | |
michael@0 | 2315 | scale[frame_type].sfc->set_scaled_offsets(&scale[frame_type], |
michael@0 | 2316 | mi_row * MI_SIZE, mi_col * MI_SIZE); |
michael@0 | 2317 | |
michael@0 | 2318 | // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this |
michael@0 | 2319 | // use the UV scaling factors. |
michael@0 | 2320 | setup_pred_block(xd, yv12_mb[frame_type], yv12, mi_row, mi_col, |
michael@0 | 2321 | &scale[frame_type], &scale[frame_type]); |
michael@0 | 2322 | |
michael@0 | 2323 | // Gets an initial list of candidate vectors from neighbours and orders them |
michael@0 | 2324 | vp9_find_mv_refs(cm, xd, tile, xd->mi_8x8[0], |
michael@0 | 2325 | xd->last_mi, |
michael@0 | 2326 | frame_type, |
michael@0 | 2327 | mbmi->ref_mvs[frame_type], mi_row, mi_col); |
michael@0 | 2328 | |
michael@0 | 2329 | // Candidate refinement carried out at encoder and decoder |
michael@0 | 2330 | vp9_find_best_ref_mvs(xd, cm->allow_high_precision_mv, |
michael@0 | 2331 | mbmi->ref_mvs[frame_type], |
michael@0 | 2332 | &frame_nearest_mv[frame_type], |
michael@0 | 2333 | &frame_near_mv[frame_type]); |
michael@0 | 2334 | |
michael@0 | 2335 | // Further refinement that is encode side only to test the top few candidates |
michael@0 | 2336 | // in full and choose the best as the centre point for subsequent searches. |
michael@0 | 2337 | // The current implementation doesn't support scaling. |
michael@0 | 2338 | if (!vp9_is_scaled(scale[frame_type].sfc) && block_size >= BLOCK_8X8) |
michael@0 | 2339 | mv_pred(cpi, x, yv12_mb[frame_type][0].buf, yv12->y_stride, |
michael@0 | 2340 | frame_type, block_size); |
michael@0 | 2341 | } |
michael@0 | 2342 | |
michael@0 | 2343 | static YV12_BUFFER_CONFIG *get_scaled_ref_frame(VP9_COMP *cpi, int ref_frame) { |
michael@0 | 2344 | YV12_BUFFER_CONFIG *scaled_ref_frame = NULL; |
michael@0 | 2345 | int fb = get_ref_frame_idx(cpi, ref_frame); |
michael@0 | 2346 | int fb_scale = get_scale_ref_frame_idx(cpi, ref_frame); |
michael@0 | 2347 | if (cpi->scaled_ref_idx[fb_scale] != cpi->common.ref_frame_map[fb]) |
michael@0 | 2348 | scaled_ref_frame = &cpi->common.yv12_fb[cpi->scaled_ref_idx[fb_scale]]; |
michael@0 | 2349 | return scaled_ref_frame; |
michael@0 | 2350 | } |
michael@0 | 2351 | |
michael@0 | 2352 | static INLINE int get_switchable_rate(const MACROBLOCK *x) { |
michael@0 | 2353 | const MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 2354 | const MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; |
michael@0 | 2355 | const int ctx = vp9_get_pred_context_switchable_interp(xd); |
michael@0 | 2356 | return SWITCHABLE_INTERP_RATE_FACTOR * |
michael@0 | 2357 | x->switchable_interp_costs[ctx][mbmi->interp_filter]; |
michael@0 | 2358 | } |
michael@0 | 2359 | |
michael@0 | 2360 | static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x, |
michael@0 | 2361 | const TileInfo *const tile, |
michael@0 | 2362 | BLOCK_SIZE bsize, |
michael@0 | 2363 | int mi_row, int mi_col, |
michael@0 | 2364 | int_mv *tmp_mv, int *rate_mv) { |
michael@0 | 2365 | MACROBLOCKD *xd = &x->e_mbd; |
michael@0 | 2366 | VP9_COMMON *cm = &cpi->common; |
michael@0 | 2367 | MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; |
michael@0 | 2368 | struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}}; |
michael@0 | 2369 | int bestsme = INT_MAX; |
michael@0 | 2370 | int further_steps, step_param; |
michael@0 | 2371 | int sadpb = x->sadperbit16; |
michael@0 | 2372 | int_mv mvp_full; |
michael@0 | 2373 | int ref = mbmi->ref_frame[0]; |
michael@0 | 2374 | int_mv ref_mv = mbmi->ref_mvs[ref][0]; |
michael@0 | 2375 | const BLOCK_SIZE block_size = get_plane_block_size(bsize, &xd->plane[0]); |
michael@0 | 2376 | |
michael@0 | 2377 | int tmp_col_min = x->mv_col_min; |
michael@0 | 2378 | int tmp_col_max = x->mv_col_max; |
michael@0 | 2379 | int tmp_row_min = x->mv_row_min; |
michael@0 | 2380 | int tmp_row_max = x->mv_row_max; |
michael@0 | 2381 | |
michael@0 | 2382 | YV12_BUFFER_CONFIG *scaled_ref_frame = get_scaled_ref_frame(cpi, ref); |
michael@0 | 2383 | |
michael@0 | 2384 | if (scaled_ref_frame) { |
michael@0 | 2385 | int i; |
michael@0 | 2386 | // Swap out the reference frame for a version that's been scaled to |
michael@0 | 2387 | // match the resolution of the current frame, allowing the existing |
michael@0 | 2388 | // motion search code to be used without additional modifications. |
michael@0 | 2389 | for (i = 0; i < MAX_MB_PLANE; i++) |
michael@0 | 2390 | backup_yv12[i] = xd->plane[i].pre[0]; |
michael@0 | 2391 | |
michael@0 | 2392 | setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL); |
michael@0 | 2393 | } |
michael@0 | 2394 | |
michael@0 | 2395 | vp9_clamp_mv_min_max(x, &ref_mv.as_mv); |
michael@0 | 2396 | |
michael@0 | 2397 | // Adjust search parameters based on small partitions' result. |
michael@0 | 2398 | if (x->fast_ms) { |
michael@0 | 2399 | // && abs(mvp_full.as_mv.row - x->pred_mv.as_mv.row) < 24 && |
michael@0 | 2400 | // abs(mvp_full.as_mv.col - x->pred_mv.as_mv.col) < 24) { |
michael@0 | 2401 | // adjust search range |
michael@0 | 2402 | step_param = 6; |
michael@0 | 2403 | if (x->fast_ms > 1) |
michael@0 | 2404 | step_param = 8; |
michael@0 | 2405 | |
michael@0 | 2406 | // Get prediction MV. |
michael@0 | 2407 | mvp_full.as_int = x->pred_mv[ref].as_int; |
michael@0 | 2408 | |
michael@0 | 2409 | // Adjust MV sign if needed. |
michael@0 | 2410 | if (cm->ref_frame_sign_bias[ref]) { |
michael@0 | 2411 | mvp_full.as_mv.col *= -1; |
michael@0 | 2412 | mvp_full.as_mv.row *= -1; |
michael@0 | 2413 | } |
michael@0 | 2414 | } else { |
michael@0 | 2415 | // Work out the size of the first step in the mv step search. |
michael@0 | 2416 | // 0 here is maximum length first step. 1 is MAX >> 1 etc. |
michael@0 | 2417 | if (cpi->sf.auto_mv_step_size && cpi->common.show_frame) { |
michael@0 | 2418 | // Take wtd average of the step_params based on the last frame's |
michael@0 | 2419 | // max mv magnitude and that based on the best ref mvs of the current |
michael@0 | 2420 | // block for the given reference. |
michael@0 | 2421 | step_param = (vp9_init_search_range(cpi, x->max_mv_context[ref]) + |
michael@0 | 2422 | cpi->mv_step_param) >> 1; |
michael@0 | 2423 | } else { |
michael@0 | 2424 | step_param = cpi->mv_step_param; |
michael@0 | 2425 | } |
michael@0 | 2426 | } |
michael@0 | 2427 | |
michael@0 | 2428 | if (cpi->sf.adaptive_motion_search && bsize < BLOCK_64X64 && |
michael@0 | 2429 | cpi->common.show_frame) { |
michael@0 | 2430 | int boffset = 2 * (b_width_log2(BLOCK_64X64) - MIN(b_height_log2(bsize), |
michael@0 | 2431 | b_width_log2(bsize))); |
michael@0 | 2432 | step_param = MAX(step_param, boffset); |
michael@0 | 2433 | } |
michael@0 | 2434 | |
michael@0 | 2435 | mvp_full.as_int = x->mv_best_ref_index[ref] < MAX_MV_REF_CANDIDATES ? |
michael@0 | 2436 | mbmi->ref_mvs[ref][x->mv_best_ref_index[ref]].as_int : |
michael@0 | 2437 | x->pred_mv[ref].as_int; |
michael@0 | 2438 | |
michael@0 | 2439 | mvp_full.as_mv.col >>= 3; |
michael@0 | 2440 | mvp_full.as_mv.row >>= 3; |
michael@0 | 2441 | |
michael@0 | 2442 | // Further step/diamond searches as necessary |
michael@0 | 2443 | further_steps = (cpi->sf.max_step_search_steps - 1) - step_param; |
michael@0 | 2444 | |
michael@0 | 2445 | if (cpi->sf.search_method == HEX) { |
michael@0 | 2446 | bestsme = vp9_hex_search(x, &mvp_full.as_mv, |
michael@0 | 2447 | step_param, |
michael@0 | 2448 | sadpb, 1, |
michael@0 | 2449 | &cpi->fn_ptr[block_size], 1, |
michael@0 | 2450 | &ref_mv.as_mv, &tmp_mv->as_mv); |
michael@0 | 2451 | } else if (cpi->sf.search_method == SQUARE) { |
michael@0 | 2452 | bestsme = vp9_square_search(x, &mvp_full.as_mv, |
michael@0 | 2453 | step_param, |
michael@0 | 2454 | sadpb, 1, |
michael@0 | 2455 | &cpi->fn_ptr[block_size], 1, |
michael@0 | 2456 | &ref_mv.as_mv, &tmp_mv->as_mv); |
michael@0 | 2457 | } else if (cpi->sf.search_method == BIGDIA) { |
michael@0 | 2458 | bestsme = vp9_bigdia_search(x, &mvp_full.as_mv, |
michael@0 | 2459 | step_param, |
michael@0 | 2460 | sadpb, 1, |
michael@0 | 2461 | &cpi->fn_ptr[block_size], 1, |
michael@0 | 2462 | &ref_mv.as_mv, &tmp_mv->as_mv); |
michael@0 | 2463 | } else { |
michael@0 | 2464 | bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param, |
michael@0 | 2465 | sadpb, further_steps, 1, |
michael@0 | 2466 | &cpi->fn_ptr[block_size], |
michael@0 | 2467 | &ref_mv, tmp_mv); |
michael@0 | 2468 | } |
michael@0 | 2469 | |
michael@0 | 2470 | x->mv_col_min = tmp_col_min; |
michael@0 | 2471 | x->mv_col_max = tmp_col_max; |
michael@0 | 2472 | x->mv_row_min = tmp_row_min; |
michael@0 | 2473 | x->mv_row_max = tmp_row_max; |
michael@0 | 2474 | |
michael@0 | 2475 | if (bestsme < INT_MAX) { |
michael@0 | 2476 | int dis; /* TODO: use dis in distortion calculation later. */ |
michael@0 | 2477 | unsigned int sse; |
michael@0 | 2478 | cpi->find_fractional_mv_step(x, &tmp_mv->as_mv, &ref_mv.as_mv, |
michael@0 | 2479 | cm->allow_high_precision_mv, |
michael@0 | 2480 | x->errorperbit, |
michael@0 | 2481 | &cpi->fn_ptr[block_size], |
michael@0 | 2482 | 0, cpi->sf.subpel_iters_per_step, |
michael@0 | 2483 | x->nmvjointcost, x->mvcost, |
michael@0 | 2484 | &dis, &sse); |
michael@0 | 2485 | } |
michael@0 | 2486 | *rate_mv = vp9_mv_bit_cost(&tmp_mv->as_mv, &ref_mv.as_mv, |
michael@0 | 2487 | x->nmvjointcost, x->mvcost, MV_COST_WEIGHT); |
michael@0 | 2488 | |
michael@0 | 2489 | if (cpi->sf.adaptive_motion_search && cpi->common.show_frame) |
michael@0 | 2490 | x->pred_mv[ref].as_int = tmp_mv->as_int; |
michael@0 | 2491 | |
michael@0 | 2492 | if (scaled_ref_frame) { |
michael@0 | 2493 | int i; |
michael@0 | 2494 | for (i = 0; i < MAX_MB_PLANE; i++) |
michael@0 | 2495 | xd->plane[i].pre[0] = backup_yv12[i]; |
michael@0 | 2496 | } |
michael@0 | 2497 | } |
michael@0 | 2498 | |
michael@0 | 2499 | static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x, |
michael@0 | 2500 | BLOCK_SIZE bsize, |
michael@0 | 2501 | int_mv *frame_mv, |
michael@0 | 2502 | int mi_row, int mi_col, |
michael@0 | 2503 | int_mv single_newmv[MAX_REF_FRAMES], |
michael@0 | 2504 | int *rate_mv) { |
michael@0 | 2505 | int pw = 4 << b_width_log2(bsize), ph = 4 << b_height_log2(bsize); |
michael@0 | 2506 | MACROBLOCKD *xd = &x->e_mbd; |
michael@0 | 2507 | MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; |
michael@0 | 2508 | const int refs[2] = { mbmi->ref_frame[0], |
michael@0 | 2509 | mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] }; |
michael@0 | 2510 | int_mv ref_mv[2]; |
michael@0 | 2511 | const BLOCK_SIZE block_size = get_plane_block_size(bsize, &xd->plane[0]); |
michael@0 | 2512 | int ite, ref; |
michael@0 | 2513 | // Prediction buffer from second frame. |
michael@0 | 2514 | uint8_t *second_pred = vpx_memalign(16, pw * ph * sizeof(uint8_t)); |
michael@0 | 2515 | |
michael@0 | 2516 | // Do joint motion search in compound mode to get more accurate mv. |
michael@0 | 2517 | struct buf_2d backup_yv12[2][MAX_MB_PLANE]; |
michael@0 | 2518 | struct buf_2d scaled_first_yv12 = xd->plane[0].pre[0]; |
michael@0 | 2519 | int last_besterr[2] = {INT_MAX, INT_MAX}; |
michael@0 | 2520 | YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = { |
michael@0 | 2521 | get_scaled_ref_frame(cpi, mbmi->ref_frame[0]), |
michael@0 | 2522 | get_scaled_ref_frame(cpi, mbmi->ref_frame[1]) |
michael@0 | 2523 | }; |
michael@0 | 2524 | |
michael@0 | 2525 | for (ref = 0; ref < 2; ++ref) { |
michael@0 | 2526 | ref_mv[ref] = mbmi->ref_mvs[refs[ref]][0]; |
michael@0 | 2527 | |
michael@0 | 2528 | if (scaled_ref_frame[ref]) { |
michael@0 | 2529 | int i; |
michael@0 | 2530 | // Swap out the reference frame for a version that's been scaled to |
michael@0 | 2531 | // match the resolution of the current frame, allowing the existing |
michael@0 | 2532 | // motion search code to be used without additional modifications. |
michael@0 | 2533 | for (i = 0; i < MAX_MB_PLANE; i++) |
michael@0 | 2534 | backup_yv12[ref][i] = xd->plane[i].pre[ref]; |
michael@0 | 2535 | setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col, NULL); |
michael@0 | 2536 | } |
michael@0 | 2537 | |
michael@0 | 2538 | xd->scale_factor[ref].sfc->set_scaled_offsets(&xd->scale_factor[ref], |
michael@0 | 2539 | mi_row, mi_col); |
michael@0 | 2540 | frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int; |
michael@0 | 2541 | } |
michael@0 | 2542 | |
michael@0 | 2543 | // Allow joint search multiple times iteratively for each ref frame |
michael@0 | 2544 | // and break out the search loop if it couldn't find better mv. |
michael@0 | 2545 | for (ite = 0; ite < 4; ite++) { |
michael@0 | 2546 | struct buf_2d ref_yv12[2]; |
michael@0 | 2547 | int bestsme = INT_MAX; |
michael@0 | 2548 | int sadpb = x->sadperbit16; |
michael@0 | 2549 | int_mv tmp_mv; |
michael@0 | 2550 | int search_range = 3; |
michael@0 | 2551 | |
michael@0 | 2552 | int tmp_col_min = x->mv_col_min; |
michael@0 | 2553 | int tmp_col_max = x->mv_col_max; |
michael@0 | 2554 | int tmp_row_min = x->mv_row_min; |
michael@0 | 2555 | int tmp_row_max = x->mv_row_max; |
michael@0 | 2556 | int id = ite % 2; |
michael@0 | 2557 | |
michael@0 | 2558 | // Initialized here because of compiler problem in Visual Studio. |
michael@0 | 2559 | ref_yv12[0] = xd->plane[0].pre[0]; |
michael@0 | 2560 | ref_yv12[1] = xd->plane[0].pre[1]; |
michael@0 | 2561 | |
michael@0 | 2562 | // Get pred block from second frame. |
michael@0 | 2563 | vp9_build_inter_predictor(ref_yv12[!id].buf, |
michael@0 | 2564 | ref_yv12[!id].stride, |
michael@0 | 2565 | second_pred, pw, |
michael@0 | 2566 | &frame_mv[refs[!id]].as_mv, |
michael@0 | 2567 | &xd->scale_factor[!id], |
michael@0 | 2568 | pw, ph, 0, |
michael@0 | 2569 | &xd->subpix, MV_PRECISION_Q3); |
michael@0 | 2570 | |
michael@0 | 2571 | // Compound motion search on first ref frame. |
michael@0 | 2572 | if (id) |
michael@0 | 2573 | xd->plane[0].pre[0] = ref_yv12[id]; |
michael@0 | 2574 | vp9_clamp_mv_min_max(x, &ref_mv[id].as_mv); |
michael@0 | 2575 | |
michael@0 | 2576 | // Use mv result from single mode as mvp. |
michael@0 | 2577 | tmp_mv.as_int = frame_mv[refs[id]].as_int; |
michael@0 | 2578 | |
michael@0 | 2579 | tmp_mv.as_mv.col >>= 3; |
michael@0 | 2580 | tmp_mv.as_mv.row >>= 3; |
michael@0 | 2581 | |
michael@0 | 2582 | // Small-range full-pixel motion search |
michael@0 | 2583 | bestsme = vp9_refining_search_8p_c(x, &tmp_mv, sadpb, |
michael@0 | 2584 | search_range, |
michael@0 | 2585 | &cpi->fn_ptr[block_size], |
michael@0 | 2586 | x->nmvjointcost, x->mvcost, |
michael@0 | 2587 | &ref_mv[id], second_pred, |
michael@0 | 2588 | pw, ph); |
michael@0 | 2589 | |
michael@0 | 2590 | x->mv_col_min = tmp_col_min; |
michael@0 | 2591 | x->mv_col_max = tmp_col_max; |
michael@0 | 2592 | x->mv_row_min = tmp_row_min; |
michael@0 | 2593 | x->mv_row_max = tmp_row_max; |
michael@0 | 2594 | |
michael@0 | 2595 | if (bestsme < INT_MAX) { |
michael@0 | 2596 | int dis; /* TODO: use dis in distortion calculation later. */ |
michael@0 | 2597 | unsigned int sse; |
michael@0 | 2598 | |
michael@0 | 2599 | bestsme = cpi->find_fractional_mv_step_comp( |
michael@0 | 2600 | x, &tmp_mv.as_mv, |
michael@0 | 2601 | &ref_mv[id].as_mv, |
michael@0 | 2602 | cpi->common.allow_high_precision_mv, |
michael@0 | 2603 | x->errorperbit, |
michael@0 | 2604 | &cpi->fn_ptr[block_size], |
michael@0 | 2605 | 0, cpi->sf.subpel_iters_per_step, |
michael@0 | 2606 | x->nmvjointcost, x->mvcost, |
michael@0 | 2607 | &dis, &sse, second_pred, |
michael@0 | 2608 | pw, ph); |
michael@0 | 2609 | } |
michael@0 | 2610 | |
michael@0 | 2611 | if (id) |
michael@0 | 2612 | xd->plane[0].pre[0] = scaled_first_yv12; |
michael@0 | 2613 | |
michael@0 | 2614 | if (bestsme < last_besterr[id]) { |
michael@0 | 2615 | frame_mv[refs[id]].as_int = tmp_mv.as_int; |
michael@0 | 2616 | last_besterr[id] = bestsme; |
michael@0 | 2617 | } else { |
michael@0 | 2618 | break; |
michael@0 | 2619 | } |
michael@0 | 2620 | } |
michael@0 | 2621 | |
michael@0 | 2622 | *rate_mv = 0; |
michael@0 | 2623 | |
michael@0 | 2624 | for (ref = 0; ref < 2; ++ref) { |
michael@0 | 2625 | if (scaled_ref_frame[ref]) { |
michael@0 | 2626 | // restore the predictor |
michael@0 | 2627 | int i; |
michael@0 | 2628 | for (i = 0; i < MAX_MB_PLANE; i++) |
michael@0 | 2629 | xd->plane[i].pre[ref] = backup_yv12[ref][i]; |
michael@0 | 2630 | } |
michael@0 | 2631 | |
michael@0 | 2632 | *rate_mv += vp9_mv_bit_cost(&frame_mv[refs[ref]].as_mv, |
michael@0 | 2633 | &mbmi->ref_mvs[refs[ref]][0].as_mv, |
michael@0 | 2634 | x->nmvjointcost, x->mvcost, MV_COST_WEIGHT); |
michael@0 | 2635 | } |
michael@0 | 2636 | |
michael@0 | 2637 | vpx_free(second_pred); |
michael@0 | 2638 | } |
michael@0 | 2639 | |
michael@0 | 2640 | static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, |
michael@0 | 2641 | const TileInfo *const tile, |
michael@0 | 2642 | BLOCK_SIZE bsize, |
michael@0 | 2643 | int64_t txfm_cache[], |
michael@0 | 2644 | int *rate2, int64_t *distortion, |
michael@0 | 2645 | int *skippable, |
michael@0 | 2646 | int *rate_y, int64_t *distortion_y, |
michael@0 | 2647 | int *rate_uv, int64_t *distortion_uv, |
michael@0 | 2648 | int *mode_excluded, int *disable_skip, |
michael@0 | 2649 | INTERPOLATION_TYPE *best_filter, |
michael@0 | 2650 | int_mv (*mode_mv)[MAX_REF_FRAMES], |
michael@0 | 2651 | int mi_row, int mi_col, |
michael@0 | 2652 | int_mv single_newmv[MAX_REF_FRAMES], |
michael@0 | 2653 | int64_t *psse, |
michael@0 | 2654 | const int64_t ref_best_rd) { |
michael@0 | 2655 | VP9_COMMON *cm = &cpi->common; |
michael@0 | 2656 | MACROBLOCKD *xd = &x->e_mbd; |
michael@0 | 2657 | MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; |
michael@0 | 2658 | const int is_comp_pred = has_second_ref(mbmi); |
michael@0 | 2659 | const int num_refs = is_comp_pred ? 2 : 1; |
michael@0 | 2660 | const int this_mode = mbmi->mode; |
michael@0 | 2661 | int_mv *frame_mv = mode_mv[this_mode]; |
michael@0 | 2662 | int i; |
michael@0 | 2663 | int refs[2] = { mbmi->ref_frame[0], |
michael@0 | 2664 | (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) }; |
michael@0 | 2665 | int_mv cur_mv[2]; |
michael@0 | 2666 | int64_t this_rd = 0; |
michael@0 | 2667 | DECLARE_ALIGNED_ARRAY(16, uint8_t, tmp_buf, MAX_MB_PLANE * 64 * 64); |
michael@0 | 2668 | int pred_exists = 0; |
michael@0 | 2669 | int intpel_mv; |
michael@0 | 2670 | int64_t rd, best_rd = INT64_MAX; |
michael@0 | 2671 | int best_needs_copy = 0; |
michael@0 | 2672 | uint8_t *orig_dst[MAX_MB_PLANE]; |
michael@0 | 2673 | int orig_dst_stride[MAX_MB_PLANE]; |
michael@0 | 2674 | int rs = 0; |
michael@0 | 2675 | |
michael@0 | 2676 | if (is_comp_pred) { |
michael@0 | 2677 | if (frame_mv[refs[0]].as_int == INVALID_MV || |
michael@0 | 2678 | frame_mv[refs[1]].as_int == INVALID_MV) |
michael@0 | 2679 | return INT64_MAX; |
michael@0 | 2680 | } |
michael@0 | 2681 | |
michael@0 | 2682 | if (this_mode == NEWMV) { |
michael@0 | 2683 | int rate_mv; |
michael@0 | 2684 | if (is_comp_pred) { |
michael@0 | 2685 | // Initialize mv using single prediction mode result. |
michael@0 | 2686 | frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int; |
michael@0 | 2687 | frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int; |
michael@0 | 2688 | |
michael@0 | 2689 | if (cpi->sf.comp_inter_joint_search_thresh <= bsize) { |
michael@0 | 2690 | joint_motion_search(cpi, x, bsize, frame_mv, |
michael@0 | 2691 | mi_row, mi_col, single_newmv, &rate_mv); |
michael@0 | 2692 | } else { |
michael@0 | 2693 | rate_mv = vp9_mv_bit_cost(&frame_mv[refs[0]].as_mv, |
michael@0 | 2694 | &mbmi->ref_mvs[refs[0]][0].as_mv, |
michael@0 | 2695 | x->nmvjointcost, x->mvcost, MV_COST_WEIGHT); |
michael@0 | 2696 | rate_mv += vp9_mv_bit_cost(&frame_mv[refs[1]].as_mv, |
michael@0 | 2697 | &mbmi->ref_mvs[refs[1]][0].as_mv, |
michael@0 | 2698 | x->nmvjointcost, x->mvcost, MV_COST_WEIGHT); |
michael@0 | 2699 | } |
michael@0 | 2700 | *rate2 += rate_mv; |
michael@0 | 2701 | } else { |
michael@0 | 2702 | int_mv tmp_mv; |
michael@0 | 2703 | single_motion_search(cpi, x, tile, bsize, mi_row, mi_col, |
michael@0 | 2704 | &tmp_mv, &rate_mv); |
michael@0 | 2705 | *rate2 += rate_mv; |
michael@0 | 2706 | frame_mv[refs[0]].as_int = |
michael@0 | 2707 | xd->mi_8x8[0]->bmi[0].as_mv[0].as_int = tmp_mv.as_int; |
michael@0 | 2708 | single_newmv[refs[0]].as_int = tmp_mv.as_int; |
michael@0 | 2709 | } |
michael@0 | 2710 | } |
michael@0 | 2711 | |
michael@0 | 2712 | // if we're near/nearest and mv == 0,0, compare to zeromv |
michael@0 | 2713 | if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) && |
michael@0 | 2714 | frame_mv[refs[0]].as_int == 0 && |
michael@0 | 2715 | !vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP) && |
michael@0 | 2716 | (num_refs == 1 || frame_mv[refs[1]].as_int == 0)) { |
michael@0 | 2717 | int rfc = mbmi->mode_context[mbmi->ref_frame[0]]; |
michael@0 | 2718 | int c1 = cost_mv_ref(cpi, NEARMV, rfc); |
michael@0 | 2719 | int c2 = cost_mv_ref(cpi, NEARESTMV, rfc); |
michael@0 | 2720 | int c3 = cost_mv_ref(cpi, ZEROMV, rfc); |
michael@0 | 2721 | |
michael@0 | 2722 | if (this_mode == NEARMV) { |
michael@0 | 2723 | if (c1 > c3) |
michael@0 | 2724 | return INT64_MAX; |
michael@0 | 2725 | } else if (this_mode == NEARESTMV) { |
michael@0 | 2726 | if (c2 > c3) |
michael@0 | 2727 | return INT64_MAX; |
michael@0 | 2728 | } else { |
michael@0 | 2729 | assert(this_mode == ZEROMV); |
michael@0 | 2730 | if (num_refs == 1) { |
michael@0 | 2731 | if ((c3 >= c2 && |
michael@0 | 2732 | mode_mv[NEARESTMV][mbmi->ref_frame[0]].as_int == 0) || |
michael@0 | 2733 | (c3 >= c1 && |
michael@0 | 2734 | mode_mv[NEARMV][mbmi->ref_frame[0]].as_int == 0)) |
michael@0 | 2735 | return INT64_MAX; |
michael@0 | 2736 | } else { |
michael@0 | 2737 | if ((c3 >= c2 && |
michael@0 | 2738 | mode_mv[NEARESTMV][mbmi->ref_frame[0]].as_int == 0 && |
michael@0 | 2739 | mode_mv[NEARESTMV][mbmi->ref_frame[1]].as_int == 0) || |
michael@0 | 2740 | (c3 >= c1 && |
michael@0 | 2741 | mode_mv[NEARMV][mbmi->ref_frame[0]].as_int == 0 && |
michael@0 | 2742 | mode_mv[NEARMV][mbmi->ref_frame[1]].as_int == 0)) |
michael@0 | 2743 | return INT64_MAX; |
michael@0 | 2744 | } |
michael@0 | 2745 | } |
michael@0 | 2746 | } |
michael@0 | 2747 | |
michael@0 | 2748 | for (i = 0; i < num_refs; ++i) { |
michael@0 | 2749 | cur_mv[i] = frame_mv[refs[i]]; |
michael@0 | 2750 | // Clip "next_nearest" so that it does not extend to far out of image |
michael@0 | 2751 | if (this_mode != NEWMV) |
michael@0 | 2752 | clamp_mv2(&cur_mv[i].as_mv, xd); |
michael@0 | 2753 | |
michael@0 | 2754 | if (mv_check_bounds(x, &cur_mv[i])) |
michael@0 | 2755 | return INT64_MAX; |
michael@0 | 2756 | mbmi->mv[i].as_int = cur_mv[i].as_int; |
michael@0 | 2757 | } |
michael@0 | 2758 | |
michael@0 | 2759 | // do first prediction into the destination buffer. Do the next |
michael@0 | 2760 | // prediction into a temporary buffer. Then keep track of which one |
michael@0 | 2761 | // of these currently holds the best predictor, and use the other |
michael@0 | 2762 | // one for future predictions. In the end, copy from tmp_buf to |
michael@0 | 2763 | // dst if necessary. |
michael@0 | 2764 | for (i = 0; i < MAX_MB_PLANE; i++) { |
michael@0 | 2765 | orig_dst[i] = xd->plane[i].dst.buf; |
michael@0 | 2766 | orig_dst_stride[i] = xd->plane[i].dst.stride; |
michael@0 | 2767 | } |
michael@0 | 2768 | |
michael@0 | 2769 | /* We don't include the cost of the second reference here, because there |
michael@0 | 2770 | * are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other |
michael@0 | 2771 | * words if you present them in that order, the second one is always known |
michael@0 | 2772 | * if the first is known */ |
michael@0 | 2773 | *rate2 += cost_mv_ref(cpi, this_mode, |
michael@0 | 2774 | mbmi->mode_context[mbmi->ref_frame[0]]); |
michael@0 | 2775 | |
michael@0 | 2776 | if (!(*mode_excluded)) { |
michael@0 | 2777 | if (is_comp_pred) { |
michael@0 | 2778 | *mode_excluded = (cpi->common.comp_pred_mode == SINGLE_PREDICTION_ONLY); |
michael@0 | 2779 | } else { |
michael@0 | 2780 | *mode_excluded = (cpi->common.comp_pred_mode == COMP_PREDICTION_ONLY); |
michael@0 | 2781 | } |
michael@0 | 2782 | } |
michael@0 | 2783 | |
michael@0 | 2784 | pred_exists = 0; |
michael@0 | 2785 | // Are all MVs integer pel for Y and UV |
michael@0 | 2786 | intpel_mv = (mbmi->mv[0].as_mv.row & 15) == 0 && |
michael@0 | 2787 | (mbmi->mv[0].as_mv.col & 15) == 0; |
michael@0 | 2788 | if (is_comp_pred) |
michael@0 | 2789 | intpel_mv &= (mbmi->mv[1].as_mv.row & 15) == 0 && |
michael@0 | 2790 | (mbmi->mv[1].as_mv.col & 15) == 0; |
michael@0 | 2791 | // Search for best switchable filter by checking the variance of |
michael@0 | 2792 | // pred error irrespective of whether the filter will be used |
michael@0 | 2793 | if (cm->mcomp_filter_type != BILINEAR) { |
michael@0 | 2794 | *best_filter = EIGHTTAP; |
michael@0 | 2795 | if (x->source_variance < |
michael@0 | 2796 | cpi->sf.disable_filter_search_var_thresh) { |
michael@0 | 2797 | *best_filter = EIGHTTAP; |
michael@0 | 2798 | vp9_zero(cpi->rd_filter_cache); |
michael@0 | 2799 | } else { |
michael@0 | 2800 | int i, newbest; |
michael@0 | 2801 | int tmp_rate_sum = 0; |
michael@0 | 2802 | int64_t tmp_dist_sum = 0; |
michael@0 | 2803 | |
michael@0 | 2804 | cpi->rd_filter_cache[SWITCHABLE_FILTERS] = INT64_MAX; |
michael@0 | 2805 | for (i = 0; i < SWITCHABLE_FILTERS; ++i) { |
michael@0 | 2806 | int j; |
michael@0 | 2807 | int64_t rs_rd; |
michael@0 | 2808 | mbmi->interp_filter = i; |
michael@0 | 2809 | vp9_setup_interp_filters(xd, mbmi->interp_filter, cm); |
michael@0 | 2810 | rs = get_switchable_rate(x); |
michael@0 | 2811 | rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0); |
michael@0 | 2812 | |
michael@0 | 2813 | if (i > 0 && intpel_mv) { |
michael@0 | 2814 | cpi->rd_filter_cache[i] = RDCOST(x->rdmult, x->rddiv, |
michael@0 | 2815 | tmp_rate_sum, tmp_dist_sum); |
michael@0 | 2816 | cpi->rd_filter_cache[SWITCHABLE_FILTERS] = |
michael@0 | 2817 | MIN(cpi->rd_filter_cache[SWITCHABLE_FILTERS], |
michael@0 | 2818 | cpi->rd_filter_cache[i] + rs_rd); |
michael@0 | 2819 | rd = cpi->rd_filter_cache[i]; |
michael@0 | 2820 | if (cm->mcomp_filter_type == SWITCHABLE) |
michael@0 | 2821 | rd += rs_rd; |
michael@0 | 2822 | } else { |
michael@0 | 2823 | int rate_sum = 0; |
michael@0 | 2824 | int64_t dist_sum = 0; |
michael@0 | 2825 | if ((cm->mcomp_filter_type == SWITCHABLE && |
michael@0 | 2826 | (!i || best_needs_copy)) || |
michael@0 | 2827 | (cm->mcomp_filter_type != SWITCHABLE && |
michael@0 | 2828 | (cm->mcomp_filter_type == mbmi->interp_filter || |
michael@0 | 2829 | (i == 0 && intpel_mv)))) { |
michael@0 | 2830 | for (j = 0; j < MAX_MB_PLANE; j++) { |
michael@0 | 2831 | xd->plane[j].dst.buf = orig_dst[j]; |
michael@0 | 2832 | xd->plane[j].dst.stride = orig_dst_stride[j]; |
michael@0 | 2833 | } |
michael@0 | 2834 | } else { |
michael@0 | 2835 | for (j = 0; j < MAX_MB_PLANE; j++) { |
michael@0 | 2836 | xd->plane[j].dst.buf = tmp_buf + j * 64 * 64; |
michael@0 | 2837 | xd->plane[j].dst.stride = 64; |
michael@0 | 2838 | } |
michael@0 | 2839 | } |
michael@0 | 2840 | vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize); |
michael@0 | 2841 | model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum); |
michael@0 | 2842 | cpi->rd_filter_cache[i] = RDCOST(x->rdmult, x->rddiv, |
michael@0 | 2843 | rate_sum, dist_sum); |
michael@0 | 2844 | cpi->rd_filter_cache[SWITCHABLE_FILTERS] = |
michael@0 | 2845 | MIN(cpi->rd_filter_cache[SWITCHABLE_FILTERS], |
michael@0 | 2846 | cpi->rd_filter_cache[i] + rs_rd); |
michael@0 | 2847 | rd = cpi->rd_filter_cache[i]; |
michael@0 | 2848 | if (cm->mcomp_filter_type == SWITCHABLE) |
michael@0 | 2849 | rd += rs_rd; |
michael@0 | 2850 | if (i == 0 && intpel_mv) { |
michael@0 | 2851 | tmp_rate_sum = rate_sum; |
michael@0 | 2852 | tmp_dist_sum = dist_sum; |
michael@0 | 2853 | } |
michael@0 | 2854 | } |
michael@0 | 2855 | if (i == 0 && cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) { |
michael@0 | 2856 | if (rd / 2 > ref_best_rd) { |
michael@0 | 2857 | for (i = 0; i < MAX_MB_PLANE; i++) { |
michael@0 | 2858 | xd->plane[i].dst.buf = orig_dst[i]; |
michael@0 | 2859 | xd->plane[i].dst.stride = orig_dst_stride[i]; |
michael@0 | 2860 | } |
michael@0 | 2861 | return INT64_MAX; |
michael@0 | 2862 | } |
michael@0 | 2863 | } |
michael@0 | 2864 | newbest = i == 0 || rd < best_rd; |
michael@0 | 2865 | |
michael@0 | 2866 | if (newbest) { |
michael@0 | 2867 | best_rd = rd; |
michael@0 | 2868 | *best_filter = mbmi->interp_filter; |
michael@0 | 2869 | if (cm->mcomp_filter_type == SWITCHABLE && i && !intpel_mv) |
michael@0 | 2870 | best_needs_copy = !best_needs_copy; |
michael@0 | 2871 | } |
michael@0 | 2872 | |
michael@0 | 2873 | if ((cm->mcomp_filter_type == SWITCHABLE && newbest) || |
michael@0 | 2874 | (cm->mcomp_filter_type != SWITCHABLE && |
michael@0 | 2875 | cm->mcomp_filter_type == mbmi->interp_filter)) { |
michael@0 | 2876 | pred_exists = 1; |
michael@0 | 2877 | } |
michael@0 | 2878 | } |
michael@0 | 2879 | |
michael@0 | 2880 | for (i = 0; i < MAX_MB_PLANE; i++) { |
michael@0 | 2881 | xd->plane[i].dst.buf = orig_dst[i]; |
michael@0 | 2882 | xd->plane[i].dst.stride = orig_dst_stride[i]; |
michael@0 | 2883 | } |
michael@0 | 2884 | } |
michael@0 | 2885 | } |
michael@0 | 2886 | // Set the appropriate filter |
michael@0 | 2887 | mbmi->interp_filter = cm->mcomp_filter_type != SWITCHABLE ? |
michael@0 | 2888 | cm->mcomp_filter_type : *best_filter; |
michael@0 | 2889 | vp9_setup_interp_filters(xd, mbmi->interp_filter, cm); |
michael@0 | 2890 | rs = cm->mcomp_filter_type == SWITCHABLE ? get_switchable_rate(x) : 0; |
michael@0 | 2891 | |
michael@0 | 2892 | if (pred_exists) { |
michael@0 | 2893 | if (best_needs_copy) { |
michael@0 | 2894 | // again temporarily set the buffers to local memory to prevent a memcpy |
michael@0 | 2895 | for (i = 0; i < MAX_MB_PLANE; i++) { |
michael@0 | 2896 | xd->plane[i].dst.buf = tmp_buf + i * 64 * 64; |
michael@0 | 2897 | xd->plane[i].dst.stride = 64; |
michael@0 | 2898 | } |
michael@0 | 2899 | } |
michael@0 | 2900 | } else { |
michael@0 | 2901 | // Handles the special case when a filter that is not in the |
michael@0 | 2902 | // switchable list (ex. bilinear, 6-tap) is indicated at the frame level |
michael@0 | 2903 | vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize); |
michael@0 | 2904 | } |
michael@0 | 2905 | |
michael@0 | 2906 | |
michael@0 | 2907 | if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) { |
michael@0 | 2908 | int tmp_rate; |
michael@0 | 2909 | int64_t tmp_dist; |
michael@0 | 2910 | model_rd_for_sb(cpi, bsize, x, xd, &tmp_rate, &tmp_dist); |
michael@0 | 2911 | rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist); |
michael@0 | 2912 | // if current pred_error modeled rd is substantially more than the best |
michael@0 | 2913 | // so far, do not bother doing full rd |
michael@0 | 2914 | if (rd / 2 > ref_best_rd) { |
michael@0 | 2915 | for (i = 0; i < MAX_MB_PLANE; i++) { |
michael@0 | 2916 | xd->plane[i].dst.buf = orig_dst[i]; |
michael@0 | 2917 | xd->plane[i].dst.stride = orig_dst_stride[i]; |
michael@0 | 2918 | } |
michael@0 | 2919 | return INT64_MAX; |
michael@0 | 2920 | } |
michael@0 | 2921 | } |
michael@0 | 2922 | |
michael@0 | 2923 | if (cpi->common.mcomp_filter_type == SWITCHABLE) |
michael@0 | 2924 | *rate2 += get_switchable_rate(x); |
michael@0 | 2925 | |
michael@0 | 2926 | if (!is_comp_pred && cpi->enable_encode_breakout) { |
michael@0 | 2927 | if (cpi->active_map_enabled && x->active_ptr[0] == 0) |
michael@0 | 2928 | x->skip = 1; |
michael@0 | 2929 | else if (x->encode_breakout) { |
michael@0 | 2930 | const BLOCK_SIZE y_size = get_plane_block_size(bsize, &xd->plane[0]); |
michael@0 | 2931 | const BLOCK_SIZE uv_size = get_plane_block_size(bsize, &xd->plane[1]); |
michael@0 | 2932 | unsigned int var, sse; |
michael@0 | 2933 | // Skipping threshold for ac. |
michael@0 | 2934 | unsigned int thresh_ac; |
michael@0 | 2935 | // The encode_breakout input |
michael@0 | 2936 | unsigned int encode_breakout = x->encode_breakout << 4; |
michael@0 | 2937 | unsigned int max_thresh = 36000; |
michael@0 | 2938 | |
michael@0 | 2939 | // Use extreme low threshold for static frames to limit skipping. |
michael@0 | 2940 | if (cpi->enable_encode_breakout == 2) |
michael@0 | 2941 | max_thresh = 128; |
michael@0 | 2942 | |
michael@0 | 2943 | // Calculate threshold according to dequant value. |
michael@0 | 2944 | thresh_ac = (xd->plane[0].dequant[1] * xd->plane[0].dequant[1]) / 9; |
michael@0 | 2945 | |
michael@0 | 2946 | // Use encode_breakout input if it is bigger than internal threshold. |
michael@0 | 2947 | if (thresh_ac < encode_breakout) |
michael@0 | 2948 | thresh_ac = encode_breakout; |
michael@0 | 2949 | |
michael@0 | 2950 | // Set a maximum for threshold to avoid big PSNR loss in low bitrate case. |
michael@0 | 2951 | if (thresh_ac > max_thresh) |
michael@0 | 2952 | thresh_ac = max_thresh; |
michael@0 | 2953 | |
michael@0 | 2954 | var = cpi->fn_ptr[y_size].vf(x->plane[0].src.buf, x->plane[0].src.stride, |
michael@0 | 2955 | xd->plane[0].dst.buf, |
michael@0 | 2956 | xd->plane[0].dst.stride, &sse); |
michael@0 | 2957 | |
michael@0 | 2958 | // Adjust threshold according to partition size. |
michael@0 | 2959 | thresh_ac >>= 8 - (b_width_log2_lookup[bsize] + |
michael@0 | 2960 | b_height_log2_lookup[bsize]); |
michael@0 | 2961 | |
michael@0 | 2962 | // Y skipping condition checking |
michael@0 | 2963 | if (sse < thresh_ac || sse == 0) { |
michael@0 | 2964 | // Skipping threshold for dc |
michael@0 | 2965 | unsigned int thresh_dc; |
michael@0 | 2966 | |
michael@0 | 2967 | thresh_dc = (xd->plane[0].dequant[0] * xd->plane[0].dequant[0] >> 6); |
michael@0 | 2968 | |
michael@0 | 2969 | // dc skipping checking |
michael@0 | 2970 | if ((sse - var) < thresh_dc || sse == var) { |
michael@0 | 2971 | unsigned int sse_u, sse_v; |
michael@0 | 2972 | unsigned int var_u, var_v; |
michael@0 | 2973 | |
michael@0 | 2974 | var_u = cpi->fn_ptr[uv_size].vf(x->plane[1].src.buf, |
michael@0 | 2975 | x->plane[1].src.stride, |
michael@0 | 2976 | xd->plane[1].dst.buf, |
michael@0 | 2977 | xd->plane[1].dst.stride, &sse_u); |
michael@0 | 2978 | |
michael@0 | 2979 | // U skipping condition checking |
michael@0 | 2980 | if ((sse_u * 4 < thresh_ac || sse_u == 0) && |
michael@0 | 2981 | (sse_u - var_u < thresh_dc || sse_u == var_u)) { |
michael@0 | 2982 | var_v = cpi->fn_ptr[uv_size].vf(x->plane[2].src.buf, |
michael@0 | 2983 | x->plane[2].src.stride, |
michael@0 | 2984 | xd->plane[2].dst.buf, |
michael@0 | 2985 | xd->plane[2].dst.stride, &sse_v); |
michael@0 | 2986 | |
michael@0 | 2987 | // V skipping condition checking |
michael@0 | 2988 | if ((sse_v * 4 < thresh_ac || sse_v == 0) && |
michael@0 | 2989 | (sse_v - var_v < thresh_dc || sse_v == var_v)) { |
michael@0 | 2990 | x->skip = 1; |
michael@0 | 2991 | |
michael@0 | 2992 | // The cost of skip bit needs to be added. |
michael@0 | 2993 | *rate2 += vp9_cost_bit(vp9_get_pred_prob_mbskip(cm, xd), 1); |
michael@0 | 2994 | |
michael@0 | 2995 | // Scaling factor for SSE from spatial domain to frequency domain |
michael@0 | 2996 | // is 16. Adjust distortion accordingly. |
michael@0 | 2997 | *distortion_uv = (sse_u + sse_v) << 4; |
michael@0 | 2998 | *distortion = (sse << 4) + *distortion_uv; |
michael@0 | 2999 | |
michael@0 | 3000 | *disable_skip = 1; |
michael@0 | 3001 | this_rd = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion); |
michael@0 | 3002 | } |
michael@0 | 3003 | } |
michael@0 | 3004 | } |
michael@0 | 3005 | } |
michael@0 | 3006 | } |
michael@0 | 3007 | } |
michael@0 | 3008 | |
michael@0 | 3009 | if (!x->skip) { |
michael@0 | 3010 | int skippable_y, skippable_uv; |
michael@0 | 3011 | int64_t sseuv = INT64_MAX; |
michael@0 | 3012 | int64_t rdcosty = INT64_MAX; |
michael@0 | 3013 | |
michael@0 | 3014 | // Y cost and distortion |
michael@0 | 3015 | super_block_yrd(cpi, x, rate_y, distortion_y, &skippable_y, psse, |
michael@0 | 3016 | bsize, txfm_cache, ref_best_rd); |
michael@0 | 3017 | |
michael@0 | 3018 | if (*rate_y == INT_MAX) { |
michael@0 | 3019 | *rate2 = INT_MAX; |
michael@0 | 3020 | *distortion = INT64_MAX; |
michael@0 | 3021 | for (i = 0; i < MAX_MB_PLANE; i++) { |
michael@0 | 3022 | xd->plane[i].dst.buf = orig_dst[i]; |
michael@0 | 3023 | xd->plane[i].dst.stride = orig_dst_stride[i]; |
michael@0 | 3024 | } |
michael@0 | 3025 | return INT64_MAX; |
michael@0 | 3026 | } |
michael@0 | 3027 | |
michael@0 | 3028 | *rate2 += *rate_y; |
michael@0 | 3029 | *distortion += *distortion_y; |
michael@0 | 3030 | |
michael@0 | 3031 | rdcosty = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion); |
michael@0 | 3032 | rdcosty = MIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, *psse)); |
michael@0 | 3033 | |
michael@0 | 3034 | super_block_uvrd(cpi, x, rate_uv, distortion_uv, &skippable_uv, &sseuv, |
michael@0 | 3035 | bsize, ref_best_rd - rdcosty); |
michael@0 | 3036 | if (*rate_uv == INT_MAX) { |
michael@0 | 3037 | *rate2 = INT_MAX; |
michael@0 | 3038 | *distortion = INT64_MAX; |
michael@0 | 3039 | for (i = 0; i < MAX_MB_PLANE; i++) { |
michael@0 | 3040 | xd->plane[i].dst.buf = orig_dst[i]; |
michael@0 | 3041 | xd->plane[i].dst.stride = orig_dst_stride[i]; |
michael@0 | 3042 | } |
michael@0 | 3043 | return INT64_MAX; |
michael@0 | 3044 | } |
michael@0 | 3045 | |
michael@0 | 3046 | *psse += sseuv; |
michael@0 | 3047 | *rate2 += *rate_uv; |
michael@0 | 3048 | *distortion += *distortion_uv; |
michael@0 | 3049 | *skippable = skippable_y && skippable_uv; |
michael@0 | 3050 | } |
michael@0 | 3051 | |
michael@0 | 3052 | for (i = 0; i < MAX_MB_PLANE; i++) { |
michael@0 | 3053 | xd->plane[i].dst.buf = orig_dst[i]; |
michael@0 | 3054 | xd->plane[i].dst.stride = orig_dst_stride[i]; |
michael@0 | 3055 | } |
michael@0 | 3056 | |
michael@0 | 3057 | return this_rd; // if 0, this will be re-calculated by caller |
michael@0 | 3058 | } |
michael@0 | 3059 | |
michael@0 | 3060 | static void swap_block_ptr(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx, |
michael@0 | 3061 | int max_plane) { |
michael@0 | 3062 | struct macroblock_plane *const p = x->plane; |
michael@0 | 3063 | struct macroblockd_plane *const pd = x->e_mbd.plane; |
michael@0 | 3064 | int i; |
michael@0 | 3065 | |
michael@0 | 3066 | for (i = 0; i < max_plane; ++i) { |
michael@0 | 3067 | p[i].coeff = ctx->coeff_pbuf[i][1]; |
michael@0 | 3068 | pd[i].qcoeff = ctx->qcoeff_pbuf[i][1]; |
michael@0 | 3069 | pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][1]; |
michael@0 | 3070 | pd[i].eobs = ctx->eobs_pbuf[i][1]; |
michael@0 | 3071 | |
michael@0 | 3072 | ctx->coeff_pbuf[i][1] = ctx->coeff_pbuf[i][0]; |
michael@0 | 3073 | ctx->qcoeff_pbuf[i][1] = ctx->qcoeff_pbuf[i][0]; |
michael@0 | 3074 | ctx->dqcoeff_pbuf[i][1] = ctx->dqcoeff_pbuf[i][0]; |
michael@0 | 3075 | ctx->eobs_pbuf[i][1] = ctx->eobs_pbuf[i][0]; |
michael@0 | 3076 | |
michael@0 | 3077 | ctx->coeff_pbuf[i][0] = p[i].coeff; |
michael@0 | 3078 | ctx->qcoeff_pbuf[i][0] = pd[i].qcoeff; |
michael@0 | 3079 | ctx->dqcoeff_pbuf[i][0] = pd[i].dqcoeff; |
michael@0 | 3080 | ctx->eobs_pbuf[i][0] = pd[i].eobs; |
michael@0 | 3081 | } |
michael@0 | 3082 | } |
michael@0 | 3083 | |
michael@0 | 3084 | void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, |
michael@0 | 3085 | int *returnrate, int64_t *returndist, |
michael@0 | 3086 | BLOCK_SIZE bsize, |
michael@0 | 3087 | PICK_MODE_CONTEXT *ctx, int64_t best_rd) { |
michael@0 | 3088 | VP9_COMMON *const cm = &cpi->common; |
michael@0 | 3089 | MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 3090 | int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0; |
michael@0 | 3091 | int y_skip = 0, uv_skip = 0; |
michael@0 | 3092 | int64_t dist_y = 0, dist_uv = 0, tx_cache[TX_MODES] = { 0 }; |
michael@0 | 3093 | x->skip_encode = 0; |
michael@0 | 3094 | ctx->skip = 0; |
michael@0 | 3095 | xd->mi_8x8[0]->mbmi.ref_frame[0] = INTRA_FRAME; |
michael@0 | 3096 | if (bsize >= BLOCK_8X8) { |
michael@0 | 3097 | if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly, |
michael@0 | 3098 | &dist_y, &y_skip, bsize, tx_cache, |
michael@0 | 3099 | best_rd) >= best_rd) { |
michael@0 | 3100 | *returnrate = INT_MAX; |
michael@0 | 3101 | return; |
michael@0 | 3102 | } |
michael@0 | 3103 | rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv, &rate_uv_tokenonly, |
michael@0 | 3104 | &dist_uv, &uv_skip, bsize); |
michael@0 | 3105 | } else { |
michael@0 | 3106 | y_skip = 0; |
michael@0 | 3107 | if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly, |
michael@0 | 3108 | &dist_y, best_rd) >= best_rd) { |
michael@0 | 3109 | *returnrate = INT_MAX; |
michael@0 | 3110 | return; |
michael@0 | 3111 | } |
michael@0 | 3112 | rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv, &rate_uv_tokenonly, |
michael@0 | 3113 | &dist_uv, &uv_skip, BLOCK_8X8); |
michael@0 | 3114 | } |
michael@0 | 3115 | |
michael@0 | 3116 | if (y_skip && uv_skip) { |
michael@0 | 3117 | *returnrate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly + |
michael@0 | 3118 | vp9_cost_bit(vp9_get_pred_prob_mbskip(cm, xd), 1); |
michael@0 | 3119 | *returndist = dist_y + dist_uv; |
michael@0 | 3120 | vp9_zero(ctx->tx_rd_diff); |
michael@0 | 3121 | } else { |
michael@0 | 3122 | int i; |
michael@0 | 3123 | *returnrate = rate_y + rate_uv + |
michael@0 | 3124 | vp9_cost_bit(vp9_get_pred_prob_mbskip(cm, xd), 0); |
michael@0 | 3125 | *returndist = dist_y + dist_uv; |
michael@0 | 3126 | if (cpi->sf.tx_size_search_method == USE_FULL_RD) |
michael@0 | 3127 | for (i = 0; i < TX_MODES; i++) { |
michael@0 | 3128 | if (tx_cache[i] < INT64_MAX && tx_cache[cm->tx_mode] < INT64_MAX) |
michael@0 | 3129 | ctx->tx_rd_diff[i] = tx_cache[i] - tx_cache[cm->tx_mode]; |
michael@0 | 3130 | else |
michael@0 | 3131 | ctx->tx_rd_diff[i] = 0; |
michael@0 | 3132 | } |
michael@0 | 3133 | } |
michael@0 | 3134 | |
michael@0 | 3135 | ctx->mic = *xd->mi_8x8[0]; |
michael@0 | 3136 | } |
michael@0 | 3137 | |
michael@0 | 3138 | int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, |
michael@0 | 3139 | const TileInfo *const tile, |
michael@0 | 3140 | int mi_row, int mi_col, |
michael@0 | 3141 | int *returnrate, |
michael@0 | 3142 | int64_t *returndistortion, |
michael@0 | 3143 | BLOCK_SIZE bsize, |
michael@0 | 3144 | PICK_MODE_CONTEXT *ctx, |
michael@0 | 3145 | int64_t best_rd_so_far) { |
michael@0 | 3146 | VP9_COMMON *cm = &cpi->common; |
michael@0 | 3147 | MACROBLOCKD *xd = &x->e_mbd; |
michael@0 | 3148 | MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; |
michael@0 | 3149 | const struct segmentation *seg = &cm->seg; |
michael@0 | 3150 | const BLOCK_SIZE block_size = get_plane_block_size(bsize, &xd->plane[0]); |
michael@0 | 3151 | MB_PREDICTION_MODE this_mode; |
michael@0 | 3152 | MV_REFERENCE_FRAME ref_frame, second_ref_frame; |
michael@0 | 3153 | unsigned char segment_id = mbmi->segment_id; |
michael@0 | 3154 | int comp_pred, i; |
michael@0 | 3155 | int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES]; |
michael@0 | 3156 | struct buf_2d yv12_mb[4][MAX_MB_PLANE]; |
michael@0 | 3157 | int_mv single_newmv[MAX_REF_FRAMES] = { { 0 } }; |
michael@0 | 3158 | static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG, |
michael@0 | 3159 | VP9_ALT_FLAG }; |
michael@0 | 3160 | int idx_list[4] = {0, |
michael@0 | 3161 | cpi->lst_fb_idx, |
michael@0 | 3162 | cpi->gld_fb_idx, |
michael@0 | 3163 | cpi->alt_fb_idx}; |
michael@0 | 3164 | int64_t best_rd = best_rd_so_far; |
michael@0 | 3165 | int64_t best_tx_rd[TX_MODES]; |
michael@0 | 3166 | int64_t best_tx_diff[TX_MODES]; |
michael@0 | 3167 | int64_t best_pred_diff[NB_PREDICTION_TYPES]; |
michael@0 | 3168 | int64_t best_pred_rd[NB_PREDICTION_TYPES]; |
michael@0 | 3169 | int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS]; |
michael@0 | 3170 | int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS]; |
michael@0 | 3171 | MB_MODE_INFO best_mbmode = { 0 }; |
michael@0 | 3172 | int j; |
michael@0 | 3173 | int mode_index, best_mode_index = 0; |
michael@0 | 3174 | unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES]; |
michael@0 | 3175 | vp9_prob comp_mode_p; |
michael@0 | 3176 | int64_t best_intra_rd = INT64_MAX; |
michael@0 | 3177 | int64_t best_inter_rd = INT64_MAX; |
michael@0 | 3178 | MB_PREDICTION_MODE best_intra_mode = DC_PRED; |
michael@0 | 3179 | MV_REFERENCE_FRAME best_inter_ref_frame = LAST_FRAME; |
michael@0 | 3180 | INTERPOLATION_TYPE tmp_best_filter = SWITCHABLE; |
michael@0 | 3181 | int rate_uv_intra[TX_SIZES], rate_uv_tokenonly[TX_SIZES]; |
michael@0 | 3182 | int64_t dist_uv[TX_SIZES]; |
michael@0 | 3183 | int skip_uv[TX_SIZES]; |
michael@0 | 3184 | MB_PREDICTION_MODE mode_uv[TX_SIZES]; |
michael@0 | 3185 | struct scale_factors scale_factor[4]; |
michael@0 | 3186 | unsigned int ref_frame_mask = 0; |
michael@0 | 3187 | unsigned int mode_mask = 0; |
michael@0 | 3188 | int64_t mode_distortions[MB_MODE_COUNT] = {-1}; |
michael@0 | 3189 | int64_t frame_distortions[MAX_REF_FRAMES] = {-1}; |
michael@0 | 3190 | int intra_cost_penalty = 20 * vp9_dc_quant(cm->base_qindex, cm->y_dc_delta_q); |
michael@0 | 3191 | const int bws = num_8x8_blocks_wide_lookup[bsize] / 2; |
michael@0 | 3192 | const int bhs = num_8x8_blocks_high_lookup[bsize] / 2; |
michael@0 | 3193 | int best_skip2 = 0; |
michael@0 | 3194 | |
michael@0 | 3195 | x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH; |
michael@0 | 3196 | |
michael@0 | 3197 | // Everywhere the flag is set the error is much higher than its neighbors. |
michael@0 | 3198 | ctx->frames_with_high_error = 0; |
michael@0 | 3199 | ctx->modes_with_high_error = 0; |
michael@0 | 3200 | |
michael@0 | 3201 | estimate_ref_frame_costs(cpi, segment_id, ref_costs_single, ref_costs_comp, |
michael@0 | 3202 | &comp_mode_p); |
michael@0 | 3203 | |
michael@0 | 3204 | for (i = 0; i < NB_PREDICTION_TYPES; ++i) |
michael@0 | 3205 | best_pred_rd[i] = INT64_MAX; |
michael@0 | 3206 | for (i = 0; i < TX_MODES; i++) |
michael@0 | 3207 | best_tx_rd[i] = INT64_MAX; |
michael@0 | 3208 | for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) |
michael@0 | 3209 | best_filter_rd[i] = INT64_MAX; |
michael@0 | 3210 | for (i = 0; i < TX_SIZES; i++) |
michael@0 | 3211 | rate_uv_intra[i] = INT_MAX; |
michael@0 | 3212 | |
michael@0 | 3213 | *returnrate = INT_MAX; |
michael@0 | 3214 | |
michael@0 | 3215 | // Create a mask set to 1 for each reference frame used by a smaller |
michael@0 | 3216 | // resolution. |
michael@0 | 3217 | if (cpi->sf.use_avoid_tested_higherror) { |
michael@0 | 3218 | switch (block_size) { |
michael@0 | 3219 | case BLOCK_64X64: |
michael@0 | 3220 | for (i = 0; i < 4; i++) { |
michael@0 | 3221 | for (j = 0; j < 4; j++) { |
michael@0 | 3222 | ref_frame_mask |= x->mb_context[i][j].frames_with_high_error; |
michael@0 | 3223 | mode_mask |= x->mb_context[i][j].modes_with_high_error; |
michael@0 | 3224 | } |
michael@0 | 3225 | } |
michael@0 | 3226 | for (i = 0; i < 4; i++) { |
michael@0 | 3227 | ref_frame_mask |= x->sb32_context[i].frames_with_high_error; |
michael@0 | 3228 | mode_mask |= x->sb32_context[i].modes_with_high_error; |
michael@0 | 3229 | } |
michael@0 | 3230 | break; |
michael@0 | 3231 | case BLOCK_32X32: |
michael@0 | 3232 | for (i = 0; i < 4; i++) { |
michael@0 | 3233 | ref_frame_mask |= |
michael@0 | 3234 | x->mb_context[x->sb_index][i].frames_with_high_error; |
michael@0 | 3235 | mode_mask |= x->mb_context[x->sb_index][i].modes_with_high_error; |
michael@0 | 3236 | } |
michael@0 | 3237 | break; |
michael@0 | 3238 | default: |
michael@0 | 3239 | // Until we handle all block sizes set it to present; |
michael@0 | 3240 | ref_frame_mask = 0; |
michael@0 | 3241 | mode_mask = 0; |
michael@0 | 3242 | break; |
michael@0 | 3243 | } |
michael@0 | 3244 | ref_frame_mask = ~ref_frame_mask; |
michael@0 | 3245 | mode_mask = ~mode_mask; |
michael@0 | 3246 | } |
michael@0 | 3247 | |
michael@0 | 3248 | for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) { |
michael@0 | 3249 | if (cpi->ref_frame_flags & flag_list[ref_frame]) { |
michael@0 | 3250 | setup_buffer_inter(cpi, x, tile, idx_list[ref_frame], ref_frame, |
michael@0 | 3251 | block_size, mi_row, mi_col, |
michael@0 | 3252 | frame_mv[NEARESTMV], frame_mv[NEARMV], |
michael@0 | 3253 | yv12_mb, scale_factor); |
michael@0 | 3254 | } |
michael@0 | 3255 | frame_mv[NEWMV][ref_frame].as_int = INVALID_MV; |
michael@0 | 3256 | frame_mv[ZEROMV][ref_frame].as_int = 0; |
michael@0 | 3257 | } |
michael@0 | 3258 | |
michael@0 | 3259 | for (mode_index = 0; mode_index < MAX_MODES; ++mode_index) { |
michael@0 | 3260 | int mode_excluded = 0; |
michael@0 | 3261 | int64_t this_rd = INT64_MAX; |
michael@0 | 3262 | int disable_skip = 0; |
michael@0 | 3263 | int compmode_cost = 0; |
michael@0 | 3264 | int rate2 = 0, rate_y = 0, rate_uv = 0; |
michael@0 | 3265 | int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0; |
michael@0 | 3266 | int skippable = 0; |
michael@0 | 3267 | int64_t tx_cache[TX_MODES]; |
michael@0 | 3268 | int i; |
michael@0 | 3269 | int this_skip2 = 0; |
michael@0 | 3270 | int64_t total_sse = INT_MAX; |
michael@0 | 3271 | int early_term = 0; |
michael@0 | 3272 | |
michael@0 | 3273 | for (i = 0; i < TX_MODES; ++i) |
michael@0 | 3274 | tx_cache[i] = INT64_MAX; |
michael@0 | 3275 | |
michael@0 | 3276 | x->skip = 0; |
michael@0 | 3277 | this_mode = vp9_mode_order[mode_index].mode; |
michael@0 | 3278 | ref_frame = vp9_mode_order[mode_index].ref_frame; |
michael@0 | 3279 | second_ref_frame = vp9_mode_order[mode_index].second_ref_frame; |
michael@0 | 3280 | |
michael@0 | 3281 | // Look at the reference frame of the best mode so far and set the |
michael@0 | 3282 | // skip mask to look at a subset of the remaining modes. |
michael@0 | 3283 | if (mode_index > cpi->sf.mode_skip_start) { |
michael@0 | 3284 | if (mode_index == (cpi->sf.mode_skip_start + 1)) { |
michael@0 | 3285 | switch (vp9_mode_order[best_mode_index].ref_frame) { |
michael@0 | 3286 | case INTRA_FRAME: |
michael@0 | 3287 | cpi->mode_skip_mask = 0; |
michael@0 | 3288 | break; |
michael@0 | 3289 | case LAST_FRAME: |
michael@0 | 3290 | cpi->mode_skip_mask = LAST_FRAME_MODE_MASK; |
michael@0 | 3291 | break; |
michael@0 | 3292 | case GOLDEN_FRAME: |
michael@0 | 3293 | cpi->mode_skip_mask = GOLDEN_FRAME_MODE_MASK; |
michael@0 | 3294 | break; |
michael@0 | 3295 | case ALTREF_FRAME: |
michael@0 | 3296 | cpi->mode_skip_mask = ALT_REF_MODE_MASK; |
michael@0 | 3297 | break; |
michael@0 | 3298 | case NONE: |
michael@0 | 3299 | case MAX_REF_FRAMES: |
michael@0 | 3300 | assert(!"Invalid Reference frame"); |
michael@0 | 3301 | } |
michael@0 | 3302 | } |
michael@0 | 3303 | if (cpi->mode_skip_mask & ((int64_t)1 << mode_index)) |
michael@0 | 3304 | continue; |
michael@0 | 3305 | } |
michael@0 | 3306 | |
michael@0 | 3307 | // Skip if the current reference frame has been masked off |
michael@0 | 3308 | if (cpi->sf.reference_masking && !cpi->set_ref_frame_mask && |
michael@0 | 3309 | (cpi->ref_frame_mask & (1 << ref_frame))) |
michael@0 | 3310 | continue; |
michael@0 | 3311 | |
michael@0 | 3312 | // Test best rd so far against threshold for trying this mode. |
michael@0 | 3313 | if ((best_rd < ((int64_t)cpi->rd_threshes[segment_id][bsize][mode_index] * |
michael@0 | 3314 | cpi->rd_thresh_freq_fact[bsize][mode_index] >> 5)) || |
michael@0 | 3315 | cpi->rd_threshes[segment_id][bsize][mode_index] == INT_MAX) |
michael@0 | 3316 | continue; |
michael@0 | 3317 | |
michael@0 | 3318 | // Do not allow compound prediction if the segment level reference |
michael@0 | 3319 | // frame feature is in use as in this case there can only be one reference. |
michael@0 | 3320 | if ((second_ref_frame > INTRA_FRAME) && |
michael@0 | 3321 | vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) |
michael@0 | 3322 | continue; |
michael@0 | 3323 | |
michael@0 | 3324 | // Skip some checking based on small partitions' result. |
michael@0 | 3325 | if (x->fast_ms > 1 && !ref_frame) |
michael@0 | 3326 | continue; |
michael@0 | 3327 | if (x->fast_ms > 2 && ref_frame != x->subblock_ref) |
michael@0 | 3328 | continue; |
michael@0 | 3329 | |
michael@0 | 3330 | if (cpi->sf.use_avoid_tested_higherror && bsize >= BLOCK_8X8) { |
michael@0 | 3331 | if (!(ref_frame_mask & (1 << ref_frame))) { |
michael@0 | 3332 | continue; |
michael@0 | 3333 | } |
michael@0 | 3334 | if (!(mode_mask & (1 << this_mode))) { |
michael@0 | 3335 | continue; |
michael@0 | 3336 | } |
michael@0 | 3337 | if (second_ref_frame != NONE |
michael@0 | 3338 | && !(ref_frame_mask & (1 << second_ref_frame))) { |
michael@0 | 3339 | continue; |
michael@0 | 3340 | } |
michael@0 | 3341 | } |
michael@0 | 3342 | |
michael@0 | 3343 | mbmi->ref_frame[0] = ref_frame; |
michael@0 | 3344 | mbmi->ref_frame[1] = second_ref_frame; |
michael@0 | 3345 | |
michael@0 | 3346 | if (!(ref_frame == INTRA_FRAME |
michael@0 | 3347 | || (cpi->ref_frame_flags & flag_list[ref_frame]))) { |
michael@0 | 3348 | continue; |
michael@0 | 3349 | } |
michael@0 | 3350 | if (!(second_ref_frame == NONE |
michael@0 | 3351 | || (cpi->ref_frame_flags & flag_list[second_ref_frame]))) { |
michael@0 | 3352 | continue; |
michael@0 | 3353 | } |
michael@0 | 3354 | |
michael@0 | 3355 | comp_pred = second_ref_frame > INTRA_FRAME; |
michael@0 | 3356 | if (comp_pred) { |
michael@0 | 3357 | if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) |
michael@0 | 3358 | if (vp9_mode_order[best_mode_index].ref_frame == INTRA_FRAME) |
michael@0 | 3359 | continue; |
michael@0 | 3360 | if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_COMP_REFMISMATCH) |
michael@0 | 3361 | if (ref_frame != best_inter_ref_frame && |
michael@0 | 3362 | second_ref_frame != best_inter_ref_frame) |
michael@0 | 3363 | continue; |
michael@0 | 3364 | } |
michael@0 | 3365 | |
michael@0 | 3366 | set_scale_factors(xd, ref_frame, second_ref_frame, scale_factor); |
michael@0 | 3367 | mbmi->uv_mode = DC_PRED; |
michael@0 | 3368 | |
michael@0 | 3369 | // Evaluate all sub-pel filters irrespective of whether we can use |
michael@0 | 3370 | // them for this frame. |
michael@0 | 3371 | mbmi->interp_filter = cm->mcomp_filter_type; |
michael@0 | 3372 | vp9_setup_interp_filters(xd, mbmi->interp_filter, cm); |
michael@0 | 3373 | |
michael@0 | 3374 | if (comp_pred) { |
michael@0 | 3375 | if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) |
michael@0 | 3376 | continue; |
michael@0 | 3377 | set_scale_factors(xd, ref_frame, second_ref_frame, scale_factor); |
michael@0 | 3378 | |
michael@0 | 3379 | mode_excluded = mode_excluded |
michael@0 | 3380 | ? mode_excluded |
michael@0 | 3381 | : cm->comp_pred_mode == SINGLE_PREDICTION_ONLY; |
michael@0 | 3382 | } else { |
michael@0 | 3383 | if (ref_frame != INTRA_FRAME && second_ref_frame != INTRA_FRAME) { |
michael@0 | 3384 | mode_excluded = |
michael@0 | 3385 | mode_excluded ? |
michael@0 | 3386 | mode_excluded : cm->comp_pred_mode == COMP_PREDICTION_ONLY; |
michael@0 | 3387 | } |
michael@0 | 3388 | } |
michael@0 | 3389 | |
michael@0 | 3390 | // Select prediction reference frames. |
michael@0 | 3391 | for (i = 0; i < MAX_MB_PLANE; i++) { |
michael@0 | 3392 | xd->plane[i].pre[0] = yv12_mb[ref_frame][i]; |
michael@0 | 3393 | if (comp_pred) |
michael@0 | 3394 | xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i]; |
michael@0 | 3395 | } |
michael@0 | 3396 | |
michael@0 | 3397 | // If the segment reference frame feature is enabled.... |
michael@0 | 3398 | // then do nothing if the current ref frame is not allowed.. |
michael@0 | 3399 | if (vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) && |
michael@0 | 3400 | vp9_get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != |
michael@0 | 3401 | (int)ref_frame) { |
michael@0 | 3402 | continue; |
michael@0 | 3403 | // If the segment skip feature is enabled.... |
michael@0 | 3404 | // then do nothing if the current mode is not allowed.. |
michael@0 | 3405 | } else if (vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP) && |
michael@0 | 3406 | (this_mode != ZEROMV && ref_frame != INTRA_FRAME)) { |
michael@0 | 3407 | continue; |
michael@0 | 3408 | // Disable this drop out case if the ref frame |
michael@0 | 3409 | // segment level feature is enabled for this segment. This is to |
michael@0 | 3410 | // prevent the possibility that we end up unable to pick any mode. |
michael@0 | 3411 | } else if (!vp9_segfeature_active(seg, segment_id, |
michael@0 | 3412 | SEG_LVL_REF_FRAME)) { |
michael@0 | 3413 | // Only consider ZEROMV/ALTREF_FRAME for alt ref frame, |
michael@0 | 3414 | // unless ARNR filtering is enabled in which case we want |
michael@0 | 3415 | // an unfiltered alternative. We allow near/nearest as well |
michael@0 | 3416 | // because they may result in zero-zero MVs but be cheaper. |
michael@0 | 3417 | if (cpi->is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) { |
michael@0 | 3418 | if ((this_mode != ZEROMV && |
michael@0 | 3419 | !(this_mode == NEARMV && |
michael@0 | 3420 | frame_mv[NEARMV][ALTREF_FRAME].as_int == 0) && |
michael@0 | 3421 | !(this_mode == NEARESTMV && |
michael@0 | 3422 | frame_mv[NEARESTMV][ALTREF_FRAME].as_int == 0)) || |
michael@0 | 3423 | ref_frame != ALTREF_FRAME) { |
michael@0 | 3424 | continue; |
michael@0 | 3425 | } |
michael@0 | 3426 | } |
michael@0 | 3427 | } |
michael@0 | 3428 | // TODO(JBB): This is to make up for the fact that we don't have sad |
michael@0 | 3429 | // functions that work when the block size reads outside the umv. We |
michael@0 | 3430 | // should fix this either by making the motion search just work on |
michael@0 | 3431 | // a representative block in the boundary ( first ) and then implement a |
michael@0 | 3432 | // function that does sads when inside the border.. |
michael@0 | 3433 | if (((mi_row + bhs) > cm->mi_rows || (mi_col + bws) > cm->mi_cols) && |
michael@0 | 3434 | this_mode == NEWMV) { |
michael@0 | 3435 | continue; |
michael@0 | 3436 | } |
michael@0 | 3437 | |
michael@0 | 3438 | #ifdef MODE_TEST_HIT_STATS |
michael@0 | 3439 | // TEST/DEBUG CODE |
michael@0 | 3440 | // Keep a rcord of the number of test hits at each size |
michael@0 | 3441 | cpi->mode_test_hits[bsize]++; |
michael@0 | 3442 | #endif |
michael@0 | 3443 | |
michael@0 | 3444 | |
michael@0 | 3445 | if (ref_frame == INTRA_FRAME) { |
michael@0 | 3446 | TX_SIZE uv_tx; |
michael@0 | 3447 | // Disable intra modes other than DC_PRED for blocks with low variance |
michael@0 | 3448 | // Threshold for intra skipping based on source variance |
michael@0 | 3449 | // TODO(debargha): Specialize the threshold for super block sizes |
michael@0 | 3450 | static const unsigned int skip_intra_var_thresh[BLOCK_SIZES] = { |
michael@0 | 3451 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
michael@0 | 3452 | }; |
michael@0 | 3453 | if ((cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) && |
michael@0 | 3454 | this_mode != DC_PRED && |
michael@0 | 3455 | x->source_variance < skip_intra_var_thresh[mbmi->sb_type]) |
michael@0 | 3456 | continue; |
michael@0 | 3457 | // Only search the oblique modes if the best so far is |
michael@0 | 3458 | // one of the neighboring directional modes |
michael@0 | 3459 | if ((cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) && |
michael@0 | 3460 | (this_mode >= D45_PRED && this_mode <= TM_PRED)) { |
michael@0 | 3461 | if (vp9_mode_order[best_mode_index].ref_frame > INTRA_FRAME) |
michael@0 | 3462 | continue; |
michael@0 | 3463 | } |
michael@0 | 3464 | mbmi->mode = this_mode; |
michael@0 | 3465 | if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) { |
michael@0 | 3466 | if (conditional_skipintra(mbmi->mode, best_intra_mode)) |
michael@0 | 3467 | continue; |
michael@0 | 3468 | } |
michael@0 | 3469 | |
michael@0 | 3470 | super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable, NULL, |
michael@0 | 3471 | bsize, tx_cache, best_rd); |
michael@0 | 3472 | |
michael@0 | 3473 | if (rate_y == INT_MAX) |
michael@0 | 3474 | continue; |
michael@0 | 3475 | |
michael@0 | 3476 | uv_tx = MIN(mbmi->tx_size, max_uv_txsize_lookup[bsize]); |
michael@0 | 3477 | if (rate_uv_intra[uv_tx] == INT_MAX) { |
michael@0 | 3478 | choose_intra_uv_mode(cpi, ctx, bsize, &rate_uv_intra[uv_tx], |
michael@0 | 3479 | &rate_uv_tokenonly[uv_tx], |
michael@0 | 3480 | &dist_uv[uv_tx], &skip_uv[uv_tx], |
michael@0 | 3481 | &mode_uv[uv_tx]); |
michael@0 | 3482 | } |
michael@0 | 3483 | |
michael@0 | 3484 | rate_uv = rate_uv_tokenonly[uv_tx]; |
michael@0 | 3485 | distortion_uv = dist_uv[uv_tx]; |
michael@0 | 3486 | skippable = skippable && skip_uv[uv_tx]; |
michael@0 | 3487 | mbmi->uv_mode = mode_uv[uv_tx]; |
michael@0 | 3488 | |
michael@0 | 3489 | rate2 = rate_y + x->mbmode_cost[mbmi->mode] + rate_uv_intra[uv_tx]; |
michael@0 | 3490 | if (this_mode != DC_PRED && this_mode != TM_PRED) |
michael@0 | 3491 | rate2 += intra_cost_penalty; |
michael@0 | 3492 | distortion2 = distortion_y + distortion_uv; |
michael@0 | 3493 | } else { |
michael@0 | 3494 | mbmi->mode = this_mode; |
michael@0 | 3495 | compmode_cost = vp9_cost_bit(comp_mode_p, second_ref_frame > INTRA_FRAME); |
michael@0 | 3496 | this_rd = handle_inter_mode(cpi, x, tile, bsize, |
michael@0 | 3497 | tx_cache, |
michael@0 | 3498 | &rate2, &distortion2, &skippable, |
michael@0 | 3499 | &rate_y, &distortion_y, |
michael@0 | 3500 | &rate_uv, &distortion_uv, |
michael@0 | 3501 | &mode_excluded, &disable_skip, |
michael@0 | 3502 | &tmp_best_filter, frame_mv, |
michael@0 | 3503 | mi_row, mi_col, |
michael@0 | 3504 | single_newmv, &total_sse, best_rd); |
michael@0 | 3505 | if (this_rd == INT64_MAX) |
michael@0 | 3506 | continue; |
michael@0 | 3507 | } |
michael@0 | 3508 | |
michael@0 | 3509 | if (cm->comp_pred_mode == HYBRID_PREDICTION) { |
michael@0 | 3510 | rate2 += compmode_cost; |
michael@0 | 3511 | } |
michael@0 | 3512 | |
michael@0 | 3513 | // Estimate the reference frame signaling cost and add it |
michael@0 | 3514 | // to the rolling cost variable. |
michael@0 | 3515 | if (second_ref_frame > INTRA_FRAME) { |
michael@0 | 3516 | rate2 += ref_costs_comp[ref_frame]; |
michael@0 | 3517 | } else { |
michael@0 | 3518 | rate2 += ref_costs_single[ref_frame]; |
michael@0 | 3519 | } |
michael@0 | 3520 | |
michael@0 | 3521 | if (!disable_skip) { |
michael@0 | 3522 | // Test for the condition where skip block will be activated |
michael@0 | 3523 | // because there are no non zero coefficients and make any |
michael@0 | 3524 | // necessary adjustment for rate. Ignore if skip is coded at |
michael@0 | 3525 | // segment level as the cost wont have been added in. |
michael@0 | 3526 | // Is Mb level skip allowed (i.e. not coded at segment level). |
michael@0 | 3527 | const int mb_skip_allowed = !vp9_segfeature_active(seg, segment_id, |
michael@0 | 3528 | SEG_LVL_SKIP); |
michael@0 | 3529 | |
michael@0 | 3530 | if (skippable) { |
michael@0 | 3531 | // Back out the coefficient coding costs |
michael@0 | 3532 | rate2 -= (rate_y + rate_uv); |
michael@0 | 3533 | // for best yrd calculation |
michael@0 | 3534 | rate_uv = 0; |
michael@0 | 3535 | |
michael@0 | 3536 | if (mb_skip_allowed) { |
michael@0 | 3537 | int prob_skip_cost; |
michael@0 | 3538 | |
michael@0 | 3539 | // Cost the skip mb case |
michael@0 | 3540 | vp9_prob skip_prob = |
michael@0 | 3541 | vp9_get_pred_prob_mbskip(cm, xd); |
michael@0 | 3542 | |
michael@0 | 3543 | if (skip_prob) { |
michael@0 | 3544 | prob_skip_cost = vp9_cost_bit(skip_prob, 1); |
michael@0 | 3545 | rate2 += prob_skip_cost; |
michael@0 | 3546 | } |
michael@0 | 3547 | } |
michael@0 | 3548 | } else if (mb_skip_allowed && ref_frame != INTRA_FRAME && !xd->lossless) { |
michael@0 | 3549 | if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) < |
michael@0 | 3550 | RDCOST(x->rdmult, x->rddiv, 0, total_sse)) { |
michael@0 | 3551 | // Add in the cost of the no skip flag. |
michael@0 | 3552 | int prob_skip_cost = vp9_cost_bit(vp9_get_pred_prob_mbskip(cm, xd), |
michael@0 | 3553 | 0); |
michael@0 | 3554 | rate2 += prob_skip_cost; |
michael@0 | 3555 | } else { |
michael@0 | 3556 | // FIXME(rbultje) make this work for splitmv also |
michael@0 | 3557 | int prob_skip_cost = vp9_cost_bit(vp9_get_pred_prob_mbskip(cm, xd), |
michael@0 | 3558 | 1); |
michael@0 | 3559 | rate2 += prob_skip_cost; |
michael@0 | 3560 | distortion2 = total_sse; |
michael@0 | 3561 | assert(total_sse >= 0); |
michael@0 | 3562 | rate2 -= (rate_y + rate_uv); |
michael@0 | 3563 | rate_y = 0; |
michael@0 | 3564 | rate_uv = 0; |
michael@0 | 3565 | this_skip2 = 1; |
michael@0 | 3566 | } |
michael@0 | 3567 | } else if (mb_skip_allowed) { |
michael@0 | 3568 | // Add in the cost of the no skip flag. |
michael@0 | 3569 | int prob_skip_cost = vp9_cost_bit(vp9_get_pred_prob_mbskip(cm, xd), |
michael@0 | 3570 | 0); |
michael@0 | 3571 | rate2 += prob_skip_cost; |
michael@0 | 3572 | } |
michael@0 | 3573 | |
michael@0 | 3574 | // Calculate the final RD estimate for this mode. |
michael@0 | 3575 | this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2); |
michael@0 | 3576 | } |
michael@0 | 3577 | |
michael@0 | 3578 | // Keep record of best intra rd |
michael@0 | 3579 | if (!is_inter_block(&xd->mi_8x8[0]->mbmi) && |
michael@0 | 3580 | this_rd < best_intra_rd) { |
michael@0 | 3581 | best_intra_rd = this_rd; |
michael@0 | 3582 | best_intra_mode = xd->mi_8x8[0]->mbmi.mode; |
michael@0 | 3583 | } |
michael@0 | 3584 | |
michael@0 | 3585 | // Keep record of best inter rd with single reference |
michael@0 | 3586 | if (is_inter_block(&xd->mi_8x8[0]->mbmi) && |
michael@0 | 3587 | !has_second_ref(&xd->mi_8x8[0]->mbmi) && |
michael@0 | 3588 | !mode_excluded && this_rd < best_inter_rd) { |
michael@0 | 3589 | best_inter_rd = this_rd; |
michael@0 | 3590 | best_inter_ref_frame = ref_frame; |
michael@0 | 3591 | } |
michael@0 | 3592 | |
michael@0 | 3593 | if (!disable_skip && ref_frame == INTRA_FRAME) { |
michael@0 | 3594 | for (i = 0; i < NB_PREDICTION_TYPES; ++i) |
michael@0 | 3595 | best_pred_rd[i] = MIN(best_pred_rd[i], this_rd); |
michael@0 | 3596 | for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) |
michael@0 | 3597 | best_filter_rd[i] = MIN(best_filter_rd[i], this_rd); |
michael@0 | 3598 | } |
michael@0 | 3599 | |
michael@0 | 3600 | // Store the respective mode distortions for later use. |
michael@0 | 3601 | if (mode_distortions[this_mode] == -1 |
michael@0 | 3602 | || distortion2 < mode_distortions[this_mode]) { |
michael@0 | 3603 | mode_distortions[this_mode] = distortion2; |
michael@0 | 3604 | } |
michael@0 | 3605 | if (frame_distortions[ref_frame] == -1 |
michael@0 | 3606 | || distortion2 < frame_distortions[ref_frame]) { |
michael@0 | 3607 | frame_distortions[ref_frame] = distortion2; |
michael@0 | 3608 | } |
michael@0 | 3609 | |
michael@0 | 3610 | // Did this mode help.. i.e. is it the new best mode |
michael@0 | 3611 | if (this_rd < best_rd || x->skip) { |
michael@0 | 3612 | int max_plane = MAX_MB_PLANE; |
michael@0 | 3613 | if (!mode_excluded) { |
michael@0 | 3614 | // Note index of best mode so far |
michael@0 | 3615 | best_mode_index = mode_index; |
michael@0 | 3616 | |
michael@0 | 3617 | if (ref_frame == INTRA_FRAME) { |
michael@0 | 3618 | /* required for left and above block mv */ |
michael@0 | 3619 | mbmi->mv[0].as_int = 0; |
michael@0 | 3620 | max_plane = 1; |
michael@0 | 3621 | } |
michael@0 | 3622 | |
michael@0 | 3623 | *returnrate = rate2; |
michael@0 | 3624 | *returndistortion = distortion2; |
michael@0 | 3625 | best_rd = this_rd; |
michael@0 | 3626 | best_mbmode = *mbmi; |
michael@0 | 3627 | best_skip2 = this_skip2; |
michael@0 | 3628 | if (!x->select_txfm_size) |
michael@0 | 3629 | swap_block_ptr(x, ctx, max_plane); |
michael@0 | 3630 | vpx_memcpy(ctx->zcoeff_blk, x->zcoeff_blk[mbmi->tx_size], |
michael@0 | 3631 | sizeof(uint8_t) * ctx->num_4x4_blk); |
michael@0 | 3632 | |
michael@0 | 3633 | // TODO(debargha): enhance this test with a better distortion prediction |
michael@0 | 3634 | // based on qp, activity mask and history |
michael@0 | 3635 | if ((cpi->sf.mode_search_skip_flags & FLAG_EARLY_TERMINATE) && |
michael@0 | 3636 | (mode_index > MIN_EARLY_TERM_INDEX)) { |
michael@0 | 3637 | const int qstep = xd->plane[0].dequant[1]; |
michael@0 | 3638 | // TODO(debargha): Enhance this by specializing for each mode_index |
michael@0 | 3639 | int scale = 4; |
michael@0 | 3640 | if (x->source_variance < UINT_MAX) { |
michael@0 | 3641 | const int var_adjust = (x->source_variance < 16); |
michael@0 | 3642 | scale -= var_adjust; |
michael@0 | 3643 | } |
michael@0 | 3644 | if (ref_frame > INTRA_FRAME && |
michael@0 | 3645 | distortion2 * scale < qstep * qstep) { |
michael@0 | 3646 | early_term = 1; |
michael@0 | 3647 | } |
michael@0 | 3648 | } |
michael@0 | 3649 | } |
michael@0 | 3650 | } |
michael@0 | 3651 | |
michael@0 | 3652 | /* keep record of best compound/single-only prediction */ |
michael@0 | 3653 | if (!disable_skip && ref_frame != INTRA_FRAME) { |
michael@0 | 3654 | int single_rd, hybrid_rd, single_rate, hybrid_rate; |
michael@0 | 3655 | |
michael@0 | 3656 | if (cm->comp_pred_mode == HYBRID_PREDICTION) { |
michael@0 | 3657 | single_rate = rate2 - compmode_cost; |
michael@0 | 3658 | hybrid_rate = rate2; |
michael@0 | 3659 | } else { |
michael@0 | 3660 | single_rate = rate2; |
michael@0 | 3661 | hybrid_rate = rate2 + compmode_cost; |
michael@0 | 3662 | } |
michael@0 | 3663 | |
michael@0 | 3664 | single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2); |
michael@0 | 3665 | hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2); |
michael@0 | 3666 | |
michael@0 | 3667 | if (second_ref_frame <= INTRA_FRAME && |
michael@0 | 3668 | single_rd < best_pred_rd[SINGLE_PREDICTION_ONLY]) { |
michael@0 | 3669 | best_pred_rd[SINGLE_PREDICTION_ONLY] = single_rd; |
michael@0 | 3670 | } else if (second_ref_frame > INTRA_FRAME && |
michael@0 | 3671 | single_rd < best_pred_rd[COMP_PREDICTION_ONLY]) { |
michael@0 | 3672 | best_pred_rd[COMP_PREDICTION_ONLY] = single_rd; |
michael@0 | 3673 | } |
michael@0 | 3674 | if (hybrid_rd < best_pred_rd[HYBRID_PREDICTION]) |
michael@0 | 3675 | best_pred_rd[HYBRID_PREDICTION] = hybrid_rd; |
michael@0 | 3676 | } |
michael@0 | 3677 | |
michael@0 | 3678 | /* keep record of best filter type */ |
michael@0 | 3679 | if (!mode_excluded && !disable_skip && ref_frame != INTRA_FRAME && |
michael@0 | 3680 | cm->mcomp_filter_type != BILINEAR) { |
michael@0 | 3681 | int64_t ref = cpi->rd_filter_cache[cm->mcomp_filter_type == SWITCHABLE ? |
michael@0 | 3682 | SWITCHABLE_FILTERS : cm->mcomp_filter_type]; |
michael@0 | 3683 | for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) { |
michael@0 | 3684 | int64_t adj_rd; |
michael@0 | 3685 | // In cases of poor prediction, filter_cache[] can contain really big |
michael@0 | 3686 | // values, which actually are bigger than this_rd itself. This can |
michael@0 | 3687 | // cause negative best_filter_rd[] values, which is obviously silly. |
michael@0 | 3688 | // Therefore, if filter_cache < ref, we do an adjusted calculation. |
michael@0 | 3689 | if (cpi->rd_filter_cache[i] >= ref) { |
michael@0 | 3690 | adj_rd = this_rd + cpi->rd_filter_cache[i] - ref; |
michael@0 | 3691 | } else { |
michael@0 | 3692 | // FIXME(rbultje) do this for comppsred also |
michael@0 | 3693 | // |
michael@0 | 3694 | // To prevent out-of-range computation in |
michael@0 | 3695 | // adj_rd = cpi->rd_filter_cache[i] * this_rd / ref |
michael@0 | 3696 | // cpi->rd_filter_cache[i] / ref is converted to a 256 based ratio. |
michael@0 | 3697 | int tmp = cpi->rd_filter_cache[i] * 256 / ref; |
michael@0 | 3698 | adj_rd = (this_rd * tmp) >> 8; |
michael@0 | 3699 | } |
michael@0 | 3700 | best_filter_rd[i] = MIN(best_filter_rd[i], adj_rd); |
michael@0 | 3701 | } |
michael@0 | 3702 | } |
michael@0 | 3703 | |
michael@0 | 3704 | /* keep record of best txfm size */ |
michael@0 | 3705 | if (bsize < BLOCK_32X32) { |
michael@0 | 3706 | if (bsize < BLOCK_16X16) |
michael@0 | 3707 | tx_cache[ALLOW_16X16] = tx_cache[ALLOW_8X8]; |
michael@0 | 3708 | |
michael@0 | 3709 | tx_cache[ALLOW_32X32] = tx_cache[ALLOW_16X16]; |
michael@0 | 3710 | } |
michael@0 | 3711 | if (!mode_excluded && this_rd != INT64_MAX) { |
michael@0 | 3712 | for (i = 0; i < TX_MODES && tx_cache[i] < INT64_MAX; i++) { |
michael@0 | 3713 | int64_t adj_rd = INT64_MAX; |
michael@0 | 3714 | adj_rd = this_rd + tx_cache[i] - tx_cache[cm->tx_mode]; |
michael@0 | 3715 | |
michael@0 | 3716 | if (adj_rd < best_tx_rd[i]) |
michael@0 | 3717 | best_tx_rd[i] = adj_rd; |
michael@0 | 3718 | } |
michael@0 | 3719 | } |
michael@0 | 3720 | |
michael@0 | 3721 | if (early_term) |
michael@0 | 3722 | break; |
michael@0 | 3723 | |
michael@0 | 3724 | if (x->skip && !comp_pred) |
michael@0 | 3725 | break; |
michael@0 | 3726 | } |
michael@0 | 3727 | |
michael@0 | 3728 | if (best_rd >= best_rd_so_far) |
michael@0 | 3729 | return INT64_MAX; |
michael@0 | 3730 | |
michael@0 | 3731 | // If we used an estimate for the uv intra rd in the loop above... |
michael@0 | 3732 | if (cpi->sf.use_uv_intra_rd_estimate) { |
michael@0 | 3733 | // Do Intra UV best rd mode selection if best mode choice above was intra. |
michael@0 | 3734 | if (vp9_mode_order[best_mode_index].ref_frame == INTRA_FRAME) { |
michael@0 | 3735 | TX_SIZE uv_tx_size = get_uv_tx_size(mbmi); |
michael@0 | 3736 | rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv_intra[uv_tx_size], |
michael@0 | 3737 | &rate_uv_tokenonly[uv_tx_size], |
michael@0 | 3738 | &dist_uv[uv_tx_size], |
michael@0 | 3739 | &skip_uv[uv_tx_size], |
michael@0 | 3740 | bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize); |
michael@0 | 3741 | } |
michael@0 | 3742 | } |
michael@0 | 3743 | |
michael@0 | 3744 | // If we are using reference masking and the set mask flag is set then |
michael@0 | 3745 | // create the reference frame mask. |
michael@0 | 3746 | if (cpi->sf.reference_masking && cpi->set_ref_frame_mask) |
michael@0 | 3747 | cpi->ref_frame_mask = ~(1 << vp9_mode_order[best_mode_index].ref_frame); |
michael@0 | 3748 | |
michael@0 | 3749 | // Flag all modes that have a distortion thats > 2x the best we found at |
michael@0 | 3750 | // this level. |
michael@0 | 3751 | for (mode_index = 0; mode_index < MB_MODE_COUNT; ++mode_index) { |
michael@0 | 3752 | if (mode_index == NEARESTMV || mode_index == NEARMV || mode_index == NEWMV) |
michael@0 | 3753 | continue; |
michael@0 | 3754 | |
michael@0 | 3755 | if (mode_distortions[mode_index] > 2 * *returndistortion) { |
michael@0 | 3756 | ctx->modes_with_high_error |= (1 << mode_index); |
michael@0 | 3757 | } |
michael@0 | 3758 | } |
michael@0 | 3759 | |
michael@0 | 3760 | // Flag all ref frames that have a distortion thats > 2x the best we found at |
michael@0 | 3761 | // this level. |
michael@0 | 3762 | for (ref_frame = INTRA_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) { |
michael@0 | 3763 | if (frame_distortions[ref_frame] > 2 * *returndistortion) { |
michael@0 | 3764 | ctx->frames_with_high_error |= (1 << ref_frame); |
michael@0 | 3765 | } |
michael@0 | 3766 | } |
michael@0 | 3767 | |
michael@0 | 3768 | assert((cm->mcomp_filter_type == SWITCHABLE) || |
michael@0 | 3769 | (cm->mcomp_filter_type == best_mbmode.interp_filter) || |
michael@0 | 3770 | (best_mbmode.ref_frame[0] == INTRA_FRAME)); |
michael@0 | 3771 | |
michael@0 | 3772 | // Updating rd_thresh_freq_fact[] here means that the different |
michael@0 | 3773 | // partition/block sizes are handled independently based on the best |
michael@0 | 3774 | // choice for the current partition. It may well be better to keep a scaled |
michael@0 | 3775 | // best rd so far value and update rd_thresh_freq_fact based on the mode/size |
michael@0 | 3776 | // combination that wins out. |
michael@0 | 3777 | if (cpi->sf.adaptive_rd_thresh) { |
michael@0 | 3778 | for (mode_index = 0; mode_index < MAX_MODES; ++mode_index) { |
michael@0 | 3779 | if (mode_index == best_mode_index) { |
michael@0 | 3780 | cpi->rd_thresh_freq_fact[bsize][mode_index] -= |
michael@0 | 3781 | (cpi->rd_thresh_freq_fact[bsize][mode_index] >> 3); |
michael@0 | 3782 | } else { |
michael@0 | 3783 | cpi->rd_thresh_freq_fact[bsize][mode_index] += RD_THRESH_INC; |
michael@0 | 3784 | if (cpi->rd_thresh_freq_fact[bsize][mode_index] > |
michael@0 | 3785 | (cpi->sf.adaptive_rd_thresh * RD_THRESH_MAX_FACT)) { |
michael@0 | 3786 | cpi->rd_thresh_freq_fact[bsize][mode_index] = |
michael@0 | 3787 | cpi->sf.adaptive_rd_thresh * RD_THRESH_MAX_FACT; |
michael@0 | 3788 | } |
michael@0 | 3789 | } |
michael@0 | 3790 | } |
michael@0 | 3791 | } |
michael@0 | 3792 | |
michael@0 | 3793 | // macroblock modes |
michael@0 | 3794 | *mbmi = best_mbmode; |
michael@0 | 3795 | x->skip |= best_skip2; |
michael@0 | 3796 | |
michael@0 | 3797 | for (i = 0; i < NB_PREDICTION_TYPES; ++i) { |
michael@0 | 3798 | if (best_pred_rd[i] == INT64_MAX) |
michael@0 | 3799 | best_pred_diff[i] = INT_MIN; |
michael@0 | 3800 | else |
michael@0 | 3801 | best_pred_diff[i] = best_rd - best_pred_rd[i]; |
michael@0 | 3802 | } |
michael@0 | 3803 | |
michael@0 | 3804 | if (!x->skip) { |
michael@0 | 3805 | for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) { |
michael@0 | 3806 | if (best_filter_rd[i] == INT64_MAX) |
michael@0 | 3807 | best_filter_diff[i] = 0; |
michael@0 | 3808 | else |
michael@0 | 3809 | best_filter_diff[i] = best_rd - best_filter_rd[i]; |
michael@0 | 3810 | } |
michael@0 | 3811 | if (cm->mcomp_filter_type == SWITCHABLE) |
michael@0 | 3812 | assert(best_filter_diff[SWITCHABLE_FILTERS] == 0); |
michael@0 | 3813 | } else { |
michael@0 | 3814 | vp9_zero(best_filter_diff); |
michael@0 | 3815 | } |
michael@0 | 3816 | |
michael@0 | 3817 | if (!x->skip) { |
michael@0 | 3818 | for (i = 0; i < TX_MODES; i++) { |
michael@0 | 3819 | if (best_tx_rd[i] == INT64_MAX) |
michael@0 | 3820 | best_tx_diff[i] = 0; |
michael@0 | 3821 | else |
michael@0 | 3822 | best_tx_diff[i] = best_rd - best_tx_rd[i]; |
michael@0 | 3823 | } |
michael@0 | 3824 | } else { |
michael@0 | 3825 | vp9_zero(best_tx_diff); |
michael@0 | 3826 | } |
michael@0 | 3827 | |
michael@0 | 3828 | set_scale_factors(xd, mbmi->ref_frame[0], mbmi->ref_frame[1], |
michael@0 | 3829 | scale_factor); |
michael@0 | 3830 | store_coding_context(x, ctx, best_mode_index, |
michael@0 | 3831 | &mbmi->ref_mvs[mbmi->ref_frame[0]][0], |
michael@0 | 3832 | &mbmi->ref_mvs[mbmi->ref_frame[1] < 0 ? 0 : |
michael@0 | 3833 | mbmi->ref_frame[1]][0], |
michael@0 | 3834 | best_pred_diff, best_tx_diff, best_filter_diff); |
michael@0 | 3835 | |
michael@0 | 3836 | return best_rd; |
michael@0 | 3837 | } |
michael@0 | 3838 | |
michael@0 | 3839 | |
michael@0 | 3840 | int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, |
michael@0 | 3841 | const TileInfo *const tile, |
michael@0 | 3842 | int mi_row, int mi_col, |
michael@0 | 3843 | int *returnrate, |
michael@0 | 3844 | int64_t *returndistortion, |
michael@0 | 3845 | BLOCK_SIZE bsize, |
michael@0 | 3846 | PICK_MODE_CONTEXT *ctx, |
michael@0 | 3847 | int64_t best_rd_so_far) { |
michael@0 | 3848 | VP9_COMMON *cm = &cpi->common; |
michael@0 | 3849 | MACROBLOCKD *xd = &x->e_mbd; |
michael@0 | 3850 | MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; |
michael@0 | 3851 | const struct segmentation *seg = &cm->seg; |
michael@0 | 3852 | const BLOCK_SIZE block_size = get_plane_block_size(bsize, &xd->plane[0]); |
michael@0 | 3853 | MV_REFERENCE_FRAME ref_frame, second_ref_frame; |
michael@0 | 3854 | unsigned char segment_id = mbmi->segment_id; |
michael@0 | 3855 | int comp_pred, i; |
michael@0 | 3856 | int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES]; |
michael@0 | 3857 | struct buf_2d yv12_mb[4][MAX_MB_PLANE]; |
michael@0 | 3858 | static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG, |
michael@0 | 3859 | VP9_ALT_FLAG }; |
michael@0 | 3860 | int idx_list[4] = {0, |
michael@0 | 3861 | cpi->lst_fb_idx, |
michael@0 | 3862 | cpi->gld_fb_idx, |
michael@0 | 3863 | cpi->alt_fb_idx}; |
michael@0 | 3864 | int64_t best_rd = best_rd_so_far; |
michael@0 | 3865 | int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise |
michael@0 | 3866 | int64_t best_tx_rd[TX_MODES]; |
michael@0 | 3867 | int64_t best_tx_diff[TX_MODES]; |
michael@0 | 3868 | int64_t best_pred_diff[NB_PREDICTION_TYPES]; |
michael@0 | 3869 | int64_t best_pred_rd[NB_PREDICTION_TYPES]; |
michael@0 | 3870 | int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS]; |
michael@0 | 3871 | int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS]; |
michael@0 | 3872 | MB_MODE_INFO best_mbmode = { 0 }; |
michael@0 | 3873 | int mode_index, best_mode_index = 0; |
michael@0 | 3874 | unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES]; |
michael@0 | 3875 | vp9_prob comp_mode_p; |
michael@0 | 3876 | int64_t best_inter_rd = INT64_MAX; |
michael@0 | 3877 | MV_REFERENCE_FRAME best_inter_ref_frame = LAST_FRAME; |
michael@0 | 3878 | INTERPOLATION_TYPE tmp_best_filter = SWITCHABLE; |
michael@0 | 3879 | int rate_uv_intra[TX_SIZES], rate_uv_tokenonly[TX_SIZES]; |
michael@0 | 3880 | int64_t dist_uv[TX_SIZES]; |
michael@0 | 3881 | int skip_uv[TX_SIZES]; |
michael@0 | 3882 | MB_PREDICTION_MODE mode_uv[TX_SIZES] = { 0 }; |
michael@0 | 3883 | struct scale_factors scale_factor[4]; |
michael@0 | 3884 | unsigned int ref_frame_mask = 0; |
michael@0 | 3885 | unsigned int mode_mask = 0; |
michael@0 | 3886 | int intra_cost_penalty = 20 * vp9_dc_quant(cpi->common.base_qindex, |
michael@0 | 3887 | cpi->common.y_dc_delta_q); |
michael@0 | 3888 | int_mv seg_mvs[4][MAX_REF_FRAMES]; |
michael@0 | 3889 | b_mode_info best_bmodes[4]; |
michael@0 | 3890 | int best_skip2 = 0; |
michael@0 | 3891 | |
michael@0 | 3892 | x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH; |
michael@0 | 3893 | vpx_memset(x->zcoeff_blk[TX_4X4], 0, 4); |
michael@0 | 3894 | |
michael@0 | 3895 | for (i = 0; i < 4; i++) { |
michael@0 | 3896 | int j; |
michael@0 | 3897 | for (j = 0; j < MAX_REF_FRAMES; j++) |
michael@0 | 3898 | seg_mvs[i][j].as_int = INVALID_MV; |
michael@0 | 3899 | } |
michael@0 | 3900 | |
michael@0 | 3901 | estimate_ref_frame_costs(cpi, segment_id, ref_costs_single, ref_costs_comp, |
michael@0 | 3902 | &comp_mode_p); |
michael@0 | 3903 | |
michael@0 | 3904 | for (i = 0; i < NB_PREDICTION_TYPES; ++i) |
michael@0 | 3905 | best_pred_rd[i] = INT64_MAX; |
michael@0 | 3906 | for (i = 0; i < TX_MODES; i++) |
michael@0 | 3907 | best_tx_rd[i] = INT64_MAX; |
michael@0 | 3908 | for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) |
michael@0 | 3909 | best_filter_rd[i] = INT64_MAX; |
michael@0 | 3910 | for (i = 0; i < TX_SIZES; i++) |
michael@0 | 3911 | rate_uv_intra[i] = INT_MAX; |
michael@0 | 3912 | |
michael@0 | 3913 | *returnrate = INT_MAX; |
michael@0 | 3914 | |
michael@0 | 3915 | // Create a mask set to 1 for each reference frame used by a smaller |
michael@0 | 3916 | // resolution. |
michael@0 | 3917 | if (cpi->sf.use_avoid_tested_higherror) { |
michael@0 | 3918 | ref_frame_mask = 0; |
michael@0 | 3919 | mode_mask = 0; |
michael@0 | 3920 | ref_frame_mask = ~ref_frame_mask; |
michael@0 | 3921 | mode_mask = ~mode_mask; |
michael@0 | 3922 | } |
michael@0 | 3923 | |
michael@0 | 3924 | for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) { |
michael@0 | 3925 | if (cpi->ref_frame_flags & flag_list[ref_frame]) { |
michael@0 | 3926 | setup_buffer_inter(cpi, x, tile, idx_list[ref_frame], ref_frame, |
michael@0 | 3927 | block_size, mi_row, mi_col, |
michael@0 | 3928 | frame_mv[NEARESTMV], frame_mv[NEARMV], |
michael@0 | 3929 | yv12_mb, scale_factor); |
michael@0 | 3930 | } |
michael@0 | 3931 | frame_mv[NEWMV][ref_frame].as_int = INVALID_MV; |
michael@0 | 3932 | frame_mv[ZEROMV][ref_frame].as_int = 0; |
michael@0 | 3933 | } |
michael@0 | 3934 | |
michael@0 | 3935 | for (mode_index = 0; mode_index < MAX_REFS; ++mode_index) { |
michael@0 | 3936 | int mode_excluded = 0; |
michael@0 | 3937 | int64_t this_rd = INT64_MAX; |
michael@0 | 3938 | int disable_skip = 0; |
michael@0 | 3939 | int compmode_cost = 0; |
michael@0 | 3940 | int rate2 = 0, rate_y = 0, rate_uv = 0; |
michael@0 | 3941 | int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0; |
michael@0 | 3942 | int skippable = 0; |
michael@0 | 3943 | int64_t tx_cache[TX_MODES]; |
michael@0 | 3944 | int i; |
michael@0 | 3945 | int this_skip2 = 0; |
michael@0 | 3946 | int64_t total_sse = INT_MAX; |
michael@0 | 3947 | int early_term = 0; |
michael@0 | 3948 | |
michael@0 | 3949 | for (i = 0; i < TX_MODES; ++i) |
michael@0 | 3950 | tx_cache[i] = INT64_MAX; |
michael@0 | 3951 | |
michael@0 | 3952 | x->skip = 0; |
michael@0 | 3953 | ref_frame = vp9_ref_order[mode_index].ref_frame; |
michael@0 | 3954 | second_ref_frame = vp9_ref_order[mode_index].second_ref_frame; |
michael@0 | 3955 | |
michael@0 | 3956 | // Look at the reference frame of the best mode so far and set the |
michael@0 | 3957 | // skip mask to look at a subset of the remaining modes. |
michael@0 | 3958 | if (mode_index > 2 && cpi->sf.mode_skip_start < MAX_MODES) { |
michael@0 | 3959 | if (mode_index == 3) { |
michael@0 | 3960 | switch (vp9_ref_order[best_mode_index].ref_frame) { |
michael@0 | 3961 | case INTRA_FRAME: |
michael@0 | 3962 | cpi->mode_skip_mask = 0; |
michael@0 | 3963 | break; |
michael@0 | 3964 | case LAST_FRAME: |
michael@0 | 3965 | cpi->mode_skip_mask = 0x0010; |
michael@0 | 3966 | break; |
michael@0 | 3967 | case GOLDEN_FRAME: |
michael@0 | 3968 | cpi->mode_skip_mask = 0x0008; |
michael@0 | 3969 | break; |
michael@0 | 3970 | case ALTREF_FRAME: |
michael@0 | 3971 | cpi->mode_skip_mask = 0x0000; |
michael@0 | 3972 | break; |
michael@0 | 3973 | case NONE: |
michael@0 | 3974 | case MAX_REF_FRAMES: |
michael@0 | 3975 | assert(!"Invalid Reference frame"); |
michael@0 | 3976 | } |
michael@0 | 3977 | } |
michael@0 | 3978 | if (cpi->mode_skip_mask & ((int64_t)1 << mode_index)) |
michael@0 | 3979 | continue; |
michael@0 | 3980 | } |
michael@0 | 3981 | |
michael@0 | 3982 | // Skip if the current reference frame has been masked off |
michael@0 | 3983 | if (cpi->sf.reference_masking && !cpi->set_ref_frame_mask && |
michael@0 | 3984 | (cpi->ref_frame_mask & (1 << ref_frame))) |
michael@0 | 3985 | continue; |
michael@0 | 3986 | |
michael@0 | 3987 | // Test best rd so far against threshold for trying this mode. |
michael@0 | 3988 | if ((best_rd < |
michael@0 | 3989 | ((int64_t)cpi->rd_thresh_sub8x8[segment_id][bsize][mode_index] * |
michael@0 | 3990 | cpi->rd_thresh_freq_sub8x8[bsize][mode_index] >> 5)) || |
michael@0 | 3991 | cpi->rd_thresh_sub8x8[segment_id][bsize][mode_index] == INT_MAX) |
michael@0 | 3992 | continue; |
michael@0 | 3993 | |
michael@0 | 3994 | // Do not allow compound prediction if the segment level reference |
michael@0 | 3995 | // frame feature is in use as in this case there can only be one reference. |
michael@0 | 3996 | if ((second_ref_frame > INTRA_FRAME) && |
michael@0 | 3997 | vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) |
michael@0 | 3998 | continue; |
michael@0 | 3999 | |
michael@0 | 4000 | mbmi->ref_frame[0] = ref_frame; |
michael@0 | 4001 | mbmi->ref_frame[1] = second_ref_frame; |
michael@0 | 4002 | |
michael@0 | 4003 | if (!(ref_frame == INTRA_FRAME |
michael@0 | 4004 | || (cpi->ref_frame_flags & flag_list[ref_frame]))) { |
michael@0 | 4005 | continue; |
michael@0 | 4006 | } |
michael@0 | 4007 | if (!(second_ref_frame == NONE |
michael@0 | 4008 | || (cpi->ref_frame_flags & flag_list[second_ref_frame]))) { |
michael@0 | 4009 | continue; |
michael@0 | 4010 | } |
michael@0 | 4011 | |
michael@0 | 4012 | comp_pred = second_ref_frame > INTRA_FRAME; |
michael@0 | 4013 | if (comp_pred) { |
michael@0 | 4014 | if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) |
michael@0 | 4015 | if (vp9_ref_order[best_mode_index].ref_frame == INTRA_FRAME) |
michael@0 | 4016 | continue; |
michael@0 | 4017 | if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_COMP_REFMISMATCH) |
michael@0 | 4018 | if (ref_frame != best_inter_ref_frame && |
michael@0 | 4019 | second_ref_frame != best_inter_ref_frame) |
michael@0 | 4020 | continue; |
michael@0 | 4021 | } |
michael@0 | 4022 | |
michael@0 | 4023 | // TODO(jingning, jkoleszar): scaling reference frame not supported for |
michael@0 | 4024 | // sub8x8 blocks. |
michael@0 | 4025 | if (ref_frame > 0 && |
michael@0 | 4026 | vp9_is_scaled(scale_factor[ref_frame].sfc)) |
michael@0 | 4027 | continue; |
michael@0 | 4028 | |
michael@0 | 4029 | if (second_ref_frame > 0 && |
michael@0 | 4030 | vp9_is_scaled(scale_factor[second_ref_frame].sfc)) |
michael@0 | 4031 | continue; |
michael@0 | 4032 | |
michael@0 | 4033 | set_scale_factors(xd, ref_frame, second_ref_frame, scale_factor); |
michael@0 | 4034 | mbmi->uv_mode = DC_PRED; |
michael@0 | 4035 | |
michael@0 | 4036 | // Evaluate all sub-pel filters irrespective of whether we can use |
michael@0 | 4037 | // them for this frame. |
michael@0 | 4038 | mbmi->interp_filter = cm->mcomp_filter_type; |
michael@0 | 4039 | vp9_setup_interp_filters(xd, mbmi->interp_filter, &cpi->common); |
michael@0 | 4040 | |
michael@0 | 4041 | if (comp_pred) { |
michael@0 | 4042 | if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) |
michael@0 | 4043 | continue; |
michael@0 | 4044 | set_scale_factors(xd, ref_frame, second_ref_frame, scale_factor); |
michael@0 | 4045 | |
michael@0 | 4046 | mode_excluded = mode_excluded |
michael@0 | 4047 | ? mode_excluded |
michael@0 | 4048 | : cm->comp_pred_mode == SINGLE_PREDICTION_ONLY; |
michael@0 | 4049 | } else { |
michael@0 | 4050 | if (ref_frame != INTRA_FRAME && second_ref_frame != INTRA_FRAME) { |
michael@0 | 4051 | mode_excluded = |
michael@0 | 4052 | mode_excluded ? |
michael@0 | 4053 | mode_excluded : cm->comp_pred_mode == COMP_PREDICTION_ONLY; |
michael@0 | 4054 | } |
michael@0 | 4055 | } |
michael@0 | 4056 | |
michael@0 | 4057 | // Select prediction reference frames. |
michael@0 | 4058 | for (i = 0; i < MAX_MB_PLANE; i++) { |
michael@0 | 4059 | xd->plane[i].pre[0] = yv12_mb[ref_frame][i]; |
michael@0 | 4060 | if (comp_pred) |
michael@0 | 4061 | xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i]; |
michael@0 | 4062 | } |
michael@0 | 4063 | |
michael@0 | 4064 | // If the segment reference frame feature is enabled.... |
michael@0 | 4065 | // then do nothing if the current ref frame is not allowed.. |
michael@0 | 4066 | if (vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) && |
michael@0 | 4067 | vp9_get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != |
michael@0 | 4068 | (int)ref_frame) { |
michael@0 | 4069 | continue; |
michael@0 | 4070 | // If the segment skip feature is enabled.... |
michael@0 | 4071 | // then do nothing if the current mode is not allowed.. |
michael@0 | 4072 | } else if (vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP) && |
michael@0 | 4073 | ref_frame != INTRA_FRAME) { |
michael@0 | 4074 | continue; |
michael@0 | 4075 | // Disable this drop out case if the ref frame |
michael@0 | 4076 | // segment level feature is enabled for this segment. This is to |
michael@0 | 4077 | // prevent the possibility that we end up unable to pick any mode. |
michael@0 | 4078 | } else if (!vp9_segfeature_active(seg, segment_id, |
michael@0 | 4079 | SEG_LVL_REF_FRAME)) { |
michael@0 | 4080 | // Only consider ZEROMV/ALTREF_FRAME for alt ref frame, |
michael@0 | 4081 | // unless ARNR filtering is enabled in which case we want |
michael@0 | 4082 | // an unfiltered alternative. We allow near/nearest as well |
michael@0 | 4083 | // because they may result in zero-zero MVs but be cheaper. |
michael@0 | 4084 | if (cpi->is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) |
michael@0 | 4085 | continue; |
michael@0 | 4086 | } |
michael@0 | 4087 | |
michael@0 | 4088 | #ifdef MODE_TEST_HIT_STATS |
michael@0 | 4089 | // TEST/DEBUG CODE |
michael@0 | 4090 | // Keep a rcord of the number of test hits at each size |
michael@0 | 4091 | cpi->mode_test_hits[bsize]++; |
michael@0 | 4092 | #endif |
michael@0 | 4093 | |
michael@0 | 4094 | if (ref_frame == INTRA_FRAME) { |
michael@0 | 4095 | int rate; |
michael@0 | 4096 | mbmi->tx_size = TX_4X4; |
michael@0 | 4097 | if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y, |
michael@0 | 4098 | &distortion_y, best_rd) >= best_rd) |
michael@0 | 4099 | continue; |
michael@0 | 4100 | rate2 += rate; |
michael@0 | 4101 | rate2 += intra_cost_penalty; |
michael@0 | 4102 | distortion2 += distortion_y; |
michael@0 | 4103 | |
michael@0 | 4104 | if (rate_uv_intra[TX_4X4] == INT_MAX) { |
michael@0 | 4105 | choose_intra_uv_mode(cpi, ctx, bsize, &rate_uv_intra[TX_4X4], |
michael@0 | 4106 | &rate_uv_tokenonly[TX_4X4], |
michael@0 | 4107 | &dist_uv[TX_4X4], &skip_uv[TX_4X4], |
michael@0 | 4108 | &mode_uv[TX_4X4]); |
michael@0 | 4109 | } |
michael@0 | 4110 | rate2 += rate_uv_intra[TX_4X4]; |
michael@0 | 4111 | rate_uv = rate_uv_tokenonly[TX_4X4]; |
michael@0 | 4112 | distortion2 += dist_uv[TX_4X4]; |
michael@0 | 4113 | distortion_uv = dist_uv[TX_4X4]; |
michael@0 | 4114 | mbmi->uv_mode = mode_uv[TX_4X4]; |
michael@0 | 4115 | tx_cache[ONLY_4X4] = RDCOST(x->rdmult, x->rddiv, rate2, distortion2); |
michael@0 | 4116 | for (i = 0; i < TX_MODES; ++i) |
michael@0 | 4117 | tx_cache[i] = tx_cache[ONLY_4X4]; |
michael@0 | 4118 | } else { |
michael@0 | 4119 | int rate; |
michael@0 | 4120 | int64_t distortion; |
michael@0 | 4121 | int64_t this_rd_thresh; |
michael@0 | 4122 | int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX; |
michael@0 | 4123 | int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX; |
michael@0 | 4124 | int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse; |
michael@0 | 4125 | int tmp_best_skippable = 0; |
michael@0 | 4126 | int switchable_filter_index; |
michael@0 | 4127 | int_mv *second_ref = comp_pred ? |
michael@0 | 4128 | &mbmi->ref_mvs[second_ref_frame][0] : NULL; |
michael@0 | 4129 | b_mode_info tmp_best_bmodes[16]; |
michael@0 | 4130 | MB_MODE_INFO tmp_best_mbmode; |
michael@0 | 4131 | BEST_SEG_INFO bsi[SWITCHABLE_FILTERS]; |
michael@0 | 4132 | int pred_exists = 0; |
michael@0 | 4133 | int uv_skippable; |
michael@0 | 4134 | |
michael@0 | 4135 | this_rd_thresh = (ref_frame == LAST_FRAME) ? |
michael@0 | 4136 | cpi->rd_thresh_sub8x8[segment_id][bsize][THR_LAST] : |
michael@0 | 4137 | cpi->rd_thresh_sub8x8[segment_id][bsize][THR_ALTR]; |
michael@0 | 4138 | this_rd_thresh = (ref_frame == GOLDEN_FRAME) ? |
michael@0 | 4139 | cpi->rd_thresh_sub8x8[segment_id][bsize][THR_GOLD] : this_rd_thresh; |
michael@0 | 4140 | xd->mi_8x8[0]->mbmi.tx_size = TX_4X4; |
michael@0 | 4141 | |
michael@0 | 4142 | cpi->rd_filter_cache[SWITCHABLE_FILTERS] = INT64_MAX; |
michael@0 | 4143 | if (cm->mcomp_filter_type != BILINEAR) { |
michael@0 | 4144 | tmp_best_filter = EIGHTTAP; |
michael@0 | 4145 | if (x->source_variance < |
michael@0 | 4146 | cpi->sf.disable_filter_search_var_thresh) { |
michael@0 | 4147 | tmp_best_filter = EIGHTTAP; |
michael@0 | 4148 | vp9_zero(cpi->rd_filter_cache); |
michael@0 | 4149 | } else { |
michael@0 | 4150 | for (switchable_filter_index = 0; |
michael@0 | 4151 | switchable_filter_index < SWITCHABLE_FILTERS; |
michael@0 | 4152 | ++switchable_filter_index) { |
michael@0 | 4153 | int newbest, rs; |
michael@0 | 4154 | int64_t rs_rd; |
michael@0 | 4155 | mbmi->interp_filter = switchable_filter_index; |
michael@0 | 4156 | vp9_setup_interp_filters(xd, mbmi->interp_filter, &cpi->common); |
michael@0 | 4157 | |
michael@0 | 4158 | tmp_rd = rd_pick_best_mbsegmentation(cpi, x, tile, |
michael@0 | 4159 | &mbmi->ref_mvs[ref_frame][0], |
michael@0 | 4160 | second_ref, |
michael@0 | 4161 | best_yrd, |
michael@0 | 4162 | &rate, &rate_y, &distortion, |
michael@0 | 4163 | &skippable, &total_sse, |
michael@0 | 4164 | (int)this_rd_thresh, seg_mvs, |
michael@0 | 4165 | bsi, switchable_filter_index, |
michael@0 | 4166 | mi_row, mi_col); |
michael@0 | 4167 | |
michael@0 | 4168 | if (tmp_rd == INT64_MAX) |
michael@0 | 4169 | continue; |
michael@0 | 4170 | cpi->rd_filter_cache[switchable_filter_index] = tmp_rd; |
michael@0 | 4171 | rs = get_switchable_rate(x); |
michael@0 | 4172 | rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0); |
michael@0 | 4173 | cpi->rd_filter_cache[SWITCHABLE_FILTERS] = |
michael@0 | 4174 | MIN(cpi->rd_filter_cache[SWITCHABLE_FILTERS], |
michael@0 | 4175 | tmp_rd + rs_rd); |
michael@0 | 4176 | if (cm->mcomp_filter_type == SWITCHABLE) |
michael@0 | 4177 | tmp_rd += rs_rd; |
michael@0 | 4178 | |
michael@0 | 4179 | newbest = (tmp_rd < tmp_best_rd); |
michael@0 | 4180 | if (newbest) { |
michael@0 | 4181 | tmp_best_filter = mbmi->interp_filter; |
michael@0 | 4182 | tmp_best_rd = tmp_rd; |
michael@0 | 4183 | } |
michael@0 | 4184 | if ((newbest && cm->mcomp_filter_type == SWITCHABLE) || |
michael@0 | 4185 | (mbmi->interp_filter == cm->mcomp_filter_type && |
michael@0 | 4186 | cm->mcomp_filter_type != SWITCHABLE)) { |
michael@0 | 4187 | tmp_best_rdu = tmp_rd; |
michael@0 | 4188 | tmp_best_rate = rate; |
michael@0 | 4189 | tmp_best_ratey = rate_y; |
michael@0 | 4190 | tmp_best_distortion = distortion; |
michael@0 | 4191 | tmp_best_sse = total_sse; |
michael@0 | 4192 | tmp_best_skippable = skippable; |
michael@0 | 4193 | tmp_best_mbmode = *mbmi; |
michael@0 | 4194 | for (i = 0; i < 4; i++) { |
michael@0 | 4195 | tmp_best_bmodes[i] = xd->mi_8x8[0]->bmi[i]; |
michael@0 | 4196 | x->zcoeff_blk[TX_4X4][i] = !xd->plane[0].eobs[i]; |
michael@0 | 4197 | } |
michael@0 | 4198 | pred_exists = 1; |
michael@0 | 4199 | if (switchable_filter_index == 0 && |
michael@0 | 4200 | cpi->sf.use_rd_breakout && |
michael@0 | 4201 | best_rd < INT64_MAX) { |
michael@0 | 4202 | if (tmp_best_rdu / 2 > best_rd) { |
michael@0 | 4203 | // skip searching the other filters if the first is |
michael@0 | 4204 | // already substantially larger than the best so far |
michael@0 | 4205 | tmp_best_filter = mbmi->interp_filter; |
michael@0 | 4206 | tmp_best_rdu = INT64_MAX; |
michael@0 | 4207 | break; |
michael@0 | 4208 | } |
michael@0 | 4209 | } |
michael@0 | 4210 | } |
michael@0 | 4211 | } // switchable_filter_index loop |
michael@0 | 4212 | } |
michael@0 | 4213 | } |
michael@0 | 4214 | |
michael@0 | 4215 | if (tmp_best_rdu == INT64_MAX) |
michael@0 | 4216 | continue; |
michael@0 | 4217 | |
michael@0 | 4218 | mbmi->interp_filter = (cm->mcomp_filter_type == SWITCHABLE ? |
michael@0 | 4219 | tmp_best_filter : cm->mcomp_filter_type); |
michael@0 | 4220 | vp9_setup_interp_filters(xd, mbmi->interp_filter, &cpi->common); |
michael@0 | 4221 | if (!pred_exists) { |
michael@0 | 4222 | // Handles the special case when a filter that is not in the |
michael@0 | 4223 | // switchable list (bilinear, 6-tap) is indicated at the frame level |
michael@0 | 4224 | tmp_rd = rd_pick_best_mbsegmentation(cpi, x, tile, |
michael@0 | 4225 | &mbmi->ref_mvs[ref_frame][0], |
michael@0 | 4226 | second_ref, |
michael@0 | 4227 | best_yrd, |
michael@0 | 4228 | &rate, &rate_y, &distortion, |
michael@0 | 4229 | &skippable, &total_sse, |
michael@0 | 4230 | (int)this_rd_thresh, seg_mvs, |
michael@0 | 4231 | bsi, 0, |
michael@0 | 4232 | mi_row, mi_col); |
michael@0 | 4233 | if (tmp_rd == INT64_MAX) |
michael@0 | 4234 | continue; |
michael@0 | 4235 | } else { |
michael@0 | 4236 | if (cpi->common.mcomp_filter_type == SWITCHABLE) { |
michael@0 | 4237 | int rs = get_switchable_rate(x); |
michael@0 | 4238 | tmp_best_rdu -= RDCOST(x->rdmult, x->rddiv, rs, 0); |
michael@0 | 4239 | } |
michael@0 | 4240 | tmp_rd = tmp_best_rdu; |
michael@0 | 4241 | total_sse = tmp_best_sse; |
michael@0 | 4242 | rate = tmp_best_rate; |
michael@0 | 4243 | rate_y = tmp_best_ratey; |
michael@0 | 4244 | distortion = tmp_best_distortion; |
michael@0 | 4245 | skippable = tmp_best_skippable; |
michael@0 | 4246 | *mbmi = tmp_best_mbmode; |
michael@0 | 4247 | for (i = 0; i < 4; i++) |
michael@0 | 4248 | xd->mi_8x8[0]->bmi[i] = tmp_best_bmodes[i]; |
michael@0 | 4249 | } |
michael@0 | 4250 | |
michael@0 | 4251 | rate2 += rate; |
michael@0 | 4252 | distortion2 += distortion; |
michael@0 | 4253 | |
michael@0 | 4254 | if (cpi->common.mcomp_filter_type == SWITCHABLE) |
michael@0 | 4255 | rate2 += get_switchable_rate(x); |
michael@0 | 4256 | |
michael@0 | 4257 | if (!mode_excluded) { |
michael@0 | 4258 | if (comp_pred) |
michael@0 | 4259 | mode_excluded = cpi->common.comp_pred_mode == SINGLE_PREDICTION_ONLY; |
michael@0 | 4260 | else |
michael@0 | 4261 | mode_excluded = cpi->common.comp_pred_mode == COMP_PREDICTION_ONLY; |
michael@0 | 4262 | } |
michael@0 | 4263 | compmode_cost = vp9_cost_bit(comp_mode_p, comp_pred); |
michael@0 | 4264 | |
michael@0 | 4265 | tmp_best_rdu = best_rd - |
michael@0 | 4266 | MIN(RDCOST(x->rdmult, x->rddiv, rate2, distortion2), |
michael@0 | 4267 | RDCOST(x->rdmult, x->rddiv, 0, total_sse)); |
michael@0 | 4268 | |
michael@0 | 4269 | if (tmp_best_rdu > 0) { |
michael@0 | 4270 | // If even the 'Y' rd value of split is higher than best so far |
michael@0 | 4271 | // then dont bother looking at UV |
michael@0 | 4272 | vp9_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col, |
michael@0 | 4273 | BLOCK_8X8); |
michael@0 | 4274 | super_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &uv_skippable, |
michael@0 | 4275 | &uv_sse, BLOCK_8X8, tmp_best_rdu); |
michael@0 | 4276 | if (rate_uv == INT_MAX) |
michael@0 | 4277 | continue; |
michael@0 | 4278 | rate2 += rate_uv; |
michael@0 | 4279 | distortion2 += distortion_uv; |
michael@0 | 4280 | skippable = skippable && uv_skippable; |
michael@0 | 4281 | total_sse += uv_sse; |
michael@0 | 4282 | |
michael@0 | 4283 | tx_cache[ONLY_4X4] = RDCOST(x->rdmult, x->rddiv, rate2, distortion2); |
michael@0 | 4284 | for (i = 0; i < TX_MODES; ++i) |
michael@0 | 4285 | tx_cache[i] = tx_cache[ONLY_4X4]; |
michael@0 | 4286 | } |
michael@0 | 4287 | } |
michael@0 | 4288 | |
michael@0 | 4289 | if (cpi->common.comp_pred_mode == HYBRID_PREDICTION) { |
michael@0 | 4290 | rate2 += compmode_cost; |
michael@0 | 4291 | } |
michael@0 | 4292 | |
michael@0 | 4293 | // Estimate the reference frame signaling cost and add it |
michael@0 | 4294 | // to the rolling cost variable. |
michael@0 | 4295 | if (second_ref_frame > INTRA_FRAME) { |
michael@0 | 4296 | rate2 += ref_costs_comp[ref_frame]; |
michael@0 | 4297 | } else { |
michael@0 | 4298 | rate2 += ref_costs_single[ref_frame]; |
michael@0 | 4299 | } |
michael@0 | 4300 | |
michael@0 | 4301 | if (!disable_skip) { |
michael@0 | 4302 | // Test for the condition where skip block will be activated |
michael@0 | 4303 | // because there are no non zero coefficients and make any |
michael@0 | 4304 | // necessary adjustment for rate. Ignore if skip is coded at |
michael@0 | 4305 | // segment level as the cost wont have been added in. |
michael@0 | 4306 | // Is Mb level skip allowed (i.e. not coded at segment level). |
michael@0 | 4307 | const int mb_skip_allowed = !vp9_segfeature_active(seg, segment_id, |
michael@0 | 4308 | SEG_LVL_SKIP); |
michael@0 | 4309 | |
michael@0 | 4310 | if (mb_skip_allowed && ref_frame != INTRA_FRAME && !xd->lossless) { |
michael@0 | 4311 | if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) < |
michael@0 | 4312 | RDCOST(x->rdmult, x->rddiv, 0, total_sse)) { |
michael@0 | 4313 | // Add in the cost of the no skip flag. |
michael@0 | 4314 | int prob_skip_cost = vp9_cost_bit(vp9_get_pred_prob_mbskip(cm, xd), |
michael@0 | 4315 | 0); |
michael@0 | 4316 | rate2 += prob_skip_cost; |
michael@0 | 4317 | } else { |
michael@0 | 4318 | // FIXME(rbultje) make this work for splitmv also |
michael@0 | 4319 | int prob_skip_cost = vp9_cost_bit(vp9_get_pred_prob_mbskip(cm, xd), |
michael@0 | 4320 | 1); |
michael@0 | 4321 | rate2 += prob_skip_cost; |
michael@0 | 4322 | distortion2 = total_sse; |
michael@0 | 4323 | assert(total_sse >= 0); |
michael@0 | 4324 | rate2 -= (rate_y + rate_uv); |
michael@0 | 4325 | rate_y = 0; |
michael@0 | 4326 | rate_uv = 0; |
michael@0 | 4327 | this_skip2 = 1; |
michael@0 | 4328 | } |
michael@0 | 4329 | } else if (mb_skip_allowed) { |
michael@0 | 4330 | // Add in the cost of the no skip flag. |
michael@0 | 4331 | int prob_skip_cost = vp9_cost_bit(vp9_get_pred_prob_mbskip(cm, xd), |
michael@0 | 4332 | 0); |
michael@0 | 4333 | rate2 += prob_skip_cost; |
michael@0 | 4334 | } |
michael@0 | 4335 | |
michael@0 | 4336 | // Calculate the final RD estimate for this mode. |
michael@0 | 4337 | this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2); |
michael@0 | 4338 | } |
michael@0 | 4339 | |
michael@0 | 4340 | // Keep record of best inter rd with single reference |
michael@0 | 4341 | if (xd->mi_8x8[0]->mbmi.ref_frame[0] > INTRA_FRAME && |
michael@0 | 4342 | xd->mi_8x8[0]->mbmi.ref_frame[1] == NONE && |
michael@0 | 4343 | !mode_excluded && |
michael@0 | 4344 | this_rd < best_inter_rd) { |
michael@0 | 4345 | best_inter_rd = this_rd; |
michael@0 | 4346 | best_inter_ref_frame = ref_frame; |
michael@0 | 4347 | } |
michael@0 | 4348 | |
michael@0 | 4349 | if (!disable_skip && ref_frame == INTRA_FRAME) { |
michael@0 | 4350 | for (i = 0; i < NB_PREDICTION_TYPES; ++i) |
michael@0 | 4351 | best_pred_rd[i] = MIN(best_pred_rd[i], this_rd); |
michael@0 | 4352 | for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) |
michael@0 | 4353 | best_filter_rd[i] = MIN(best_filter_rd[i], this_rd); |
michael@0 | 4354 | } |
michael@0 | 4355 | |
michael@0 | 4356 | // Did this mode help.. i.e. is it the new best mode |
michael@0 | 4357 | if (this_rd < best_rd || x->skip) { |
michael@0 | 4358 | if (!mode_excluded) { |
michael@0 | 4359 | int max_plane = MAX_MB_PLANE; |
michael@0 | 4360 | // Note index of best mode so far |
michael@0 | 4361 | best_mode_index = mode_index; |
michael@0 | 4362 | |
michael@0 | 4363 | if (ref_frame == INTRA_FRAME) { |
michael@0 | 4364 | /* required for left and above block mv */ |
michael@0 | 4365 | mbmi->mv[0].as_int = 0; |
michael@0 | 4366 | max_plane = 1; |
michael@0 | 4367 | } |
michael@0 | 4368 | |
michael@0 | 4369 | *returnrate = rate2; |
michael@0 | 4370 | *returndistortion = distortion2; |
michael@0 | 4371 | best_rd = this_rd; |
michael@0 | 4372 | best_yrd = best_rd - |
michael@0 | 4373 | RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv); |
michael@0 | 4374 | best_mbmode = *mbmi; |
michael@0 | 4375 | best_skip2 = this_skip2; |
michael@0 | 4376 | if (!x->select_txfm_size) |
michael@0 | 4377 | swap_block_ptr(x, ctx, max_plane); |
michael@0 | 4378 | vpx_memcpy(ctx->zcoeff_blk, x->zcoeff_blk[mbmi->tx_size], |
michael@0 | 4379 | sizeof(uint8_t) * ctx->num_4x4_blk); |
michael@0 | 4380 | |
michael@0 | 4381 | for (i = 0; i < 4; i++) |
michael@0 | 4382 | best_bmodes[i] = xd->mi_8x8[0]->bmi[i]; |
michael@0 | 4383 | |
michael@0 | 4384 | // TODO(debargha): enhance this test with a better distortion prediction |
michael@0 | 4385 | // based on qp, activity mask and history |
michael@0 | 4386 | if ((cpi->sf.mode_search_skip_flags & FLAG_EARLY_TERMINATE) && |
michael@0 | 4387 | (mode_index > MIN_EARLY_TERM_INDEX)) { |
michael@0 | 4388 | const int qstep = xd->plane[0].dequant[1]; |
michael@0 | 4389 | // TODO(debargha): Enhance this by specializing for each mode_index |
michael@0 | 4390 | int scale = 4; |
michael@0 | 4391 | if (x->source_variance < UINT_MAX) { |
michael@0 | 4392 | const int var_adjust = (x->source_variance < 16); |
michael@0 | 4393 | scale -= var_adjust; |
michael@0 | 4394 | } |
michael@0 | 4395 | if (ref_frame > INTRA_FRAME && |
michael@0 | 4396 | distortion2 * scale < qstep * qstep) { |
michael@0 | 4397 | early_term = 1; |
michael@0 | 4398 | } |
michael@0 | 4399 | } |
michael@0 | 4400 | } |
michael@0 | 4401 | } |
michael@0 | 4402 | |
michael@0 | 4403 | /* keep record of best compound/single-only prediction */ |
michael@0 | 4404 | if (!disable_skip && ref_frame != INTRA_FRAME) { |
michael@0 | 4405 | int single_rd, hybrid_rd, single_rate, hybrid_rate; |
michael@0 | 4406 | |
michael@0 | 4407 | if (cpi->common.comp_pred_mode == HYBRID_PREDICTION) { |
michael@0 | 4408 | single_rate = rate2 - compmode_cost; |
michael@0 | 4409 | hybrid_rate = rate2; |
michael@0 | 4410 | } else { |
michael@0 | 4411 | single_rate = rate2; |
michael@0 | 4412 | hybrid_rate = rate2 + compmode_cost; |
michael@0 | 4413 | } |
michael@0 | 4414 | |
michael@0 | 4415 | single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2); |
michael@0 | 4416 | hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2); |
michael@0 | 4417 | |
michael@0 | 4418 | if (second_ref_frame <= INTRA_FRAME && |
michael@0 | 4419 | single_rd < best_pred_rd[SINGLE_PREDICTION_ONLY]) { |
michael@0 | 4420 | best_pred_rd[SINGLE_PREDICTION_ONLY] = single_rd; |
michael@0 | 4421 | } else if (second_ref_frame > INTRA_FRAME && |
michael@0 | 4422 | single_rd < best_pred_rd[COMP_PREDICTION_ONLY]) { |
michael@0 | 4423 | best_pred_rd[COMP_PREDICTION_ONLY] = single_rd; |
michael@0 | 4424 | } |
michael@0 | 4425 | if (hybrid_rd < best_pred_rd[HYBRID_PREDICTION]) |
michael@0 | 4426 | best_pred_rd[HYBRID_PREDICTION] = hybrid_rd; |
michael@0 | 4427 | } |
michael@0 | 4428 | |
michael@0 | 4429 | /* keep record of best filter type */ |
michael@0 | 4430 | if (!mode_excluded && !disable_skip && ref_frame != INTRA_FRAME && |
michael@0 | 4431 | cm->mcomp_filter_type != BILINEAR) { |
michael@0 | 4432 | int64_t ref = cpi->rd_filter_cache[cm->mcomp_filter_type == SWITCHABLE ? |
michael@0 | 4433 | SWITCHABLE_FILTERS : cm->mcomp_filter_type]; |
michael@0 | 4434 | for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) { |
michael@0 | 4435 | int64_t adj_rd; |
michael@0 | 4436 | // In cases of poor prediction, filter_cache[] can contain really big |
michael@0 | 4437 | // values, which actually are bigger than this_rd itself. This can |
michael@0 | 4438 | // cause negative best_filter_rd[] values, which is obviously silly. |
michael@0 | 4439 | // Therefore, if filter_cache < ref, we do an adjusted calculation. |
michael@0 | 4440 | if (cpi->rd_filter_cache[i] >= ref) |
michael@0 | 4441 | adj_rd = this_rd + cpi->rd_filter_cache[i] - ref; |
michael@0 | 4442 | else // FIXME(rbultje) do this for comppred also |
michael@0 | 4443 | adj_rd = this_rd - (ref - cpi->rd_filter_cache[i]) * this_rd / ref; |
michael@0 | 4444 | best_filter_rd[i] = MIN(best_filter_rd[i], adj_rd); |
michael@0 | 4445 | } |
michael@0 | 4446 | } |
michael@0 | 4447 | |
michael@0 | 4448 | /* keep record of best txfm size */ |
michael@0 | 4449 | if (bsize < BLOCK_32X32) { |
michael@0 | 4450 | if (bsize < BLOCK_16X16) { |
michael@0 | 4451 | tx_cache[ALLOW_8X8] = tx_cache[ONLY_4X4]; |
michael@0 | 4452 | tx_cache[ALLOW_16X16] = tx_cache[ALLOW_8X8]; |
michael@0 | 4453 | } |
michael@0 | 4454 | tx_cache[ALLOW_32X32] = tx_cache[ALLOW_16X16]; |
michael@0 | 4455 | } |
michael@0 | 4456 | if (!mode_excluded && this_rd != INT64_MAX) { |
michael@0 | 4457 | for (i = 0; i < TX_MODES && tx_cache[i] < INT64_MAX; i++) { |
michael@0 | 4458 | int64_t adj_rd = INT64_MAX; |
michael@0 | 4459 | if (ref_frame > INTRA_FRAME) |
michael@0 | 4460 | adj_rd = this_rd + tx_cache[i] - tx_cache[cm->tx_mode]; |
michael@0 | 4461 | else |
michael@0 | 4462 | adj_rd = this_rd; |
michael@0 | 4463 | |
michael@0 | 4464 | if (adj_rd < best_tx_rd[i]) |
michael@0 | 4465 | best_tx_rd[i] = adj_rd; |
michael@0 | 4466 | } |
michael@0 | 4467 | } |
michael@0 | 4468 | |
michael@0 | 4469 | if (early_term) |
michael@0 | 4470 | break; |
michael@0 | 4471 | |
michael@0 | 4472 | if (x->skip && !comp_pred) |
michael@0 | 4473 | break; |
michael@0 | 4474 | } |
michael@0 | 4475 | |
michael@0 | 4476 | if (best_rd >= best_rd_so_far) |
michael@0 | 4477 | return INT64_MAX; |
michael@0 | 4478 | |
michael@0 | 4479 | // If we used an estimate for the uv intra rd in the loop above... |
michael@0 | 4480 | if (cpi->sf.use_uv_intra_rd_estimate) { |
michael@0 | 4481 | // Do Intra UV best rd mode selection if best mode choice above was intra. |
michael@0 | 4482 | if (vp9_ref_order[best_mode_index].ref_frame == INTRA_FRAME) { |
michael@0 | 4483 | TX_SIZE uv_tx_size = get_uv_tx_size(mbmi); |
michael@0 | 4484 | rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv_intra[uv_tx_size], |
michael@0 | 4485 | &rate_uv_tokenonly[uv_tx_size], |
michael@0 | 4486 | &dist_uv[uv_tx_size], |
michael@0 | 4487 | &skip_uv[uv_tx_size], |
michael@0 | 4488 | BLOCK_8X8); |
michael@0 | 4489 | } |
michael@0 | 4490 | } |
michael@0 | 4491 | |
michael@0 | 4492 | // If we are using reference masking and the set mask flag is set then |
michael@0 | 4493 | // create the reference frame mask. |
michael@0 | 4494 | if (cpi->sf.reference_masking && cpi->set_ref_frame_mask) |
michael@0 | 4495 | cpi->ref_frame_mask = ~(1 << vp9_ref_order[best_mode_index].ref_frame); |
michael@0 | 4496 | |
michael@0 | 4497 | if (best_rd == INT64_MAX && bsize < BLOCK_8X8) { |
michael@0 | 4498 | *returnrate = INT_MAX; |
michael@0 | 4499 | *returndistortion = INT_MAX; |
michael@0 | 4500 | return best_rd; |
michael@0 | 4501 | } |
michael@0 | 4502 | |
michael@0 | 4503 | assert((cm->mcomp_filter_type == SWITCHABLE) || |
michael@0 | 4504 | (cm->mcomp_filter_type == best_mbmode.interp_filter) || |
michael@0 | 4505 | (best_mbmode.ref_frame[0] == INTRA_FRAME)); |
michael@0 | 4506 | |
michael@0 | 4507 | // Updating rd_thresh_freq_fact[] here means that the different |
michael@0 | 4508 | // partition/block sizes are handled independently based on the best |
michael@0 | 4509 | // choice for the current partition. It may well be better to keep a scaled |
michael@0 | 4510 | // best rd so far value and update rd_thresh_freq_fact based on the mode/size |
michael@0 | 4511 | // combination that wins out. |
michael@0 | 4512 | if (cpi->sf.adaptive_rd_thresh) { |
michael@0 | 4513 | for (mode_index = 0; mode_index < MAX_REFS; ++mode_index) { |
michael@0 | 4514 | if (mode_index == best_mode_index) { |
michael@0 | 4515 | cpi->rd_thresh_freq_sub8x8[bsize][mode_index] -= |
michael@0 | 4516 | (cpi->rd_thresh_freq_sub8x8[bsize][mode_index] >> 3); |
michael@0 | 4517 | } else { |
michael@0 | 4518 | cpi->rd_thresh_freq_sub8x8[bsize][mode_index] += RD_THRESH_INC; |
michael@0 | 4519 | if (cpi->rd_thresh_freq_sub8x8[bsize][mode_index] > |
michael@0 | 4520 | (cpi->sf.adaptive_rd_thresh * RD_THRESH_MAX_FACT)) { |
michael@0 | 4521 | cpi->rd_thresh_freq_sub8x8[bsize][mode_index] = |
michael@0 | 4522 | cpi->sf.adaptive_rd_thresh * RD_THRESH_MAX_FACT; |
michael@0 | 4523 | } |
michael@0 | 4524 | } |
michael@0 | 4525 | } |
michael@0 | 4526 | } |
michael@0 | 4527 | |
michael@0 | 4528 | // macroblock modes |
michael@0 | 4529 | *mbmi = best_mbmode; |
michael@0 | 4530 | x->skip |= best_skip2; |
michael@0 | 4531 | if (best_mbmode.ref_frame[0] == INTRA_FRAME) { |
michael@0 | 4532 | for (i = 0; i < 4; i++) |
michael@0 | 4533 | xd->mi_8x8[0]->bmi[i].as_mode = best_bmodes[i].as_mode; |
michael@0 | 4534 | } else { |
michael@0 | 4535 | for (i = 0; i < 4; ++i) |
michael@0 | 4536 | vpx_memcpy(&xd->mi_8x8[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info)); |
michael@0 | 4537 | |
michael@0 | 4538 | mbmi->mv[0].as_int = xd->mi_8x8[0]->bmi[3].as_mv[0].as_int; |
michael@0 | 4539 | mbmi->mv[1].as_int = xd->mi_8x8[0]->bmi[3].as_mv[1].as_int; |
michael@0 | 4540 | } |
michael@0 | 4541 | |
michael@0 | 4542 | for (i = 0; i < NB_PREDICTION_TYPES; ++i) { |
michael@0 | 4543 | if (best_pred_rd[i] == INT64_MAX) |
michael@0 | 4544 | best_pred_diff[i] = INT_MIN; |
michael@0 | 4545 | else |
michael@0 | 4546 | best_pred_diff[i] = best_rd - best_pred_rd[i]; |
michael@0 | 4547 | } |
michael@0 | 4548 | |
michael@0 | 4549 | if (!x->skip) { |
michael@0 | 4550 | for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) { |
michael@0 | 4551 | if (best_filter_rd[i] == INT64_MAX) |
michael@0 | 4552 | best_filter_diff[i] = 0; |
michael@0 | 4553 | else |
michael@0 | 4554 | best_filter_diff[i] = best_rd - best_filter_rd[i]; |
michael@0 | 4555 | } |
michael@0 | 4556 | if (cm->mcomp_filter_type == SWITCHABLE) |
michael@0 | 4557 | assert(best_filter_diff[SWITCHABLE_FILTERS] == 0); |
michael@0 | 4558 | } else { |
michael@0 | 4559 | vp9_zero(best_filter_diff); |
michael@0 | 4560 | } |
michael@0 | 4561 | |
michael@0 | 4562 | if (!x->skip) { |
michael@0 | 4563 | for (i = 0; i < TX_MODES; i++) { |
michael@0 | 4564 | if (best_tx_rd[i] == INT64_MAX) |
michael@0 | 4565 | best_tx_diff[i] = 0; |
michael@0 | 4566 | else |
michael@0 | 4567 | best_tx_diff[i] = best_rd - best_tx_rd[i]; |
michael@0 | 4568 | } |
michael@0 | 4569 | } else { |
michael@0 | 4570 | vp9_zero(best_tx_diff); |
michael@0 | 4571 | } |
michael@0 | 4572 | |
michael@0 | 4573 | set_scale_factors(xd, mbmi->ref_frame[0], mbmi->ref_frame[1], |
michael@0 | 4574 | scale_factor); |
michael@0 | 4575 | store_coding_context(x, ctx, best_mode_index, |
michael@0 | 4576 | &mbmi->ref_mvs[mbmi->ref_frame[0]][0], |
michael@0 | 4577 | &mbmi->ref_mvs[mbmi->ref_frame[1] < 0 ? 0 : |
michael@0 | 4578 | mbmi->ref_frame[1]][0], |
michael@0 | 4579 | best_pred_diff, best_tx_diff, best_filter_diff); |
michael@0 | 4580 | |
michael@0 | 4581 | return best_rd; |
michael@0 | 4582 | } |