pickinter.c 53.3 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5
6
 *  that can be found in the LICENSE file in the root of the source
 *  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.
John Koleszar's avatar
John Koleszar committed
9
10
11
12
 */


#include <limits.h>
13
#include "vpx_config.h"
John Koleszar's avatar
John Koleszar committed
14
15
16
#include "onyx_int.h"
#include "modecosts.h"
#include "encodeintra.h"
17
#include "vp8/common/common.h"
John Koleszar's avatar
John Koleszar committed
18
#include "vp8/common/entropymode.h"
John Koleszar's avatar
John Koleszar committed
19
#include "pickinter.h"
John Koleszar's avatar
John Koleszar committed
20
#include "vp8/common/findnearmv.h"
John Koleszar's avatar
John Koleszar committed
21
#include "encodemb.h"
John Koleszar's avatar
John Koleszar committed
22
23
#include "vp8/common/reconinter.h"
#include "vp8/common/reconintra4x4.h"
24
#include "vp8/common/variance.h"
John Koleszar's avatar
John Koleszar committed
25
#include "mcomp.h"
26
#include "rdopt.h"
John Koleszar's avatar
John Koleszar committed
27
#include "vpx_mem/vpx_mem.h"
28
29
30
#if CONFIG_TEMPORAL_DENOISING
#include "denoising.h"
#endif
John Koleszar's avatar
John Koleszar committed
31

John Koleszar's avatar
John Koleszar committed
32
extern int VP8_UVSSE(MACROBLOCK *x);
John Koleszar's avatar
John Koleszar committed
33
34
35
36
37

#ifdef SPEEDSTATS
extern unsigned int cnt_pm;
#endif

38
extern const int vp8_ref_frame_order[MAX_MODES];
John Koleszar's avatar
John Koleszar committed
39
40
41
42
extern const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES];

extern int vp8_cost_mv_ref(MB_PREDICTION_MODE m, const int near_mv_ref_ct[4]);

Marco's avatar
Marco committed
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
// Fixed point implementation of a skin color classifier. Skin color
// is model by a Gaussian distribution in the CbCr color space.
// See ../../test/skin_color_detector_test.cc where the reference
// skin color classifier is defined.

// Fixed-point skin color model parameters.
static const int skin_mean[2] = {7463, 9614};                 // q6
static const int skin_inv_cov[4] = {4107, 1663, 1663, 2157};  // q16
static const int skin_threshold = 1570636;                    // q18

// Evaluates the Mahalanobis distance measure for the input CbCr values.
static int evaluate_skin_color_difference(int cb, int cr)
{
  const int cb_q6 = cb << 6;
  const int cr_q6 = cr << 6;
  const int cb_diff_q12 = (cb_q6 - skin_mean[0]) * (cb_q6 - skin_mean[0]);
  const int cbcr_diff_q12 = (cb_q6 - skin_mean[0]) * (cr_q6 - skin_mean[1]);
  const int cr_diff_q12 = (cr_q6 - skin_mean[1]) * (cr_q6 - skin_mean[1]);
  const int cb_diff_q2 = (cb_diff_q12 + (1 << 9)) >> 10;
  const int cbcr_diff_q2 = (cbcr_diff_q12 + (1 << 9)) >> 10;
  const int cr_diff_q2 = (cr_diff_q12 + (1 << 9)) >> 10;
  const int skin_diff = skin_inv_cov[0] * cb_diff_q2 +
      skin_inv_cov[1] * cbcr_diff_q2 +
      skin_inv_cov[2] * cbcr_diff_q2 +
      skin_inv_cov[3] * cr_diff_q2;
  return skin_diff;
}

static int macroblock_corner_grad(unsigned char* signal, int stride,
                                  int offsetx, int offsety, int sgnx, int sgny)
{
  int y1 = signal[offsetx * stride + offsety];
  int y2 = signal[offsetx * stride + offsety + sgny];
  int y3 = signal[(offsetx + sgnx) * stride + offsety];
  int y4 = signal[(offsetx + sgnx) * stride + offsety + sgny];
  return MAX(MAX(abs(y1 - y2), abs(y1 - y3)), abs(y1 - y4));
}

static int check_dot_artifact_candidate(VP8_COMP *cpi,
                                        MACROBLOCK *x,
                                        unsigned char *target_last,
                                        int stride,
                                        unsigned char* last_ref,
                                        int mb_row,
                                        int mb_col,
                                        int channel)
{
  int threshold1 = 6;
  int threshold2 = 3;
  unsigned int max_num = (cpi->common.MBs) / 10;
  int grad_last = 0;
  int grad_source = 0;
  int index = mb_row * cpi->common.mb_cols + mb_col;
  // Threshold for #consecutive (base layer) frames using zero_last mode.
  int num_frames = 30;
  int shift = 15;
  if (channel > 0) {
    shift = 7;
  }
  if (cpi->oxcf.number_of_layers > 1)
  {
    num_frames = 20;
  }
  x->zero_last_dot_suppress = 0;
  // Blocks on base layer frames that have been using ZEROMV_LAST repeatedly
  // (i.e, at least |x| consecutive frames are candidates for increasing the
  // rd adjustment for zero_last mode.
  // Only allow this for at most |max_num| blocks per frame.
  // Don't allow this for screen content input.
  if (cpi->current_layer == 0 &&
      cpi->consec_zero_last_mvbias[index] > num_frames &&
      x->mbs_zero_last_dot_suppress < max_num &&
      !cpi->oxcf.screen_content_mode)
  {
    // If this block is checked here, label it so we don't check it again until
    // ~|x| framaes later.
    x->zero_last_dot_suppress = 1;
    // Dot artifact is noticeable as strong gradient at corners of macroblock,
    // for flat areas. As a simple detector for now, we look for a high
    // corner gradient on last ref, and a smaller gradient on source.
    // Check 4 corners, return if any satisfy condition.
    // Top-left:
    grad_last = macroblock_corner_grad(last_ref, stride, 0, 0, 1, 1);
    grad_source = macroblock_corner_grad(target_last, stride, 0, 0, 1, 1);
    if (grad_last >= threshold1 && grad_source <= threshold2)
    {
       x->mbs_zero_last_dot_suppress++;
       return 1;
    }
    // Top-right:
    grad_last = macroblock_corner_grad(last_ref, stride, 0, shift, 1, -1);
    grad_source = macroblock_corner_grad(target_last, stride, 0, shift, 1, -1);
    if (grad_last >= threshold1 && grad_source <= threshold2)
    {
      x->mbs_zero_last_dot_suppress++;
      return 1;
    }
    // Bottom-left:
    grad_last = macroblock_corner_grad(last_ref, stride, shift, 0, -1, 1);
    grad_source = macroblock_corner_grad(target_last, stride, shift, 0, -1, 1);
    if (grad_last >= threshold1 && grad_source <= threshold2)
    {
      x->mbs_zero_last_dot_suppress++;
      return 1;
    }
    // Bottom-right:
    grad_last = macroblock_corner_grad(last_ref, stride, shift, shift, -1, -1);
    grad_source = macroblock_corner_grad(target_last, stride, shift, shift, -1, -1);
    if (grad_last >= threshold1 && grad_source <= threshold2)
    {
      x->mbs_zero_last_dot_suppress++;
      return 1;
    }
    return 0;
  }
  return 0;
}

// Checks if the input yCbCr values corresponds to skin color.
static int is_skin_color(int y, int cb, int cr)
{
  if (y < 40 || y > 220)
  {
    return 0;
  }
  return (evaluate_skin_color_difference(cb, cr) < skin_threshold);
}

