vp9_encodeframe.c 91.9 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
23
#include "vp9/common/vp9_entropymode.h"
#include "vp9/common/vp9_findnearmv.h"
24
#include "vp9/common/vp9_idct.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
25
26
27
#include "vp9/common/vp9_mvref_common.h"
#include "vp9/common/vp9_pred_common.h"
#include "vp9/common/vp9_quant_common.h"
28
#include "vp9/common/vp9_reconintra.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
29
#include "vp9/common/vp9_reconinter.h"
30
#include "vp9/common/vp9_seg_common.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/common/vp9_systemdependent.h"
40
#include "vp9/encoder/vp9_tokenize.h"
41
42
#include "vp9/encoder/vp9_vaq.h"

Paul Wilkins's avatar
Paul Wilkins committed
43

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

46

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

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

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

80
static void adjust_act_zbin(VP9_COMP *cpi, MACROBLOCK *x);
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
85
 *  vp9_activity_masking().
86
 */
87
#define ACTIVITY_AVG_MIN (64)
88

89
90
91
/* Motion vector component magnitude threshold for defining fast motion. */
#define FAST_MOTION_MV_THRESH (24)

92
93
94
95
96
/* 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.
 */
97
98
99
100
101
102
103
104
105
106
107
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
};

108
static unsigned int get_sby_perpixel_variance(VP9_COMP *cpi, MACROBLOCK *x,
109
                                              BLOCK_SIZE bs) {
110
111
112
113
  unsigned int var, sse;
  var = cpi->fn_ptr[bs].vf(x->plane[0].src.buf,
                           x->plane[0].src.stride,
                           VP9_VAR_OFFS, 0, &sse);
114
115
116
117
  return (var + (1 << (num_pels_log2_lookup[bs] - 1))) >>
      num_pels_log2_lookup[bs];
}

118
// Original activity measure from Tim T's code.
119
static unsigned int tt_activity_measure(MACROBLOCK *x) {
John Koleszar's avatar
John Koleszar committed
120
121
122
123
124
125
126
127
128
  unsigned int act;
  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.).
   */
John Koleszar's avatar
John Koleszar committed
129
130
  act = vp9_variance16x16(x->plane[0].src.buf, x->plane[0].src.stride,
                          VP9_VAR_OFFS, 0, &sse);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
131
  act <<= 4;
John Koleszar's avatar
John Koleszar committed
132
133
134
135
136
137

  /* If the region is flat, lower the activity some more. */
  if (act < 8 << 12)
    act = act < 5 << 12 ? act : 5 << 12;

  return act;
138
139
}

140
// Stub for alternative experimental activity measures.
141
142
static unsigned int alt_activity_measure(MACROBLOCK *x, int use_dc_pred) {
  return vp9_encode_intra(x, use_dc_pred);
143
144
145
146
}

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

John Koleszar's avatar
John Koleszar committed
151
152
  if (ALT_ACT_MEASURE) {
    int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);
153

John Koleszar's avatar
John Koleszar committed
154
    // Or use and alternative.
155
    mb_activity = alt_activity_measure(x, use_dc_pred);
John Koleszar's avatar
John Koleszar committed
156
157
  } else {
    // Original activity measure from Tim T's code.
158
    mb_activity = tt_activity_measure(x);
John Koleszar's avatar
John Koleszar committed
159
  }
160

161
162
  if (mb_activity < ACTIVITY_AVG_MIN)
    mb_activity = ACTIVITY_AVG_MIN;
163

John Koleszar's avatar
John Koleszar committed
164
  return mb_activity;
165
166
167
}

// Calculate an "average" mb activity value for the frame
168
#define ACT_MEDIAN 0
169
static void calc_av_activity(VP9_COMP *cpi, int64_t activity_sum) {
170
#if ACT_MEDIAN
John Koleszar's avatar
John Koleszar committed
171
172
173
174
175
176
177
178
  // 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
179
180
    CHECK_MEM_ERROR(&cpi->common, sortlist, vpx_calloc(sizeof(unsigned int),
                    cpi->common.MBs));
John Koleszar's avatar
John Koleszar committed
181
182
183

    // Copy map to sort list
    vpx_memcpy(sortlist, cpi->mb_activity_map,
Jim Bankoski's avatar
Jim Bankoski committed
184
        sizeof(unsigned int) * cpi->common.MBs);
John Koleszar's avatar
John Koleszar committed
185
186
187
188
189
190
191
192
193

    // 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;
194
195
196
        } else {
          break;
        }
