vp9_encodeframe.c 96.6 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
 */

Dmitry Kovalev's avatar
Dmitry Kovalev committed
11 12 13 14
#include <limits.h>
#include <math.h>
#include <stdio.h>

Jim Bankoski's avatar
Jim Bankoski committed
15
#include "./vp9_rtcd.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
16 17 18 19
#include "./vpx_config.h"

#include "vpx_ports/vpx_timer.h"

20
#include "vp9/common/vp9_common.h"
Yaowu Xu's avatar
Yaowu Xu committed
21
#include "vp9/common/vp9_entropy.h"
22
#include "vp9/common/vp9_entropymode.h"
23
#include "vp9/common/vp9_idct.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
24 25 26
#include "vp9/common/vp9_mvref_common.h"
#include "vp9/common/vp9_pred_common.h"
#include "vp9/common/vp9_quant_common.h"
27
#include "vp9/common/vp9_reconintra.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
28
#include "vp9/common/vp9_reconinter.h"
29
#include "vp9/common/vp9_seg_common.h"
30
#include "vp9/common/vp9_systemdependent.h"
31
#include "vp9/common/vp9_tile_common.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
32 33 34
#include "vp9/encoder/vp9_encodeframe.h"
#include "vp9/encoder/vp9_encodemb.h"
#include "vp9/encoder/vp9_encodemv.h"
35
#include "vp9/encoder/vp9_extend.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
36
#include "vp9/encoder/vp9_onyx_int.h"
37
#include "vp9/encoder/vp9_pickmode.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
38 39
#include "vp9/encoder/vp9_rdopt.h"
#include "vp9/encoder/vp9_segmentation.h"
40
#include "vp9/encoder/vp9_tokenize.h"
41 42
#include "vp9/encoder/vp9_vaq.h"

Yaowu Xu's avatar
Yaowu Xu committed
43
#define DBG_PRNT_SEGMAP 0
44

45

46
// #define ENC_DEBUG
47
#ifdef ENC_DEBUG
John Koleszar's avatar
John Koleszar committed
48
int enc_debug = 0;
49 50
#endif

51
static INLINE uint8_t *get_sb_index(MACROBLOCK *x, BLOCK_SIZE subsize) {
52 53 54 55 56
  switch (subsize) {
    case BLOCK_64X64:
    case BLOCK_64X32:
    case BLOCK_32X64:
    case BLOCK_32X32:
57
      return &x->sb_index;
58 59 60
    case BLOCK_32X16:
    case BLOCK_16X32:
    case BLOCK_16X16:
61
      return &x->mb_index;
62 63 64
    case BLOCK_16X8:
    case BLOCK_8X16:
    case BLOCK_8X8:
65
      return &x->b_index;
66 67 68
    case BLOCK_8X4:
    case BLOCK_4X8:
    case BLOCK_4X4:
69
      return &x->ab_index;
70 71 72 73 74 75
    default:
      assert(0);
      return NULL;
  }
}

Jim Bankoski's avatar
Jim Bankoski committed
76
static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
77
                              int mi_row, int mi_col, BLOCK_SIZE bsize);
78

79
static void adjust_act_zbin(VP9_COMP *cpi, MACROBLOCK *x);
80

81 82 83 84
// activity_avg must be positive, or flat regions could get a zero weight
//  (infinite lambda), which confounds analysis.
// This also avoids the need for divide by zero checks in
//  vp9_activity_masking().
85
#define ACTIVITY_AVG_MIN (64)
86

87
// Motion vector component magnitude threshold for defining fast motion.
88 89
#define FAST_MOTION_MV_THRESH (24)

90 91 92 93
// This is used as a reference when computing the source variance for the
//  purposes of activity masking.
// Eventually this should be replaced by custom no-reference routines,
//  which will be faster.
94 95 96 97 98 99 100 101 102 103 104
static const uint8_t VP9_VAR_OFFS[64] = {
  128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128
};

105
static unsigned int get_sby_perpixel_variance(VP9_COMP *cpi, MACROBLOCK *x,
106
                                              BLOCK_SIZE bs) {
107
  unsigned int var, sse;
108
  var = cpi->fn_ptr[bs].vf(x->plane[0].src.buf, x->plane[0].src.stride,
109
                           VP9_VAR_OFFS, 0, &sse);
110
  return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
111 112
}

