vp9_firstpass.c 93.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
#include <limits.h>
12
#include <math.h>
13
#include <stdio.h>
14
15
16
17
18
19
20
21
22

#include "./vpx_scale_rtcd.h"

#include "vpx_mem/vpx_mem.h"
#include "vpx_scale/vpx_scale.h"
#include "vpx_scale/yv12config.h"

#include "vp9/common/vp9_entropymv.h"
#include "vp9/common/vp9_quant_common.h"
23
#include "vp9/common/vp9_reconinter.h"  // vp9_setup_dst_planes()
24
#include "vp9/common/vp9_systemdependent.h"
Marco Paniconi's avatar
Marco Paniconi committed
25
#include "vp9/encoder/vp9_aq_variance.h"
26
#include "vp9/encoder/vp9_block.h"
27
28
#include "vp9/encoder/vp9_encodeframe.h"
#include "vp9/encoder/vp9_encodemb.h"
29
#include "vp9/encoder/vp9_encodemv.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
30
#include "vp9/encoder/vp9_encoder.h"
31
32
33
#include "vp9/encoder/vp9_extend.h"
#include "vp9/encoder/vp9_firstpass.h"
#include "vp9/encoder/vp9_mcomp.h"
34
#include "vp9/encoder/vp9_quantize.h"
35
#include "vp9/encoder/vp9_rd.h"
36
#include "vp9/encoder/vp9_variance.h"
John Koleszar's avatar
John Koleszar committed
37

38
39
40
#define OUTPUT_FPF          0
#define ARF_STATS_OUTPUT    0

41
42
#define GROUP_ADAPTIVE_MAXQ 0

Paul Wilkins's avatar
Paul Wilkins committed
43
#define BOOST_BREAKOUT      12.5
44
#define BOOST_FACTOR        12.5
Paul Wilkins's avatar
Paul Wilkins committed
45
#define ERR_DIVISOR         128.0
Paul Wilkins's avatar
Paul Wilkins committed
46
47
#define FACTOR_PT_LOW       0.70
#define FACTOR_PT_HIGH      0.90
48
49
50
51
#define FIRST_PASS_Q        10.0
#define GF_MAX_BOOST        96.0
#define INTRA_MODE_PENALTY  1024
#define KF_MAX_BOOST        128.0
Paul Wilkins's avatar
Paul Wilkins committed
52
#define MIN_ARF_GF_BOOST    240
53
54
55
56
57
#define MIN_DECAY_FACTOR    0.01
#define MIN_GF_INTERVAL     4
#define MIN_KF_BOOST        300
#define NEW_MV_MODE_PENALTY 32
#define SVC_FACTOR_PT_LOW   0.45
58
#define DARK_THRESH         64
59
#define DEFAULT_GRP_WEIGHT  1.0
Paul Wilkins's avatar
CQ Mode    
Paul Wilkins committed
60

61
#define DOUBLE_DIVIDE_CHECK(x) ((x) < 0 ? (x) - 0.000001 : (x) + 0.000001)
John Koleszar's avatar
John Koleszar committed
62

63
64
65
#if ARF_STATS_OUTPUT
unsigned int arf_count = 0;
#endif
66

67
68
69
70
71
72
static void swap_yv12(YV12_BUFFER_CONFIG *a, YV12_BUFFER_CONFIG *b) {
  YV12_BUFFER_CONFIG temp = *a;
  *a = *b;
  *b = temp;
}

73
74
// Resets the first pass file to the given position using a relative seek from
// the current position.
Paul Wilkins's avatar
Paul Wilkins committed
75
static void reset_fpf_position(TWO_PASS *p,
76
                               const FIRSTPASS_STATS *position) {
77
  p->stats_in = position;
John Koleszar's avatar
John Koleszar committed
78
79
}

Adrian Grange's avatar
Adrian Grange committed
80
// Read frame stats at an offset from the current position.
81
82
83
84
static const FIRSTPASS_STATS *read_frame_stats(const TWO_PASS *p, int offset) {
  if ((offset >= 0 && p->stats_in + offset >= p->stats_in_end) ||
      (offset < 0 && p->stats_in + offset < p->stats_in_start)) {
    return NULL;
John Koleszar's avatar
John Koleszar committed
85
86
  }

87
  return &p->stats_in[offset];
88
89
}

Paul Wilkins's avatar
Paul Wilkins committed
90
static int input_stats(TWO_PASS *p, FIRSTPASS_STATS *fps) {
91
  if (p->stats_in >= p->stats_in_end)
John Koleszar's avatar
John Koleszar committed
92
    return EOF;
93

94
95
  *fps = *p->stats_in;
  ++p->stats_in;
John Koleszar's avatar
John Koleszar committed
96
  return 1;
97
98
}

99
100
static void output_stats(FIRSTPASS_STATS *stats,
                         struct vpx_codec_pkt_list *pktlist) {
John Koleszar's avatar
John Koleszar committed
101
102
103
104
105
  struct vpx_codec_cx_pkt pkt;
  pkt.kind = VPX_CODEC_STATS_PKT;
  pkt.data.twopass_stats.buf = stats;
  pkt.data.twopass_stats.sz = sizeof(FIRSTPASS_STATS);
  vpx_codec_pkt_list_add(pktlist, &pkt);
106
107
108

// TEMP debug code
#if OUTPUT_FPF
John Koleszar's avatar
John Koleszar committed
109
110
111
112
  {
    FILE *fpfile;
    fpfile = fopen("firstpass.stt", "a");

113
    fprintf(fpfile, "%12.0f %12.4f %12.0f %12.0f %12.0f %12.4f %12.4f"
John Koleszar's avatar
John Koleszar committed
114
115
116
            "%12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f"
            "%12.0f %12.0f %12.4f %12.0f %12.0f %12.4f\n",
            stats->frame,
117
            stats->weight,
John Koleszar's avatar
John Koleszar committed
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
            stats->intra_error,
            stats->coded_error,
            stats->sr_coded_error,
            stats->pcnt_inter,
            stats->pcnt_motion,
            stats->pcnt_second_ref,
            stats->pcnt_neutral,
            stats->MVr,
            stats->mvr_abs,
            stats->MVc,
            stats->mvc_abs,
            stats->MVrv,
            stats->MVcv,
            stats->mv_in_out_count,
            stats->new_mv_count,
            stats->count,
            stats->duration);
    fclose(fpfile);
  }
137
138
139
#endif
}