John Koleszar's avatar
John Koleszar committed
197
198
      }
    }
199

John Koleszar's avatar
John Koleszar committed
200
201
    // 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
202
        sortlist[(cpi->common.MBs >> 1) + 1]) >> 1;
203

John Koleszar's avatar
John Koleszar committed
204
    cpi->activity_avg = median;
205

John Koleszar's avatar
John Koleszar committed
206
207
    vpx_free(sortlist);
  }
208
#else
John Koleszar's avatar
John Koleszar committed
209
  // Simple mean for now
Jim Bankoski's avatar
Jim Bankoski committed
210
  cpi->activity_avg = (unsigned int) (activity_sum / cpi->common.MBs);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
211
#endif  // ACT_MEDIAN
212

213
214
  if (cpi->activity_avg < ACTIVITY_AVG_MIN)
    cpi->activity_avg = ACTIVITY_AVG_MIN;
215

John Koleszar's avatar
John Koleszar committed
216
217
218
  // Experimental code: return fixed value normalized for several clips
  if (ALT_ACT_MEASURE)
    cpi->activity_avg = 100000;
219
220
}

221
#define USE_ACT_INDEX   0
222
#define OUTPUT_NORM_ACT_STATS   0
223
224

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

John Koleszar's avatar
John Koleszar committed
230
231
232
  int64_t act;
  int64_t a;
  int64_t b;
233
234

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

John Koleszar's avatar
John Koleszar committed
239
240
  // Reset pointers to start of activity map
  x->mb_activity_ptr = cpi->mb_activity_map;
241

John Koleszar's avatar
John Koleszar committed
242
243
244
245
246
247
  // 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);
248

John Koleszar's avatar
John Koleszar committed
249
250
251
      // Calculate a normalized activity number
      a = act + 4 * cpi->activity_avg;
      b = 4 * act + cpi->activity_avg;
252

John Koleszar's avatar
John Koleszar committed
253
      if (b >= a)
Jim Bankoski's avatar
Jim Bankoski committed
254
      *(x->activity_ptr) = (int)((b + (a >> 1)) / a) - 1;
John Koleszar's avatar
John Koleszar committed
255
      else
Jim Bankoski's avatar
Jim Bankoski committed
256
      *(x->activity_ptr) = 1 - (int)((a + (b >> 1)) / b);
257
258

#if OUTPUT_NORM_ACT_STATS
John Koleszar's avatar
John Koleszar committed
259
      fprintf(f, " %6d", *(x->mb_activity_ptr));
260
#endif
John Koleszar's avatar
John Koleszar committed
261
262
263
      // Increment activity map pointers
      x->mb_activity_ptr++;
    }
264
265

#if OUTPUT_NORM_ACT_STATS
John Koleszar's avatar
John Koleszar committed
266
    fprintf(f, "\n");
267
#endif
John Koleszar's avatar
John Koleszar committed
268
  }
269
270

#if OUTPUT_NORM_ACT_STATS
John Koleszar's avatar
John Koleszar committed
271
  fclose(f);
272
273
#endif
}
Dmitry Kovalev's avatar
Dmitry Kovalev committed
274
#endif  // USE_ACT_INDEX
275
276
277