113
// Original activity measure from Tim T's code.
114
static unsigned int tt_activity_measure(MACROBLOCK *x) {
John Koleszar's avatar
John Koleszar committed
115 116 117 118 119 120 121 122
  unsigned int sse;
  /* TODO: This could also be done over smaller areas (8x8), but that would
   *  require extensive changes elsewhere, as lambda is assumed to be fixed
   *  over an entire MB in most of the code.
   * Another option is to compute four 8x8 variances, and pick a single
   *  lambda using a non-linear combination (e.g., the smallest, or second
   *  smallest, etc.).
   */
123 124 125 126 127 128
  unsigned int act = vp9_variance16x16(x->plane[0].src.buf,
                                       x->plane[0].src.stride,
                                       VP9_VAR_OFFS, 0, &sse) << 4;
  // If the region is flat, lower the activity some more.
  if (act < (8 << 12))
    act = MIN(act, 5 << 12);
John Koleszar's avatar
John Koleszar committed
129 130

  return act;
131 132
}

133
// Stub for alternative experimental activity measures.
134 135
static unsigned int alt_activity_measure(MACROBLOCK *x, int use_dc_pred) {
  return vp9_encode_intra(x, use_dc_pred);
136 137 138 139
}

// Measure the activity of the current macroblock
// What we measure here is TBD so abstracted to this function
140
#define ALT_ACT_MEASURE 1
141
static unsigned int mb_activity_measure(MACROBLOCK *x, int mb_row, int mb_col) {
John Koleszar's avatar
John Koleszar committed
142
  unsigned int mb_activity;
143

John Koleszar's avatar
John Koleszar committed
144
  if (ALT_ACT_MEASURE) {
145
    const int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);
146

John Koleszar's avatar
John Koleszar committed
147
    // Or use and alternative.
148
    mb_activity = alt_activity_measure(x, use_dc_pred);
John Koleszar's avatar
John Koleszar committed
149 150
  } else {
    // Original activity measure from Tim T's code.
151
    mb_activity = tt_activity_measure(x);
John Koleszar's avatar
John Koleszar committed
152
  }
153

154
  return MAX(mb_activity, ACTIVITY_AVG_MIN);
155 156 157
}

// Calculate an "average" mb activity value for the frame
158
#define ACT_MEDIAN 0
159
static void calc_av_activity(VP9_COMP *cpi, int64_t activity_sum) {
160
#if ACT_MEDIAN
John Koleszar's avatar
John Koleszar committed
161 162 163 164 165 166 167 168
  // Find median: Simple n^2 algorithm for experimentation
  {
    unsigned int median;
    unsigned int i, j;
    unsigned int *sortlist;
    unsigned int tmp;

    // Create a list to sort to
169 170
    CHECK_MEM_ERROR(&cpi->common, sortlist, vpx_calloc(sizeof(unsigned int),
                    cpi->common.MBs));
John Koleszar's avatar
John Koleszar committed
171 172 173

    // Copy map to sort list
    vpx_memcpy(sortlist, cpi->mb_activity_map,
Jim Bankoski's avatar
Jim Bankoski committed
174
        sizeof(unsigned int) * cpi->common.MBs);
John Koleszar's avatar
John Koleszar committed
175 176 177 178 179 180 181 182 183

    // Ripple each value down to its correct position
    for (i = 1; i < cpi->common.MBs; i ++) {
      for (j = i; j > 0; j --) {
        if (sortlist[j] < sortlist[j - 1]) {
          // Swap values
          tmp = sortlist[j - 1];
          sortlist[j - 1] = sortlist[j];
          sortlist[j] = tmp;
184 185 186
        } else {
          break;
        }
John Koleszar's avatar
John Koleszar committed
187 188
      }
    }
189

John Koleszar's avatar
John Koleszar committed
190 191
    // Even number MBs so estimate median as mean of two either side.
    median = (1 + sortlist[cpi->common.MBs >> 1] +
Jim Bankoski's avatar
Jim Bankoski committed
192
        sortlist[(cpi->common.MBs >> 1) + 1]) >> 1;
193

John Koleszar's avatar
John Koleszar committed
194
    cpi->activity_avg = median;
195

John Koleszar's avatar
John Koleszar committed
196 197
    vpx_free(sortlist);
  }
198
#else
John Koleszar's avatar
John Koleszar committed
199
  // Simple mean for now
Jim Bankoski's avatar
Jim Bankoski committed
200
  cpi->activity_avg = (unsigned int) (activity_sum / cpi->common.MBs);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
201
#endif  // ACT_MEDIAN
202

203 204
  if (cpi->activity_avg < ACTIVITY_AVG_MIN)
    cpi->activity_avg = ACTIVITY_AVG_MIN;
205

John Koleszar's avatar
John Koleszar committed
206 207 208
  // Experimental code: return fixed value normalized for several clips
  if (ALT_ACT_MEASURE)
    cpi->activity_avg = 100000;
209 210
}