140
141
142
143
144
145
#if CONFIG_FP_MB_STATS
static void output_fpmb_stats(uint8_t *this_frame_mb_stats, VP9_COMMON *cm,
                         struct vpx_codec_pkt_list *pktlist) {
  struct vpx_codec_cx_pkt pkt;
  pkt.kind = VPX_CODEC_FPMB_STATS_PKT;
  pkt.data.firstpass_mb_stats.buf = this_frame_mb_stats;
146
  pkt.data.firstpass_mb_stats.sz = cm->initial_mbs * sizeof(uint8_t);
147
148
149
150
  vpx_codec_pkt_list_add(pktlist, &pkt);
}
#endif

John Koleszar's avatar
John Koleszar committed
151
static void zero_stats(FIRSTPASS_STATS *section) {
152
153
  section->frame = 0.0;
  section->weight = 0.0;
John Koleszar's avatar
John Koleszar committed
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
  section->intra_error = 0.0;
  section->coded_error = 0.0;
  section->sr_coded_error = 0.0;
  section->pcnt_inter  = 0.0;
  section->pcnt_motion  = 0.0;
  section->pcnt_second_ref = 0.0;
  section->pcnt_neutral = 0.0;
  section->MVr        = 0.0;
  section->mvr_abs     = 0.0;
  section->MVc        = 0.0;
  section->mvc_abs     = 0.0;
  section->MVrv       = 0.0;
  section->MVcv       = 0.0;
  section->mv_in_out_count  = 0.0;
  section->new_mv_count = 0.0;
  section->count      = 0.0;
  section->duration   = 1.0;
171
  section->spatial_layer_id = 0;
172
173
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
174
175
static void accumulate_stats(FIRSTPASS_STATS *section,
                             const FIRSTPASS_STATS *frame) {
John Koleszar's avatar
John Koleszar committed
176
  section->frame += frame->frame;
177
  section->weight += frame->weight;
178
  section->spatial_layer_id = frame->spatial_layer_id;
John Koleszar's avatar
John Koleszar committed
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
  section->intra_error += frame->intra_error;
  section->coded_error += frame->coded_error;
  section->sr_coded_error += frame->sr_coded_error;
  section->pcnt_inter  += frame->pcnt_inter;
  section->pcnt_motion += frame->pcnt_motion;
  section->pcnt_second_ref += frame->pcnt_second_ref;
  section->pcnt_neutral += frame->pcnt_neutral;
  section->MVr        += frame->MVr;
  section->mvr_abs     += frame->mvr_abs;
  section->MVc        += frame->MVc;
  section->mvc_abs     += frame->mvc_abs;
  section->MVrv       += frame->MVrv;
  section->MVcv       += frame->MVcv;
  section->mv_in_out_count  += frame->mv_in_out_count;
  section->new_mv_count += frame->new_mv_count;
  section->count      += frame->count;
  section->duration   += frame->duration;
196
197
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
198
199
static void subtract_stats(FIRSTPASS_STATS *section,
                           const FIRSTPASS_STATS *frame) {
John Koleszar's avatar
John Koleszar committed
200
  section->frame -= frame->frame;
201
  section->weight -= frame->weight;
John Koleszar's avatar
John Koleszar committed
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
  section->intra_error -= frame->intra_error;
  section->coded_error -= frame->coded_error;
  section->sr_coded_error -= frame->sr_coded_error;
  section->pcnt_inter  -= frame->pcnt_inter;
  section->pcnt_motion -= frame->pcnt_motion;
  section->pcnt_second_ref -= frame->pcnt_second_ref;
  section->pcnt_neutral -= frame->pcnt_neutral;
  section->MVr        -= frame->MVr;
  section->mvr_abs     -= frame->mvr_abs;
  section->MVc        -= frame->MVc;
  section->mvc_abs     -= frame->mvc_abs;
  section->MVrv       -= frame->MVrv;
  section->MVcv       -= frame->MVcv;
  section->mv_in_out_count  -= frame->mv_in_out_count;
  section->new_mv_count -= frame->new_mv_count;
  section->count      -= frame->count;
  section->duration   -= frame->duration;
219
220
}

221

222
223
// Calculate a modified Error used in distributing bits between easier and
// harder frames.
224
225
static double calculate_modified_err(const TWO_PASS *twopass,
                                     const VP9EncoderConfig *oxcf,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
226
                                     const FIRSTPASS_STATS *this_frame) {
227
  const FIRSTPASS_STATS *const stats = &twopass->total_stats;
228
229
230
231
232
  const double av_weight = stats->weight / stats->count;
  const double av_err = (stats->coded_error * av_weight) / stats->count;
  const double modified_error =
    av_err * pow(this_frame->coded_error * this_frame->weight /
                 DOUBLE_DIVIDE_CHECK(av_err), oxcf->two_pass_vbrbias / 100.0);
233
234
  return fclamp(modified_error,
                twopass->modified_error_min, twopass->modified_error_max);
John Koleszar's avatar
John Koleszar committed
235
236
}

237
// This function returns the maximum target rate per frame.
238
239
static int frame_max_bits(const RATE_CONTROL *rc,
                          const VP9EncoderConfig *oxcf) {
240
  int64_t max_bits = ((int64_t)rc->avg_frame_bandwidth *
Dmitry Kovalev's avatar
Dmitry Kovalev committed
241
                          (int64_t)oxcf->two_pass_vbrmax_section) / 100;
Yaowu Xu's avatar
Yaowu Xu committed
242
  if (max_bits < 0)
Paul Wilkins's avatar
Paul Wilkins committed
243
    max_bits = 0;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
244
245
  else if (max_bits > rc->max_frame_bandwidth)
    max_bits = rc->max_frame_bandwidth;
Paul Wilkins's avatar
Paul Wilkins committed
246

Yaowu Xu's avatar
Yaowu Xu committed
247
  return (int)max_bits;
John Koleszar's avatar
John Koleszar committed
248
249
}

250
void vp9_init_first_pass(VP9_COMP *cpi) {
251
  zero_stats(&cpi->twopass.total_stats);
John Koleszar's avatar
John Koleszar committed
252
253
}

254
void vp9_end_first_pass(VP9_COMP *cpi) {
255
  if (is_two_pass_svc(cpi)) {
256
257
258
259
260
261
262
263
    int i;
    for (i = 0; i < cpi->svc.number_spatial_layers; ++i) {
      output_stats(&cpi->svc.layer_context[i].twopass.total_stats,
                   cpi->output_pkt_list);
    }
  } else {
    output_stats(&cpi->twopass.total_stats, cpi->output_pkt_list);
  }
264
}
John Koleszar's avatar
John Koleszar committed
265

266
267
268
269
270
271
272
273
274
275
276
277
278
static vp9_variance_fn_t get_block_variance_fn(BLOCK_SIZE bsize) {
  switch (bsize) {
    case BLOCK_8X8:
      return vp9_mse8x8;
    case BLOCK_16X8:
      return vp9_mse16x8;
    case BLOCK_8X16:
      return vp9_mse8x16;
    default:
      return vp9_mse16x16;
  }
}

279
280
281
static unsigned int get_prediction_error(BLOCK_SIZE bsize,
                                         const struct buf_2d *src,
                                         const struct buf_2d *ref) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
282
  unsigned int sse;
283
284
  const vp9_variance_fn_t fn = get_block_variance_fn(bsize);
  fn(src->buf, src->stride, ref->buf, ref->stride, &sse);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
285
  return sse;
286
287
}

288
289
290
291
292
293
294
#if CONFIG_VP9_HIGHBITDEPTH
static vp9_variance_fn_t highbd_get_block_variance_fn(BLOCK_SIZE bsize,
                                                      int bd) {
  switch (bd) {
    default:
      switch (bsize) {
        case BLOCK_8X8:
295
          return vp9_highbd_mse8x8;
296
        case BLOCK_16X8:
297
          return vp9_highbd_mse16x8;
298
        case BLOCK_8X16:
299
          return vp9_highbd_mse8x16;
300
        default:
301
          return vp9_highbd_mse16x16;
302
303
304
305
306
      }
      break;
    case 10:
      switch (bsize) {
        case BLOCK_8X8:
307
          return vp9_highbd_10_mse8x8;
308
        case BLOCK_16X8:
309
          return vp9_highbd_10_mse16x8;
310
        case BLOCK_8X16:
311
          return vp9_highbd_10_mse8x16;
312
        default:
313
          return vp9_highbd_10_mse16x16;
314
315
316
317
318
      }
      break;
    case 12:
      switch (bsize) {
        case BLOCK_8X8:
319
          return vp9_highbd_12_mse8x8;
320
        case BLOCK_16X8:
321
          return vp9_highbd_12_mse16x8;
322
        case BLOCK_8X16:
323
          return vp9_highbd_12_mse8x16;
324
        default:
325
          return vp9_highbd_12_mse16x16;
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
      }
      break;
  }
}

static unsigned int highbd_get_prediction_error(BLOCK_SIZE bsize,
                                                const struct buf_2d *src,
                                                const struct buf_2d *ref,
                                                int bd) {
  unsigned int sse;
  const vp9_variance_fn_t fn = highbd_get_block_variance_fn(bsize, bd);
  fn(src->buf, src->stride, ref->buf, ref->stride, &sse);
  return sse;
}
#endif  // CONFIG_VP9_HIGHBITDEPTH

342
343
// Refine the motion search range according to the frame dimension
// for first pass test.
344
static int get_search_range(const VP9_COMP *cpi) {
345
  int sr = 0;
346
  const int dim = MIN(cpi->initial_width, cpi->initial_height);
347
348
349
350
351
352

  while ((dim << sr) < MAX_FULL_PEL_VAL)
    ++sr;
  return sr;
}

353
static void first_pass_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
354
                                     const MV *ref_mv, MV *best_mv,
355
                                     int *best_motion_err) {
John Koleszar's avatar
John Koleszar committed
356
  MACROBLOCKD *const xd = &x->e_mbd;
357
  MV tmp_mv = {0, 0};
358
  MV ref_mv_full = {ref_mv->row >> 3, ref_mv->col >> 3};
359
  int num00, tmp_err, n;
hkuang's avatar
hkuang committed
360
  const BLOCK_SIZE bsize = xd->mi[0].src_mi->mbmi.sb_type;
361
  vp9_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[bsize];
362
  const int new_mv_mode_penalty = NEW_MV_MODE_PENALTY;
363

364
365
  int step_param = 3;
  int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
366
  const int sr = get_search_range(cpi);
367
  step_param += sr;
368
369
  further_steps -= sr;

Adrian Grange's avatar
Adrian Grange committed
370
  // Override the default variance function to use MSE.
371
  v_fn_ptr.vf = get_block_variance_fn(bsize);
372
373
374
375
376
#if CONFIG_VP9_HIGHBITDEPTH
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
    v_fn_ptr.vf = highbd_get_block_variance_fn(bsize, xd->bd);
  }
