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_tile_common.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
31
32
33
#include "vp9/encoder/vp9_encodeframe.h"
#include "vp9/encoder/vp9_encodemb.h"
#include "vp9/encoder/vp9_encodemv.h"
34
#include "vp9/encoder/vp9_extend.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
35
36
37
#include "vp9/encoder/vp9_onyx_int.h"
#include "vp9/encoder/vp9_rdopt.h"
#include "vp9/encoder/vp9_segmentation.h"
38
#include "vp9/common/vp9_systemdependent.h"
39
#include "vp9/encoder/vp9_tokenize.h"
40
41
#include "vp9/encoder/vp9_vaq.h"

Paul Wilkins's avatar
Paul Wilkins committed
42

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
/* 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
84
 *  vp9_activity_masking().
85
 */
86
#define ACTIVITY_AVG_MIN (64)
87

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

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

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

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

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

  return act;
135
136
}

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

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

John Koleszar's avatar
John Koleszar committed
148
149
  if (ALT_ACT_MEASURE) {
    int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);
150

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

158
159
  if (mb_activity < ACTIVITY_AVG_MIN)
    mb_activity = ACTIVITY_AVG_MIN;
160

John Koleszar's avatar
John Koleszar committed
161
  return mb_activity;
162
163
164
}

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

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

    // 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;
191
192
193
        } else {
          break;
        }
John Koleszar's avatar
John Koleszar committed
194
195
      }
    }
196

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

John Koleszar's avatar
John Koleszar committed
201
    cpi->activity_avg = median;
202

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

210
211
  if (cpi->activity_avg < ACTIVITY_AVG_MIN)
    cpi->activity_avg = ACTIVITY_AVG_MIN;
212

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

218
#define USE_ACT_INDEX   0
219
#define OUTPUT_NORM_ACT_STATS   0
220
221

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

John Koleszar's avatar
John Koleszar committed
227
228
229
  int64_t act;
  int64_t a;
  int64_t b;
230
231

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

John Koleszar's avatar
John Koleszar committed
236
237
  // Reset pointers to start of activity map
  x->mb_activity_ptr = cpi->mb_activity_map;
238

John Koleszar's avatar
John Koleszar committed
239
240
241
242
243
244
  // 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);
245

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

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

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

#if OUTPUT_NORM_ACT_STATS
John Koleszar's avatar
John Koleszar committed
263
    fprintf(f, "\n");
264
#endif
John Koleszar's avatar
John Koleszar committed
265
  }
266
267

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

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

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

John Koleszar's avatar
John Koleszar committed
286
287
288
  int mb_row, mb_col;
  unsigned int mb_activity;
  int64_t activity_sum = 0;
289

290
291
  x->mb_activity_ptr = cpi->mb_activity_map;

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

John Koleszar's avatar
John Koleszar committed
307
      // measure activity
308
      mb_activity = mb_activity_measure(x, mb_row, mb_col);
309

John Koleszar's avatar
John Koleszar committed
310
311
      // Keep frame sum
      activity_sum += mb_activity;
312

John Koleszar's avatar
John Koleszar committed
313
314
      // Store MB level activity details.
      *x->mb_activity_ptr = mb_activity;
315

John Koleszar's avatar
John Koleszar committed
316
317
      // Increment activity map pointer
      x->mb_activity_ptr++;
318

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

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

John Koleszar's avatar
John Koleszar committed
327
328
  // Calculate an "average" MB activity
  calc_av_activity(cpi, activity_sum);
329

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

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

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

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

John Koleszar's avatar
John Koleszar committed
356
357
  // Activity based Zbin adjustment
  adjust_act_zbin(cpi, x);
358
}
John Koleszar's avatar
John Koleszar committed
359

360
361
362
363
// 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
364
  VP9_COMMON *const cm = &cpi->common;
365
366
367
  int target_rate = cpi->rc.sb64_target_rate << 8;   // convert to bits << 8

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

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

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

429
430
431
432
433
  // 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;

434
435
  *mi_addr = *mi;

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

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

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

460
461
    if ((cpi->oxcf.aq_mode == VARIANCE_AQ) ||
        (cpi->oxcf.aq_mode == COMPLEXITY_AQ)) {
462
463
464
    vp9_mb_init_quantizer(cpi, x);
  }

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

473
  if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) {
474
475
    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
476
477
  }

478
  x->skip = ctx->skip;
479
  vpx_memcpy(x->zcoeff_blk[mbmi->tx_size], ctx->zcoeff_blk,
480
             sizeof(uint8_t) * ctx->num_4x4_blk);
481

Ronald S. Bultje's avatar
Ronald S. Bultje committed
482
483
484
  if (!output_enabled)
    return;

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

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

526
527
528
    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];
529
    }
Adrian Grange's avatar
Adrian Grange committed
530

531
532
533
    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;
534

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

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

548
549
550
  // Set current frame pointer.
  x->e_mbd.cur_buf = src;

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

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

572
  set_skip_context(xd, cpi->above_context, cpi->left_context, mi_row, mi_col);
573

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

578
579
580
  xd->mi_8x8 = cm->mi_grid_visible + idx_str;
  xd->prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str;

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

585
  xd->mi_8x8[0] = cm->mi + idx_str;
586

587
  mbmi = &xd->mi_8x8[0]->mbmi;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
588
589

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

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

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

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

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

  /* segment ID */
612
  if (seg->enabled) {
613
    if (cpi->oxcf.aq_mode != VARIANCE_AQ) {
614
615
616
617
      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
618
619
    vp9_mb_init_quantizer(cpi, x);

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

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

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

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

660
  // Use the lower precision, but faster, 32x32 fdct for mode selection.
661
  x->use_lp32x32fdct = 1;
662

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

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

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

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

688
  x->source_variance = get_sby_perpixel_variance(cpi, x, bsize);
689

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

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

Ronald S. Bultje's avatar
Ronald S. Bultje committed
703
  if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
704
    vp9_activity_masking(cpi, x);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
705

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

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

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

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

749
  if (!frame_is_intra_only(cm)) {
750
    const int seg_ref_active = vp9_segfeature_active(&cm->seg, mbmi->segment_id,
751
                                                     SEG_LVL_REF_FRAME);
752
753

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

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

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

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

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
798
                            PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8],
799
                            BLOCK_SIZE bsize) {
Jim Bankoski's avatar
Jim Bankoski committed
800
801
  MACROBLOCK *const x = &cpi->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
802
  int p;
Jim Bankoski's avatar
Jim Bankoski committed
803
804
  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
805
806
  int mi_width = num_8x8_blocks_wide_lookup[bsize];
  int mi_height = num_8x8_blocks_high_lookup[bsize];
807
  for (p = 0; p < MAX_MB_PLANE; p++) {
Jim Bankoski's avatar
Jim Bankoski committed
808
    vpx_memcpy(
809
        cpi->above_context[p] + ((mi_col * 2) >> xd->plane[p].subsampling_x),
Jim Bankoski's avatar
Jim Bankoski committed
810
811
812
        a + num_4x4_blocks_wide * p,
        (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
        xd->plane[p].subsampling_x);
Jim Bankoski's avatar
Jim Bankoski committed
813
    vpx_memcpy(
814
        cpi->left_context[p]
Jim Bankoski's avatar
Jim Bankoski committed
815
816
817
818
819
            + ((mi_row & MI_MASK) * 2 >> xd->plane[p].subsampling_y),
        l + num_4x4_blocks_high * p,
        (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
        xd->plane[p].subsampling_y);
  }