211
#define USE_ACT_INDEX   0
212
#define OUTPUT_NORM_ACT_STATS   0
213 214

#if USE_ACT_INDEX
215
// Calculate an activity index for each mb
216 217
static void calc_activity_index(VP9_COMP *cpi, MACROBLOCK *x) {
  VP9_COMMON *const cm = &cpi->common;
John Koleszar's avatar
John Koleszar committed
218
  int mb_row, mb_col;
219

John Koleszar's avatar
John Koleszar committed
220 221 222
  int64_t act;
  int64_t a;
  int64_t b;
223 224

#if OUTPUT_NORM_ACT_STATS
John Koleszar's avatar
John Koleszar committed
225 226
  FILE *f = fopen("norm_act.stt", "a");
  fprintf(f, "\n%12d\n", cpi->activity_avg);
227 228
#endif

John Koleszar's avatar
John Koleszar committed
229 230
  // Reset pointers to start of activity map
  x->mb_activity_ptr = cpi->mb_activity_map;
231

John Koleszar's avatar
John Koleszar committed
232 233 234 235 236 237
  // Calculate normalized mb activity number.
  for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) {
    // for each macroblock col in image
    for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) {
      // Read activity from the map
      act = *(x->mb_activity_ptr);
238

John Koleszar's avatar
John Koleszar committed
239 240 241
      // Calculate a normalized activity number
      a = act + 4 * cpi->activity_avg;
      b = 4 * act + cpi->activity_avg;
242

John Koleszar's avatar
John Koleszar committed
243
      if (b >= a)
Jim Bankoski's avatar
Jim Bankoski committed
244
      *(x->activity_ptr) = (int)((b + (a >> 1)) / a) - 1;
John Koleszar's avatar
John Koleszar committed
245
      else
Jim Bankoski's avatar
Jim Bankoski committed
246
      *(x->activity_ptr) = 1 - (int)((a + (b >> 1)) / b);
247 248

#if OUTPUT_NORM_ACT_STATS
John Koleszar's avatar
John Koleszar committed
249
      fprintf(f, " %6d", *(x->mb_activity_ptr));
250
#endif
John Koleszar's avatar
John Koleszar committed
251 252 253
      // Increment activity map pointers
      x->mb_activity_ptr++;
    }
254 255

#if OUTPUT_NORM_ACT_STATS
John Koleszar's avatar
John Koleszar committed
256
    fprintf(f, "\n");
257
#endif
John Koleszar's avatar
John Koleszar committed
258
  }
259 260

#if OUTPUT_NORM_ACT_STATS
John Koleszar's avatar
John Koleszar committed
261
  fclose(f);
262 263
#endif
}
Dmitry Kovalev's avatar
Dmitry Kovalev committed
264
#endif  // USE_ACT_INDEX
265 266 267

// Loop through all MBs. Note activity of each, average activity and
// calculate a normalized activity for each
268
static void build_activity_map(VP9_COMP *cpi) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
269
  MACROBLOCK *const x = &cpi->mb;
John Koleszar's avatar
John Koleszar committed
270
  MACROBLOCKD *xd = &x->e_mbd;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
271
  VP9_COMMON *const cm = &cpi->common;
272

273
#if ALT_ACT_MEASURE
274
  YV12_BUFFER_CONFIG *new_yv12 = get_frame_new_buffer(cm);
John Koleszar's avatar
John Koleszar committed
275 276
  int recon_yoffset;
  int recon_y_stride = new_yv12->y_stride;
277 278
#endif

John Koleszar's avatar
John Koleszar committed
279 280 281
  int mb_row, mb_col;
  unsigned int mb_activity;
  int64_t activity_sum = 0;
282

283 284
  x->mb_activity_ptr = cpi->mb_activity_map;