#endif  // CONFIG_VP9_HIGHBITDEPTH
John Koleszar's avatar
John Koleszar committed
377

Adrian Grange's avatar
Adrian Grange committed
378
  // Center the initial step/diamond search on best mv.
379
  tmp_err = cpi->diamond_search_sad(x, &cpi->ss_cfg, &ref_mv_full, &tmp_mv,
380
                                    step_param,
381
                                    x->sadperbit16, &num00, &v_fn_ptr, ref_mv);
Deb Mukherjee's avatar
Deb Mukherjee committed
382
383
  if (tmp_err < INT_MAX)
    tmp_err = vp9_get_mvpred_var(x, &tmp_mv, ref_mv, &v_fn_ptr, 1);
John Koleszar's avatar
John Koleszar committed
384
385
386
387
388
  if (tmp_err < INT_MAX - new_mv_mode_penalty)
    tmp_err += new_mv_mode_penalty;

  if (tmp_err < *best_motion_err) {
    *best_motion_err = tmp_err;
389
    *best_mv = tmp_mv;
John Koleszar's avatar
John Koleszar committed
390
391
  }

Adrian Grange's avatar
Adrian Grange committed
392
  // Carry out further step/diamond searches as necessary.
John Koleszar's avatar
John Koleszar committed
393
394
395
396
  n = num00;
  num00 = 0;

  while (n < further_steps) {
Adrian Grange's avatar
Adrian Grange committed
397
    ++n;
John Koleszar's avatar
John Koleszar committed
398

399
    if (num00) {
Adrian Grange's avatar
Adrian Grange committed
400
      --num00;
401
    } else {
402
      tmp_err = cpi->diamond_search_sad(x, &cpi->ss_cfg, &ref_mv_full, &tmp_mv,
John Koleszar's avatar
John Koleszar committed
403
                                        step_param + n, x->sadperbit16,
404
                                        &num00, &v_fn_ptr, ref_mv);
Deb Mukherjee's avatar
Deb Mukherjee committed
405
406
      if (tmp_err < INT_MAX)
        tmp_err = vp9_get_mvpred_var(x, &tmp_mv, ref_mv, &v_fn_ptr, 1);
John Koleszar's avatar
John Koleszar committed
407
      if (tmp_err < INT_MAX - new_mv_mode_penalty)
John Koleszar's avatar
John Koleszar committed
408
409
        tmp_err += new_mv_mode_penalty;

John Koleszar's avatar
John Koleszar committed
410
      if (tmp_err < *best_motion_err) {
John Koleszar's avatar
John Koleszar committed
411
        *best_motion_err = tmp_err;
412
        *best_mv = tmp_mv;
John Koleszar's avatar
John Koleszar committed
413
      }
John Koleszar's avatar
John Koleszar committed
414
    }
John Koleszar's avatar
John Koleszar committed
415
  }
