Coverage Report

Created: 2026-06-09 09:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vlc/contrib/contrib-build/libvpx/vp8/encoder/pickinter.c
Line
Count
Source
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5
 *  that can be found in the LICENSE file in the root of the source
6
 *  tree. An additional intellectual property rights grant can be found
7
 *  in the file PATENTS.  All contributing project authors may
8
 *  be found in the AUTHORS file in the root of the source tree.
9
 */
10
11
#include <assert.h>
12
#include <limits.h>
13
#include "vpx_config.h"
14
#include "./vpx_dsp_rtcd.h"
15
#include "onyx_int.h"
16
#include "modecosts.h"
17
#include "encodeintra.h"
18
#include "vp8/common/common.h"
19
#include "vp8/common/entropymode.h"
20
#include "pickinter.h"
21
#include "vp8/common/findnearmv.h"
22
#include "encodemb.h"
23
#include "vp8/common/reconinter.h"
24
#include "vp8/common/reconintra.h"
25
#include "vp8/common/reconintra4x4.h"
26
#include "vpx_dsp/variance.h"
27
#include "mcomp.h"
28
#include "vp8/common/vp8_skin_detection.h"
29
#include "rdopt.h"
30
#include "vpx_dsp/vpx_dsp_common.h"
31
#include "vpx_mem/vpx_mem.h"
32
#if CONFIG_TEMPORAL_DENOISING
33
#include "denoising.h"
34
#endif
35
36
#ifdef SPEEDSTATS
37
extern unsigned int cnt_pm;
38
#endif
39
40
extern const int vp8_ref_frame_order[MAX_MODES];
41
extern const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES];
42
43
static int macroblock_corner_grad(unsigned char *signal, int stride,
44
                                  int offsetx, int offsety, int sgnx,
45
0
                                  int sgny) {
46
0
  int y1 = signal[offsetx * stride + offsety];
47
0
  int y2 = signal[offsetx * stride + offsety + sgny];
48
0
  int y3 = signal[(offsetx + sgnx) * stride + offsety];
49
0
  int y4 = signal[(offsetx + sgnx) * stride + offsety + sgny];
50
0
  return VPXMAX(VPXMAX(abs(y1 - y2), abs(y1 - y3)), abs(y1 - y4));
51
0
}
52
53
static int check_dot_artifact_candidate(VP8_COMP *cpi, MACROBLOCK *x,
54
                                        unsigned char *target_last, int stride,
55
                                        unsigned char *last_ref, int mb_row,
56
0
                                        int mb_col, int channel) {
57
0
  int threshold1 = 6;
58
0
  int threshold2 = 3;
59
0
  unsigned int max_num = (cpi->common.MBs) / 10;
60
0
  int grad_last = 0;
61
0
  int grad_source = 0;
62
0
  int index = mb_row * cpi->common.mb_cols + mb_col;
63
  // Threshold for #consecutive (base layer) frames using zero_last mode.
64
0
  int num_frames = 30;
65
0
  int shift = 15;
66
0
  if (channel > 0) {
67
0
    shift = 7;
68
0
  }
69
0
  if (cpi->oxcf.number_of_layers > 1) {
70
0
    num_frames = 20;
71
0
  }
72
0
  x->zero_last_dot_suppress = 0;
73
  // Blocks on base layer frames that have been using ZEROMV_LAST repeatedly
74
  // (i.e, at least |x| consecutive frames are candidates for increasing the
75
  // rd adjustment for zero_last mode.
76
  // Only allow this for at most |max_num| blocks per frame.
77
  // Don't allow this for screen content input.
78
0
  if (cpi->current_layer == 0 &&
79
0
      cpi->consec_zero_last_mvbias[index] > num_frames &&
80
0
      x->mbs_zero_last_dot_suppress < max_num &&
81
0
      !cpi->oxcf.screen_content_mode) {
82
    // If this block is checked here, label it so we don't check it again until
83
    // ~|x| framaes later.
84
0
    x->zero_last_dot_suppress = 1;
85
    // Dot artifact is noticeable as strong gradient at corners of macroblock,
86
    // for flat areas. As a simple detector for now, we look for a high
87
    // corner gradient on last ref, and a smaller gradient on source.
88
    // Check 4 corners, return if any satisfy condition.
89
    // Top-left:
90
0
    grad_last = macroblock_corner_grad(last_ref, stride, 0, 0, 1, 1);
91
0
    grad_source = macroblock_corner_grad(target_last, stride, 0, 0, 1, 1);
92
0
    if (grad_last >= threshold1 && grad_source <= threshold2) {
93
0
      x->mbs_zero_last_dot_suppress++;
94
0
      return 1;
95
0
    }
96
    // Top-right:
97
0
    grad_last = macroblock_corner_grad(last_ref, stride, 0, shift, 1, -1);
98
0
    grad_source = macroblock_corner_grad(target_last, stride, 0, shift, 1, -1);
99
0
    if (grad_last >= threshold1 && grad_source <= threshold2) {
100
0
      x->mbs_zero_last_dot_suppress++;
101
0
      return 1;
102
0
    }
103
    // Bottom-left:
104
0
    grad_last = macroblock_corner_grad(last_ref, stride, shift, 0, -1, 1);
105
0
    grad_source = macroblock_corner_grad(target_last, stride, shift, 0, -1, 1);
106
0
    if (grad_last >= threshold1 && grad_source <= threshold2) {
107
0
      x->mbs_zero_last_dot_suppress++;
108
0
      return 1;
109
0
    }
110
    // Bottom-right:
111
0
    grad_last = macroblock_corner_grad(last_ref, stride, shift, shift, -1, -1);
112
0
    grad_source =
113
0
        macroblock_corner_grad(target_last, stride, shift, shift, -1, -1);
114
0
    if (grad_last >= threshold1 && grad_source <= threshold2) {
115
0
      x->mbs_zero_last_dot_suppress++;
116
0
      return 1;
117
0
    }
118
0
    return 0;
119
0
  }
120
0
  return 0;
121
0
}
122
123
int vp8_skip_fractional_mv_step(MACROBLOCK *mb, BLOCK *b, BLOCKD *d,
124
                                int_mv *bestmv, int_mv *ref_mv,
125
                                int error_per_bit,
126
                                const vp8_variance_fn_ptr_t *vfp,
127
                                int *mvcost[2], int *distortion,
128
0
                                unsigned int *sse) {
129
0
  (void)b;
130
0
  (void)d;
131
0
  (void)ref_mv;
132
0
  (void)error_per_bit;
133
0
  (void)vfp;
134
0
  (void)mb;
135
0
  (void)mvcost;
136
0
  (void)distortion;
137
0
  (void)sse;
138
0
  bestmv->as_mv.row = clamp(bestmv->as_mv.row * 8, SHRT_MIN, SHRT_MAX);
139
0
  bestmv->as_mv.col = clamp(bestmv->as_mv.col * 8, SHRT_MIN, SHRT_MAX);
140
0
  return 0;
141
0
}
142
143
int vp8_get_inter_mbpred_error(MACROBLOCK *mb, const vp8_variance_fn_ptr_t *vfp,
144
0
                               unsigned int *sse, int_mv this_mv) {
145
0
  BLOCK *b = &mb->block[0];
146
0
  BLOCKD *d = &mb->e_mbd.block[0];
147
0
  unsigned char *what = (*(b->base_src) + b->src);
148
0
  int what_stride = b->src_stride;
149
0
  int pre_stride = mb->e_mbd.pre.y_stride;
150
0
  unsigned char *in_what = mb->e_mbd.pre.y_buffer + d->offset;
151
0
  int in_what_stride = pre_stride;
152
0
  int xoffset = this_mv.as_mv.col & 7;
153
0
  int yoffset = this_mv.as_mv.row & 7;
154
155
0
  in_what += (this_mv.as_mv.row >> 3) * pre_stride + (this_mv.as_mv.col >> 3);
156
157
0
  if (xoffset | yoffset) {
158
0
    return vfp->svf(in_what, in_what_stride, xoffset, yoffset, what,
159
0
                    what_stride, sse);
160
0
  } else {
161
0
    return vfp->vf(what, what_stride, in_what, in_what_stride, sse);
162
0
  }
163
0
}
164
165
0
static int get_prediction_error(BLOCK *be, BLOCKD *b) {
166
0
  unsigned char *sptr;
167
0
  unsigned char *dptr;
168
0
  sptr = (*(be->base_src) + be->src);
169
0
  dptr = b->predictor;
170
171
0
  return vpx_get4x4sse_cs(sptr, be->src_stride, dptr, 16);
172
0
}
173
174
static int pick_intra4x4block(MACROBLOCK *x, int ib,
175
                              B_PREDICTION_MODE *best_mode,
176
                              const int *mode_costs, int *bestrate,
177
0
                              int *bestdistortion) {
178
0
  BLOCKD *b = &x->e_mbd.block[ib];
179
0
  BLOCK *be = &x->block[ib];
180
0
  int dst_stride = x->e_mbd.dst.y_stride;
181
0
  unsigned char *dst = x->e_mbd.dst.y_buffer + b->offset;
182
0
  B_PREDICTION_MODE mode;
183
0
  int best_rd = INT_MAX;
184
0
  int rate;
185
0
  int distortion;
186
187
0
  unsigned char *Above = dst - dst_stride;
188
0
  unsigned char *yleft = dst - 1;
189
0
  unsigned char top_left = Above[-1];
190
191
0
  for (mode = B_DC_PRED; mode <= B_HE_PRED; ++mode) {
192
0
    int this_rd;
193
194
0
    rate = mode_costs[mode];
195
196
0
    vp8_intra4x4_predict(Above, yleft, dst_stride, mode, b->predictor, 16,
197
0
                         top_left);
198
0
    distortion = get_prediction_error(be, b);
199
0
    this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
200
201
0
    if (this_rd < best_rd) {
202
0
      *bestrate = rate;
203
0
      *bestdistortion = distortion;
204
0
      best_rd = this_rd;
205
0
      *best_mode = mode;
206
0
    }
207
0
  }
208
209
0
  b->bmi.as_mode = *best_mode;
210
0
  vp8_encode_intra4x4block(x, ib);
211
0
  return best_rd;
212
0
}
213
214
0
static int pick_intra4x4mby_modes(MACROBLOCK *mb, int *Rate, int *best_dist) {
215
0
  MACROBLOCKD *const xd = &mb->e_mbd;
216
0
  int i;
217
0
  int cost = mb->mbmode_cost[xd->frame_type][B_PRED];
218
0
  int error;
219
0
  int distortion = 0;
220
0
  const int *bmode_costs;
221
222
0
  intra_prediction_down_copy(xd, xd->dst.y_buffer - xd->dst.y_stride + 16);
223
224
0
  bmode_costs = mb->inter_bmode_costs;
225
226
0
  for (i = 0; i < 16; ++i) {
227
0
    MODE_INFO *const mic = xd->mode_info_context;
228
0
    const int mis = xd->mode_info_stride;
229
230
0
    B_PREDICTION_MODE best_mode = B_MODE_COUNT;
231
0
    int r = 0, d = 0;
232
233
0
    if (mb->e_mbd.frame_type == KEY_FRAME) {
234
0
      const B_PREDICTION_MODE A = above_block_mode(mic, i, mis);
235
0
      const B_PREDICTION_MODE L = left_block_mode(mic, i);
236
237
0
      bmode_costs = mb->bmode_costs[A][L];
238
0
    }
239
240
0
    pick_intra4x4block(mb, i, &best_mode, bmode_costs, &r, &d);
241
242
0
    cost += r;
243
0
    distortion += d;
244
0
    assert(best_mode != B_MODE_COUNT);
245
0
    mic->bmi[i].as_mode = best_mode;
246
247
    /* Break out case where we have already exceeded best so far value
248
     * that was passed in
249
     */
250
0
    if (distortion > *best_dist) break;
251
0
  }
252
253
0
  *Rate = cost;
254
255
0
  if (i == 16) {
256
0
    *best_dist = distortion;
257
0
    error = RDCOST(mb->rdmult, mb->rddiv, cost, distortion);
258
0
  } else {
259
0
    *best_dist = INT_MAX;
260
0
    error = INT_MAX;
261
0
  }
262
263
0
  return error;
264
0
}
265
266
0
static void pick_intra_mbuv_mode(MACROBLOCK *mb) {
267
0
  MACROBLOCKD *x = &mb->e_mbd;
268
0
  unsigned char *uabove_row = x->dst.u_buffer - x->dst.uv_stride;
269
0
  unsigned char *vabove_row = x->dst.v_buffer - x->dst.uv_stride;
270
0
  unsigned char *usrc_ptr = (mb->block[16].src + *mb->block[16].base_src);
271
0
  unsigned char *vsrc_ptr = (mb->block[20].src + *mb->block[20].base_src);
272
0
  int uvsrc_stride = mb->block[16].src_stride;
273
0
  unsigned char uleft_col[8];
274
0
  unsigned char vleft_col[8];
275
0
  unsigned char utop_left = uabove_row[-1];
276
0
  unsigned char vtop_left = vabove_row[-1];
277
0
  int i, j;
278
0
  int expected_udc;
279
0
  int expected_vdc;
280
0
  int shift;
281
0
  int Uaverage = 0;
282
0
  int Vaverage = 0;
283
0
  int diff;
284
0
  int pred_error[4] = { 0, 0, 0, 0 }, best_error = INT_MAX;
285
0
  MB_PREDICTION_MODE best_mode = MB_MODE_COUNT;
286
287
0
  for (i = 0; i < 8; ++i) {
288
0
    uleft_col[i] = x->dst.u_buffer[i * x->dst.uv_stride - 1];
289
0
    vleft_col[i] = x->dst.v_buffer[i * x->dst.uv_stride - 1];
290
0
  }
291
292
0
  if (!x->up_available && !x->left_available) {
293
0
    expected_udc = 128;
294
0
    expected_vdc = 128;
295
0
  } else {
296
0
    shift = 2;
297
298
0
    if (x->up_available) {
299
0
      for (i = 0; i < 8; ++i) {
300
0
        Uaverage += uabove_row[i];
301
0
        Vaverage += vabove_row[i];
302
0
      }
303
304
0
      shift++;
305
0
    }
306
307
0
    if (x->left_available) {
308
0
      for (i = 0; i < 8; ++i) {
309
0
        Uaverage += uleft_col[i];
310
0
        Vaverage += vleft_col[i];
311
0
      }
312
313
0
      shift++;
314
0
    }
315
316
0
    expected_udc = (Uaverage + (1 << (shift - 1))) >> shift;
317
0
    expected_vdc = (Vaverage + (1 << (shift - 1))) >> shift;
318
0
  }
319
320
0
  for (i = 0; i < 8; ++i) {
321
0
    for (j = 0; j < 8; ++j) {
322
0
      int predu = uleft_col[i] + uabove_row[j] - utop_left;
323
0
      int predv = vleft_col[i] + vabove_row[j] - vtop_left;
324
0
      int u_p, v_p;
325
326
0
      u_p = usrc_ptr[j];
327
0
      v_p = vsrc_ptr[j];
328
329
0
      if (predu < 0) predu = 0;
330
331
0
      if (predu > 255) predu = 255;
332
333
0
      if (predv < 0) predv = 0;
334
335
0
      if (predv > 255) predv = 255;
336
337
0
      diff = u_p - expected_udc;
338
0
      pred_error[DC_PRED] += diff * diff;
339
0
      diff = v_p - expected_vdc;
340
0
      pred_error[DC_PRED] += diff * diff;
341
342
0
      diff = u_p - uabove_row[j];
343
0
      pred_error[V_PRED] += diff * diff;
344
0
      diff = v_p - vabove_row[j];
345
0
      pred_error[V_PRED] += diff * diff;
346
347
0
      diff = u_p - uleft_col[i];
348
0
      pred_error[H_PRED] += diff * diff;
349
0
      diff = v_p - vleft_col[i];
350
0
      pred_error[H_PRED] += diff * diff;
351
352
0
      diff = u_p - predu;
353
0
      pred_error[TM_PRED] += diff * diff;
354
0
      diff = v_p - predv;
355
0
      pred_error[TM_PRED] += diff * diff;
356
0
    }
357
358
0
    usrc_ptr += uvsrc_stride;
359
0
    vsrc_ptr += uvsrc_stride;
360
361
0
    if (i == 3) {
362
0
      usrc_ptr = (mb->block[18].src + *mb->block[18].base_src);
363
0
      vsrc_ptr = (mb->block[22].src + *mb->block[22].base_src);
364
0
    }
365
0
  }
366
367
0
  for (i = DC_PRED; i <= TM_PRED; ++i) {
368
0
    if (best_error > pred_error[i]) {
369
0
      best_error = pred_error[i];
370
0
      best_mode = (MB_PREDICTION_MODE)i;
371
0
    }
372
0
  }
373
374
0
  assert(best_mode != MB_MODE_COUNT);
375
0
  mb->e_mbd.mode_info_context->mbmi.uv_mode = best_mode;
376
0
}
377
378
0
static void update_mvcount(MACROBLOCK *x, int_mv *best_ref_mv) {
379
0
  MACROBLOCKD *xd = &x->e_mbd;
380
  /* Split MV modes currently not supported when RD is nopt enabled,
381
   * therefore, only need to modify MVcount in NEWMV mode. */
382
0
  if (xd->mode_info_context->mbmi.mode == NEWMV) {
383
0
    const int row_val =
384
0
        ((xd->mode_info_context->mbmi.mv.as_mv.row - best_ref_mv->as_mv.row) >>
385
0
         1);
386
0
    const int row_idx = mv_max + row_val;
387
0
    const int col_val =
388
0
        ((xd->mode_info_context->mbmi.mv.as_mv.col - best_ref_mv->as_mv.col) >>
389
0
         1);
390
0
    const int col_idx = mv_max + col_val;
391
0
    if (row_idx >= 0 && row_idx < MVvals && col_idx >= 0 && col_idx < MVvals) {
392
0
      x->MVcount[0][row_idx]++;
393
0
      x->MVcount[1][col_idx]++;
394
0
    }
395
0
  }
396
0
}
397
398
#if CONFIG_MULTI_RES_ENCODING
399
static void get_lower_res_motion_info(VP8_COMP *cpi, MACROBLOCKD *xd,
400
                                      int *dissim, int *parent_ref_frame,
401
                                      MB_PREDICTION_MODE *parent_mode,
402
                                      int_mv *parent_ref_mv, int mb_row,
403
                                      int mb_col) {
404
  LOWER_RES_MB_INFO *store_mode_info =
405
      ((LOWER_RES_FRAME_INFO *)cpi->oxcf.mr_low_res_mode_info)->mb_info;
406
  unsigned int parent_mb_index;
407
408
  /* Consider different down_sampling_factor.  */
409
  {
410
    /* TODO: Removed the loop that supports special down_sampling_factor
411
     * such as 2, 4, 8. Will revisit it if needed.
412
     * Should also try using a look-up table to see if it helps
413
     * performance. */
414
    int parent_mb_row, parent_mb_col;
415
416
    parent_mb_row = mb_row * cpi->oxcf.mr_down_sampling_factor.den /
417
                    cpi->oxcf.mr_down_sampling_factor.num;
418
    parent_mb_col = mb_col * cpi->oxcf.mr_down_sampling_factor.den /
419
                    cpi->oxcf.mr_down_sampling_factor.num;
420
    parent_mb_index = parent_mb_row * cpi->mr_low_res_mb_cols + parent_mb_col;
421
  }
422
423
  /* Read lower-resolution mode & motion result from memory.*/
424
  *parent_ref_frame = store_mode_info[parent_mb_index].ref_frame;
425
  *parent_mode = store_mode_info[parent_mb_index].mode;
426
  *dissim = store_mode_info[parent_mb_index].dissim;
427
428
  /* For highest-resolution encoder, adjust dissim value. Lower its quality
429
   * for good performance. */
430
  if (cpi->oxcf.mr_encoder_id == (cpi->oxcf.mr_total_resolutions - 1))
431
    *dissim >>= 1;
432
433
  if (*parent_ref_frame != INTRA_FRAME) {
434
    /* Consider different down_sampling_factor.
435
     * The result can be rounded to be more precise, but it takes more time.
436
     */
437
    (*parent_ref_mv).as_mv.row = store_mode_info[parent_mb_index].mv.as_mv.row *
438
                                 cpi->oxcf.mr_down_sampling_factor.num /
439
                                 cpi->oxcf.mr_down_sampling_factor.den;
440
    (*parent_ref_mv).as_mv.col = store_mode_info[parent_mb_index].mv.as_mv.col *
441
                                 cpi->oxcf.mr_down_sampling_factor.num /
442
                                 cpi->oxcf.mr_down_sampling_factor.den;
443
444
    vp8_clamp_mv2(parent_ref_mv, xd);
445
  }
446
}
447
#endif
448
449
0
static void check_for_encode_breakout(unsigned int sse, MACROBLOCK *x) {
450
0
  MACROBLOCKD *xd = &x->e_mbd;
451
452
0
  unsigned int threshold =
453
0
      (xd->block[0].dequant[1] * xd->block[0].dequant[1] >> 4);
454
455
0
  if (threshold < x->encode_breakout) threshold = x->encode_breakout;
456
457
0
  if (sse < threshold) {
458
    /* Check u and v to make sure skip is ok */
459
0
    unsigned int sse2 = 0;
460
461
0
    sse2 = VP8_UVSSE(x);
462
463
0
    if (sse2 * 2 < x->encode_breakout) {
464
0
      x->skip = 1;
465
0
    } else {
466
0
      x->skip = 0;
467
0
    }
468
0
  }
469
0
}
470
471
static int evaluate_inter_mode(unsigned int *sse, int rate2, int *distortion2,
472
0
                               VP8_COMP *cpi, MACROBLOCK *x, int rd_adj) {
473
0
  MB_PREDICTION_MODE this_mode = x->e_mbd.mode_info_context->mbmi.mode;
474
0
  int_mv mv = x->e_mbd.mode_info_context->mbmi.mv;
475
0
  int this_rd;
476
0
  int denoise_aggressive = 0;
477
  /* Exit early and don't compute the distortion if this macroblock
478
   * is marked inactive. */
479
0
  if (cpi->active_map_enabled && x->active_ptr[0] == 0) {
480
0
    *sse = 0;
481
0
    *distortion2 = 0;
482
0
    x->skip = 1;
483
0
    return INT_MAX;
484
0
  }
485
486
0
  if ((this_mode != NEWMV) || !(cpi->sf.half_pixel_search) ||
487
0
      cpi->common.full_pixel == 1) {
488
0
    *distortion2 =
489
0
        vp8_get_inter_mbpred_error(x, &cpi->fn_ptr[BLOCK_16X16], sse, mv);
490
0
  }
491
492
0
  this_rd = RDCOST(x->rdmult, x->rddiv, rate2, *distortion2);
493
494
0
#if CONFIG_TEMPORAL_DENOISING
495
0
  if (cpi->oxcf.noise_sensitivity > 0) {
496
0
    denoise_aggressive =
497
0
        (cpi->denoiser.denoiser_mode == kDenoiserOnYUVAggressive) ? 1 : 0;
498
0
  }
499
0
#endif
500
501
  // Adjust rd for ZEROMV and LAST, if LAST is the closest reference frame.
502
  // TODO: We should also add condition on distance of closest to current.
503
0
  if (!cpi->oxcf.screen_content_mode && this_mode == ZEROMV &&
504
0
      x->e_mbd.mode_info_context->mbmi.ref_frame == LAST_FRAME &&
505
0
      (denoise_aggressive || (cpi->closest_reference_frame == LAST_FRAME))) {
506
    // No adjustment if block is considered to be skin area.
507
0
    if (x->is_skin) rd_adj = 100;
508
509
0
    this_rd = (int)(((int64_t)this_rd) * rd_adj / 100);
510
0
  }
511
512
0
  check_for_encode_breakout(*sse, x);
513
0
  return this_rd;
514
0
}
515
516
static void calculate_zeromv_rd_adjustment(VP8_COMP *cpi, MACROBLOCK *x,
517
0
                                           int *rd_adjustment) {
518
0
  MODE_INFO *mic = x->e_mbd.mode_info_context;
519
0
  int_mv mv_l, mv_a, mv_al;
520
0
  int local_motion_check = 0;
521
522
0
  if (cpi->lf_zeromv_pct > 40) {
523
    /* left mb */
524
0
    mic -= 1;
525
0
    mv_l = mic->mbmi.mv;
526
527
0
    if (mic->mbmi.ref_frame != INTRA_FRAME) {
528
0
      if (abs(mv_l.as_mv.row) < 8 && abs(mv_l.as_mv.col) < 8) {
529
0
        local_motion_check++;
530
0
      }
531
0
    }
532
533
    /* above-left mb */
534
0
    mic -= x->e_mbd.mode_info_stride;
535
0
    mv_al = mic->mbmi.mv;
536
537
0
    if (mic->mbmi.ref_frame != INTRA_FRAME) {
538
0
      if (abs(mv_al.as_mv.row) < 8 && abs(mv_al.as_mv.col) < 8) {
539
0
        local_motion_check++;
540
0
      }
541
0
    }
542
543
    /* above mb */
544
0
    mic += 1;
545
0
    mv_a = mic->mbmi.mv;
546
547
0
    if (mic->mbmi.ref_frame != INTRA_FRAME) {
548
0
      if (abs(mv_a.as_mv.row) < 8 && abs(mv_a.as_mv.col) < 8) {
549
0
        local_motion_check++;
550
0
      }
551
0
    }
552
553
0
    if (((!x->e_mbd.mb_to_top_edge || !x->e_mbd.mb_to_left_edge) &&
554
0
         local_motion_check > 0) ||
555
0
        local_motion_check > 2) {
556
0
      *rd_adjustment = 80;
557
0
    } else if (local_motion_check > 0) {
558
0
      *rd_adjustment = 90;
559
0
    }
560
0
  }
561
0
}
562
563
void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
564
                         int recon_uvoffset, int *returnrate,