Scott LaVarnway's avatar
Scott LaVarnway committed
171
172
173
174
175
176
int vp8_skip_fractional_mv_step(MACROBLOCK *mb, BLOCK *b, BLOCKD *d,
                                int_mv *bestmv, int_mv *ref_mv,
                                int error_per_bit,
                                const vp8_variance_fn_ptr_t *vfp,
                                int *mvcost[2], int *distortion,
                                unsigned int *sse)
John Koleszar's avatar
John Koleszar committed
177
178
179
180
181
{
    (void) b;
    (void) d;
    (void) ref_mv;
    (void) error_per_bit;
182
    (void) vfp;
John Koleszar's avatar
John Koleszar committed
183
    (void) mvcost;
184
    (void) distortion;
185
    (void) sse;
Scott LaVarnway's avatar
Scott LaVarnway committed
186
187
    bestmv->as_mv.row <<= 3;
    bestmv->as_mv.col <<= 3;
John Koleszar's avatar
John Koleszar committed
188
189
190
191
    return 0;
}


192
int vp8_get_inter_mbpred_error(MACROBLOCK *mb,
193
194
195
                                  const vp8_variance_fn_ptr_t *vfp,
                                  unsigned int *sse,
                                  int_mv this_mv)
John Koleszar's avatar
John Koleszar committed
196
197
198
199
200
201
{

    BLOCK *b = &mb->block[0];
    BLOCKD *d = &mb->e_mbd.block[0];
    unsigned char *what = (*(b->base_src) + b->src);
    int what_stride = b->src_stride;
Scott LaVarnway's avatar
Scott LaVarnway committed
202
203
204
    int pre_stride = mb->e_mbd.pre.y_stride;
    unsigned char *in_what = mb->e_mbd.pre.y_buffer + d->offset ;
    int in_what_stride = pre_stride;
205
206
    int xoffset = this_mv.as_mv.col & 7;
    int yoffset = this_mv.as_mv.row & 7;
John Koleszar's avatar
John Koleszar committed
207

Scott LaVarnway's avatar
Scott LaVarnway committed
208
    in_what += (this_mv.as_mv.row >> 3) * pre_stride + (this_mv.as_mv.col >> 3);
John Koleszar's avatar
John Koleszar committed
209
210
211

    if (xoffset | yoffset)
    {
212
        return vfp->svf(in_what, in_what_stride, xoffset, yoffset, what, what_stride, sse);
John Koleszar's avatar
John Koleszar committed
213
214
215
    }
    else
    {
216
        return vfp->vf(what, what_stride, in_what, in_what_stride, sse);
John Koleszar's avatar
John Koleszar committed
217
218
219
220
221
222
223
    }

}


unsigned int vp8_get4x4sse_cs_c
(
224
    const unsigned char *src_ptr,
John Koleszar's avatar
John Koleszar committed
225
    int  source_stride,
226
    const unsigned char *ref_ptr,
227
    int  recon_stride
John Koleszar's avatar
John Koleszar committed
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
)
{
    int distortion = 0;
    int r, c;

    for (r = 0; r < 4; r++)
    {
        for (c = 0; c < 4; c++)
        {
            int diff = src_ptr[c] - ref_ptr[c];
            distortion += diff * diff;
        }

        src_ptr += source_stride;
        ref_ptr += recon_stride;
    }

    return distortion;
}

John Koleszar's avatar
John Koleszar committed
248
static int get_prediction_error(BLOCK *be, BLOCKD *b)
John Koleszar's avatar
John Koleszar committed
249
250
251
252
253
254
{
    unsigned char *sptr;
    unsigned char *dptr;
    sptr = (*(be->base_src) + be->src);
    dptr = b->predictor;

John Koleszar's avatar
John Koleszar committed
255
    return vp8_get4x4sse_cs(sptr, be->src_stride, dptr, 16);
John Koleszar's avatar
John Koleszar committed
256
257
258
259
260

}

static int pick_intra4x4block(
    MACROBLOCK *x,
261
    int ib,
John Koleszar's avatar
John Koleszar committed
262
    B_PREDICTION_MODE *best_mode,
263
    const int *mode_costs,
John Koleszar's avatar
John Koleszar committed
264
265
266
267

    int *bestrate,
    int *bestdistortion)
{
268
269
270

    BLOCKD *b = &x->e_mbd.block[ib];
    BLOCK *be = &x->block[ib];
Scott LaVarnway's avatar
Scott LaVarnway committed
271
    int dst_stride = x->e_mbd.dst.y_stride;
272
    unsigned char *dst = x->e_mbd.dst.y_buffer + b->offset;
John Koleszar's avatar
John Koleszar committed
273
    B_PREDICTION_MODE mode;
John Koleszar's avatar
John Koleszar committed
274
    int best_rd = INT_MAX;
John Koleszar's avatar
John Koleszar committed
275
276
277
    int rate;
    int distortion;

278
279
280
281
    unsigned char *Above = dst - dst_stride;
    unsigned char *yleft = dst - 1;
    unsigned char top_left = Above[-1];

282
    for (mode = B_DC_PRED; mode <= B_HE_PRED; mode++)
John Koleszar's avatar
John Koleszar committed
283
284
285
286
    {
        int this_rd;

        rate = mode_costs[mode];
287

Johann's avatar
Johann committed
288
289
        vp8_intra4x4_predict(Above, yleft, dst_stride, mode,
                             b->predictor, 16, top_left);
John Koleszar's avatar
John Koleszar committed
290
        distortion = get_prediction_error(be, b);
Yunqing Wang's avatar
Yunqing Wang committed
291
        this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
John Koleszar's avatar
John Koleszar committed
292
293
294
295
296
297
298
299
300

        if (this_rd < best_rd)
        {
            *bestrate = rate;
            *bestdistortion = distortion;
            best_rd = this_rd;
            *best_mode = mode;
        }
    }
Scott LaVarnway's avatar
Scott LaVarnway committed
301

302
    b->bmi.as_mode = *best_mode;
John Koleszar's avatar
John Koleszar committed
303
    vp8_encode_intra4x4block(x, ib);
John Koleszar's avatar
John Koleszar committed
304
305
306
307
    return best_rd;
}