John Koleszar's avatar
John Koleszar committed
416
417
}

418
419
420
421
422
423
424
425
426
427
static BLOCK_SIZE get_bsize(const VP9_COMMON *cm, int mb_row, int mb_col) {
  if (2 * mb_col + 1 < cm->mi_cols) {
    return 2 * mb_row + 1 < cm->mi_rows ? BLOCK_16X16
                                        : BLOCK_16X8;
  } else {
    return 2 * mb_row + 1 < cm->mi_rows ? BLOCK_8X16
                                        : BLOCK_8X8;
  }
}

428
static int find_fp_qindex(vpx_bit_depth_t bit_depth) {
429
430
431
  int i;

  for (i = 0; i < QINDEX_RANGE; ++i)
432
    if (vp9_convert_qindex_to_q(i, bit_depth) >= FIRST_PASS_Q)
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
      break;

  if (i == QINDEX_RANGE)
    i--;

  return i;
}

static void set_first_pass_params(VP9_COMP *cpi) {
  VP9_COMMON *const cm = &cpi->common;
  if (!cpi->refresh_alt_ref_frame &&
      (cm->current_video_frame == 0 ||
       (cpi->frame_flags & FRAMEFLAGS_KEY))) {
    cm->frame_type = KEY_FRAME;
  } else {
    cm->frame_type = INTER_FRAME;
  }
  // Do not use periodic key frames.
  cpi->rc.frames_to_key = INT_MAX;
}

454
void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
John Koleszar's avatar
John Koleszar committed
455
  int mb_row, mb_col;
456
  MACROBLOCK *const x = &cpi->td.mb;
457
  VP9_COMMON *const cm = &cpi->common;
John Koleszar's avatar
John Koleszar committed
458
  MACROBLOCKD *const xd = &x->e_mbd;
James Zern's avatar
James Zern committed
459
  TileInfo tile;
460
461
  struct macroblock_plane *const p = x->plane;
  struct macroblockd_plane *const pd = xd->plane;
462
  const PICK_MODE_CONTEXT *ctx = &cpi->td.pc_root->none;
463
  int i;
John Koleszar's avatar
John Koleszar committed
464
465

  int recon_yoffset, recon_uvoffset;
466
  YV12_BUFFER_CONFIG *const lst_yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
467
  YV12_BUFFER_CONFIG *gld_yv12 = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
468
  YV12_BUFFER_CONFIG *const new_yv12 = get_frame_new_buffer(cm);
469
470
471
  int recon_y_stride = lst_yv12->y_stride;
  int recon_uv_stride = lst_yv12->uv_stride;
  int uv_mb_height = 16 >> (lst_yv12->y_height > lst_yv12->uv_height);
John Koleszar's avatar
John Koleszar committed
472
473
474
475
476
477
  int64_t intra_error = 0;
  int64_t coded_error = 0;
  int64_t sr_coded_error = 0;

  int sum_mvr = 0, sum_mvc = 0;
  int sum_mvr_abs = 0, sum_mvc_abs = 0;
478
  int64_t sum_mvrs = 0, sum_mvcs = 0;
John Koleszar's avatar
John Koleszar committed
479
480
481
  int mvcount = 0;
  int intercount = 0;
  int second_ref_count = 0;
482
  const int intrapenalty = INTRA_MODE_PENALTY;
John Koleszar's avatar
John Koleszar committed
483
484
485
  int neutral_count = 0;
  int new_mv_count = 0;
  int sum_in_vectors = 0;
486
  MV lastmv = {0, 0};
Paul Wilkins's avatar
Paul Wilkins committed
487
  TWO_PASS *twopass = &cpi->twopass;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
488
  const MV zero_mv = {0, 0};
489
  const YV12_BUFFER_CONFIG *first_ref_buf = lst_yv12;
