vp9_encodeframe.c 96.7 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];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
503 504
      const MV_REFERENCE_FRAME rf1 = mbmi->ref_frame[0];
      const MV_REFERENCE_FRAME rf2 = mbmi->ref_frame[1];
505 506
      best_mv[0].as_int = ctx->best_ref_mv[0].as_int;
      best_mv[1].as_int = ctx->best_ref_mv[1].as_int;
Deb Mukherjee's avatar
Deb Mukherjee committed
507
      if (mbmi->mode == NEWMV) {
508
        best_mv[0].as_int = mbmi->ref_mvs[rf1][0].as_int;
Yaowu Xu's avatar
Yaowu Xu committed
509
        if (rf2 > 0)
510
          best_mv[1].as_int = mbmi->ref_mvs[rf2][0].as_int;
Deb Mukherjee's avatar
Deb Mukherjee committed
511
      }
512 513 514
      mbmi->best_mv[0].as_int = best_mv[0].as_int;
      mbmi->best_mv[1].as_int = best_mv[1].as_int;
      vp9_update_mv_count(cpi, x, best_mv);
515
    }
Jingning Han's avatar
Jingning Han committed
516

517 518 519
    if (cm->mcomp_filter_type == SWITCHABLE && is_inter_mode(mbmi->mode)) {
      const int ctx = vp9_get_pred_context_switchable_interp(xd);
      ++cm->counts.switchable_interp[ctx][mbmi->interp_filter];
520
    }
Adrian Grange's avatar
Adrian Grange committed
521

522 523 524
    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;
525

526
    for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
527
      cpi->rd_filter_diff[i] += ctx->best_filter_diff[i];
John Koleszar's avatar
John Koleszar committed
528
  }
Adrian Grange's avatar
Adrian Grange committed
529 530
}

Jim Bankoski's avatar
Jim Bankoski committed
531
void vp9_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
532 533 534 535 536
                          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};
537 538
  int i;

539 540 541
  // Set current frame pointer.
  x->e_mbd.cur_buf = src;

542 543
  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
544
                     NULL, x->e_mbd.plane[i].subsampling_x,
545
                     x->e_mbd.plane[i].subsampling_y);
John Koleszar's avatar
John Koleszar committed
546 547
}

James Zern's avatar
James Zern committed
548 549
static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile,
                        int mi_row, int mi_col, BLOCK_SIZE bsize) {
550 551 552
  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
553
  MB_MODE_INFO *mbmi;
554
  const int idx_str = xd->mode_info_stride * mi_row + mi_col;
Jim Bankoski's avatar
Jim Bankoski committed
555 556
  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
557 558
  const int mb_row = mi_row >> 1;
  const int mb_col = mi_col >> 1;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
559
  const int idx_map = mb_row * cm->mb_cols + mb_col;
560
  const struct segmentation *const seg = &cm->seg;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
561

562
  set_skip_context(xd, cpi->above_context, cpi->left_context, mi_row, mi_col);
563

Ronald S. Bultje's avatar
Ronald S. Bultje committed
564 565 566 567
  // Activity map pointer
  x->mb_activity_ptr = &cpi->mb_activity_map[idx_map];
  x->active_ptr = cpi->active_map + idx_map;

568 569 570
  xd->mi_8x8 = cm->mi_grid_visible + idx_str;
  xd->prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str;

571 572
  // Special case: if prev_mi is NULL, the previous mode info context
  // cannot be used.
573 574
  xd->last_mi = cm->prev_mi ? xd->prev_mi_8x8[0] : NULL;

575
  xd->mi_8x8[0] = cm->mi + idx_str;
576

577
  mbmi = &xd->mi_8x8[0]->mbmi;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
578 579

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

Yaowu Xu's avatar
Yaowu Xu committed
582 583
  // Set up limit values for MV components
  // mv beyond the range do not produce new/different prediction block
584 585
  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
586 587
  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
588 589

  // Set up distance of MB to edge of frame in 1/8th pel units
Jim Bankoski's avatar
Jim Bankoski committed
590
  assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
James Zern's avatar
James Zern committed
591 592
  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
593 594

  /* set up source buffers */
595
  vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
596 597 598 599 600 601

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

  /* segment ID */
602
  if (seg->enabled) {
603
    if (cpi->oxcf.aq_mode != VARIANCE_AQ) {
604 605
      const uint8_t *const map = seg->update_map ? cpi->segmentation_map
                                                 : cm->last_frame_seg_map;
606 607
      mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
    }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
608 609
    vp9_mb_init_quantizer(cpi, x);

610 611 612
    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
613 614 615 616
      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
617
      const int p16 = ((mb_row & 1) << 1) + (mb_col & 1);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
618
      const int p32 = ((mb_row & 2) << 2) + ((mb_col & 2) << 1);
James Zern's avatar
James Zern committed
619 620
      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
621

Jim Bankoski's avatar
Jim Bankoski committed
622 623
      cpi->seg0_progress = ((y * mb_cols + x * 4 + p32 + p16 + tile_progress)
          << 16) / cm->MBs;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
624
    }
625 626

    x->encode_breakout = cpi->segment_encode_breakout[mbmi->segment_id];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
627 628
  } else {
    mbmi->segment_id = 0;
629
    x->encode_breakout = cpi->oxcf.encode_breakout;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
630 631 632
  }
}