// Loop through all MBs. Note activity of each, average activity and
// calculate a normalized activity for each
278
static void build_activity_map(VP9_COMP *cpi) {
Jim Bankoski's avatar
Jim Bankoski committed
279
  MACROBLOCK * const x = &cpi->mb;
John Koleszar's avatar
John Koleszar committed
280
  MACROBLOCKD *xd = &x->e_mbd;
Jim Bankoski's avatar
Jim Bankoski committed
281
  VP9_COMMON * const cm = &cpi->common;
282

283
#if ALT_ACT_MEASURE
284
  YV12_BUFFER_CONFIG *new_yv12 = get_frame_new_buffer(cm);
John Koleszar's avatar
John Koleszar committed
285
286
  int recon_yoffset;
  int recon_y_stride = new_yv12->y_stride;
287
288
#endif

John Koleszar's avatar
John Koleszar committed
289
290
291
  int mb_row, mb_col;
  unsigned int mb_activity;
  int64_t activity_sum = 0;
292

293
294
  x->mb_activity_ptr = cpi->mb_activity_map;

John Koleszar's avatar
John Koleszar committed
295
296
  // for each macroblock row in image
  for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) {
297
#if ALT_ACT_MEASURE
John Koleszar's avatar
John Koleszar committed
298
299
300
    // reset above block coeffs
    xd->up_available = (mb_row != 0);
    recon_yoffset = (mb_row * recon_y_stride * 16);
301
#endif
John Koleszar's avatar
John Koleszar committed
302
303
    // for each macroblock col in image
    for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) {
304
#if ALT_ACT_MEASURE
305
      xd->plane[0].dst.buf = new_yv12->y_buffer + recon_yoffset;
John Koleszar's avatar
John Koleszar committed
306
307
      xd->left_available = (mb_col != 0);
      recon_yoffset += 16;
308
#endif
309

John Koleszar's avatar
John Koleszar committed
310
      // measure activity
311
      mb_activity = mb_activity_measure(x, mb_row, mb_col);
312

John Koleszar's avatar
John Koleszar committed
313
314
      // Keep frame sum
      activity_sum += mb_activity;
315

John Koleszar's avatar
John Koleszar committed
316
317
      // Store MB level activity details.
      *x->mb_activity_ptr = mb_activity;
318

John Koleszar's avatar
John Koleszar committed
319
320
      // Increment activity map pointer
      x->mb_activity_ptr++;
321

John Koleszar's avatar
John Koleszar committed
322
      // adjust to the next column of source macroblocks
John Koleszar's avatar
John Koleszar committed
323
      x->plane[0].src.buf += 16;
John Koleszar's avatar
John Koleszar committed
324
    }
325

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

John Koleszar's avatar
John Koleszar committed
330
331
  // Calculate an "average" MB activity
  calc_av_activity(cpi, activity_sum);
332

333
#if USE_ACT_INDEX
John Koleszar's avatar
John Koleszar committed
334
335
  // Calculate an activity index number of each mb
  calc_activity_index(cpi, x);
336
#endif
337
338
}

339
// Macroblock activity masking
340
void vp9_activity_masking(VP9_COMP *cpi, MACROBLOCK *x) {
341
#if USE_ACT_INDEX
John Koleszar's avatar
John Koleszar committed
342
343
344
  x->rdmult += *(x->mb_activity_ptr) * (x->rdmult >> 2);
  x->errorperbit = x->rdmult * 100 / (110 * x->rddiv);
  x->errorperbit += (x->errorperbit == 0);
345
#else
John Koleszar's avatar
John Koleszar committed
346
347
348
  int64_t a;
  int64_t b;
  int64_t act = *(x->mb_activity_ptr);
349

John Koleszar's avatar
John Koleszar committed
350
351
352
  // Apply the masking to the RD multiplier.
  a = act + (2 * cpi->activity_avg);
  b = (2 * act) + cpi->activity_avg;
353

Jim Bankoski's avatar
Jim Bankoski committed
354
  x->rdmult = (unsigned int) (((int64_t) x->rdmult * b + (a >> 1)) / a);
John Koleszar's avatar
John Koleszar committed
355
356
  x->errorperbit = x->rdmult * 100 / (110 * x->rddiv);
  x->errorperbit += (x->errorperbit == 0);
357
#endif
358

John Koleszar's avatar
John Koleszar committed
359
360
  // Activity based Zbin adjustment
  adjust_act_zbin(cpi, x);
361
}
John Koleszar's avatar
John Koleszar committed
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
397
398
399
400
401
402
403
404
405
406
407
408
// 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) {
  VP9_COMMON * const cm = &cpi->common;
  int target_rate = cpi->rc.sb64_target_rate << 8;   // convert to bits << 8

  const int mi_offset = mi_row * cm->mi_cols + mi_col;
  const int bw = 1 << mi_width_log2(BLOCK_64X64);
  const int bh = 1 << mi_height_log2(BLOCK_64X64);
  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