490
491
  LAYER_CONTEXT *const lc = is_two_pass_svc(cpi) ?
        &cpi->svc.layer_context[cpi->svc.spatial_layer_id] : NULL;
Paul Wilkins's avatar
Paul Wilkins committed
492
493
  double intra_factor;
  double brightness_factor;
John Koleszar's avatar
John Koleszar committed
494

495
#if CONFIG_FP_MB_STATS
496
  if (cpi->use_fp_mb_stats) {
497
    vp9_zero_array(cpi->twopass.frame_mb_stats_buf, cm->initial_mbs);
498
  }
499
500
#endif

501
  vp9_clear_system_state();
John Koleszar's avatar
John Koleszar committed
502

Paul Wilkins's avatar
Paul Wilkins committed
503
504
505
  intra_factor = 0.0;
  brightness_factor = 0.0;

506
  set_first_pass_params(cpi);
507
  vp9_set_quantizer(cm, find_fp_qindex(cm->bit_depth));
508

509
510
  if (lc != NULL) {
    twopass = &lc->twopass;
511

512
513
514
515
516
517
518
519
520
    cpi->lst_fb_idx = cpi->svc.spatial_layer_id;
    cpi->ref_frame_flags = VP9_LAST_FLAG;

    if (cpi->svc.number_spatial_layers + cpi->svc.spatial_layer_id <
        REF_FRAMES) {
      cpi->gld_fb_idx =
          cpi->svc.number_spatial_layers + cpi->svc.spatial_layer_id;
      cpi->ref_frame_flags |= VP9_GOLD_FLAG;
      cpi->refresh_golden_frame = (lc->current_video_frame_in_layer == 0);
521
    } else {
522
      cpi->refresh_golden_frame = 0;
523
524
    }

525
526
527
    if (lc->current_video_frame_in_layer == 0)
      cpi->ref_frame_flags = 0;

528
529
530
531
    vp9_scale_references(cpi);

    // Use either last frame or alt frame for motion search.
    if (cpi->ref_frame_flags & VP9_LAST_FLAG) {
532
533
534
      first_ref_buf = vp9_get_scaled_ref_frame(cpi, LAST_FRAME);
      if (first_ref_buf == NULL)
        first_ref_buf = get_ref_frame_buffer(cpi, LAST_FRAME);
535
536
537
    }

    if (cpi->ref_frame_flags & VP9_GOLD_FLAG) {
538
      BufferPool *const pool = cm->buffer_pool;
539
540
541
542
      const int ref_idx =
          cm->ref_frame_map[get_ref_frame_idx(cpi, GOLDEN_FRAME)];
      const int scaled_idx = cpi->scaled_ref_idx[GOLDEN_FRAME - 1];

543
      gld_yv12 = (scaled_idx != ref_idx) ? &pool->frame_bufs[scaled_idx].buf :
544
545
546
                 get_ref_frame_buffer(cpi, GOLDEN_FRAME);
    } else {
      gld_yv12 = NULL;
547
548
    }

549
550
551
    recon_y_stride = new_yv12->y_stride;
    recon_uv_stride = new_yv12->uv_stride;
    uv_mb_height = 16 >> (new_yv12->y_height > new_yv12->uv_height);
552

553
554
555
    set_ref_ptrs(cm, xd,
                 (cpi->ref_frame_flags & VP9_LAST_FLAG) ? LAST_FRAME: NONE,
                 (cpi->ref_frame_flags & VP9_GOLD_FLAG) ? GOLDEN_FRAME : NONE);
556
557
558

    cpi->Source = vp9_scale_if_required(cm, cpi->un_scaled_source,
                                        &cpi->scaled_source);
559
560
  }

561
562
  vp9_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y);

John Koleszar's avatar
John Koleszar committed
563
  vp9_setup_src_planes(x, cpi->Source, 0, 0);
564
  vp9_setup_pre_planes(xd, 0, first_ref_buf, 0, 0, NULL);
565
  vp9_setup_dst_planes(xd->plane, new_yv12, 0, 0);
John Koleszar's avatar
John Koleszar committed
566

hkuang's avatar
hkuang committed
567
568
  xd->mi = cm->mi;
  xd->mi[0].src_mi = &xd->mi[0];
John Koleszar's avatar
John Koleszar committed
569

570
  vp9_frame_init_quantizer(cpi);
John Koleszar's avatar
John Koleszar committed
571

572
573
  for (i = 0; i < MAX_MB_PLANE; ++i) {
    p[i].coeff = ctx->coeff_pbuf[i][1];
574
    p[i].qcoeff = ctx->qcoeff_pbuf[i][1];
575
    pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][1];
576
    p[i].eobs = ctx->eobs_pbuf[i][1];
577
  }
578
  x->skip_recode = 0;
579

Dmitry Kovalev's avatar
Dmitry Kovalev committed
580
581
  vp9_init_mv_probs(cm);
  vp9_initialize_rd_consts(cpi);
John Koleszar's avatar
John Koleszar committed
582

Adrian Grange's avatar
Adrian Grange committed
583
  // Tiling is ignored in the first pass.
James Zern's avatar
James Zern committed
584
585
  vp9_tile_init(&tile, cm, 0, 0);

Adrian Grange's avatar
Adrian Grange committed
586
  for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) {
587
    MV best_ref_mv = {0, 0};
John Koleszar's avatar
John Koleszar committed
588

Adrian Grange's avatar
Adrian Grange committed
589
    // Reset above block coeffs.
John Koleszar's avatar
John Koleszar committed
590
591
    xd->up_available = (mb_row != 0);
    recon_yoffset = (mb_row * recon_y_stride * 16);
Alex Converse's avatar
Alex Converse committed
592
    recon_uvoffset = (mb_row * recon_uv_stride * uv_mb_height);
John Koleszar's avatar
John Koleszar committed
593

594
    // Set up limit values for motion vectors to prevent them extending
Adrian Grange's avatar
Adrian Grange committed
595
    // outside the UMV borders.
596
    x->mv_row_min = -((mb_row * 16) + BORDER_MV_PIXELS_B16);
John Koleszar's avatar
John Koleszar committed
597
    x->mv_row_max = ((cm->mb_rows - 1 - mb_row) * 16)
598
                    + BORDER_MV_PIXELS_B16;
John Koleszar's avatar
John Koleszar committed
599

Adrian Grange's avatar
Adrian Grange committed
600
    for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) {
John Koleszar's avatar
John Koleszar committed
601
      int this_error;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
602
      const int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);