565
                         int *returndistortion, int *returnintra, int mb_row,
566
0
                         int mb_col) {
567
0
  BLOCK *b = &x->block[0];
568
0
  BLOCKD *d = &x->e_mbd.block[0];
569
0
  MACROBLOCKD *xd = &x->e_mbd;
570
0
  MB_MODE_INFO best_mbmode;
571
572
0
  int_mv best_ref_mv_sb[2] = { { 0 }, { 0 } };
573
0
  int_mv mode_mv_sb[2][MB_MODE_COUNT];
574
0
  int_mv best_ref_mv;
575
0
  int_mv *mode_mv;
576
0
  MB_PREDICTION_MODE this_mode;
577
0
  int num00;
578
0
  int mdcounts[4];
579
0
  int best_rd = INT_MAX;
580
0
  int rd_adjustment = 100;
581
0
  int best_intra_rd = INT_MAX;
582
0
  int mode_index;
583
0
  int rate;
584
0
  int rate2;
585
0
  int distortion2;
586
0
  int bestsme = INT_MAX;
587
0
  int best_mode_index = 0;
588
0
  unsigned int sse = UINT_MAX, best_rd_sse = UINT_MAX;
589
0
#if CONFIG_TEMPORAL_DENOISING
590
0
  unsigned int zero_mv_sse = UINT_MAX, best_sse = UINT_MAX;
591
0
#endif
592
593
0
  int sf_improved_mv_pred = cpi->sf.improved_mv_pred;
594
595
#if CONFIG_MULTI_RES_ENCODING
596
  int dissim = INT_MAX;
597
  int parent_ref_frame = 0;
598
  int_mv parent_ref_mv;
599
  MB_PREDICTION_MODE parent_mode = 0;
600
  int parent_ref_valid = 0;
601
#endif
602
603
0
  int_mv mvp;
604
605
0
  int near_sadidx[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
606
0
  int saddone = 0;
607
  /* search range got from mv_pred(). It uses step_param levels. (0-7) */
608
0
  int sr = 0;
609
610
0
  unsigned char *plane[4][3] = { { 0, 0 } };
611
0
  int ref_frame_map[4];
612
0
  int sign_bias = 0;
613
0
  int dot_artifact_candidate = 0;
614
0
  get_predictor_pointers(cpi, plane, recon_yoffset, recon_uvoffset);
615
616
  // If the current frame is using LAST as a reference, check for
617
  // biasing the mode selection for dot artifacts.
618
0
  if (cpi->ref_frame_flags & VP8_LAST_FRAME) {
619
0
    unsigned char *target_y = x->src.y_buffer;
620
0
    unsigned char *target_u = x->block[16].src + *x->block[16].base_src;
621
0
    unsigned char *target_v = x->block[20].src + *x->block[20].base_src;
622
0
    int stride = x->src.y_stride;
623
0
    int stride_uv = x->block[16].src_stride;
624
0
#if CONFIG_TEMPORAL_DENOISING
625
0
    if (cpi->oxcf.noise_sensitivity) {
626
0
      const int uv_denoise = (cpi->oxcf.noise_sensitivity >= 2) ? 1 : 0;
627
0
      target_y =
628
0
          cpi->denoiser.yv12_running_avg[LAST_FRAME].y_buffer + recon_yoffset;
629
0
      stride = cpi->denoiser.yv12_running_avg[LAST_FRAME].y_stride;
630
0
      if (uv_denoise) {
631
0
        target_u = cpi->denoiser.yv12_running_avg[LAST_FRAME].u_buffer +
632
0
                   recon_uvoffset;
633
0
        target_v = cpi->denoiser.yv12_running_avg[LAST_FRAME].v_buffer +
634
0
                   recon_uvoffset;
635
0
        stride_uv = cpi->denoiser.yv12_running_avg[LAST_FRAME].uv_stride;
636
0
      }
637
0
    }
638
0
#endif
639
0
    assert(plane[LAST_FRAME][0] != NULL);
640
0
    dot_artifact_candidate = check_dot_artifact_candidate(
641
0
        cpi, x, target_y, stride, plane[LAST_FRAME][0], mb_row, mb_col, 0);
642
    // If not found in Y channel, check UV channel.
643
0
    if (!dot_artifact_candidate) {
644
0
      assert(plane[LAST_FRAME][1] != NULL);
645
0
      dot_artifact_candidate = check_dot_artifact_candidate(
646
0
          cpi, x, target_u, stride_uv, plane[LAST_FRAME][1], mb_row, mb_col, 1);
647
0
      if (!dot_artifact_candidate) {
648
0
        assert(plane[LAST_FRAME][2] != NULL);
649
0
        dot_artifact_candidate = check_dot_artifact_candidate(
650
0
            cpi, x, target_v, stride_uv, plane[LAST_FRAME][2], mb_row, mb_col,
651
0
            2);
652
0
      }
653
0
    }
654
0
  }
655
656
#if CONFIG_MULTI_RES_ENCODING
657
  // |parent_ref_valid| will be set here if potentially we can do mv resue for
658
  // this higher resol (|cpi->oxcf.mr_encoder_id| > 0) frame.
659
  // |parent_ref_valid| may be reset depending on |parent_ref_frame| for
660
  // the current macroblock below.
661
  parent_ref_valid = cpi->oxcf.mr_encoder_id && cpi->mr_low_res_mv_avail;
662
  if (parent_ref_valid) {
663
    int parent_ref_flag;
664
665
    get_lower_res_motion_info(cpi, xd, &dissim, &parent_ref_frame, &parent_mode,
666
                              &parent_ref_mv, mb_row, mb_col);
667
668
    /* TODO(jkoleszar): The references available (ref_frame_flags) to the
669
     * lower res encoder should match those available to this encoder, but
670
     * there seems to be a situation where this mismatch can happen in the
671
     * case of frame dropping and temporal layers. For example,
672
     * GOLD being disallowed in ref_frame_flags, but being returned as
673
     * parent_ref_frame.
674
     *
675
     * In this event, take the conservative approach of disabling the
676
     * lower res info for this MB.
677
     */
678
679
    parent_ref_flag = 0;
680
    // Note availability for mv reuse is only based on last and golden.
681
    if (parent_ref_frame == LAST_FRAME)
682
      parent_ref_flag = (cpi->ref_frame_flags & VP8_LAST_FRAME);
683
    else if (parent_ref_frame == GOLDEN_FRAME)
684
      parent_ref_flag = (cpi->ref_frame_flags & VP8_GOLD_FRAME);
685
686
    // assert(!parent_ref_frame || parent_ref_flag);
687
688
    // If |parent_ref_frame| did not match either last or golden then
689
    // shut off mv reuse.
690
    if (parent_ref_frame && !parent_ref_flag) parent_ref_valid = 0;
691
692
    // Don't do mv reuse since we want to allow for another mode besides
693
    // ZEROMV_LAST to remove dot artifact.
694
    if (dot_artifact_candidate) parent_ref_valid = 0;
695
  }
696
#endif
697
698
  // Check if current macroblock is in skin area.
699
0
  x->is_skin = 0;
700
0
  if (!cpi->oxcf.screen_content_mode) {
701
0
    int block_index = mb_row * cpi->common.mb_cols + mb_col;
702
0
    x->is_skin = cpi->skin_map[block_index];
703
0
  }
704
0
#if CONFIG_TEMPORAL_DENOISING
705
0
  if (cpi->oxcf.noise_sensitivity) {
706
    // Under aggressive denoising mode, should we use skin map to reduce
707
    // denoiser
708
    // and ZEROMV bias? Will need to revisit the accuracy of this detection for
709
    // very noisy input. For now keep this as is (i.e., don't turn it off).
710
    // if (cpi->denoiser.denoiser_mode == kDenoiserOnYUVAggressive)
711
    //   x->is_skin = 0;
712
0
  }
713
0
#endif
714
715
0
  mode_mv = mode_mv_sb[sign_bias];
716
0
  best_ref_mv.as_int = 0;
717
0
  memset(mode_mv_sb, 0, sizeof(mode_mv_sb));
718
0
  memset(&best_mbmode, 0, sizeof(best_mbmode));
719
720
/* Setup search priorities */
721
#if CONFIG_MULTI_RES_ENCODING
722
  if (parent_ref_valid && parent_ref_frame && dissim < 8) {
723
    ref_frame_map[0] = -1;
724
    ref_frame_map[1] = parent_ref_frame;
725
    ref_frame_map[2] = -1;
726
    ref_frame_map[3] = -1;
727
  } else
728
#endif
729
0
    get_reference_search_order(cpi, ref_frame_map);
730
731
  /* Check to see if there is at least 1 valid reference frame that we need
732
   * to calculate near_mvs.
733
   */
734
0
  if (ref_frame_map[1] > 0) {
735
0
    sign_bias = vp8_find_near_mvs_bias(
736
0
        &x->e_mbd, x->e_mbd.mode_info_context, mode_mv_sb, best_ref_mv_sb,
737
0
        mdcounts, ref_frame_map[1], cpi->common.ref_frame_sign_bias);
738
739
0
    mode_mv = mode_mv_sb[sign_bias];
740
0
    best_ref_mv.as_int = best_ref_mv_sb[sign_bias].as_int;
741
0
  }
742
743
  /* Count of the number of MBs tested so far this frame */
744
0
  x->mbs_tested_so_far++;
745
746
0
  *returnintra = INT_MAX;
747
0
  x->skip = 0;
748
749
0
  x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME;
750
751
  /* If the frame has big static background and current MB is in low
752
   *  motion area, its mode decision is biased to ZEROMV mode.
753
   *  No adjustment if cpu_used is <= -12 (i.e., cpi->Speed >= 12).
754
   *  At such speed settings, ZEROMV is already heavily favored.
755
   */
756
0
  if (cpi->Speed < 12) {
757
0
    calculate_zeromv_rd_adjustment(cpi, x, &rd_adjustment);
758
0
  }
759
760
0
#if CONFIG_TEMPORAL_DENOISING
761
0
  if (cpi->oxcf.noise_sensitivity) {
762
0
    rd_adjustment = (int)(rd_adjustment *
763
0
                          cpi->denoiser.denoise_pars.pickmode_mv_bias / 100);
764
0
  }
765
0
#endif
766
767
0
  if (dot_artifact_candidate) {
768
    // Bias against ZEROMV_LAST mode.
769
0
    rd_adjustment = 150;
770
0
  }
771
772
  /* if we encode a new mv this is important
773
   * find the best new motion vector
774
   */
775
0
  for (mode_index = 0; mode_index < MAX_MODES; ++mode_index) {
776
0
    int frame_cost;
777
0
    int this_rd = INT_MAX;
778
0
    int this_ref_frame = ref_frame_map[vp8_ref_frame_order[mode_index]];
779
780
0
    if (best_rd <= x->rd_threshes[mode_index]) continue;
781
782
0
    if (this_ref_frame < 0) continue;
783
784
0
    x->e_mbd.mode_info_context->mbmi.ref_frame = this_ref_frame;
785
786
    /* everything but intra */
787
0
    if (x->e_mbd.mode_info_context->mbmi.ref_frame) {
788
0
      x->e_mbd.pre.y_buffer = plane[this_ref_frame][0];
789
0
      x->e_mbd.pre.u_buffer = plane[this_ref_frame][1];
790
0
      x->e_mbd.pre.v_buffer = plane[this_ref_frame][2];
791
792
0
      if (sign_bias != cpi->common.ref_frame_sign_bias[this_ref_frame]) {
793
0
        sign_bias = cpi->common.ref_frame_sign_bias[this_ref_frame];
794
0
        mode_mv = mode_mv_sb[sign_bias];
795
0
        best_ref_mv.as_int = best_ref_mv_sb[sign_bias].as_int;
796
0
      }
797
798
#if CONFIG_MULTI_RES_ENCODING
799
      if (parent_ref_valid) {
800
        if (vp8_mode_order[mode_index] == NEARESTMV &&
801
            mode_mv[NEARESTMV].as_int == 0)
802
          continue;
803
        if (vp8_mode_order[mode_index] == NEARMV && mode_mv[NEARMV].as_int == 0)
804
          continue;
805
806
        if (vp8_mode_order[mode_index] == NEWMV && parent_mode == ZEROMV &&
807
            best_ref_mv.as_int == 0)
808
          continue;
809
        else if (vp8_mode_order[mode_index] == NEWMV && dissim == 0 &&
810
                 best_ref_mv.as_int == parent_ref_mv.as_int)
811
          continue;
812
      }
813
#endif
814
0
    }
815
816
    /* Check to see if the testing frequency for this mode is at its max
817
     * If so then prevent it from being tested and increase the threshold
818
     * for its testing */
819
0
    if (x->mode_test_hit_counts[mode_index] &&
820
0
        (cpi->mode_check_freq[mode_index] > 1)) {
821
0
      if (x->mbs_tested_so_far <= (cpi->mode_check_freq[mode_index] *
822
0
                                   x->mode_test_hit_counts[mode_index])) {
823
        /* Increase the threshold for coding this mode to make it less
824
         * likely to be chosen */
825
0
        x->rd_thresh_mult[mode_index] += 4;
826
827
0
        if (x->rd_thresh_mult[mode_index] > MAX_THRESHMULT) {
828
0
          x->rd_thresh_mult[mode_index] = MAX_THRESHMULT;
829
0
        }
830
831
0
        x->rd_threshes[mode_index] =
832
0
            (cpi->rd_baseline_thresh[mode_index] >> 7) *
833
0
            x->rd_thresh_mult[mode_index];
834
0
        continue;
835
0
      }
836
0
    }
837
838
    /* We have now reached the point where we are going to test the current
839
     * mode so increment the counter for the number of times it has been
840
     * tested */
841
0
    x->mode_test_hit_counts[mode_index]++;
842
843
0
    rate2 = 0;
844
0
    distortion2 = 0;
845
846
0
    this_mode = vp8_mode_order[mode_index];
847
848
0
    x->e_mbd.mode_info_context->mbmi.mode = this_mode;
849
0
    x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED;
850
851
    /* Work out the cost assosciated with selecting the reference frame */
852
0
    frame_cost = x->ref_frame_cost[x->e_mbd.mode_info_context->mbmi.ref_frame];
853
0
    rate2 += frame_cost;
854
855
    /* Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
856
     * unless ARNR filtering is enabled in which case we want
857
     * an unfiltered alternative */
858
0
    if (cpi->is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
859
0
      if (this_mode != ZEROMV ||
860
0
          x->e_mbd.mode_info_context->mbmi.ref_frame != ALTREF_FRAME) {
861
0
        continue;
862
0
      }
863
0
    }
864
865
0
    switch (this_mode) {
866
0
      case B_PRED:
867
        /* Pass best so far to pick_intra4x4mby_modes to use as breakout */
868
0
        distortion2 = best_rd_sse;
869
0
        pick_intra4x4mby_modes(x, &rate, &distortion2);
870
871
0
        if (distortion2 == INT_MAX) {
872
0
          this_rd = INT_MAX;
873
0
        } else {
874
0
          rate2 += rate;
875
0
          distortion2 = vpx_variance16x16(*(b->base_src), b->src_stride,
876
0
                                          x->e_mbd.predictor, 16, &sse);
877
0
          this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
878
879
0
          if (this_rd < best_intra_rd) {
880
0
            best_intra_rd = this_rd;
881
0
            *returnintra = distortion2;
882
0
          }
883
0
        }
884
885
0
        break;
886
887
0
      case SPLITMV:
888
889
        /* Split MV modes currently not supported when RD is not enabled. */
890
0
        break;
891
892
0
      case DC_PRED:
893
0
      case V_PRED:
894
0
      case H_PRED:
895
0
      case TM_PRED:
896
0
        vp8_build_intra_predictors_mby_s(
897
0
            xd, xd->dst.y_buffer - xd->dst.y_stride, xd->dst.y_buffer - 1,
898
0
            xd->dst.y_stride, xd->predictor, 16);
899
0
        distortion2 = vpx_variance16x16(*(b->base_src), b->src_stride,
900
0
                                        x->e_mbd.predictor, 16, &sse);
901
0
        rate2 += x->mbmode_cost[x->e_mbd.frame_type]
902
0
                               [x->e_mbd.mode_info_context->mbmi.mode];
903
0
        this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
904
905
0
        if (this_rd < best_intra_rd) {
906
0
          best_intra_rd = this_rd;
907
0
          *returnintra = distortion2;
908
0
        }
909
0
        break;
910
911
0
      case NEWMV: {
912
0
        int thissme;
913
0
        int step_param;
914
0
        int further_steps;
915
0
        int n = 0;
916
0
        int sadpb = x->sadperbit16;
917
0
        int_mv mvp_full;
918
919
0
        int col_min = ((best_ref_mv.as_mv.col + 7) >> 3) - MAX_FULL_PEL_VAL;
920
0
        int row_min = ((best_ref_mv.as_mv.row + 7) >> 3) - MAX_FULL_PEL_VAL;
921
0
        int col_max = (best_ref_mv.as_mv.col >> 3) + MAX_FULL_PEL_VAL;
922
0
        int row_max = (best_ref_mv.as_mv.row >> 3) + MAX_FULL_PEL_VAL;
923
924
0
        int tmp_col_min = x->mv_col_min;
925
0
        int tmp_col_max = x->mv_col_max;
926
0
        int tmp_row_min = x->mv_row_min;
927
0
        int tmp_row_max = x->mv_row_max;
928
929
0
        int speed_adjust = (cpi->Speed > 5) ? ((cpi->Speed >= 8) ? 3 : 2) : 1;
930
931
        /* Further step/diamond searches as necessary */
932
0
        step_param = cpi->sf.first_step + speed_adjust;
933
934
#if CONFIG_MULTI_RES_ENCODING
935
        /* If lower-res frame is not available for mv reuse (because of
936
           frame dropping or different temporal layer pattern), then higher
937
           resol encoder does motion search without any previous knowledge.
938
           Also, since last frame motion info is not stored, then we can not
939
           use improved_mv_pred. */
940
        if (cpi->oxcf.mr_encoder_id) sf_improved_mv_pred = 0;
941
942
        // Only use parent MV as predictor if this candidate reference frame
943
        // (|this_ref_frame|) is equal to |parent_ref_frame|.
944
        if (parent_ref_valid && (parent_ref_frame == this_ref_frame)) {
945
          /* Use parent MV as predictor. Adjust search range
946
           * accordingly.
947
           */
948
          mvp.as_int = parent_ref_mv.as_int;
949
          mvp_full.as_mv.col = parent_ref_mv.as_mv.col >> 3;
950
          mvp_full.as_mv.row = parent_ref_mv.as_mv.row >> 3;
951
952
          if (dissim <= 32)
953
            step_param += 3;
954
          else if (dissim <= 128)
955
            step_param += 2;
956
          else
957
            step_param += 1;
958
        } else
959
#endif
960
0
        {
961
0
          if (sf_improved_mv_pred) {
962
0
            if (!saddone) {
963
0
              vp8_cal_sad(cpi, xd, x, recon_yoffset, &near_sadidx[0]);
964
0
              saddone = 1;
965
0
            }
966
967
0
            vp8_mv_pred(cpi, &x->e_mbd, x->e_mbd.mode_info_context, &mvp,
968
0
                        x->e_mbd.mode_info_context->mbmi.ref_frame,
969
0
                        cpi->common.ref_frame_sign_bias, &sr, &near_sadidx[0]);
970
971
0
            sr += speed_adjust;
972
            /* adjust search range according to sr from mv prediction */
973
0
            if (sr > step_param) step_param = sr;
974
975
0
            mvp_full.as_mv.col = mvp.as_mv.col >> 3;
976
0
            mvp_full.as_mv.row = mvp.as_mv.row >> 3;
977
0
          } else {
978
0
            mvp.as_int = best_ref_mv.as_int;
979
0
            mvp_full.as_mv.col = best_ref_mv.as_mv.col >> 3;
980
0
            mvp_full.as_mv.row = best_ref_mv.as_mv.row >> 3;
981
0
          }
982
0
        }
983
984
#if CONFIG_MULTI_RES_ENCODING
985
        if (parent_ref_valid && (parent_ref_frame == this_ref_frame) &&
986
            dissim <= 2 &&
987
            VPXMAX(abs(best_ref_mv.as_mv.row - parent_ref_mv.as_mv.row),
988
                   abs(best_ref_mv.as_mv.col - parent_ref_mv.as_mv.col)) <= 4) {
989
          d->bmi.mv.as_int = mvp_full.as_int;
990
          mode_mv[NEWMV].as_int = mvp_full.as_int;
991
992
          cpi->find_fractional_mv_step(
993
              x, b, d, &d->bmi.mv, &best_ref_mv, x->errorperbit,
994
              &cpi->fn_ptr[BLOCK_16X16], cpi->mb.mvcost, &distortion2, &sse);
995
        } else
996
#endif
997
0
        {
998
          /* Get intersection of UMV window and valid MV window to
999
           * reduce # of checks in diamond search. */
1000
0
          if (x->mv_col_min < col_min) x->mv_col_min = col_min;
1001
0
          if (x->mv_col_max > col_max) x->mv_col_max = col_max;
1002
0
          if (x->mv_row_min < row_min) x->mv_row_min = row_min;
1003
0
          if (x->mv_row_max > row_max) x->mv_row_max = row_max;
1004
1005
0
          further_steps =
1006
0
              (cpi->Speed >= 8)
1007
0
                  ? 0
1008
0
                  : (cpi->sf.max_step_search_steps - 1 - step_param);
1009
1010
0
          if (cpi->sf.search_method == HEX) {
1011
#if CONFIG_MULTI_RES_ENCODING
1012
            /* TODO: In higher-res pick_inter_mode, step_param is used to
1013
             * modify hex search range. Here, set step_param to 0 not to
1014
             * change the behavior in lowest-resolution encoder.
1015
             * Will improve it later.
1016
             */
1017
            /* Set step_param to 0 to ensure large-range motion search
1018
             * when mv reuse if not valid (i.e. |parent_ref_valid| = 0),
1019
             * or if this candidate reference frame (|this_ref_frame|) is
1020
             * not equal to |parent_ref_frame|.
1021
             */
1022
            if (!parent_ref_valid || (parent_ref_frame != this_ref_frame))
1023
              step_param = 0;
1024
#endif
1025
0
            bestsme = vp8_hex_search(x, b, d, &mvp_full, &d->bmi.mv, step_param,
1026
0
                                     sadpb, &cpi->fn_ptr[BLOCK_16X16],
1027
0
                                     x->mvsadcost, &best_ref_mv);
1028
0
            mode_mv[NEWMV].as_int = d->bmi.mv.as_int;
1029
0
          } else {
1030
0
            bestsme = cpi->diamond_search_sad(
1031
0
                x, b, d, &mvp_full, &d->bmi.mv, step_param, sadpb, &num00,
1032
0
                &cpi->fn_ptr[BLOCK_16X16], x->mvcost, &best_ref_mv);
1033
0
            mode_mv[NEWMV].as_int = d->bmi.mv.as_int;
1034
1035
            /* Further step/diamond searches as necessary */
1036
0
            n = num00;
1037
0
            num00 = 0;
1038
1039
0
            while (n < further_steps) {
1040
0
              n++;
1041
1042
0
              if (num00) {
1043
0
                num00--;
1044
0
              } else {
1045
0
                thissme = cpi->diamond_search_sad(
1046
0
                    x, b, d, &mvp_full, &d->bmi.mv, step_param + n, sadpb,
1047
0
                    &num00, &cpi->fn_ptr[BLOCK_16X16], x->mvcost, &best_ref_mv);
1048
0
                if (thissme < bestsme) {
1049
0
                  bestsme = thissme;
1050
0
                  mode_mv[NEWMV].as_int = d->bmi.mv.as_int;
1051
0
                } else {
1052
0
                  d->bmi.mv.as_int = mode_mv[NEWMV].as_int;
1053
0
                }
1054
0
              }
1055
0
            }
1056
0
          }
1057
1058
0
          x->mv_col_min = tmp_col_min;
1059
0
          x->mv_col_max = tmp_col_max;
1060
0
          x->mv_row_min = tmp_row_min;
1061
0
          x->mv_row_max = tmp_row_max;
1062
1063
0
          if (bestsme < INT_MAX) {
1064
0
            cpi->find_fractional_mv_step(
1065
0
                x, b, d, &d->bmi.mv, &best_ref_mv, x->errorperbit,
1066
0
                &cpi->fn_ptr[BLOCK_16X16], cpi->mb.mvcost, &distortion2, &sse);
1067
0
          }
1068
0
        }
1069
1070
0
        mode_mv[NEWMV].as_int = d->bmi.mv.as_int;
1071
        // The clamp below is not necessary from the perspective
1072
        // of VP8 bitstream, but is added to improve ChromeCast
1073
        // mirroring's robustness. Please do not remove.
1074
0
        vp8_clamp_mv2(&mode_mv[this_mode], xd);
1075
        /* mv cost; */
1076
0
        rate2 +=
1077
0
            vp8_mv_bit_cost(&mode_mv[NEWMV], &best_ref_mv, cpi->mb.mvcost, 128);
1078
0
      }
1079
        // fall through
1080
1081
0
      case NEARESTMV:
1082
0
      case NEARMV:
1083
0
        if (mode_mv[this_mode].as_int == 0) continue;
1084
        // fall through
1085
1086
0
      case ZEROMV:
1087
1088
        /* Trap vectors that reach beyond the UMV borders
1089
         * Note that ALL New MV, Nearest MV Near MV and Zero MV code drops
1090
         * through to this point because of the lack of break statements
1091
         * in the previous two cases.
1092
         */
1093
0
        if (((mode_mv[this_mode].as_mv.row >> 3) < x->mv_row_min) ||
1094
0
            ((mode_mv[this_mode].as_mv.row >> 3) > x->mv_row_max) ||
1095
0
            ((mode_mv[this_mode].as_mv.col >> 3) < x->mv_col_min) ||
1096
0
            ((mode_mv[this_mode].as_mv.col >> 3) > x->mv_col_max)) {
1097
0
          continue;
1098
0
        }
1099
1100
0
        rate2 += vp8_cost_mv_ref(this_mode, mdcounts);
1101
0
        x->e_mbd.mode_info_context->mbmi.mv.as_int = mode_mv[this_mode].as_int;
1102
0
        this_rd = evaluate_inter_mode(&sse, rate2, &distortion2, cpi, x,
1103
0
                                      rd_adjustment);
1104
1105
0
        break;
1106
0
      default: break;
1107
0
    }
1108
1109
0
#if CONFIG_TEMPORAL_DENOISING
1110
0
    if (cpi->oxcf.noise_sensitivity) {
1111
      /* Store for later use by denoiser. */
1112
      // Don't denoise with GOLDEN OR ALTREF is they are old reference
1113
      // frames (greater than MAX_GF_ARF_DENOISE_RANGE frames in past).
1114
0
      int skip_old_reference = ((this_ref_frame != LAST_FRAME) &&
1115
0
                                (cpi->common.current_video_frame -
1116
0
                                     cpi->current_ref_frames[this_ref_frame] >
1117
0
                                 MAX_GF_ARF_DENOISE_RANGE))
1118
0
                                   ? 1
1119
0
                                   : 0;
1120
0
      if (this_mode == ZEROMV && sse < zero_mv_sse && !skip_old_reference) {
1121
0
        zero_mv_sse = sse;
1122
0
        x->best_zeromv_reference_frame =
1123
0
            x->e_mbd.mode_info_context->mbmi.ref_frame;
1124
0
      }
1125
1126
      // Store the best NEWMV in x for later use in the denoiser.
1127
0
      if (x->e_mbd.mode_info_context->mbmi.mode == NEWMV && sse < best_sse &&
1128
0
          !skip_old_reference) {
1129
0
        best_sse = sse;
1130
0
        x->best_sse_inter_mode = NEWMV;
1131
0
        x->best_sse_mv = x->e_mbd.mode_info_context->mbmi.mv;
1132
0
        x->need_to_clamp_best_mvs =
1133
0
            x->e_mbd.mode_info_context->mbmi.need_to_clamp_mvs;
1134
0
        x->best_reference_frame = x->e_mbd.mode_info_context->mbmi.ref_frame;
1135
0
      }
1136
0
    }
1137
0
#endif
1138
1139
0
    if (this_rd < best_rd || x->skip) {
1140
      /* Note index of best mode */
1141
0
      best_mode_index = mode_index;
1142
1143
0
      *returnrate = rate2;
1144
0
      *returndistortion = distortion2;
1145
0
      best_rd_sse = sse;
1146
0
      best_rd = this_rd;
1147
0
      memcpy(&best_mbmode, &x->e_mbd.mode_info_context->mbmi,
1148
0
             sizeof(MB_MODE_INFO));
1149
1150
      /* Testing this mode gave rise to an improvement in best error
1151
       * score. Lower threshold a bit for next time
1152
       */
1153
0
      x->rd_thresh_mult[mode_index] =
1154
0
          (x->rd_thresh_mult[mode_index] >= (MIN_THRESHMULT + 2))
1155
0
              ? x->rd_thresh_mult[mode_index] - 2
1156
0
              : MIN_THRESHMULT;
1157
0
      x->rd_threshes[mode_index] = (cpi->rd_baseline_thresh[mode_index] >> 7) *
1158
0
                                   x->rd_thresh_mult[mode_index];
1159
0
    }
1160
1161
    /* If the mode did not help improve the best error case then raise the
1162
     * threshold for testing that mode next time around.
1163
     */
1164
0
    else {
1165
0
      x->rd_thresh_mult[mode_index] += 4;
1166
1167
0
      if (x->rd_thresh_mult[mode_index] > MAX_THRESHMULT) {
1168
0
        x->rd_thresh_mult[mode_index] = MAX_THRESHMULT;
1169
0
      }
1170
1171
0
      x->rd_threshes[mode_index] = (cpi->rd_baseline_thresh[mode_index] >> 7) *
1172
0
                                   x->rd_thresh_mult[mode_index];
1173
0
    }
1174
1175
0
    if (x->skip) break;
1176
0
  }
1177
1178
  /* Reduce the activation RD thresholds for the best choice mode */
1179
0
  if ((cpi->rd_baseline_thresh[best_mode_index] > 0) &&
1180
0
      (cpi->rd_baseline_thresh[best_mode_index] < (INT_MAX >> 2))) {
1181
0
    int best_adjustment = (x->rd_thresh_mult[best_mode_index] >> 3);
1182
1183
0
    x->rd_thresh_mult[best_mode_index] =
1184
0
        (x->rd_thresh_mult[best_mode_index] >=
1185
0
         (MIN_THRESHMULT + best_adjustment))
1186
0
            ? x->rd_thresh_mult[best_mode_index] - best_adjustment
1187
0
            : MIN_THRESHMULT;
1188
0
    x->rd_threshes[best_mode_index] =
1189
0
        (cpi->rd_baseline_thresh[best_mode_index] >> 7) *
1190
0
        x->rd_thresh_mult[best_mode_index];
1191
0
  }
1192
1193
0
  {
1194
0
    int this_rdbin = (*returndistortion >> 7);
1195
1196
0
    if (this_rdbin >= 1024) {
1197
0
      this_rdbin = 1023;
1198
0
    }
1199
1200
0
    x->error_bins[this_rdbin]++;
1201
0
  }
1202
1203
0
#if CONFIG_TEMPORAL_DENOISING
1204
0
  if (cpi->oxcf.noise_sensitivity) {
1205
0
    int block_index = mb_row * cpi->common.mb_cols + mb_col;
1206
0
    int reevaluate = 0;
1207
0
    int is_noisy = 0;
1208
0
    if (x->best_sse_inter_mode == DC_PRED) {
1209
      /* No best MV found. */
1210
0
      x->best_sse_inter_mode = best_mbmode.mode;
1211
0
      x->best_sse_mv = best_mbmode.mv;
1212
0
      x->need_to_clamp_best_mvs = best_mbmode.need_to_clamp_mvs;
1213
0
      x->best_reference_frame = best_mbmode.ref_frame;
1214
0
      best_sse = best_rd_sse;
1215
0
    }
1216
    // For non-skin blocks that have selected ZEROMV for this current frame,
1217
    // and have been selecting ZEROMV_LAST (on the base layer frame) at
1218
    // least |x~20| consecutive past frames in a row, label the block for
1219
    // possible increase in denoising strength. We also condition this
1220
    // labeling on there being significant denoising in the scene
1221
0
    if (cpi->oxcf.noise_sensitivity == 4) {
1222
0
      if (cpi->denoiser.nmse_source_diff >
1223
0
          70 * cpi->denoiser.threshold_aggressive_mode / 100) {
1224
0
        is_noisy = 1;
1225
0
      }
1226
0
    } else {
1227
0
      if (cpi->mse_source_denoised > 1000) is_noisy = 1;
1228
0
    }
1229
0
    x->increase_denoising = 0;
1230
0
    if (!x->is_skin && x->best_sse_inter_mode == ZEROMV &&
1231
0
        (x->best_reference_frame == LAST_FRAME ||
1232
0
         x->best_reference_frame == cpi->closest_reference_frame) &&
1233
0
        cpi->consec_zero_last[block_index] >= 20 && is_noisy) {
1234
0
      x->increase_denoising = 1;
1235
0
    }
1236
0
    x->denoise_zeromv = 0;
1237
0
    vp8_denoiser_denoise_mb(&cpi->denoiser, x, best_sse, zero_mv_sse,
1238
0
                            recon_yoffset, recon_uvoffset, &cpi->common.lf_info,
1239
0
                            mb_row, mb_col, block_index,
1240
0
                            cpi->consec_zero_last_mvbias[block_index]);
1241
1242
    // Reevaluate ZEROMV after denoising: for large noise content
1243
    // (i.e., cpi->mse_source_denoised is above threshold), do this for all
1244
    // blocks that did not pick ZEROMV as best mode but are using ZEROMV
1245
    // for denoising. Otherwise, always re-evaluate for blocks that picked
1246
    // INTRA mode as best mode.
1247
    // Avoid blocks that have been biased against ZERO_LAST
1248
    // (i.e., dot artifact candidate blocks).
1249
0
    reevaluate = (best_mbmode.ref_frame == INTRA_FRAME) ||
1250
0
                 (best_mbmode.mode != ZEROMV && x->denoise_zeromv &&
1251
0
                  cpi->mse_source_denoised > 2000);
1252
0
    if (!dot_artifact_candidate && reevaluate &&
1253
0
        x->best_zeromv_reference_frame != INTRA_FRAME) {
1254
0
      int this_rd = 0;
1255
0
      int this_ref_frame = x->best_zeromv_reference_frame;
1256
0
      rd_adjustment = 100;
1257
0
      rate2 =
1258
0
          x->ref_frame_cost[this_ref_frame] + vp8_cost_mv_ref(ZEROMV, mdcounts);
1259
0
      distortion2 = 0;
1260
1261
      /* set up the proper prediction buffers for the frame */
1262
0
      x->e_mbd.mode_info_context->mbmi.ref_frame = this_ref_frame;
1263
0
      x->e_mbd.pre.y_buffer = plane[this_ref_frame][0];
1264
0
      x->e_mbd.pre.u_buffer = plane[this_ref_frame][1];
1265
0
      x->e_mbd.pre.v_buffer = plane[this_ref_frame][2];
1266
1267
0
      x->e_mbd.mode_info_context->mbmi.mode = ZEROMV;
1268
0
      x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED;
1269
0
      x->e_mbd.mode_info_context->mbmi.mv.as_int = 0;
1270
0
      this_rd =
1271
0
          evaluate_inter_mode(&sse, rate2, &distortion2, cpi, x, rd_adjustment);
1272
1273
0
      if (this_rd < best_rd) {
1274
0
        memcpy(&best_mbmode, &x->e_mbd.mode_info_context->mbmi,
1275
0
               sizeof(MB_MODE_INFO));
1276
0
      }
1277
0
    }
1278
0
  }
1279
0
#endif
1280
1281
0
  if (cpi->is_src_frame_alt_ref &&
1282
0
      (best_mbmode.mode != ZEROMV || best_mbmode.ref_frame != ALTREF_FRAME)) {
1283
0
    x->e_mbd.mode_info_context->mbmi.mode = ZEROMV;
1284
0
    x->e_mbd.mode_info_context->mbmi.ref_frame = ALTREF_FRAME;
1285
0
    x->e_mbd.mode_info_context->mbmi.mv.as_int = 0;
1286
0
    x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED;
1287
0
    x->e_mbd.mode_info_context->mbmi.mb_skip_coeff =
1288
0
        (cpi->common.mb_no_coeff_skip);
1289
0
    x->e_mbd.mode_info_context->mbmi.partitioning = 0;
1290
1291
0
    return;
1292
0
  }
1293
1294
  /* set to the best mb mode, this copy can be skip if x->skip since it
1295
   * already has the right content */
1296
0
  if (!x->skip) {
1297
0
    memcpy(&x->e_mbd.mode_info_context->mbmi, &best_mbmode,
1298
0
           sizeof(MB_MODE_INFO));
1299
0
  }
1300
1301
0
  if (best_mbmode.mode <= B_PRED) {
1302
    /* set mode_info_context->mbmi.uv_mode */
1303
0
    pick_intra_mbuv_mode(x);
1304
0
  }
1305
1306
0
  if (sign_bias !=
1307
0
      cpi->common.ref_frame_sign_bias[xd->mode_info_context->mbmi.ref_frame]) {
1308
0
    best_ref_mv.as_int = best_ref_mv_sb[!sign_bias].as_int;
1309
0
  }
1310
1311
0
  update_mvcount(x, &best_ref_mv);
1312
0
}
1313
1314
0
void vp8_pick_intra_mode(MACROBLOCK *x, int *rate) {
1315
0
  int error4x4, error16x16 = INT_MAX;
1316
0
  int rate_, best_rate = 0, distortion, best_sse;
1317
0
  MB_PREDICTION_MODE mode, best_mode = DC_PRED;
1318
0
  int this_rd;
1319
0
  unsigned int sse;
1320
0
  BLOCK *b = &x->block[0];
1321
0
  MACROBLOCKD *xd = &x->e_mbd;
1322
1323
0
  xd->mode_info_context->mbmi.ref_frame = INTRA_FRAME;
1324
1325
0
  pick_intra_mbuv_mode(x);
1326
1327
0
  for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
1328
0
    xd->mode_info_context->mbmi.mode = mode;
1329
0
    vp8_build_intra_predictors_mby_s(xd, xd->dst.y_buffer - xd->dst.y_stride,
1330
0
                                     xd->dst.y_buffer - 1, xd->dst.y_stride,
1331
0
                                     xd->predictor, 16);
1332
0
    distortion = vpx_variance16x16(*(b->base_src), b->src_stride, xd->predictor,
1333
0
                                   16, &sse);
1334
0
    rate_ = x->mbmode_cost[xd->frame_type][mode];
1335
0
    this_rd = RDCOST(x->rdmult, x->rddiv, rate_, distortion);
1336
1337
0
    if (error16x16 > this_rd) {
1338
0
      error16x16 = this_rd;
1339
0
      best_mode = mode;
1340
0
      best_sse = sse;
1341
0
      best_rate = rate_;
1342
0
    }
1343
0
  }
1344
0
  xd->mode_info_context->mbmi.mode = best_mode;
1345
1346
0
  error4x4 = pick_intra4x4mby_modes(x, &rate_, &best_sse);
1347
0
  if (error4x4 < error16x16) {
1348
0
    xd->mode_info_context->mbmi.mode = B_PRED;
1349
0
    best_rate = rate_;
1350
0
  }
1351
1352
0
  *rate = best_rate;
1353
0
}