409
static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
410
                         BLOCK_SIZE bsize, int output_enabled) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
411
  int i, x_idx, y;
412
413
414
  VP9_COMMON *const cm = &cpi->common;
  MACROBLOCK *const x = &cpi->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
415
416
  struct macroblock_plane *const p = x->plane;
  struct macroblockd_plane *const pd = xd->plane;
John Koleszar's avatar
John Koleszar committed
417
  MODE_INFO *mi = &ctx->mic;
418
419
  MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
  MODE_INFO *mi_addr = xd->mi_8x8[0];
420

John Koleszar's avatar
John Koleszar committed
421
  int mb_mode_index = ctx->best_mode_index;
422
  const int mis = cm->mode_info_stride;
Jim Bankoski's avatar
Jim Bankoski committed
423
  const int mi_width = num_8x8_blocks_wide_lookup[bsize];
Jim Bankoski's avatar
Jim Bankoski committed
424
  const int mi_height = num_8x8_blocks_high_lookup[bsize];
425
  int max_plane;
Adrian Grange's avatar
Adrian Grange committed
426

427
  assert(mi->mbmi.mode < MB_MODE_COUNT);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
428
429
  assert(mi->mbmi.ref_frame[0] < MAX_REF_FRAMES);
  assert(mi->mbmi.ref_frame[1] < MAX_REF_FRAMES);
430
  assert(mi->mbmi.sb_type == bsize);
431

432
433
434
435
436
  // 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;

437
438
  *mi_addr = *mi;

439
440
  max_plane = is_inter_block(mbmi) ? MAX_MB_PLANE : 1;
  for (i = 0; i < max_plane; ++i) {
441
    p[i].coeff = ctx->coeff_pbuf[i][1];
442
    p[i].qcoeff = ctx->qcoeff_pbuf[i][1];
443
    pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][1];
444
    p[i].eobs = ctx->eobs_pbuf[i][1];
445
446
  }

447
448
  for (i = max_plane; i < MAX_MB_PLANE; ++i) {
    p[i].coeff = ctx->coeff_pbuf[i][2];
449
    p[i].qcoeff = ctx->qcoeff_pbuf[i][2];
450
    pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][2];
451
    p[i].eobs = ctx->eobs_pbuf[i][2];
452
453
  }

John Koleszar's avatar
John Koleszar committed
454
455
  // Restore the coding context of the MB to that that was in place
  // when the mode was picked for it
456
457
  for (y = 0; y < mi_height; y++)
    for (x_idx = 0; x_idx < mi_width; x_idx++)
James Zern's avatar
James Zern committed
458
      if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx
459
        && (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
460
        xd->mi_8x8[x_idx + y * mis] = mi_addr;
461
      }
462

463
464
    if ((cpi->oxcf.aq_mode == VARIANCE_AQ) ||
        (cpi->oxcf.aq_mode == COMPLEXITY_AQ)) {
465
466
467
    vp9_mb_init_quantizer(cpi, x);
  }

468
469
  // FIXME(rbultje) I'm pretty sure this should go to the end of this block
  // (i.e. after the output_enabled)
470
471
  if (bsize < BLOCK_32X32) {
    if (bsize < BLOCK_16X16)
472
473
      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
474
  }
Adrian Grange's avatar
Adrian Grange committed
475

476
  if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) {
477
478
    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
479
480
  }

481
  x->skip = ctx->skip;
482
  vpx_memcpy(x->zcoeff_blk[mbmi->tx_size], ctx->zcoeff_blk,
483
             sizeof(uint8_t) * ctx->num_4x4_blk);
484

Ronald S. Bultje's avatar
Ronald S. Bultje committed
485
486
487
  if (!output_enabled)
    return;

488
  if (!vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
489
    for (i = 0; i < TX_MODES; i++)
490
      cpi->rd_tx_select_diff[i] += ctx->tx_rd_diff[i];
491
492
  }