603
      const BLOCK_SIZE bsize = get_bsize(cm, mb_row, mb_col);
604
605
606
      double log_intra;
      int level_sample;

607
608
609
#if CONFIG_FP_MB_STATS
      const int mb_index = mb_row * cm->mb_cols + mb_col;
#endif
610

611
      vp9_clear_system_state();
John Koleszar's avatar
John Koleszar committed
612

613
614
615
      xd->plane[0].dst.buf = new_yv12->y_buffer + recon_yoffset;
      xd->plane[1].dst.buf = new_yv12->u_buffer + recon_uvoffset;
      xd->plane[2].dst.buf = new_yv12->v_buffer + recon_uvoffset;
John Koleszar's avatar
John Koleszar committed
616
      xd->left_available = (mb_col != 0);
hkuang's avatar
hkuang committed
617
618
      xd->mi[0].src_mi->mbmi.sb_type = bsize;
      xd->mi[0].src_mi->mbmi.ref_frame[0] = INTRA_FRAME;
James Zern's avatar
James Zern committed
619
      set_mi_row_col(xd, &tile,
620
621
                     mb_row << 1, num_8x8_blocks_high_lookup[bsize],
                     mb_col << 1, num_8x8_blocks_wide_lookup[bsize],
James Zern's avatar
James Zern committed
622
                     cm->mi_rows, cm->mi_cols);
Jingning Han's avatar
Jingning Han committed
623

Adrian Grange's avatar
Adrian Grange committed
624
      // Do intra 16x16 prediction.
625
      x->skip_encode = 0;
hkuang's avatar
hkuang committed
626
627
      xd->mi[0].src_mi->mbmi.mode = DC_PRED;
      xd->mi[0].src_mi->mbmi.tx_size = use_dc_pred ?
628
629
630
         (bsize >= BLOCK_16X16 ? TX_16X16 : TX_8X8) : TX_4X4;
      vp9_encode_intra_block_plane(x, bsize, 0);
      this_error = vp9_get_mb_ss(x->plane[0].src_diff);
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
#if CONFIG_VP9_HIGHBITDEPTH
      if (cm->use_highbitdepth) {
        switch (cm->bit_depth) {
          case VPX_BITS_8:
            break;
          case VPX_BITS_10:
            this_error >>= 4;
            break;
          case VPX_BITS_12:
            this_error >>= 8;
            break;
          default:
            assert(0 && "cm->bit_depth should be VPX_BITS_8, "
                        "VPX_BITS_10 or VPX_BITS_12");
            return;
        }
      }
#endif  // CONFIG_VP9_HIGHBITDEPTH
649

Paul Wilkins's avatar
Paul Wilkins committed
650
      vp9_clear_system_state();
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
      log_intra = log(this_error + 1.0);
      if (log_intra < 10.0)
        intra_factor += 1.0 + ((10.0 - log_intra) * 0.05);
      else
        intra_factor += 1.0;

#if CONFIG_VP9_HIGHBITDEPTH
      if (cm->use_highbitdepth)
        level_sample = CONVERT_TO_SHORTPTR(x->plane[0].src.buf)[0];
      else
        level_sample = x->plane[0].src.buf[0];
#else
      level_sample = x->plane[0].src.buf[0];
#endif
      if ((level_sample < DARK_THRESH) && (log_intra < 9.0))
        brightness_factor += 1.0 + (0.01 * (DARK_THRESH - level_sample));
      else
        brightness_factor += 1.0;

Adrian Grange's avatar
Adrian Grange committed
670
671
      // Intrapenalty below deals with situations where the intra and inter
      // error scores are very low (e.g. a plain black frame).
672
673
674
675
      // We do not have special cases in first pass for 0,0 and nearest etc so
      // all inter modes carry an overhead cost estimate for the mv.
      // When the error score is very low this causes us to pick all or lots of
      // INTRA modes and throw lots of key frames.
John Koleszar's avatar
John Koleszar committed
676
677
678
      // This penalty adds a cost matching that of a 0,0 mv to the intra case.
      this_error += intrapenalty;

Adrian Grange's avatar
Adrian Grange committed
679
      // Accumulate the intra error.
John Koleszar's avatar
John Koleszar committed
680
681
      intra_error += (int64_t)this_error;

682
683
#if CONFIG_FP_MB_STATS
      if (cpi->use_fp_mb_stats) {
684
        // initialization
685
        cpi->twopass.frame_mb_stats_buf[mb_index] = 0;
686
687
688
      }
#endif

689
690
      // Set up limit values for motion vectors to prevent them extending
      // outside the UMV borders.
691
      x->mv_col_min = -((mb_col * 16) + BORDER_MV_PIXELS_B16);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
692
      x->mv_col_max = ((cm->mb_cols - 1 - mb_col) * 16) + BORDER_MV_PIXELS_B16;
John Koleszar's avatar
John Koleszar committed
693

Adrian Grange's avatar
Adrian Grange committed
694
      // Other than for the first frame do a motion search.
695
696
      if ((lc == NULL && cm->current_video_frame > 0) ||
          (lc != NULL && lc->current_video_frame_in_layer > 0)) {
697
        int tmp_err, motion_error, raw_motion_error;
698
699
        // Assume 0,0 motion with no mv overhead.
        MV mv = {0, 0} , tmp_mv = {0, 0};
700
        struct buf_2d unscaled_last_source_buf_2d;
701

702
        xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset;
703
704
705
706
707
708
709
710
711
712
713
714
#if CONFIG_VP9_HIGHBITDEPTH
        if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
          motion_error = highbd_get_prediction_error(
              bsize, &x->plane[0].src, &xd->plane[0].pre[0], xd->bd);
        } else {
          motion_error = get_prediction_error(
              bsize, &x->plane[0].src, &xd->plane[0].pre[0]);
        }