John Koleszar's avatar
John Koleszar committed
285 286
  // for each macroblock row in image
  for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) {
287
#if ALT_ACT_MEASURE
John Koleszar's avatar
John Koleszar committed
288 289 290
    // reset above block coeffs
    xd->up_available = (mb_row != 0);
    recon_yoffset = (mb_row * recon_y_stride * 16);
291
#endif
John Koleszar's avatar
John Koleszar committed
292 293
    // for each macroblock col in image
    for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) {
294
#if ALT_ACT_MEASURE
295
      xd->plane[0].dst.buf = new_yv12->y_buffer + recon_yoffset;
John Koleszar's avatar
John Koleszar committed
296 297
      xd->left_available = (mb_col != 0);
      recon_yoffset += 16;
298
#endif
299

John Koleszar's avatar
John Koleszar committed
300
      // measure activity
301
      mb_activity = mb_activity_measure(x, mb_row, mb_col);
302

John Koleszar's avatar
John Koleszar committed
303 304
      // Keep frame sum
      activity_sum += mb_activity;
305

John Koleszar's avatar
John Koleszar committed
306 307
      // Store MB level activity details.
      *x->mb_activity_ptr = mb_activity;
308

John Koleszar's avatar
John Koleszar committed
309 310
      // Increment activity map pointer
      x->mb_activity_ptr++;
311

John Koleszar's avatar
John Koleszar committed
312
      // adjust to the next column of source macroblocks
John Koleszar's avatar
John Koleszar committed
313
      x->plane[0].src.buf += 16;
John Koleszar's avatar
John Koleszar committed
314
    }
315

John Koleszar's avatar
John Koleszar committed
316
    // adjust to the next row of mbs
John Koleszar's avatar
John Koleszar committed
317
    x->plane[0].src.buf += 16 * x->plane[0].src.stride - 16 * cm->mb_cols;
John Koleszar's avatar
John Koleszar committed
318
  }
319

John Koleszar's avatar
John Koleszar committed
320 321
  // Calculate an "average" MB activity
  calc_av_activity(cpi, activity_sum);
322

323
#if USE_ACT_INDEX
John Koleszar's avatar
John Koleszar committed
324 325
  // Calculate an activity index number of each mb
  calc_activity_index(cpi, x);
326
#endif
327 328
}

329
// Macroblock activity masking
330
void vp9_activity_masking(VP9_COMP *cpi, MACROBLOCK *x) {
331
#if USE_ACT_INDEX
John Koleszar's avatar
John Koleszar committed
332 333 334
  x->rdmult += *(x->mb_activity_ptr) * (x->rdmult >> 2);
  x->errorperbit = x->rdmult * 100 / (110 * x->rddiv);
  x->errorperbit += (x->errorperbit == 0);
335
#else
336
  const int64_t act = *(x->mb_activity_ptr);
337

John Koleszar's avatar
John Koleszar committed
338
  // Apply the masking to the RD multiplier.
339 340
  const int64_t a = act + (2 * cpi->activity_avg);
  const int64_t b = (2 * act) + cpi->activity_avg;
341

Jim Bankoski's avatar
Jim Bankoski committed
342
  x->rdmult = (unsigned int) (((int64_t) x->rdmult * b + (a >> 1)) / a);
John Koleszar's avatar
John Koleszar committed
343 344
  x->errorperbit = x->rdmult * 100 / (110 * x->rddiv);
  x->errorperbit += (x->errorperbit == 0);
345
#endif
346

John Koleszar's avatar
John Koleszar committed
347 348
  // Activity based Zbin adjustment
  adjust_act_zbin(cpi, x);
349
}
John Koleszar's avatar
John Koleszar committed
350

351 352 353 354
// Select a segment for the current SB64
static void select_in_frame_q_segment(VP9_COMP *cpi,
                                      int mi_row, int mi_col,
                                      int output_enabled, int projected_rate) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
355
  VP9_COMMON *const cm = &cpi->common;
356 357 358
  int target_rate = cpi->rc.sb64_target_rate << 8;   // convert to bits << 8

  const int mi_offset = mi_row * cm->mi_cols + mi_col;
359 360
  const int bw = num_8x8_blocks_wide_lookup[BLOCK_64X64];
  const int bh = num_8x8_blocks_high_lookup[BLOCK_64X64];
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396
  const int xmis = MIN(cm->mi_cols - mi_col, bw);
  const int ymis = MIN(cm->mi_rows - mi_row, bh);
  int complexity_metric = 64;
  int x, y;

  unsigned char segment;

  if (!output_enabled) {
    segment = 0;
  } else {
    // Rate depends on fraction of a SB64 in frame (xmis * ymis / bw * bh).
    // It is converted to bits * 256 units
    target_rate = (cpi->rc.sb64_target_rate * xmis * ymis * 256) / (bw * bh);

    if (projected_rate < (target_rate / 4)) {
      segment = 2;
    } else if (projected_rate < (target_rate / 2)) {
      segment = 1;
    } else {
      segment = 0;
    }

    complexity_metric =
      clamp((int)((projected_rate * 64) / target_rate), 16, 255);
  }

  // Fill in the entires in the segment map corresponding to this SB64
  for (y = 0; y < ymis; y++) {
    for (x = 0; x < xmis; x++) {
      cpi->segmentation_map[mi_offset + y * cm->mi_cols + x] = segment;
      cpi->complexity_map[mi_offset + y * cm->mi_cols + x] =
        (unsigned char)complexity_metric;
    }
  }
}