308
static int pick_intra4x4mby_modes
309
310
311
312
313
(
    MACROBLOCK *mb,
    int *Rate,
    int *best_dist
)
John Koleszar's avatar
John Koleszar committed
314
315
316
317
{
    MACROBLOCKD *const xd = &mb->e_mbd;
    int i;
    int cost = mb->mbmode_cost [xd->frame_type] [B_PRED];
318
    int error;
John Koleszar's avatar
John Koleszar committed
319
    int distortion = 0;
320
    const int *bmode_costs;
John Koleszar's avatar
John Koleszar committed
321

Scott LaVarnway's avatar
Scott LaVarnway committed
322
    intra_prediction_down_copy(xd, xd->dst.y_buffer - xd->dst.y_stride + 16);
John Koleszar's avatar
John Koleszar committed
323

Scott LaVarnway's avatar
Scott LaVarnway committed
324
325
    bmode_costs = mb->inter_bmode_costs;

John Koleszar's avatar
John Koleszar committed
326
327
328
329
    for (i = 0; i < 16; i++)
    {
        MODE_INFO *const mic = xd->mode_info_context;
        const int mis = xd->mode_info_stride;
Scott LaVarnway's avatar
Scott LaVarnway committed
330

John Koleszar's avatar
John Koleszar committed
331
332
333
        B_PREDICTION_MODE UNINITIALIZED_IS_SAFE(best_mode);
        int UNINITIALIZED_IS_SAFE(r), UNINITIALIZED_IS_SAFE(d);

Scott LaVarnway's avatar
Scott LaVarnway committed
334
335
336
337
338
339
340
341
342
        if (mb->e_mbd.frame_type == KEY_FRAME)
        {
            const B_PREDICTION_MODE A = above_block_mode(mic, i, mis);
            const B_PREDICTION_MODE L = left_block_mode(mic, i);

            bmode_costs  = mb->bmode_costs[A][L];
        }


John Koleszar's avatar
John Koleszar committed
343
        pick_intra4x4block(mb, i, &best_mode, bmode_costs, &r, &d);
John Koleszar's avatar
John Koleszar committed
344
345
346

        cost += r;
        distortion += d;
Scott LaVarnway's avatar
Scott LaVarnway committed
347
        mic->bmi[i].as_mode = best_mode;
John Koleszar's avatar
John Koleszar committed
348

John Koleszar's avatar
John Koleszar committed
349
350
351
        /* Break out case where we have already exceeded best so far value
         * that was passed in
         */
John Koleszar's avatar
John Koleszar committed
352
353
354
355
356
357
358
        if (distortion > *best_dist)
            break;
    }

    *Rate = cost;

    if (i == 16)
359
    {
John Koleszar's avatar
John Koleszar committed
360
        *best_dist = distortion;
Yunqing Wang's avatar
Yunqing Wang committed
361
        error = RDCOST(mb->rdmult, mb->rddiv, cost, distortion);
362
    }
John Koleszar's avatar
John Koleszar committed
363
    else
364
    {
John Koleszar's avatar
John Koleszar committed
365
        *best_dist = INT_MAX;
366
367
        error = INT_MAX;
    }
John Koleszar's avatar
John Koleszar committed
368
369
370
371

    return error;
}

372
static void pick_intra_mbuv_mode(MACROBLOCK *mb)
John Koleszar's avatar
John Koleszar committed
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
{

    MACROBLOCKD *x = &mb->e_mbd;
    unsigned char *uabove_row = x->dst.u_buffer - x->dst.uv_stride;
    unsigned char *vabove_row = x->dst.v_buffer - x->dst.uv_stride;
    unsigned char *usrc_ptr = (mb->block[16].src + *mb->block[16].base_src);
    unsigned char *vsrc_ptr = (mb->block[20].src + *mb->block[20].base_src);
    int uvsrc_stride = mb->block[16].src_stride;
    unsigned char uleft_col[8];
    unsigned char vleft_col[8];
    unsigned char utop_left = uabove_row[-1];
    unsigned char vtop_left = vabove_row[-1];
    int i, j;
    int expected_udc;
    int expected_vdc;
    int shift;
    int Uaverage = 0;
    int Vaverage = 0;
    int diff;
    int pred_error[4] = {0, 0, 0, 0}, best_error = INT_MAX;
    MB_PREDICTION_MODE UNINITIALIZED_IS_SAFE(best_mode);


    for (i = 0; i < 8; i++)
    {
        uleft_col[i] = x->dst.u_buffer [i* x->dst.uv_stride -1];
        vleft_col[i] = x->dst.v_buffer [i* x->dst.uv_stride -1];
    }

    if (!x->up_available && !x->left_available)
    {
        expected_udc = 128;
        expected_vdc = 128;
    }
    else
    {
        shift = 2;

        if (x->up_available)
        {

            for (i = 0; i < 8; i++)
            {
                Uaverage += uabove_row[i];
                Vaverage += vabove_row[i];
            }

            shift ++;

        }

        if (x->left_available)
        {
            for (i = 0; i < 8; i++)
            {
                Uaverage += uleft_col[i];
                Vaverage += vleft_col[i];
            }

            shift ++;

        }

        expected_udc = (Uaverage + (1 << (shift - 1))) >> shift;
        expected_vdc = (Vaverage + (1 << (shift - 1))) >> shift;
    }


    for (i = 0; i < 8; i++)
    {
        for (j = 0; j < 8; j++)
        {

            int predu = uleft_col[i] + uabove_row[j] - utop_left;
            int predv = vleft_col[i] + vabove_row[j] - vtop_left;
            int u_p, v_p;

            u_p = usrc_ptr[j];
            v_p = vsrc_ptr[j];

            if (predu < 0)
                predu = 0;

            if (predu > 255)
                predu = 255;

            if (predv < 0)
                predv = 0;

            if (predv > 255)
                predv = 255;


            diff = u_p - expected_udc;
            pred_error[DC_PRED] += diff * diff;
            diff = v_p - expected_vdc;
            pred_error[DC_PRED] += diff * diff;


            diff = u_p - uabove_row[j];
            pred_error[V_PRED] += diff * diff;
            diff = v_p - vabove_row[j];
            pred_error[V_PRED] += diff * diff;


            diff = u_p - uleft_col[i];
            pred_error[H_PRED] += diff * diff;
            diff = v_p - vleft_col[i];
            pred_error[H_PRED] += diff * diff;


            diff = u_p - predu;
            pred_error[TM_PRED] += diff * diff;
            diff = v_p - predv;
            pred_error[TM_PRED] += diff * diff;


        }

        usrc_ptr += uvsrc_stride;
        vsrc_ptr += uvsrc_stride;

        if (i == 3)
        {
            usrc_ptr = (mb->block[18].src + *mb->block[18].base_src);
            vsrc_ptr = (mb->block[22].src + *mb->block[22].base_src);
        }



    }


    for (i = DC_PRED; i <= TM_PRED; i++)
    {
        if (best_error > pred_error[i])
        {
            best_error = pred_error[i];
            best_mode = (MB_PREDICTION_MODE)i;
        }
    }


516
    mb->e_mbd.mode_info_context->mbmi.uv_mode = best_mode;
John Koleszar's avatar
John Koleszar committed
517
518
519

}

520
static void update_mvcount(MACROBLOCK *x, int_mv *best_ref_mv)
521
{
522
    MACROBLOCKD *xd = &x->e_mbd;
523
524
    /* Split MV modes currently not supported when RD is nopt enabled,
     * therefore, only need to modify MVcount in NEWMV mode. */
525
526
    if (xd->mode_info_context->mbmi.mode == NEWMV)
    {
527
        x->MVcount[0][mv_max+((xd->mode_info_context->mbmi.mv.as_mv.row -
528
                                      best_ref_mv->as_mv.row) >> 1)]++;
529
        x->MVcount[1][mv_max+((xd->mode_info_context->mbmi.mv.as_mv.col -
530
                                      best_ref_mv->as_mv.col) >> 1)]++;
531
532
533
    }
}

534
535
536
537
538
539
540
541