#else
        motion_error = get_prediction_error(
            bsize, &x->plane[0].src, &xd->plane[0].pre[0]);
#endif  // CONFIG_VP9_HIGHBITDEPTH
715

716
717
718
719
720
721
722
        // Compute the motion error of the 0,0 motion using the last source
        // frame as the reference. Skip the further motion search on
        // reconstructed frame if this error is small.
        unscaled_last_source_buf_2d.buf =
            cpi->unscaled_last_source->y_buffer + recon_yoffset;
        unscaled_last_source_buf_2d.stride =
            cpi->unscaled_last_source->y_stride;
723
724
725
726
727
728
729
730
731
732
733
734
#if CONFIG_VP9_HIGHBITDEPTH
        if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
          raw_motion_error = highbd_get_prediction_error(
              bsize, &x->plane[0].src, &unscaled_last_source_buf_2d, xd->bd);
        } else {
          raw_motion_error = get_prediction_error(
              bsize, &x->plane[0].src, &unscaled_last_source_buf_2d);
        }
#else
        raw_motion_error = get_prediction_error(
            bsize, &x->plane[0].src, &unscaled_last_source_buf_2d);
#endif  // CONFIG_VP9_HIGHBITDEPTH
735
736

        // TODO(pengchong): Replace the hard-coded threshold
737
        if (raw_motion_error > 25 || lc != NULL) {
738
739
          // Test last reference frame using the previous best mv as the
          // starting point (best reference) for the search.
740
          first_pass_motion_search(cpi, x, &best_ref_mv, &mv, &motion_error);
John Koleszar's avatar
John Koleszar committed
741

742
743
          // If the current best reference mv is not centered on 0,0 then do a
          // 0,0 based search as well.
744
          if (!is_zero_mv(&best_ref_mv)) {
745
            tmp_err = INT_MAX;
746
            first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv, &tmp_err);
747
748
749

            if (tmp_err < motion_error) {
              motion_error = tmp_err;
750
              mv = tmp_mv;
751
            }
John Koleszar's avatar
John Koleszar committed
752
753
          }

754
          // Search in an older reference frame.
755
756
757
          if (((lc == NULL && cm->current_video_frame > 1) ||
               (lc != NULL && lc->current_video_frame_in_layer > 1))
              && gld_yv12 != NULL) {
758
759
760
761
            // Assume 0,0 motion with no mv overhead.
            int gf_motion_error;

            xd->plane[0].pre[0].buf = gld_yv12->y_buffer + recon_yoffset;
762
763
764
765
766
767
768
769
770
771
772
773
#if CONFIG_VP9_HIGHBITDEPTH
            if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
              gf_motion_error = highbd_get_prediction_error(
                  bsize, &x->plane[0].src, &xd->plane[0].pre[0], xd->bd);
            } else {
              gf_motion_error = get_prediction_error(
                  bsize, &x->plane[0].src, &xd->plane[0].pre[0]);
            }
#else
            gf_motion_error = get_prediction_error(
                bsize, &x->plane[0].src, &xd->plane[0].pre[0]);
#endif  // CONFIG_VP9_HIGHBITDEPTH
774

775
            first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv,
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
                                     &gf_motion_error);

            if (gf_motion_error < motion_error && gf_motion_error < this_error)
              ++second_ref_count;

            // Reset to last frame as reference buffer.
            xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset;
            xd->plane[1].pre[0].buf = first_ref_buf->u_buffer + recon_uvoffset;
            xd->plane[2].pre[0].buf = first_ref_buf->v_buffer + recon_uvoffset;

            // In accumulating a score for the older reference frame take the
            // best of the motion predicted score and the intra coded error
            // (just as will be done for) accumulation of "coded_error" for
            // the last frame.
            if (gf_motion_error < this_error)
              sr_coded_error += gf_motion_error;
            else
              sr_coded_error += this_error;
          } else {
            sr_coded_error += motion_error;
796
          }
797
798
        } else {
          sr_coded_error += motion_error;
799
        }
800

Adrian Grange's avatar
Adrian Grange committed
801
        // Start by assuming that intra mode is best.
802
803
        best_ref_mv.row = 0;
        best_ref_mv.col = 0;
John Koleszar's avatar
John Koleszar committed
804

805
806
807
#if CONFIG_FP_MB_STATS
        if (cpi->use_fp_mb_stats) {
          // intra predication statistics
808
809
          cpi->twopass.frame_mb_stats_buf[mb_index] = 0;
          cpi->twopass.frame_mb_stats_buf[mb_index] |= FPMB_DCINTRA_MASK;
810
811
812
813
814
          cpi->twopass.frame_mb_stats_buf[mb_index] |= FPMB_MOTION_ZERO_MASK;
          if (this_error > FPMB_ERROR_LARGE_TH) {
            cpi->twopass.frame_mb_stats_buf[mb_index] |= FPMB_ERROR_LARGE_MASK;
          } else if (this_error < FPMB_ERROR_SMALL_TH) {
            cpi->twopass.frame_mb_stats_buf[mb_index] |= FPMB_ERROR_SMALL_MASK;
815
816
817
818
          }
        }
#endif