James Zern's avatar
James Zern committed
633 634
static void pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
                          int mi_row, int mi_col,
635
                          int *totalrate, int64_t *totaldist,
636
                          BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
637
                          int64_t best_rd) {
638 639 640
  VP9_COMMON *const cm = &cpi->common;
  MACROBLOCK *const x = &cpi->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
641 642 643
  struct macroblock_plane *const p = x->plane;
  struct macroblockd_plane *const pd = xd->plane;
  int i;
644
  int orig_rdmult = x->rdmult;
645 646 647 648
  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
649

650
  // Use the lower precision, but faster, 32x32 fdct for mode selection.
651
  x->use_lp32x32fdct = 1;
652

653
  if (bsize < BLOCK_8X8) {
654 655
    // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
    // there is nothing to be done.
656
    if (x->ab_index != 0) {
657 658
      *totalrate = 0;
      *totaldist = 0;
659
      return;
660
    }
661
  }
662

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

666
  for (i = 0; i < MAX_MB_PLANE; ++i) {
667
    p[i].coeff = ctx->coeff_pbuf[i][0];
668
    p[i].qcoeff = ctx->qcoeff_pbuf[i][0];
669
    pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][0];
670
    p[i].eobs = ctx->eobs_pbuf[i][0];
671
  }
672
  ctx->is_coded = 0;
673
  x->skip_recode = 0;
674

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

678
  x->source_variance = get_sby_perpixel_variance(cpi, x, bsize);
679

680
  if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
681 682
    const int energy = bsize <= BLOCK_16X16 ? x->mb_energy
                                            : vp9_block_energy(cpi, x, bsize);
683
    xd->mi_8x8[0]->mbmi.segment_id = vp9_vaq_segment_id(energy);
684 685 686 687
    rdmult_ratio = vp9_vaq_rdmult_ratio(energy);
    vp9_mb_init_quantizer(cpi, x);
  }

Ronald S. Bultje's avatar
Ronald S. Bultje committed
688
  if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
689
    vp9_activity_masking(cpi, x);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
690

691
  if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
692 693
    vp9_clear_system_state();  // __asm emms;
    x->rdmult = round(x->rdmult * rdmult_ratio);
694 695 696 697 698 699 700 701
  } 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);
702
  }
703

704 705
  // Find best coding mode & reconstruct the MB so it is available
  // as a predictor for MBs that follow in the SB
706
  if (frame_is_intra_only(cm)) {
707 708
    vp9_rd_pick_intra_mode_sb(cpi, x, totalrate, totaldist, bsize, ctx,
                              best_rd);
709 710
  } else {
    if (bsize >= BLOCK_8X8)
James Zern's avatar
James Zern committed
711 712
      vp9_rd_pick_inter_mode_sb(cpi, x, tile, mi_row, mi_col,
                                totalrate, totaldist, bsize, ctx, best_rd);
713
    else
James Zern's avatar
James Zern committed
714
      vp9_rd_pick_inter_mode_sub8x8(cpi, x, tile, mi_row, mi_col, totalrate,
715 716
                                    totaldist, bsize, ctx, best_rd);
  }
717

718
  if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
719 720 721 722 723 724
    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
725
}