Jim Bankoski's avatar
Jim Bankoski committed
397
static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
398
                         BLOCK_SIZE bsize, int output_enabled) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
399
  int i, x_idx, y;
400 401 402
  VP9_COMMON *const cm = &cpi->common;
  MACROBLOCK *const x = &cpi->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
403 404
  struct macroblock_plane *const p = x->plane;
  struct macroblockd_plane *const pd = xd->plane;
John Koleszar's avatar
John Koleszar committed
405
  MODE_INFO *mi = &ctx->mic;
406 407
  MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
  MODE_INFO *mi_addr = xd->mi_8x8[0];
408

409
  const int mb_mode_index = ctx->best_mode_index;
410
  const int mis = cm->mode_info_stride;
Jim Bankoski's avatar
Jim Bankoski committed
411
  const int mi_width = num_8x8_blocks_wide_lookup[bsize];
Jim Bankoski's avatar
Jim Bankoski committed
412
  const int mi_height = num_8x8_blocks_high_lookup[bsize];
413
  int max_plane;
Adrian Grange's avatar
Adrian Grange committed
414

415
  assert(mi->mbmi.mode < MB_MODE_COUNT);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
416 417
  assert(mi->mbmi.ref_frame[0] < MAX_REF_FRAMES);
  assert(mi->mbmi.ref_frame[1] < MAX_REF_FRAMES);
418
  assert(mi->mbmi.sb_type == bsize);
419

420 421 422 423 424
  // For in frame adaptive Q copy over the chosen segment id into the
  // mode innfo context for the chosen mode / partition.
  if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && output_enabled)
    mi->mbmi.segment_id = xd->mi_8x8[0]->mbmi.segment_id;

425 426
  *mi_addr = *mi;

427 428
  max_plane = is_inter_block(mbmi) ? MAX_MB_PLANE : 1;
  for (i = 0; i < max_plane; ++i) {
429
    p[i].coeff = ctx->coeff_pbuf[i][1];
430
    p[i].qcoeff = ctx->qcoeff_pbuf[i][1];
431
    pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][1];
432
    p[i].eobs = ctx->eobs_pbuf[i][1];
433 434
  }

435 436
  for (i = max_plane; i < MAX_MB_PLANE; ++i) {
    p[i].coeff = ctx->coeff_pbuf[i][2];
437
    p[i].qcoeff = ctx->qcoeff_pbuf[i][2];
438
    pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][2];
439
    p[i].eobs = ctx->eobs_pbuf[i][2];
440 441
  }

John Koleszar's avatar
John Koleszar committed
442 443
  // Restore the coding context of the MB to that that was in place
  // when the mode was picked for it
444 445
  for (y = 0; y < mi_height; y++)
    for (x_idx = 0; x_idx < mi_width; x_idx++)
James Zern's avatar
James Zern committed
446
      if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx
447
        && (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
448
        xd->mi_8x8[x_idx + y * mis] = mi_addr;
449
      }
450

451 452
    if ((cpi->oxcf.aq_mode == VARIANCE_AQ) ||
        (cpi->oxcf.aq_mode == COMPLEXITY_AQ)) {
453 454 455
    vp9_mb_init_quantizer(cpi, x);
  }

456 457
  // FIXME(rbultje) I'm pretty sure this should go to the end of this block
  // (i.e. after the output_enabled)
458 459
  if (bsize < BLOCK_32X32) {
    if (bsize < BLOCK_16X16)
460 461
      ctx->tx_rd_diff[ALLOW_16X16] = ctx->tx_rd_diff[ALLOW_8X8];
    ctx->tx_rd_diff[ALLOW_32X32] = ctx->tx_rd_diff[ALLOW_16X16];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
462
  }
Adrian Grange's avatar
Adrian Grange committed
463

464
  if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) {
465 466
    mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
    mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
John Koleszar's avatar
John Koleszar committed
467 468
  }

469
  x->skip = ctx->skip;
470
  vpx_memcpy(x->zcoeff_blk[mbmi->tx_size], ctx->zcoeff_blk,
471
             sizeof(uint8_t) * ctx->num_4x4_blk);
472