John Koleszar's avatar
John Koleszar committed
819
        if (motion_error <= this_error) {
Adrian Grange's avatar
Adrian Grange committed
820
821
822
          // Keep a count of cases where the inter and intra were very close
          // and very low. This helps with scene cut detection for example in
          // cropped clips with black bars at the sides or top and bottom.
Dmitry Kovalev's avatar
Dmitry Kovalev committed
823
824
          if (((this_error - intrapenalty) * 9 <= motion_error * 10) &&
              this_error < 2 * intrapenalty)
Adrian Grange's avatar
Adrian Grange committed
825
            ++neutral_count;
John Koleszar's avatar
John Koleszar committed
826

827
828
          mv.row *= 8;
          mv.col *= 8;
John Koleszar's avatar
John Koleszar committed
829
          this_error = motion_error;
hkuang's avatar
hkuang committed
830
831
832
833
834
          xd->mi[0].src_mi->mbmi.mode = NEWMV;
          xd->mi[0].src_mi->mbmi.mv[0].as_mv = mv;
          xd->mi[0].src_mi->mbmi.tx_size = TX_4X4;
          xd->mi[0].src_mi->mbmi.ref_frame[0] = LAST_FRAME;
          xd->mi[0].src_mi->mbmi.ref_frame[1] = NONE;
835
          vp9_build_inter_predictors_sby(xd, mb_row << 1, mb_col << 1, bsize);
836
          vp9_encode_sby_pass1(x, bsize);
837
838
839
840
841
842
          sum_mvr += mv.row;
          sum_mvr_abs += abs(mv.row);
          sum_mvc += mv.col;
          sum_mvc_abs += abs(mv.col);
          sum_mvrs += mv.row * mv.row;
          sum_mvcs += mv.col * mv.col;
Adrian Grange's avatar
Adrian Grange committed
843
          ++intercount;
John Koleszar's avatar
John Koleszar committed
844

845
          best_ref_mv = mv;
John Koleszar's avatar
John Koleszar committed
846

847
848
#if CONFIG_FP_MB_STATS
          if (cpi->use_fp_mb_stats) {
849
            // inter predication statistics
850
851
            cpi->twopass.frame_mb_stats_buf[mb_index] = 0;
            cpi->twopass.frame_mb_stats_buf[mb_index] &= ~FPMB_DCINTRA_MASK;
852
853
            cpi->twopass.frame_mb_stats_buf[mb_index] |= FPMB_MOTION_ZERO_MASK;
            if (this_error > FPMB_ERROR_LARGE_TH) {
854
              cpi->twopass.frame_mb_stats_buf[mb_index] |=
855
856
                  FPMB_ERROR_LARGE_MASK;
            } else if (this_error < FPMB_ERROR_SMALL_TH) {
857
              cpi->twopass.frame_mb_stats_buf[mb_index] |=
858
                  FPMB_ERROR_SMALL_MASK;
859
            }
860
861
862
          }
#endif

863
          if (!is_zero_mv(&mv)) {
Adrian Grange's avatar
Adrian Grange committed
864
            ++mvcount;
John Koleszar's avatar
John Koleszar committed
865

866
867
#if CONFIG_FP_MB_STATS
            if (cpi->use_fp_mb_stats) {
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
              cpi->twopass.frame_mb_stats_buf[mb_index] &=
                  ~FPMB_MOTION_ZERO_MASK;
              // check estimated motion direction
              if (mv.as_mv.col > 0 && mv.as_mv.col >= abs(mv.as_mv.row)) {
                // right direction
                cpi->twopass.frame_mb_stats_buf[mb_index] |=
                    FPMB_MOTION_RIGHT_MASK;
              } else if (mv.as_mv.row < 0 &&
                         abs(mv.as_mv.row) >= abs(mv.as_mv.col)) {
                // up direction
                cpi->twopass.frame_mb_stats_buf[mb_index] |=
                    FPMB_MOTION_UP_MASK;
              } else if (mv.as_mv.col < 0 &&
                         abs(mv.as_mv.col) >= abs(mv.as_mv.row)) {
                // left direction
                cpi->twopass.frame_mb_stats_buf[mb_index] |=
                    FPMB_MOTION_LEFT_MASK;
              } else {
                // down direction
                cpi->twopass.frame_mb_stats_buf[mb_index] |=
                    FPMB_MOTION_DOWN_MASK;
              }
890
891
892
            }
#endif

Adrian Grange's avatar
Adrian Grange committed
893
            // Non-zero vector, was it different from the last non zero vector?
894
            if (!is_equal_mv(&mv, &lastmv))
Adrian Grange's avatar
Adrian Grange committed
895
              ++new_mv_count;
896
            lastmv = mv;
John Koleszar's avatar
John Koleszar committed
897

Adrian Grange's avatar
Adrian Grange committed
898
            // Does the row vector point inwards or outwards?
John Koleszar's avatar
John Koleszar committed
899
            if (mb_row < cm->mb_rows / 2) {
900
              if (mv.row > 0)
Adrian Grange's avatar
Adrian Grange committed
901
                --sum_in_vectors;
902
              else if (mv.row < 0)
Adrian Grange's avatar
Adrian Grange committed
903
                ++sum_in_vectors;
John Koleszar's avatar
John Koleszar committed
904
            } else if (mb_row > cm->mb_rows / 2) {
905
              if (mv.row > 0)
Adrian Grange's avatar
Adrian Grange committed
906
                ++sum_in_vectors;
907
              else if (mv.row < 0)
Adrian Grange's avatar
Adrian Grange committed
908
                --sum_in_vectors;
John Koleszar's avatar
John Koleszar committed
909
910
            }

Adrian Grange's avatar
Adrian Grange committed
911
            // Does the col vector point inwards or outwards?
John Koleszar's avatar
John Koleszar committed
912
            if (mb_col < cm->mb_cols / 2) {
913
              if (mv.col > 0)
Adrian Grange's avatar
Adrian Grange committed
914
                --sum_in_vectors;
915
              else if (mv.col < 0)
Adrian Grange's avatar
Adrian Grange committed
916
                ++sum_in_vectors;
John Koleszar's avatar
John Koleszar committed
917
            } else if (mb_col > cm->mb_cols / 2) {
918
              if (mv.col > 0)
Adrian Grange's avatar
Adrian Grange committed
919
                ++sum_in_vectors;
920
              else if (mv.col < 0)
Adrian Grange's avatar
Adrian Grange committed
921
                --sum_in_vectors;
John Koleszar's avatar
John Koleszar committed
922
923
            }
          }
John Koleszar's avatar
John Koleszar committed
924
        }
925
      } else {
John Koleszar's avatar
John Koleszar committed
926
        sr_coded_error += (int64_t)this_error;
927
      }