493
  if (frame_is_intra_only(cm)) {
494
#if CONFIG_INTERNAL_STATS
John Koleszar's avatar
John Koleszar committed
495
496
497
498
499
500
501
502
    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
503
      THR_D207_PRED /*D207_PRED*/,
John Koleszar's avatar
John Koleszar committed
504
505
506
      THR_D63_PRED /*D63_PRED*/,
      THR_TM /*TM_PRED*/,
    };
507
    cpi->mode_chosen_counts[kf_mode_index[mi->mbmi.mode]]++;
508
#endif
John Koleszar's avatar
John Koleszar committed
509
510
511
  } else {
    // Note how often each mode chosen as best
    cpi->mode_chosen_counts[mb_mode_index]++;
512
    if (is_inter_block(mbmi)
513
        && (mbmi->sb_type < BLOCK_8X8 || mbmi->mode == NEWMV)) {
514
      int_mv best_mv[2];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
515
516
      const MV_REFERENCE_FRAME rf1 = mbmi->ref_frame[0];
      const MV_REFERENCE_FRAME rf2 = mbmi->ref_frame[1];
517
518
      best_mv[0].as_int = ctx->best_ref_mv.as_int;
      best_mv[1].as_int = ctx->second_best_ref_mv.as_int;
Deb Mukherjee's avatar
Deb Mukherjee committed
519
      if (mbmi->mode == NEWMV) {
520
        best_mv[0].as_int = mbmi->ref_mvs[rf1][0].as_int;
Yaowu Xu's avatar
Yaowu Xu committed
521
        if (rf2 > 0)
522
          best_mv[1].as_int = mbmi->ref_mvs[rf2][0].as_int;
Deb Mukherjee's avatar
Deb Mukherjee committed
523
      }
524
525
526
      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);
527
    }
Jingning Han's avatar
Jingning Han committed
528

529
530
531
    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];
532
    }
Adrian Grange's avatar
Adrian Grange committed
533

534
535
536
    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;
537

538
    for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
539
      cpi->rd_filter_diff[i] += ctx->best_filter_diff[i];
John Koleszar's avatar
John Koleszar committed
540
  }
Adrian Grange's avatar
Adrian Grange committed
541
542
}

Jim Bankoski's avatar
Jim Bankoski committed
543
void vp9_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
544
545
546
547
548
                          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};
549
550
  int i;

551
552
553
  // Set current frame pointer.
  x->e_mbd.cur_buf = src;

554
555
  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
556
                     NULL, x->e_mbd.plane[i].subsampling_x,
557
                     x->e_mbd.plane[i].subsampling_y);
John Koleszar's avatar
John Koleszar committed
558
559
}

