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)) {
726
    const int seg_ref_active = vp9_segfeature_active(&cm->seg, mbmi->segment_id,
727
                                                     SEG_LVL_REF_FRAME);
728
729

    if (!seg_ref_active)
730
      cm->counts.intra_inter[vp9_get_intra_inter_context(xd)]
Dmitry Kovalev's avatar
Dmitry Kovalev committed
731
                            [is_inter_block(mbmi)]++;
Adrian Grange's avatar
Adrian Grange committed
732

733
734
735
    // If the segment reference feature is enabled we have only a single
    // reference frame allowed for the segment so exclude it from
    // the reference frame counts used to work out probabilities.
Dmitry Kovalev's avatar
Dmitry Kovalev committed
736
    if (is_inter_block(mbmi) && !seg_ref_active) {
737
      if (cm->reference_mode == REFERENCE_MODE_SELECT)
738
        cm->counts.comp_inter[vp9_get_reference_mode_context(cm, xd)]
Dmitry Kovalev's avatar
Dmitry Kovalev committed
739
                             [has_second_ref(mbmi)]++;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
740

Dmitry Kovalev's avatar
Dmitry Kovalev committed
741
      if (has_second_ref(mbmi)) {
742
        cm->counts.comp_ref[vp9_get_pred_context_comp_ref_p(cm, xd)]
Dmitry Kovalev's avatar
Dmitry Kovalev committed
743
                           [mbmi->ref_frame[0] == GOLDEN_FRAME]++;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
744
      } else {
745
        cm->counts.single_ref[vp9_get_pred_context_single_ref_p1(xd)][0]
Dmitry Kovalev's avatar
Dmitry Kovalev committed
746
                             [mbmi->ref_frame[0] != LAST_FRAME]++;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
747
        if (mbmi->ref_frame[0] != LAST_FRAME)
748
          cm->counts.single_ref[vp9_get_pred_context_single_ref_p2(xd)][1]
Dmitry Kovalev's avatar
Dmitry Kovalev committed
749
                               [mbmi->ref_frame[0] != GOLDEN_FRAME]++;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
750
      }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
751
    }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
752
753
  }
}
John Koleszar's avatar
John Koleszar committed
754

755
static BLOCK_SIZE *get_sb_partitioning(MACROBLOCK *x, BLOCK_SIZE bsize) {
756
  switch (bsize) {
757
    case BLOCK_64X64:
758
      return &x->sb64_partitioning;
759
    case BLOCK_32X32:
760
      return &x->sb_partitioning[x->sb_index];
761
    case BLOCK_16X16:
762
      return &x->mb_partitioning[x->sb_index][x->mb_index];
763
    case BLOCK_8X8:
764
      return &x->b_partitioning[x->sb_index][x->mb_index][x->b_index];
765
766
    default:
      assert(0);
767
      return NULL;
768
769
770
771
772
773
  }
}

static void restore_context(VP9_COMP *cpi, int mi_row, int mi_col,
                            ENTROPY_CONTEXT a[16 * MAX_MB_PLANE],
                            ENTROPY_CONTEXT l[16 * MAX_MB_PLANE],
Jim Bankoski's avatar
Jim Bankoski committed
774
                            PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8],
775
                            BLOCK_SIZE bsize) {
Jim Bankoski's avatar
Jim Bankoski committed
776
777
  MACROBLOCK *const x = &cpi->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
778
  int p;
Jim Bankoski's avatar
Jim Bankoski committed
779
780
  const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
  const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
Jim Bankoski's avatar
Jim Bankoski committed
781
782
  int mi_width = num_8x8_blocks_wide_lookup[bsize];
  int mi_height = num_8x8_blocks_high_lookup[bsize];
783
  for (p = 0; p < MAX_MB_PLANE; p++) {
Jim Bankoski's avatar
Jim Bankoski committed
784
    vpx_memcpy(
785
        cpi->above_context[p] + ((mi_col * 2) >> xd->plane[p].subs