Ronald S. Bultje's avatar
Ronald S. Bultje committed
473 474 475
  if (!output_enabled)
    return;

476
  if (!vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
477
    for (i = 0; i < TX_MODES; i++)
478
      cpi->rd_tx_select_diff[i] += ctx->tx_rd_diff[i];
479 480
  }

481
  if (frame_is_intra_only(cm)) {
482
#if CONFIG_INTERNAL_STATS
John Koleszar's avatar
John Koleszar committed
483 484 485 486 487 488 489 490
    static const int kf_mode_index[] = {
      THR_DC /*DC_PRED*/,
      THR_V_PRED /*V_PRED*/,
      THR_H_PRED /*H_PRED*/,
      THR_D45_PRED /*D45_PRED*/,
      THR_D135_PRED /*D135_PRED*/,
      THR_D117_PRED /*D117_PRED*/,
      THR_D153_PRED /*D153_PRED*/,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
491
      THR_D207_PRED /*D207_PRED*/,
John Koleszar's avatar
John Koleszar committed
492 493 494
      THR_D63_PRED /*D63_PRED*/,
      THR_TM /*TM_PRED*/,
    };
495
    cpi->mode_chosen_counts[kf_mode_index[mi->mbmi.mode]]++;
496
#endif
John Koleszar's avatar
John Koleszar committed
497 498 499
  } else {
    // Note how often each mode chosen as best
    cpi->mode_chosen_counts[mb_mode_index]++;
500 501
    if (is_inter_block(mbmi) &&
        (mbmi->sb_type < BLOCK_8X8 || mbmi->mode == NEWMV)) {
502
      int_mv best_mv[2];
Yaowu Xu's avatar
Yaowu Xu committed
503
      for (i = 0; i < 1 + has_second_ref(mbmi); ++i)
Jingning Han's avatar
Jingning Han committed
504
        best_mv[i].as_int = mbmi->ref_mvs[mbmi->ref_frame[i]][0].as_int;
505
      vp9_update_mv_count(cpi, x, best_mv);
506
    }
Jingning Han's avatar
Jingning Han committed
507

508
    if (cm->interp_filter == SWITCHABLE && is_inter_mode(mbmi->mode)) {
509 510
      const int ctx = vp9_get_pred_context_switchable_interp(xd);
      ++cm->counts.switchable_interp[ctx][mbmi->interp_filter];
511
    }
Adrian Grange's avatar
Adrian Grange committed
512

513 514 515
    cpi->rd_comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
    cpi->rd_comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
    cpi->rd_comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
516

517
    for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
518
      cpi->rd_filter_diff[i] += ctx->best_filter_diff[i];
John Koleszar's avatar
John Koleszar committed
519
  }
Adrian Grange's avatar
Adrian Grange committed
520 521
}

Jim Bankoski's avatar
Jim Bankoski committed
522
void vp9_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
523 524 525 526 527
                          int mi_row, int mi_col) {
  uint8_t *const buffers[4] = {src->y_buffer, src->u_buffer, src->v_buffer,
                               src->alpha_buffer};
  const int strides[4] = {src->y_stride, src->uv_stride, src->uv_stride,
                          src->alpha_stride};
528 529
  int i;

530 531 532
  // Set current frame pointer.
  x->e_mbd.cur_buf = src;

533 534
  for (i = 0; i < MAX_MB_PLANE; i++)
    setup_pred_plane(&x->plane[i].src, buffers[i], strides[i], mi_row, mi_col,
Jim Bankoski's avatar
Jim Bankoski committed
535
                     NULL, x->e_mbd.plane[i].subsampling_x,
536
                     x->e_mbd.plane[i].subsampling_y);
John Koleszar's avatar
John Koleszar committed
537 538
}