James Zern's avatar
James Zern committed
560
561
static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile,
                        int mi_row, int mi_col, BLOCK_SIZE bsize) {
562
563
564
  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
565
566
  MB_MODE_INFO *mbmi;
  const int dst_fb_idx = cm->new_fb_idx;
567
  const int idx_str = xd->mode_info_stride * mi_row + mi_col;
Jim Bankoski's avatar
Jim Bankoski committed
568
569
  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
570
571
  const int mb_row = mi_row >> 1;
  const int mb_col = mi_col >> 1;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
572
  const int idx_map = mb_row * cm->mb_cols + mb_col;
573
  const struct segmentation *const seg = &cm->seg;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
574

575
  set_skip_context(xd, cpi->above_context, cpi->left_context, mi_row, mi_col);
576

Ronald S. Bultje's avatar
Ronald S. Bultje committed
577
578
579
580
  // Activity map pointer
  x->mb_activity_ptr = &cpi->mb_activity_map[idx_map];
  x->active_ptr = cpi->active_map + idx_map;

581
582
583
  xd->mi_8x8 = cm->mi_grid_visible + idx_str;
  xd->prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str;

584
585
  // Special case: if prev_mi is NULL, the previous mode info context
  // cannot be used.
586
587
  xd->last_mi = cm->prev_mi ? xd->prev_mi_8x8[0] : NULL;

588
  xd->mi_8x8[0] = cm->mi + idx_str;
589

590
  mbmi = &xd->mi_8x8[0]->mbmi;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
591
592

  // Set up destination pointers
593
  setup_dst_planes(xd, &cm->yv12_fb[dst_fb_idx], mi_row, mi_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
594

Yaowu Xu's avatar
Yaowu Xu committed
595
596
  // Set up limit values for MV components
  // mv beyond the range do not produce new/different prediction block
597
598
  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
599
600
  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
601
602

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

  /* set up source buffers */
608
  vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
609
610
611
612
613
614

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

  /* segment ID */
615
  if (seg->enabled) {
616
    if (cpi->oxcf.aq_mode != VARIANCE_AQ) {
617
618
619
620
      uint8_t *map = seg->update_map ? cpi->segmentation_map
          : cm->last_frame_seg_map;
      mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
    }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
621
622
    vp9_mb_init_quantizer(cpi, x);

623
624
625
    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
626
627
628
629
      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
630
      const int p16 = ((mb_row & 1) << 1) + (mb_col & 1);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
631
      const int p32 = ((mb_row & 2) << 2) + ((mb_col & 2) << 1);
James Zern's avatar
James Zern committed
632
633
      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
634

Jim Bankoski's avatar
Jim Bankoski committed
635
636
      cpi->seg0_progress = ((y * mb_cols + x * 4 + p32 + p16 + tile_progress)
          << 16) / cm->MBs;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
637
    }
638
639

    x->encode_breakout = cpi->segment_encode_breakout[mbmi->segment_id];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
640
641
  } else {
    mbmi->segment_id = 0;
642
    x->encode_breakout = cpi->oxcf.encode_breakout;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
643
644
645
  }
}

James Zern's avatar
James Zern committed
646
647
static void pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
                          int mi_row, int mi_col,
648
                          int *totalrate, int64_t *totaldist,
649
                          BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
650
                          int64_t best_rd) {
651
652
653
  VP9_COMMON *const cm = &cpi->common;
  MACROBLOCK *const x = &cpi->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
654
655
656
  struct macroblock_plane *const p = x->plane;
  struct macroblockd_plane *const pd = xd->plane;
  int i;
657
  int orig_rdmult = x->rdmult;
658
659
660
661
  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
662

663
  // Use the lower precision, but faster, 32x32 fdct for mode selection.
664
  x->use_lp32x32fdct = 1;
665

666
  if (bsize < BLOCK_8X8) {
667
668
    // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
    // there is nothing to be done.
669
    if (x->ab_index != 0) {
670
671
      *totalrate = 0;
      *totaldist = 0;
672
      return;
673
    }
674
  }
675

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

679
  for (i = 0; i < MAX_MB_PLANE; ++i) {
680
    p[i].coeff = ctx->coeff_pbuf[i][0];
681
    p[i].qcoeff = ctx->qcoeff_pbuf[i][0];
682
    pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][0];
683
    p[i].eobs = ctx->eobs_pbuf[i][0];
684
  }
685
  ctx->is_coded = 0;
686
  x->skip_recode = 0;
687

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

691
  x->source_variance = get_sby_perpixel_variance(cpi, x, bsize);
692

693
  if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
694
695
696
697
698
699
700
    int energy;
    if (bsize <= BLOCK_16X16) {
      energy = x->mb_energy;
    } else {
      energy = vp9_block_energy(cpi, x, bsize);
    }

701
    xd->mi_8x8[0]->mbmi.segment_id = vp9_vaq_segment_id(energy);
702
703
704
705
    rdmult_ratio = vp9_vaq_rdmult_ratio(energy);
    vp9_mb_init_quantizer(cpi, x);
  }

Ronald S. Bultje's avatar
Ronald S. Bultje committed
706
  if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
707
    vp9_activity_masking(cpi, x);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
708

709
  if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
710
711
    vp9_clear_system_state();  // __asm emms;
    x->rdmult = round(x->rdmult * rdmult_ratio);
712
713
714
715
716
717
718
719
  } 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);
720
  }
721

722
723
  // Find best coding mode & reconstruct the MB so it is available
  // as a predictor for MBs that follow in the SB