#if CONFIG_MULTI_RES_ENCODING
static
void get_lower_res_motion_info(VP8_COMP *cpi, MACROBLOCKD *xd, int *dissim,
                               int *parent_ref_frame,
                               MB_PREDICTION_MODE *parent_mode,
                               int_mv *parent_ref_mv, int mb_row, int mb_col)
{
542
543
    LOWER_RES_MB_INFO* store_mode_info
                          = ((LOWER_RES_FRAME_INFO*)cpi->oxcf.mr_low_res_mode_info)->mb_info;
544
545
546
547
548
549
550
551
552
553
    unsigned int parent_mb_index;

    /* Consider different down_sampling_factor.  */
    {
        /* TODO: Removed the loop that supports special down_sampling_factor
         * such as 2, 4, 8. Will revisit it if needed.
         * Should also try using a look-up table to see if it helps
         * performance. */
        int parent_mb_row, parent_mb_col;

554
        parent_mb_row = mb_row*cpi->oxcf.mr_down_sampling_factor.den
555
                    /cpi->oxcf.mr_down_sampling_factor.num;
556
        parent_mb_col = mb_col*cpi->oxcf.mr_down_sampling_factor.den
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
                    /cpi->oxcf.mr_down_sampling_factor.num;
        parent_mb_index = parent_mb_row*cpi->mr_low_res_mb_cols + parent_mb_col;
    }

    /* Read lower-resolution mode & motion result from memory.*/
    *parent_ref_frame = store_mode_info[parent_mb_index].ref_frame;
    *parent_mode =  store_mode_info[parent_mb_index].mode;
    *dissim = store_mode_info[parent_mb_index].dissim;

    /* For highest-resolution encoder, adjust dissim value. Lower its quality
     * for good performance. */
    if (cpi->oxcf.mr_encoder_id == (cpi->oxcf.mr_total_resolutions - 1))
        *dissim>>=1;

    if(*parent_ref_frame != INTRA_FRAME)
    {
        /* Consider different down_sampling_factor.
         * The result can be rounded to be more precise, but it takes more time.
         */
        (*parent_ref_mv).as_mv.row = store_mode_info[parent_mb_index].mv.as_mv.row
                                  *cpi->oxcf.mr_down_sampling_factor.num
                                  /cpi->oxcf.mr_down_sampling_factor.den;
        (*parent_ref_mv).as_mv.col = store_mode_info[parent_mb_index].mv.as_mv.col
                                  *cpi->oxcf.mr_down_sampling_factor.num
                                  /cpi->oxcf.mr_down_sampling_factor.den;

        vp8_clamp_mv2(parent_ref_mv, xd);
    }
}
#endif

588
589
static void check_for_encode_breakout(unsigned int sse, MACROBLOCK* x)
{
590
591
592
593
594
595
596
597
598
    MACROBLOCKD *xd = &x->e_mbd;

    unsigned int threshold = (xd->block[0].dequant[1]
        * xd->block[0].dequant[1] >>4);

    if(threshold < x->encode_breakout)
        threshold = x->encode_breakout;

    if (sse < threshold )
599
    {
John Koleszar's avatar
John Koleszar committed
600
        /* Check u and v to make sure skip is ok */
601
        unsigned int sse2 = 0;
602
603
604
605
606
607
608
609
610
611

        sse2 = VP8_UVSSE(x);

        if (sse2 * 2 < x->encode_breakout)
            x->skip = 1;
        else
            x->skip = 0;
    }
}

612
613
static int evaluate_inter_mode(unsigned int* sse, int rate2, int* distortion2,
                               VP8_COMP *cpi, MACROBLOCK *x, int rd_adj)
614
615
616
617
{
    MB_PREDICTION_MODE this_mode = x->e_mbd.mode_info_context->mbmi.mode;
    int_mv mv = x->e_mbd.mode_info_context->mbmi.mv;
    int this_rd;
618
    int denoise_aggressive = 0;
619
620
621
622
623
624
625
626
627
628
629
630
    /* Exit early and don't compute the distortion if this macroblock
     * is marked inactive. */
    if (cpi->active_map_enabled && x->active_ptr[0] == 0)
    {
        *sse = 0;
        *distortion2 = 0;
        x->skip = 1;
        return INT_MAX;
    }

    if((this_mode != NEWMV) ||
        !(cpi->sf.half_pixel_search) || cpi->common.full_pixel==1)
631
        *distortion2 = vp8_get_inter_mbpred_error(x,
632
633
634
635
636
                                              &cpi->fn_ptr[BLOCK_16X16],
                                              sse, mv);

    this_rd = RDCOST(x->rdmult, x->rddiv, rate2, *distortion2);

637
638
639
640
641
642
643
#if CONFIG_TEMPORAL_DENOISING
    if (cpi->oxcf.noise_sensitivity > 0) {
      denoise_aggressive =
        (cpi->denoiser.denoiser_mode == kDenoiserOnYUVAggressive) ? 1 : 0;
    }
#endif

644
    // Adjust rd for ZEROMV and LAST, if LAST is the closest reference frame.
Marco's avatar
Marco committed
645
646
647
648
649
650
651
652
653
654
655
    // TODO: We should also add condition on distance of closest to current.
    if(!cpi->oxcf.screen_content_mode &&
       this_mode == ZEROMV &&
       x->e_mbd.mode_info_context->mbmi.ref_frame == LAST_FRAME &&
       (denoise_aggressive || (cpi->closest_reference_frame == LAST_FRAME)))
    {
        // No adjustment if block is considered to be skin area.
        if(x->is_skin)
            rd_adj = 100;

        this_rd = ((int64_t)this_rd) * rd_adj / 100;
656
657
    }

658
659
660
    check_for_encode_breakout(*sse, x);
    return this_rd;
}
661

662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
static void calculate_zeromv_rd_adjustment(VP8_COMP *cpi, MACROBLOCK *x,
                                    int *rd_adjustment)
{
    MODE_INFO *mic = x->e_mbd.mode_info_context;
    int_mv mv_l, mv_a, mv_al;
    int local_motion_check = 0;

    if (cpi->lf_zeromv_pct > 40)
    {
        /* left mb */
        mic -= 1;
        mv_l = mic->mbmi.mv;

        if (mic->mbmi.ref_frame != INTRA_FRAME)
            if( abs(mv_l.as_mv.row) < 8 && abs(mv_l.as_mv.col) < 8)
                local_motion_check++;

        /* above-left mb */
        mic -= x->e_mbd.mode_info_stride;
        mv_al = mic->mbmi.mv;

        if (mic->mbmi.ref_frame != INTRA_FRAME)
            if( abs(mv_al.as_mv.row) < 8 && abs(mv_al.as_mv.col) < 8)
                local_motion_check++;

        /* above mb */
        mic += 1;
        mv_a = mic->mbmi.mv;

        if (mic->mbmi.ref_frame != INTRA_FRAME)
            if( abs(mv_a.as_mv.row) < 8 && abs(mv_a.as_mv.col) < 8)
                local_motion_check++;

        if (((!x->e_mbd.mb_to_top_edge || !x->e_mbd.mb_to_left_edge)
            && local_motion_check >0) ||  local_motion_check >2 )
            *rd_adjustment = 80;
        else if (local_motion_check > 0)
            *rd_adjustment = 90;
    }
}

703
704
void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
                         int recon_uvoffset, int *returnrate,
705
706
                         int *returndistortion, int *returnintra, int mb_row,
                         int mb_col)