James Zern's avatar
James Zern committed
539 540
static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile,
                        int mi_row, int mi_col, BLOCK_SIZE bsize) {
541 542 543
  MACROBLOCK *const x = &cpi->mb;
  VP9_COMMON *const cm = &cpi->common;
  MACROBLOCKD *const xd = &x->e_mbd;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
544
  MB_MODE_INFO *mbmi;
545
  const int idx_str = xd->mode_info_stride * mi_row + mi_col;
Jim Bankoski's avatar
Jim Bankoski committed
546 547
  const int mi_width = num_8x8_blocks_wide_lookup[bsize];
  const int mi_height = num_8x8_blocks_high_lookup[bsize];
Jingning Han's avatar
Jingning Han committed
548 549
  const int mb_row = mi_row >> 1;
  const int mb_col = mi_col >> 1;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
550
  const int idx_map = mb_row * cm->mb_cols + mb_col;
551
  const struct segmentation *const seg = &cm->seg;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
552

553
  set_skip_context(xd, cpi->above_context, cpi->left_context, mi_row, mi_col);
554

Ronald S. Bultje's avatar
Ronald S. Bultje committed
555 556 557 558
  // Activity map pointer
  x->mb_activity_ptr = &cpi->mb_activity_map[idx_map];
  x->active_ptr = cpi->active_map + idx_map;

559 560 561
  xd->mi_8x8 = cm->mi_grid_visible + idx_str;
  xd->prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str;

562 563
  // Special case: if prev_mi is NULL, the previous mode info context
  // cannot be used.
564 565
  xd->last_mi = cm->prev_mi ? xd->prev_mi_8x8[0] : NULL;

566
  xd->mi_8x8[0] = cm->mi + idx_str;
567

568
  mbmi = &xd->mi_8x8[0]->mbmi;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
569 570

  // Set up destination pointers
571
  setup_dst_planes(xd, get_frame_new_buffer(cm), mi_row, mi_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
572

Yaowu Xu's avatar
Yaowu Xu committed
573 574
  // Set up limit values for MV components
  // mv beyond the range do not produce new/different prediction block
575 576
  x->mv_row_min = -(((mi_row + mi_height) * MI_SIZE) + VP9_INTERP_EXTEND);
  x->mv_col_min = -(((mi_col + mi_width) * MI_SIZE) + VP9_INTERP_EXTEND);
Yaowu Xu's avatar
Yaowu Xu committed
577 578
  x->mv_row_max = (cm->mi_rows - mi_row) * MI_SIZE + VP9_INTERP_EXTEND;
  x->mv_col_max = (cm->mi_cols - mi_col) * MI_SIZE + VP9_INTERP_EXTEND;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
579 580

  // Set up distance of MB to edge of frame in 1/8th pel units
Jim Bankoski's avatar
Jim Bankoski committed
581
  assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
James Zern's avatar
James Zern committed
582 583
  set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width,
                 cm->mi_rows, cm->mi_cols);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
584 585

  /* set up source buffers */
586
  vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
587 588 589 590 591 592

  /* R/D setup */
  x->rddiv = cpi->RDDIV;
  x->rdmult = cpi->RDMULT;

  /* segment ID */
593
  if (seg->enabled) {
594
    if (cpi->oxcf.aq_mode != VARIANCE_AQ) {
595 596
      const uint8_t *const map = seg->update_map ? cpi->segmentation_map
                                                 : cm->last_frame_seg_map;
597 598
      mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
    }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
599 600
    vp9_mb_init_quantizer(cpi, x);

601 602 603
    if (seg->enabled && cpi->seg0_cnt > 0 &&
        !vp9_segfeature_active(seg, 0, SEG_LVL_REF_FRAME) &&
        vp9_segfeature_active(seg, 1, SEG_LVL_REF_FRAME)) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
604 605 606 607
      cpi->seg0_progress = (cpi->seg0_idx << 16) / cpi->seg0_cnt;
    } else {
      const int y = mb_row & ~3;
      const int x = mb_col & ~3;
Jim Bankoski's avatar
Jim Bankoski committed
608
      const int p16 = ((mb_row & 1) << 1) + (mb_col & 1);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
609
      const int p32 = ((mb_row & 2) << 2) + ((mb_col & 2) << 1);
James Zern's avatar
James Zern committed
610 611
      const int tile_progress = tile->mi_col_start * cm->mb_rows >> 1;
      const int mb_cols = (tile->mi_col_end - tile->mi_col_start) >> 1;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
612

Jim Bankoski's avatar
Jim Bankoski committed
613 614
      cpi->seg0_progress = ((y * mb_cols + x * 4 + p32 + p16 + tile_progress)
          << 16) / cm->MBs;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
615
    }
616 617

    x->encode_breakout = cpi->segment_encode_breakout[mbmi->segment_id];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
618 619
  } else {
    mbmi->segment_id = 0;
620
    x->encode_breakout = cpi->oxcf.encode_breakout;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
621 622 623
  }
}