724
  if (frame_is_intra_only(cm)) {
725
726
    vp9_rd_pick_intra_mode_sb(cpi, x, totalrate, totaldist, bsize, ctx,
                              best_rd);
727
728
  } else {
    if (bsize >= BLOCK_8X8)
James Zern's avatar
James Zern committed
729
730
      vp9_rd_pick_inter_mode_sb(cpi, x, tile, mi_row, mi_col,
                                totalrate, totaldist, bsize, ctx, best_rd);
731
    else
James Zern's avatar
James Zern committed
732
      vp9_rd_pick_inter_mode_sub8x8(cpi, x, tile, mi_row, mi_col, totalrate,
733
734
                                    totaldist, bsize, ctx, best_rd);
  }
735

736
  if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
737
738
739
740
741
742
    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
743
}
Adrian Grange's avatar
Adrian Grange committed
744

745
746
747
748
static void update_stats(VP9_COMP *cpi) {
  VP9_COMMON *const cm = &cpi->common;
  MACROBLOCK *const x = &cpi->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
749
  MODE_INFO *mi = xd->mi_8x8[0];
750
  MB_MODE_INFO *const mbmi = &mi->mbmi;
Adrian Grange's avatar
Adrian Grange committed
751

752
  if (!frame_is_intra_only(cm)) {
753
    const int seg_ref_active = vp9_segfeature_active(&cm->seg, mbmi->segment_id,
754
                                                     SEG_LVL_REF_FRAME);
755
756

    if (!seg_ref_active)
757
      cpi->intra_inter_count[vp9_get_intra_inter_context(xd)]
Dmitry Kovalev's avatar
Dmitry Kovalev committed
758
                            [is_inter_block(mbmi)]++;
Adrian Grange's avatar
Adrian Grange committed
759

760
761
762
    // 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
763
    if (is_inter_block(mbmi) && !seg_ref_active) {
764
      if (cm->reference_mode == REFERENCE_MODE_SELECT)
765
        cm->counts.comp_inter[vp9_get_reference_mode_context(cm, xd)]
Dmitry Kovalev's avatar
Dmitry Kovalev committed
766
                             [has_second_ref(mbmi)]++;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
767

Dmitry Kovalev's avatar
Dmitry Kovalev committed
768
      if (has_second_ref(mbmi)) {
769
        cm->counts.comp_ref[vp9_get_pred_context_comp_ref_p(cm, xd)]
Dmitry Kovalev's avatar
Dmitry Kovalev committed
770
                           [mbmi->ref_frame[0] == GOLDEN_FRAME]++;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
771
      } else {
772
        cm->counts.single_ref[vp9_get_pred_context_single_ref_p1(xd)][0]
Dmitry Kovalev's avatar
Dmitry Kovalev committed
773
                             [mbmi->ref_frame[0] != LAST_FRAME]++;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
774
        if (mbmi->ref_frame[0] != LAST_FRAME)
775
          cm->counts.single_ref[vp9_get_pred_context_single_ref_p2(xd)][1]
Dmitry Kovalev's avatar
Dmitry Kovalev committed
776
                               [mbmi->ref_frame[0] != GOLDEN_FRAME]++;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
777
      }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
778
    }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
779
780
  }
}
John Koleszar's avatar
John Koleszar committed
781

782
static BLOCK_SIZE *get_sb_partitioning(MACROBLOCK *x, BLOCK_SIZE bsize) {
783
  switch (bsize) {
784
    case BLOCK_64X64:
785
      return &x->sb64_partitioning;
786
    case BLOCK_32X32:
787
      return &x->sb_partitioning[x->sb_index];
788
    case BLOCK_16X16:
789
      return &x->mb_partitioning[x->sb_index][x->mb_index];
790
    case BLOCK_8X8:
791
      return &x->b_partitioning[x->sb_index][x->mb_index][x->b_index];
792
793
    default:
      assert(0);
794
      return NULL;
795
796
797
798
799
800
  }
}

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
801
                            PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8],
802
                            BLOCK_SIZE bsize) {
Jim Bankoski's avatar
Jim Bankoski committed
803
804
  MACROBLOCK *const x = &cpi->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
805
  int p