John Koleszar's avatar
John Koleszar committed
707
708
709
710
711
{
    BLOCK *b = &x->block[0];
    BLOCKD *d = &x->e_mbd.block[0];
    MACROBLOCKD *xd = &x->e_mbd;
    MB_MODE_INFO best_mbmode;
712

713
714
    int_mv best_ref_mv_sb[2];
    int_mv mode_mv_sb[2][MB_MODE_COUNT];
Scott LaVarnway's avatar
Scott LaVarnway committed
715
    int_mv best_ref_mv;
716
    int_mv *mode_mv;
John Koleszar's avatar
John Koleszar committed
717
718
719
    MB_PREDICTION_MODE this_mode;
    int num00;
    int mdcounts[4];
John Koleszar's avatar
John Koleszar committed
720
    int best_rd = INT_MAX;
721
    int rd_adjustment = 100;
John Koleszar's avatar
John Koleszar committed
722
723
724
725
726
    int best_intra_rd = INT_MAX;
    int mode_index;
    int rate;
    int rate2;
    int distortion2;
727
    int bestsme = INT_MAX;
John Koleszar's avatar
John Koleszar committed
728
    int best_mode_index = 0;
729
    unsigned int sse = UINT_MAX, best_rd_sse = UINT_MAX;
730
#if CONFIG_TEMPORAL_DENOISING
731
    unsigned int zero_mv_sse = UINT_MAX, best_sse = UINT_MAX;
732
#endif
John Koleszar's avatar
John Koleszar committed
733

Marco Paniconi's avatar
Marco Paniconi committed
734
    int sf_improved_mv_pred = cpi->sf.improved_mv_pred;
Marco's avatar
Marco committed
735
736
737
738
739
740
741
742
743

#if CONFIG_MULTI_RES_ENCODING
    int dissim = INT_MAX;
    int parent_ref_frame = 0;
    int_mv parent_ref_mv;
    MB_PREDICTION_MODE parent_mode = 0;
    int parent_ref_valid = 0;
#endif

Scott LaVarnway's avatar
Scott LaVarnway committed
744
    int_mv mvp;
745

746
747
    int near_sadidx[8] = {0, 1, 2, 3, 4, 5, 6, 7};
    int saddone=0;
John Koleszar's avatar
John Koleszar committed
748
749
    /* search range got from mv_pred(). It uses step_param levels. (0-7) */
    int sr=0;
750

751
    unsigned char *plane[4][3];
752
    int ref_frame_map[4];
753
    int sign_bias = 0;
Marco's avatar
Marco committed
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
    int dot_artifact_candidate = 0;
    // For detecting dot artifact.
    unsigned char* target = x->src.y_buffer;
    unsigned char* target_u = x->block[16].src + *x->block[16].base_src;
    unsigned char* target_v = x->block[20].src + *x->block[20].base_src;
    int stride = x->src.y_stride;
    int stride_uv = x->block[16].src_stride;
#if CONFIG_TEMPORAL_DENOISING
    if (cpi->oxcf.noise_sensitivity) {
      int uv_denoise = (cpi->oxcf.noise_sensitivity >= 2) ? 1 : 0;
      target =
          cpi->denoiser.yv12_running_avg[LAST_FRAME].y_buffer + recon_yoffset;
      stride = cpi->denoiser.yv12_running_avg[LAST_FRAME].y_stride;
      if (uv_denoise) {
        target_u =
            cpi->denoiser.yv12_running_avg[LAST_FRAME].u_buffer + recon_uvoffset;
        target_v =
            cpi->denoiser.yv12_running_avg[LAST_FRAME].v_buffer + recon_uvoffset;
        stride_uv = cpi->denoiser.yv12_running_avg[LAST_FRAME].uv_stride;
      }
    }
#endif
John Koleszar's avatar
John Koleszar committed
776

Marco's avatar
Marco committed
777
    get_predictor_pointers(cpi, plane, recon_yoffset, recon_uvoffset);
778

Marco's avatar
Marco committed
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
    dot_artifact_candidate =
        check_dot_artifact_candidate(cpi, x,
            target, stride,
            plane[LAST_FRAME][0], mb_row, mb_col, 0);
    // If not found in Y channel, check UV channel.
    if (!dot_artifact_candidate) {
      dot_artifact_candidate =
          check_dot_artifact_candidate(cpi, x,
              target_u, stride_uv,
              plane[LAST_FRAME][1], mb_row, mb_col, 1);
      if (!dot_artifact_candidate) {
        dot_artifact_candidate =
            check_dot_artifact_candidate(cpi, x,
                target_v, stride_uv,
                plane[LAST_FRAME][2], mb_row, mb_col, 2);
      }
    }

#if CONFIG_MULTI_RES_ENCODING
    // |parent_ref_valid| will be set here if potentially we can do mv resue for
    // this higher resol (|cpi->oxcf.mr_encoder_id| > 0) frame.
    // |parent_ref_valid| may be reset depending on |parent_ref_frame| for
    // the current macroblock below.
    parent_ref_valid = cpi->oxcf.mr_encoder_id && cpi->mr_low_res_mv_avail;
803
    if (parent_ref_valid)
804
805
806
    {
        int parent_ref_flag;

807
808
        get_lower_res_motion_info(cpi, xd, &dissim, &parent_ref_frame,
                                  &parent_mode, &parent_ref_mv, mb_row, mb_col);
809
810
811
812
813
814
815
816
817
818
819

        /* TODO(jkoleszar): The references available (ref_frame_flags) to the
         * lower res encoder should match those available to this encoder, but
         * there seems to be a situation where this mismatch can happen in the
         * case of frame dropping and temporal layers. For example,
         * GOLD being disallowed in ref_frame_flags, but being returned as
         * parent_ref_frame.
         *
         * In this event, take the conservative approach of disabling the
         * lower res info for this MB.
         */
Marco's avatar
Marco committed
820

821
        parent_ref_flag = 0;
Marco's avatar
Marco committed
822
        // Note availability for mv reuse is only based on last and golden.
823
824
825
826
827
828
        if (parent_ref_frame == LAST_FRAME)
            parent_ref_flag = (cpi->ref_frame_flags & VP8_LAST_FRAME);
        else if (parent_ref_frame == GOLDEN_FRAME)
            parent_ref_flag = (cpi->ref_frame_flags & VP8_GOLD_FRAME);

        //assert(!parent_ref_frame || parent_ref_flag);
Marco's avatar
Marco committed
829
830
831

        // If |parent_ref_frame| did not match either last or golden then
        // shut off mv reuse.
832
833
        if (parent_ref_frame && !parent_ref_flag)
            parent_ref_valid = 0;
Marco's avatar
Marco committed
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857

        // Don't do mv reuse since we want to allow for another mode besides
        // ZEROMV_LAST to remove dot artifact.
        if (dot_artifact_candidate)
          parent_ref_valid = 0;
    }
#endif

    // Check if current macroblock is in skin area.
    {
    const int y = x->src.y_buffer[7 * x->src.y_stride + 7];
    const int cb = x->src.u_buffer[3 * x->src.uv_stride + 3];
    const int cr = x->src.v_buffer[3 * x->src.uv_stride + 3];
    x->is_skin = 0;
    if (!cpi->oxcf.screen_content_mode)
      x->is_skin = is_skin_color(y, cb, cr);
    }
#if CONFIG_TEMPORAL_DENOISING
    if (cpi->oxcf.noise_sensitivity) {
      // Under aggressive denoising mode, should we use skin map to reduce denoiser
      // and ZEROMV bias? Will need to revisit the accuracy of this detection for
      // very noisy input. For now keep this as is (i.e., don't turn it off). 
      // if (cpi->denoiser.denoiser_mode == kDenoiserOnYUVAggressive)
      //   x->is_skin = 0;
858
    }
859
#endif
860

861
862
863
    mode_mv = mode_mv_sb[sign_bias];
    best_ref_mv.as_int = 0;
    vpx_memset(mode_mv_sb, 0, sizeof(mode_mv_sb));
864
    vpx_memset(&best_mbmode, 0, sizeof(best_mbmode));
John Koleszar's avatar
John Koleszar committed
865

866
    /* Setup search priorities */
867
#if CONFIG_MULTI_RES_ENCODING
868
    if (parent_ref_valid && parent_ref_frame && dissim < 8)
869
    {
870
        ref_frame_map[0] = -1;
871
872
873
874
875
        ref_frame_map[1] = parent_ref_frame;
        ref_frame_map[2] = -1;
        ref_frame_map[3] = -1;
    } else
#endif
876
    get_reference_search_order(cpi, ref_frame_map);
John Koleszar's avatar
John Koleszar committed
877

878
879
880
881
882
    /* Check to see if there is at least 1 valid reference frame that we need
     * to calculate near_mvs.
     */
    if (ref_frame_map[1] > 0)
    {
883
884
885
886
887
888
889
890
891
892
        sign_bias = vp8_find_near_mvs_bias(&x->e_mbd,
                                           x->e_mbd.mode_info_context,
                                           mode_mv_sb,
                                           best_ref_mv_sb,
                                           mdcounts,
                                           ref_frame_map[1],
                                           cpi->common.ref_frame_sign_bias);

        mode_mv = mode_mv_sb[sign_bias];
        best_ref_mv.as_int = best_ref_mv_sb[sign_bias].as_int;
893
894
    }

John Koleszar's avatar
John Koleszar committed
895
    /* Count of the number of MBs tested so far this frame */
896
    x->mbs_tested_so_far++;
John Koleszar's avatar
John Koleszar committed
897

Paul Wilkins's avatar
Paul Wilkins committed
898
    *returnintra = INT_MAX;
John Koleszar's avatar
John Koleszar committed
899
900
    x->skip = 0;

901
    x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME;
John Koleszar's avatar
John Koleszar committed
902

903
    /* If the frame has big static background and current MB is in low
Marco's avatar
Marco committed
904
905
906
907
908
909
910
    *  motion area, its mode decision is biased to ZEROMV mode.
    *  No adjustment if cpu_used is <= -12 (i.e., cpi->Speed >= 12). 
    *  At such speed settings, ZEROMV is already heavily favored.
    */
    if (cpi->Speed < 12) {
      calculate_zeromv_rd_adjustment(cpi, x, &rd_adjustment);
    }
911

912
913
914
915
916
917
918
#if CONFIG_TEMPORAL_DENOISING
    if (cpi->oxcf.noise_sensitivity) {
      rd_adjustment = (int)(rd_adjustment *
          cpi->denoiser.denoise_pars.pickmode_mv_bias / 100);
    }
#endif

Marco's avatar
Marco committed
919
920
921
922
923
924
925
    if (dot_artifact_candidate)
    {
        // Bias against ZEROMV_LAST mode.
        rd_adjustment = 150;
    }


John Koleszar's avatar
John Koleszar committed
926
927
928
    /* if we encode a new mv this is important
     * find the best new motion vector
     */
John Koleszar's avatar
John Koleszar committed
929
930
931
932
    for (mode_index = 0; mode_index < MAX_MODES; mode_index++)
    {
        int frame_cost;
        int this_rd = INT_MAX;
933
        int this_ref_frame = ref_frame_map[vp8_ref_frame_order[mode_index]];
John Koleszar's avatar
John Koleszar committed
934

935
        if (best_rd <= x->rd_threshes[mode_index])
John Koleszar's avatar
John Koleszar committed
936
937
            continue;

938
        if (this_ref_frame < 0)
John Koleszar's avatar
John Koleszar committed
939
940
            continue;

941
942
        x->e_mbd.mode_info_context->mbmi.ref_frame = this_ref_frame;

John Koleszar's avatar
John Koleszar committed
943
        /* everything but intra */
944
        if (x->e_mbd.mode_info_context->mbmi.ref_frame)
John Koleszar's avatar
John Koleszar committed
945
        {
946
947
948
            x->e_mbd.pre.y_buffer = plane[this_ref_frame][0];
            x->e_mbd.pre.u_buffer = plane[this_ref_frame][1];
            x->e_mbd.pre.v_buffer = plane[this_ref_frame][2];
949

950
            if (sign_bias != cpi->common.ref_frame_sign_bias[this_ref_frame])
951
            {
952
953
954
                sign_bias = cpi->common.ref_frame_sign_bias[this_ref_frame];
                mode_mv = mode_mv_sb[sign_bias];
                best_ref_mv.as_int = best_ref_mv_sb[sign_bias].as_int;
955
            }
956
957

#if CONFIG_MULTI_RES_ENCODING
958
            if (parent_ref_valid)
959
960
961
962
963
964
965
966
967
            {
                if (vp8_mode_order[mode_index] == NEARESTMV &&
                    mode_mv[NEARESTMV].as_int ==0)
                    continue;
                if (vp8_mode_order[mode_index] == NEARMV &&
                    mode_mv[NEARMV].as_int ==0)
                    continue;

                if (vp8_mode_order[mode_index] == NEWMV && parent_mode == ZEROMV
John Koleszar's avatar
John Koleszar committed
968
                    && best_ref_mv.as_int==0)
969
970
971
972
973
974
975
976
977
978
979
                    continue;
                else if(vp8_mode_order[mode_index] == NEWMV && dissim==0
                    && best_ref_mv.as_int==parent_ref_mv.as_int)
                    continue;
            }
#endif
        }

        /* Check to see if the testing frequency for this mode is at its max
         * If so then prevent it from being tested and increase the threshold
         * for its testing */
980
        if (x->mode_test_hit_counts[mode_index] &&
981
982
                                         (cpi->mode_check_freq[mode_index] > 1))
        {
983
984
            if (x->mbs_tested_so_far <= (cpi->mode_check_freq[mode_index] *
                                         x->mode_test_hit_counts[mode_index]))
985
986
987
            {
                /* Increase the threshold for coding this mode to make it less
                 * likely to be chosen */
988
                x->rd_thresh_mult[mode_index] += 4;
989

990
991
                if (x->rd_thresh_mult[mode_index] > MAX_THRESHMULT)
                    x->rd_thresh_mult[mode_index] = MAX_THRESHMULT;
992

993
                x->rd_threshes[mode_index] =
994
                                 (cpi->rd_baseline_thresh[mode_index] >> 7) *
995
                                 x->rd_thresh_mult[mode_index];
996
997
                continue;
            }
John Koleszar's avatar
John Koleszar committed
998
999
        }

1000
1001
1002
        /* We have now reached the point where we are going to test the current
         * mode so increment the counter for the number of times it has been
         * tested */
1003
        x->mode_test_hit_counts[mode_index] ++;
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014

        rate2 = 0;
        distortion2 = 0;

        this_mode = vp8_mode_order[mode_index];

        x->e_mbd.mode_info_context->mbmi.mode = this_mode;
        x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED;

        /* Work out the cost assosciated with selecting the reference frame */
        frame_cost =
1015
            x->ref_frame_cost[x->e_mbd.mode_info_context->mbmi.ref_frame];
1016
1017
1018
1019
1020
        rate2 += frame_cost;

        /* Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
         * unless ARNR filtering is enabled in which case we want
         * an unfiltered alternative */
1021
        if (cpi->is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
John Koleszar's avatar
John Koleszar committed
1022
        {
1023
1024
            if (this_mode != ZEROMV ||
                x->e_mbd.mode_info_context->mbmi.ref_frame != ALTREF_FRAME)
John Koleszar's avatar
John Koleszar committed
1025
1026
1027
1028
1029
1030
                continue;
        }

        switch (this_mode)
        {
        case B_PRED:
1031
            /* Pass best so far to pick_intra4x4mby_modes to use as breakout */
1032
            distortion2 = best_rd_sse;
John Koleszar's avatar
John Koleszar committed
1033
            pick_intra4x4mby_modes(x, &rate, &distortion2);
John Koleszar's avatar
John Koleszar committed
1034
1035
1036
1037
1038
1039
1040

            if (distortion2 == INT_MAX)
            {
                this_rd = INT_MAX;
            }
            else
            {
1041
                rate2 += rate;
John Koleszar's avatar
John Koleszar committed
1042
                distortion2 = vp8_variance16x16(
1043
                                    *(b->base_src), b->src_stride,
1044
                                    x->e_mbd.predictor, 16, &sse);
Yunqing Wang's avatar
Yunqing Wang committed
1045
                this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
John Koleszar's avatar
John Koleszar committed
1046
1047
1048
1049

                if (this_rd < best_intra_rd)
                {
                    best_intra_rd = this_rd;
Paul Wilkins's avatar
Paul Wilkins committed
1050
                    *returnintra = distortion2;
John Koleszar's avatar
John Koleszar committed
1051
1052
1053
1054
1055
1056
1057
                }
            }

            break;

        case SPLITMV:

John Koleszar's avatar
John Koleszar committed
1058
            /* Split MV modes currently not supported when RD is not enabled. */
John Koleszar's avatar
John Koleszar committed
1059
1060
1061
1062
1063
1064
            break;

        case DC_PRED:
        case V_PRED:
        case H_PRED:
        case TM_PRED:
1065
1066
1067
1068
1069
1070
            vp8_build_intra_predictors_mby_s(xd,
                                             xd->dst.y_buffer - xd->dst.y_stride,
                                             xd->dst.y_buffer - 1,
                                             xd->dst.y_stride,
                                             xd->predictor,
                                             16);
John Koleszar's avatar
John Koleszar committed
1071
            distortion2 = vp8_variance16x16
1072
                                          (*(b->base_src), b->src_stride,
1073
                                          x->e_mbd.predictor, 16, &sse);
1074
            rate2 += x->mbmode_cost[x->e_mbd.frame_type][x->e_mbd.mode_info_context->mbmi.mode];
Yunqing Wang's avatar
Yunqing Wang committed
1075
            this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
John Koleszar's avatar
John Koleszar committed
1076
1077
1078
1079

            if (this_rd < best_intra_rd)
            {
                best_intra_rd = this_rd;
Paul Wilkins's avatar
Paul Wilkins committed
1080
                *returnintra = distortion2;
John Koleszar's avatar
John Koleszar committed
1081
1082
1083
1084
1085
1086
1087
1088
1089
            }
            break;

        case NEWMV:
        {
            int thissme;
            int step_param;
            int further_steps;
            int n = 0;
1090
            int sadpb = x->sadperbit16;
1091
            int_mv mvp_full;
John Koleszar's avatar
John Koleszar committed
1092

1093
1094
            int col_min = ((best_ref_mv.as_mv.col+7)>>3) - MAX_FULL_PEL_VAL;
            int row_min = ((best_ref_mv.as_mv.row+7)>>3) - MAX_FULL_PEL_VAL;
1095
1096
1097
1098
            int col_max = (best_ref_mv.as_mv.col>>3)
                         + MAX_FULL_PEL_VAL;
            int row_max = (best_ref_mv.as_mv.row>>3)
                         + MAX_FULL_PEL_VAL;
1099
1100
1101
1102
1103
1104

            int tmp_col_min = x->mv_col_min;
            int tmp_col_max = x->mv_col_max;
            int tmp_row_min = x->mv_row_min;
            int tmp_row_max = x->mv_row_max;

1105
            int speed_adjust = (cpi->Speed > 5) ? ((cpi->Speed >= 8)? 3 : 2) : 1;
John Koleszar's avatar
John Koleszar committed
1106

John Koleszar's avatar
John Koleszar committed
1107
            /* Further step/diamond searches as necessary */
1108
1109
            step_param = cpi->sf.first_step + speed_adjust;

1110
#if CONFIG_MULTI_RES_ENCODING
Marco's avatar
Marco committed
1111
1112
1113
1114
            /* If lower-res frame is not available for mv reuse (because of
               frame dropping or different temporal layer pattern), then higher
               resol encoder does motion search without any previous knowledge.
               Also, since last frame motion info is not stored, then we can not
1115
               use improved_mv_pred. */
Marco's avatar
Marco committed
1116
            if (cpi->oxcf.mr_encoder_id)
Marco Paniconi's avatar
Marco Paniconi committed
1117
                sf_improved_mv_pred = 0;
1118

Marco's avatar
Marco committed
1119
1120
1121
            // Only use parent MV as predictor if this candidate reference frame
            // (|this_ref_frame|) is equal to |parent_ref_frame|.
            if (parent_ref_valid && (parent_ref_frame == this_ref_frame))
1122
            {
John Koleszar's avatar
John Koleszar committed
1123
1124
1125
                /* Use parent MV as predictor. Adjust search range
                 * accordingly.
                 */
1126
1127
1128
1129
1130
1131
1132
1133
1134
                mvp.as_int = parent_ref_mv.as_int;
                mvp_full.as_mv.col = parent_ref_mv.as_mv.col>>3;
                mvp_full.as_mv.row = parent_ref_mv.as_mv.row>>3;

                if(dissim <=32) step_param += 3;
                else if(dissim <=128) step_param += 2;
                else step_param += 1;
            }else
#endif
John Koleszar's avatar
John Koleszar committed
1135
            {
Marco Paniconi's avatar
Marco Paniconi committed
1136
                if(sf_improved_mv_pred)
1137
                {
1138
1139
1140
1141
1142
                    if(!saddone)
                    {
                        vp8_cal_sad(cpi,xd,x, recon_yoffset ,&near_sadidx[0] );
                        saddone = 1;
                    }
1143

1144
1145
1146
1147
                    vp8_mv_pred(cpi, &x->e_mbd, x->e_mbd.mode_info_context,
                                &mvp,x->e_mbd.mode_info_context->mbmi.ref_frame,
                                cpi->common.ref_frame_sign_bias, &sr,
                                &near_sadidx[0]);
1148

1149
                    sr += speed_adjust;
John Koleszar's avatar
John Koleszar committed
1150
                    /* adjust search range according to sr from mv prediction */
1151
1152
                    if(sr > step_param)
                        step_param = sr;
1153

1154
1155
1156
1157
1158
1159
1160
1161
1162
                    mvp_full.as_mv.col = mvp.as_mv.col>>3;
                    mvp_full.as_mv.row = mvp.as_mv.row>>3;
                }else
                {
                    mvp.as_int = best_ref_mv.as_int;
                    mvp_full.as_mv.col = best_ref_mv.as_mv.col>>3;
                    mvp_full.as_mv.row = best_ref_mv.as_mv.row>>3;
                }
            }
1163

1164
#if CONFIG_MULTI_RES_ENCODING
Marco's avatar
Marco committed
1165
1166
            if (parent_ref_valid && (parent_ref_frame == this_ref_frame) &&
                dissim <= 2 &&
1167
1168
                MAX(abs(best_ref_mv.as_mv.row - parent_ref_mv.as_mv.row),
                    abs(best_ref_mv.as_mv.col - parent_ref_mv.as_mv.col)) <= 4)
1169
            {
1170
1171
                d->bmi.mv.as_int = mvp_full.as_int;
                mode_mv[NEWMV].as_int = mvp_full.as_int;
John Koleszar's avatar
John Koleszar committed
1172

1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
                cpi->find_fractional_mv_step(x, b, d, &d->bmi.mv, &best_ref_mv,
                                             x->errorperbit,
                                             &cpi->fn_ptr[BLOCK_16X16],
                                             cpi->mb.mvcost,
                                             &distortion2,&sse);
            }else
#endif
            {
                /* Get intersection of UMV window and valid MV window to
                 * reduce # of checks in diamond search. */
                if (x->mv_col_min < col_min )
                    x->mv_col_min = col_min;
                if (x->mv_col_max > col_max )
                    x->mv_col_max = col_max;
                if (x->mv_row_min < row_min )
                    x->mv_row_min = row_min;
                if (x->mv_row_max > row_max )
                    x->mv_row_max = row_max;
1191

1192
1193
                further_steps = (cpi->Speed >= 8)?
                           0: (cpi->sf.max_step_search_steps - 1 - step_param);
1194

1195
1196
                if (cpi->sf.search_method == HEX)
                {
Yunqing Wang's avatar
Yunqing Wang committed
1197
1198
1199
1200
1201
1202
#if CONFIG_MULTI_RES_ENCODING
                /* TODO: In higher-res pick_inter_mode, step_param is used to
                 * modify hex search range. Here, set step_param to 0 not to
                 * change the behavior in lowest-resolution encoder.
                 * Will improve it later.
                 */
Marco's avatar
Marco committed
1203
1204
1205
1206
1207
1208
                /* Set step_param to 0 to ensure large-range motion search
                 * when mv reuse if not valid (i.e. |parent_ref_valid| = 0),
                 * or if this candidate reference frame (|this_ref_frame|) is
                 * not equal to |parent_ref_frame|.
                 */
                if (!parent_ref_valid || (parent_ref_frame != this_ref_frame))
1209
                    step_param = 0;
Yunqing Wang's avatar
Yunqing Wang committed
1210
#endif
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
                    bestsme = vp8_hex_search(x, b, d, &mvp_full, &d->bmi.mv,
                                          step_param, sadpb,
                                          &cpi->fn_ptr[BLOCK_16X16],
                                          x->mvsadcost, x->mvcost, &best_ref_mv);
                    mode_mv[NEWMV].as_int = d->bmi.mv.as_int;
                }
                else
                {
                    bestsme = cpi->diamond_search_sad(x, b, d, &mvp_full,
                                          &d->bmi.mv, step_param, sadpb, &num00,
                                          &cpi->fn_ptr[BLOCK_16X16],
                                          x->mvcost, &best_ref_mv);
                    mode_mv[NEWMV].as_int = d->bmi.mv.as_int;
John Koleszar's avatar
John Koleszar committed
1224

John Koleszar's avatar
John Koleszar committed
1225
                    /* Further step/diamond searches as necessary */
1226
1227
                    n = num00;
                    num00 = 0;
John Koleszar's avatar
John Koleszar committed
1228

1229
                    while (n < further_steps)
John Koleszar's avatar
John Koleszar committed
1230
                    {
1231
1232
1233
1234
                        n++;

                        if (num00)
                            num00--;
John Koleszar's avatar
John Koleszar committed
1235
1236
                        else
                        {
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
                            thissme =
                            cpi->diamond_search_sad(x, b, d, &mvp_full,
                                                    &d->bmi.mv,
                                                    step_param + n,
                                                    sadpb, &num00,
                                                    &cpi->fn_ptr[BLOCK_16X16],
                                                    x->mvcost, &best_ref_mv);
                            if (thissme < bestsme)
                            {
                                bestsme = thissme;
                                mode_mv[NEWMV].as_int = d->bmi.mv.as_int;
                            }
                            else
                            {
                                d->bmi.mv.as_int = mode_mv[NEWMV].as_int;
                            }
John Koleszar's avatar
John Koleszar committed
1253
1254
1255
1256
                        }
                    }
                }

1257
1258
1259
1260
                x->mv_col_min = tmp_col_min;
                x->mv_col_max = tmp_col_max;
                x->mv_row_min = tmp_row_min;
                x->mv_row_max = tmp_row_max;
John Koleszar's avatar
John Koleszar committed
1261

1262
1263
1264
                if (bestsme < INT_MAX)
                    cpi->find_fractional_mv_step(x, b, d, &d->bmi.mv,
                                             &best_ref_mv, x->errorperbit,
1265
1266
1267
                                             &cpi->fn_ptr[BLOCK_16X16],
                                             cpi->mb.mvcost,
                                             &distortion2,&sse);
1268
            }
John Koleszar's avatar
John Koleszar committed
1269

Scott LaVarnway's avatar
Scott LaVarnway committed
1270
            mode_mv[NEWMV].as_int = d->bmi.mv.as_int;
John Koleszar's avatar
John Koleszar committed
1271

John Koleszar's avatar
John Koleszar committed
1272
            /* mv cost; */
1273
1274
            rate2 += vp8_mv_bit_cost(&mode_mv[NEWMV], &best_ref_mv,
                                     cpi->mb.mvcost, 128);
1275
        }
John Koleszar's avatar
John Koleszar committed
1276
1277
1278
1279

        case NEARESTMV:
        case NEARMV:

Scott LaVarnway's avatar
Scott LaVarnway committed
1280
            if (mode_mv[this_mode].as_int == 0)
John Koleszar's avatar
John Koleszar committed
1281
1282
1283
1284
                continue;

        case ZEROMV:

1285
1286
1287
1288
1289
1290
1291
1292
1293
            /* Trap vectors that reach beyond the UMV borders
             * Note that ALL New MV, Nearest MV Near MV and Zero MV code drops
             * through to this point because of the lack of break statements
             * in the previous two cases.
             */
            if (((mode_mv[this_mode].as_mv.row >> 3) < x->mv_row_min) ||
                ((mode_mv[this_mode].as_mv.row >> 3) > x->mv_row_max) ||
                ((mode_mv[this_mode].as_mv.col >> 3) < x->mv_col_min) ||
                ((mode_mv[this_mode].as_mv.col >> 3) > x->mv_col_max))
John Koleszar's avatar
John Koleszar committed
1294
1295
1296
                continue;

            rate2 += vp8_cost_mv_ref(this_mode, mdcounts);
1297
1298
            x->e_mbd.mode_info_context->mbmi.mv.as_int =
                                                    mode_mv[this_mode].as_int;
1299
1300
            this_rd = evaluate_inter_mode(&sse, rate2, &distortion2, cpi, x,
                                          rd_adjustment);
John Koleszar's avatar
John Koleszar committed
1301
1302
1303
1304
1305
1306

            break;
        default:
            break;
        }

1307
1308
1309
#if CONFIG_TEMPORAL_DENOISING
        if (cpi->oxcf.noise_sensitivity)
        {
John Koleszar's avatar
John Koleszar committed
1310
            /* Store for later use by denoiser. */
1311
1312
1313
1314
1315
1316
1317
1318
            // Dont' denoise with GOLDEN OR ALTREF is they are old reference
            // frames (greater than MAX_GF_ARF_DENOISE_RANGE frames in past).
            int skip_old_reference = ((this_ref_frame != LAST_FRAME) &&
                (cpi->common.current_video_frame -
                 cpi->current_ref_frames[this_ref_frame] >
                 MAX_GF_ARF_DENOISE_RANGE)) ? 1 : 0;
            if (this_mode == ZEROMV && sse < zero_mv_sse &&
                !skip_old_reference)
1319
1320
1321
1322
1323
1324
            {
                zero_mv_sse = sse;
                x->best_zeromv_reference_frame =
                        x->e_mbd.mode_info_context->mbmi.ref_frame;
            }

Marco's avatar
Marco committed
1325
            // Store the best NEWMV in x for later use in the denoiser.
1326
            if (x->e_mbd.mode_info_context->mbmi.mode == NEWMV &&
1327
                sse < best_sse && !skip_old_reference)
1328
1329
1330
1331
1332
1333
1334
1335
1336
            {
                best_sse = sse;
                x->best_sse_inter_mode = NEWMV;
                x->best_sse_mv = x->e_mbd.mode_info_context->mbmi.mv;
                x->need_to_clamp_best_mvs =
                    x->e_mbd.mode_info_context->mbmi.need_to_clamp_mvs;
                x->best_reference_frame =
                    x->e_mbd.mode_info_context->mbmi.ref_frame;
            }
Stefan Holmer's avatar