vp9_encodeframe.c 90.8 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 37 38
#include "vp9/encoder/vp9_onyx_int.h"
#include "vp9/encoder/vp9_rdopt.h"
#include "vp9/encoder/vp9_segmentation.h"
39
#include "vp9/encoder/vp9_tokenize.h"
40 41
#include "vp9/encoder/vp9_vaq.h"

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

44

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

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

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

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

80 81 82 83
// 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().
84
#define ACTIVITY_AVG_MIN (64)
85

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

89 90 91 92
// 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.
93 94 95 96 97 98 99 100 101 102 103
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
};

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

112
// Original activity measure from Tim T's code.
113
static unsigned int tt_activity_measure(MACROBLOCK *x) {
John Koleszar's avatar
John Koleszar committed
114 115 116 117 118 119 120 121
  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.).
   */
122 123 124 125 126 127
  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
128 129

  return act;
130 131
}

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

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

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

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

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

// Calculate an "average" mb activity value for the frame
157
#define ACT_MEDIAN 0
158
static void calc_av_activity(VP9_COMP *cpi, int64_t activity_sum) {
159
#if ACT_MEDIAN
John Koleszar's avatar
John Koleszar committed
160 161 162 163 164 165 166 167
  // 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
168 169
    CHECK_MEM_ERROR(&cpi->common, sortlist, vpx_calloc(sizeof(unsigned int),
                    cpi->common.MBs));
John Koleszar's avatar
John Koleszar committed
170 171 172

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

    // 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;
183 184 185
        } else {
          break;
        }
John Koleszar's avatar
John Koleszar committed
186 187
      }
    }
188

John Koleszar's avatar
John Koleszar committed
189 190
    // 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
191
        sortlist[(cpi->common.MBs >> 1) + 1]) >> 1;
192

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

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

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

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

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

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

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

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

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

John Koleszar's avatar
John Koleszar committed
231 232 233 234 235 236
  // 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);
237

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

350 351 352 353
// 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
354
  VP9_COMMON *const cm = &cpi->common;
355 356 357
  int target_rate = cpi->rc.sb64_target_rate << 8;   // convert to bits << 8

  const int mi_offset = mi_row * cm->mi_cols + mi_col;
358 359
  const int bw = num_8x8_blocks_wide_lookup[BLOCK_64X64];
  const int bh = num_8x8_blocks_high_lookup[BLOCK_64X64];
360 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
  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
396
static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
397
                         BLOCK_SIZE bsize, int output_enabled) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
398
  int i, x_idx, y;
399 400 401
  VP9_COMMON *const cm = &cpi->common;
  MACROBLOCK *const x = &cpi->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
402 403
  struct macroblock_plane *const p = x->plane;
  struct macroblockd_plane *const pd = xd->plane;
John Koleszar's avatar
John Koleszar committed
404
  MODE_INFO *mi = &ctx->mic;
405 406
  MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
  MODE_INFO *mi_addr = xd->mi_8x8[0];
407

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

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

419 420 421 422 423
  // 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;

424 425
  *mi_addr = *mi;

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

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

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

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

455 456
  // FIXME(rbultje) I'm pretty sure this should go to the end of this block
  // (i.e. after the output_enabled)
457 458
  if (bsize < BLOCK_32X32) {
    if (bsize < BLOCK_16X16)
459 460
      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
461
  }
Adrian Grange's avatar
Adrian Grange committed
462

463
  if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) {
464 465
    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
466 467
  }

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

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

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

480
  if (frame_is_intra_only(cm)) {
481
#if CONFIG_INTERNAL_STATS
John Koleszar's avatar
John Koleszar committed
482 483 484 485 486 487 488 489
    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
490
      THR_D207_PRED /*D207_PRED*/,
John Koleszar's avatar
John Koleszar committed
491 492 493
      THR_D63_PRED /*D63_PRED*/,
      THR_TM /*TM_PRED*/,
    };
494
    cpi->mode_chosen_counts[kf_mode_index[mi->mbmi.mode]]++;
495
#endif
John Koleszar's avatar
John Koleszar committed
496 497 498
  } else {
    // Note how often each mode chosen as best
    cpi->mode_chosen_counts[mb_mode_index]++;
499 500
    if (is_inter_block(mbmi) &&
        (mbmi->sb_type < BLOCK_8X8 || mbmi->mode == NEWMV)) {
501
      int_mv best_mv[2];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
502 503
      const MV_REFERENCE_FRAME rf1 = mbmi->ref_frame[0];
      const MV_REFERENCE_FRAME rf2 = mbmi->ref_frame[1];
504 505
      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
506
      if (mbmi->mode == NEWMV) {
507
        best_mv[0].as_int = mbmi->ref_mvs[rf1][0].as_int;
Yaowu Xu's avatar
Yaowu Xu committed
508
        if (rf2 > 0)
509
          best_mv[1].as_int = mbmi->ref_mvs[rf2][0].as_int;
Deb Mukherjee's avatar
Deb Mukherjee committed
510
      }
511 512 513
      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);
514
    }
Jingning Han's avatar
Jingning Han committed
515

516 517 518
    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];
519
    }
Adrian Grange's avatar
Adrian Grange committed
520

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

717
  if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
718 719 720 721 722 723
    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
724
}
Adrian Grange's avatar
Adrian Grange committed
725