624 625 626 627 628
static void rd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
                             int mi_row, int mi_col,
                             int *totalrate, int64_t *totaldist,
                             BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
                             int64_t best_rd) {
629 630 631
  VP9_COMMON *const cm = &cpi->common;
  MACROBLOCK *const x = &cpi->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
632 633 634
  struct macroblock_plane *const p = x->plane;
  struct macroblockd_plane *const pd = xd->plane;
  int i;
635
  int orig_rdmult = x->rdmult;
636 637 638 639
  double rdmult_ratio;

  vp9_clear_system_state();  // __asm emms;
  rdmult_ratio = 1.0;  // avoid uninitialized warnings
Ronald S. Bultje's avatar
Ronald S. Bultje committed
640

641
  // Use the lower precision, but faster, 32x32 fdct for mode selection.
642
  x->use_lp32x32fdct = 1;
643

644
  if (bsize < BLOCK_8X8) {
645 646
    // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
    // there is nothing to be done.
647
    if (x->ab_index != 0) {
648 649
      *totalrate = 0;
      *totaldist = 0;
650
      return;
651
    }
652
  }
653

James Zern's avatar
James Zern committed
654
  set_offsets(cpi, tile, mi_row, mi_col, bsize);
655
  xd->mi_8x8[0]->mbmi.sb_type = bsize;
656

657
  for (i = 0; i < MAX_MB_PLANE; ++i) {
658
    p[i].coeff = ctx->coeff_pbuf[i][0];
659
    p[i].qcoeff = ctx->qcoeff_pbuf[i][0];
660
    pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][0];
661
    p[i].eobs = ctx->eobs_pbuf[i][0];
662
  }
663
  ctx->is_coded = 0;
664
  x->skip_recode = 0;
665

666
  // Set to zero to make sure we do not use the previous encoded frame stats
667
  xd->mi_8x8[0]->mbmi.skip_coeff = 0;
668

669
  x->source_variance = get_sby_perpixel_variance(cpi, x, bsize);
670

671
  if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
672 673
    const int energy = bsize <= BLOCK_16X16 ? x->mb_energy
                                            : vp9_block_energy(cpi, x, bsize);
674
    xd->mi_8x8[0]->mbmi.segment_id = vp9_vaq_segment_id(energy);
675 676 677 678
    rdmult_ratio = vp9_vaq_rdmult_ratio(energy);
    vp9_mb_init_quantizer(cpi, x);
  }

Ronald S. Bultje's avatar
Ronald S. Bultje committed
679
  if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
680
    vp9_activity_masking(cpi, x);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
681

682
  if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
683 684
    vp9_clear_system_state();  // __asm emms;
    x->rdmult = round(x->rdmult * rdmult_ratio);
685 686 687 688 689 690 691 692
  } else if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
    const int mi_offset = mi_row * cm->mi_cols + mi_col;
    unsigned char complexity = cpi->complexity_map[mi_offset];
    const int is_edge = (mi_row == 0) || (mi_row == (cm->mi_rows - 1)) ||
                        (mi_col == 0) || (mi_col == (cm->mi_cols - 1));

    if (!is_edge && (complexity > 128))
      x->rdmult = x->rdmult  + ((x->rdmult * (complexity - 128)) / 256);
693
  }
694

695 696
  // Find best coding mode & reconstruct the MB so it is available
  // as a predictor for MBs that follow in the SB
697
  if (frame_is_intra_only(cm)) {
698 699
    vp9_rd_pick_intra_mode_sb(cpi, x, totalrate, totaldist, bsize, ctx,
                              best_rd);
700 701
  } else {
    if (bsize >= BLOCK_8X8)
James Zern's avatar
James Zern committed
702 703
      vp9_rd_pick_inter_mode_sb(cpi, x, tile, mi_row, mi_col,
                                totalrate, totaldist, bsize, ctx, best_rd);
704
    else
James Zern's avatar
James Zern committed
705
      vp9_rd_pick_inter_mode_sub8x8(cpi, x, tile, mi_row, mi_col, totalrate,
706 707
                                    totaldist, bsize, ctx, best_rd);
  }
708

709
  if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
710 711 712 713 714 715
    x->rdmult = orig_rdmult;
    if (*totalrate != INT_MAX) {
      vp9_clear_system_state();  // __asm emms;
      *totalrate = round(*totalrate * rdmult_ratio);
    }
  }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
716
}
Adrian Grange's avatar
Adrian Grange committed
717

718 719 720 721
static void update_stats(VP9_COMP *cpi) {
  VP9_COMMON *const cm = &cpi->common;
  MACROBLOCK *const x = &cpi->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
722
  MODE_INFO *mi = xd->mi_8x8[0];
723
  MB_MODE_INFO *const mbmi = &mi->mbmi;
Adrian Grange's avatar
Adrian Grange committed
724

725
  if (!frame_is_intra_only(cm)) {