vp9_encodeframe.c 90.7 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5
6
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
7
 *  in the file PATENTS.  All contributing project authors may
8
 *  be found in the AUTHORS file in the root of the source tree.
John Koleszar's avatar
John Koleszar committed
9
10
 */

Dmitry Kovalev's avatar
Dmitry Kovalev committed
11
12
13
14
#include <limits.h>
#include <math.h>
#include <stdio.h>

Jim Bankoski's avatar
Jim Bankoski committed
15
#include "./vp9_rtcd.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
16
17
18
19
#include "./vpx_config.h"

#include "vpx_ports/vpx_timer.h"

20
#include "vp9/common/vp9_common.h"
Yaowu Xu's avatar
Yaowu Xu committed
21
#include "vp9/common/vp9_entropy.h"
22
#include "vp9/common/vp9_entropymode.h"
23
#include "vp9/common/vp9_idct.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
24
25
26
#include "vp9/common/vp9_mvref_common.h"
#include "vp9/common/vp9_pred_common.h"
#include "vp9/common/vp9_quant_common.h"
27
#include "vp9/common/vp9_reconintra.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
28
#include "vp9/common/vp9_reconinter.h"
29
#include "vp9/common/vp9_seg_common.h"
30
#include "vp9/common/vp9_systemdependent.h"
31
#include "vp9/common/vp9_tile_common.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
32
33
34
#include "vp9/encoder/vp9_encodeframe.h"
#include "vp9/encoder/vp9_encodemb.h"
#include "vp9/encoder/vp9_encodemv.h"
35
#include "vp9/encoder/vp9_extend.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
36
37
38
#include "vp9/encoder/vp9_onyx_int.h"
#include "vp9/encoder/vp9_rdopt.h"
#include "vp9/encoder/vp9_segmentation.h"
39
#include "vp9/encoder/vp9_tokenize.h"
40
41
#include "vp9/encoder/vp9_vaq.h"

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

44

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

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

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

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

80
81
82
83
// activity_avg must be positive, or flat regions could get a zero weight
//  (infinite lambda), which confounds analysis.
// This also avoids the need for divide by zero checks in
//  vp9_activity_masking().
84
#define ACTIVITY_AVG_MIN (64)
85

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

89
90
91
92
// This is used as a reference when computing the source variance for the
//  purposes of activity masking.
// Eventually this should be replaced by custom no-reference routines,
//  which will be faster.
93
94
95
96
97
98
99
100
101
102
103
static const uint8_t VP9_VAR_OFFS[64] = {
  128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128
};

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

112
// Original activity measure from Tim T's code.
113
static unsigned int tt_activity_measure(MACROBLOCK *x) {
John Koleszar's avatar
John Koleszar committed
114
115
116
117
118
119
120
121
  unsigned int sse;
  /* TODO: This could also be done over smaller areas (8x8), but that would
   *  require extensive changes elsewhere, as lambda is assumed to be fixed
   *  over an entire MB in most of the code.
   * Another option is to compute four 8x8 variances, and pick a single
   *  lambda using a non-linear combination (e.g., the smallest, or second
   *  smallest, etc.).
   */
122
123
124
125
126
127
  unsigned int act = vp9_variance16x16(x->plane[0].src.buf,
                                       x->plane[0].src.stride,
                                       VP9_VAR_OFFS, 0, &sse) << 4;
  // If the region is flat, lower the activity some more.
  if (act < (8 << 12))
    act = MIN(act, 5 << 12);
John Koleszar's avatar
John Koleszar committed
128
129

  return act;
130
131
}

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

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

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

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

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

// Calculate an "average" mb activity value for the frame
157
#define ACT_MEDIAN 0
158
static void calc_av_activity(VP9_COMP *cpi, int64_t activity_sum) {
159
#if ACT_MEDIAN
John Koleszar's avatar
John Koleszar committed
160
161
162
163
164
165
166
167
  // Find median: Simple n^2 algorithm for experimentation
  {
    unsigned int median;
    unsigned int i, j;
    unsigned int *sortlist;
    unsigned int tmp;

    // Create a list to sort to
168
169
    CHECK_MEM_ERROR(&cpi->common, sortlist, vpx_calloc(sizeof(unsigned int),
                    cpi->common.MBs));
John Koleszar's avatar
John Koleszar committed
170
171
172

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

    // Ripple each value down to its correct position
    for (i = 1; i < cpi->common.MBs; i ++) {
      for (j = i; j > 0; j --) {
        if (sortlist[j] < sortlist[j - 1]) {
          // Swap values
          tmp = sortlist[j - 1];
          sortlist[j - 1] = sortlist[j];
          sortlist[j] = tmp;
183
184
185
        } else {
          break;
        }
John Koleszar's avatar
John Koleszar committed
186
187
      }
    }
188

John Koleszar's avatar
John Koleszar committed
189
190
    // Even number MBs so estimate median as mean of two either side.
    median = (1 + sortlist[cpi->common.MBs >> 1] +
Jim Bankoski's avatar
Jim Bankoski committed
191
        sortlist[(cpi->common.MBs >> 1) + 1]) >> 1;
192

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

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

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

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

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

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

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

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

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

John Koleszar's avatar
John Koleszar committed
231
232
233
234
235
236
  // Calculate normalized mb activity number.
  for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) {
    // for each macroblock col in image
    for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) {
      // Read activity from the map
      act = *(x->mb_activity_ptr);
237

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

350
351
352
353
// Select a segment for the current SB64
static void select_in_frame_q_segment(VP9_COMP *cpi,
                                      int mi_row, int mi_col,
                                      int output_enabled, int projected_rate) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
354
  VP9_COMMON *const cm = &cpi->common;
355
356
357
  int target_rate = cpi->rc.sb64_target_rate << 8;   // convert to bits << 8

  const int mi_offset = mi_row * cm->mi_cols + mi_col;
358
359
  const int bw = num_8x8_blocks_wide_lookup[BLOCK_64X64];
  const int bh = num_8x8_blocks_high_lookup[BLOCK_64X64];
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
  const int xmis = MIN(cm->mi_cols - mi_col, bw);
  const int ymis = MIN(cm->mi_rows - mi_row, bh);
  int complexity_metric = 64;
  int x, y;

  unsigned char segment;

  if (!output_enabled) {
    segment = 0;
  } else {
    // Rate depends on fraction of a SB64 in frame (xmis * ymis / bw * bh).
    // It is converted to bits * 256 units
    target_rate = (cpi->rc.sb64_target_rate * xmis * ymis * 256) / (bw * bh);

    if (projected_rate < (target_rate / 4)) {
      segment = 2;
    } else if (projected_rate < (target_rate / 2)) {
      segment = 1;
    } else {
      segment = 0;
    }

    complexity_metric =
      clamp((int)((projected_rate * 64) / target_rate), 16, 255);
  }

  // Fill in the entires in the segment map corresponding to this SB64
  for (y = 0; y < ymis; y++) {
    for (x = 0; x < xmis; x++) {
      cpi->segmentation_map[mi_offset + y * cm->mi_cols + x] = segment;
      cpi->complexity_map[mi_offset + y * cm->mi_cols + x] =
        (unsigned char)complexity_metric;
    }
  }
}

Jim Bankoski's avatar
Jim Bankoski committed
396
static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
397
                         BLOCK_SIZE bsize, int output_enabled) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
398
  int i, x_idx, y;
399
400
401
  VP9_COMMON *const cm = &cpi->common;
  MACROBLOCK *const x = &cpi->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
402
403
  struct macroblock_plane *const p = x->plane;
  struct macroblockd_plane *const pd = xd->plane;
John Koleszar's avatar
John Koleszar committed
404
  MODE_INFO *mi = &ctx->mic;
405
406
  MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
  MODE_INFO *mi_addr = xd->mi_8x8[0];
407

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

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

419
420
421
422
423
  // For in frame adaptive Q copy over the chosen segment id into the
  // mode innfo context for the chosen mode / partition.
  if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && output_enabled)
    mi->mbmi.segment_id = xd->mi_8x8[0]->mbmi.segment_id;

424
425
  *mi_addr = *mi;

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

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

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

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

455
456
  // FIXME(rbultje) I'm pretty sure this should go to the end of this block
  // (i.e. after the output_enabled)
457
458
  if (bsize < BLOCK_32X32) {
    if (bsize < BLOCK_16X16)
459
460
      ctx->tx_rd_diff[ALLOW_16X16] = ctx->tx_rd_diff[ALLOW_8X8];
    ctx->tx_rd_diff[ALLOW_32X32] = ctx->tx_rd_diff[ALLOW_16X16];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
461
  }
Adrian Grange's avatar
Adrian Grange committed
462

463
  if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) {
464
465
    mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
    mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
John Koleszar's avatar
John Koleszar committed
466
467
  }

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

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

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

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

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

521
522
523
    cpi->rd_comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
    cpi->rd_comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
    cpi->rd_comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
524

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

Jim Bankoski's avatar
Jim Bankoski committed
530
void vp9_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
531
532
533
534
535
                          int mi_row, int mi_col) {
  uint8_t *const buffers[4] = {src->y_buffer, src->u_buffer, src->v_buffer,
                               src->alpha_buffer};
  const int strides[4] = {src->y_stride, src->uv_stride, src->uv_stride,
                          src->alpha_stride};
536
537
  int i;

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

541
542
  for (i = 0; i < MAX_MB_PLANE; i++)
    setup_pred_plane(&x->plane[i].src, buffers[i], strides[i], mi_row, mi_col,
Jim Bankoski's avatar
Jim Bankoski committed
543
                     NULL, x->e_mbd.plane[i].subsampling_x,
544
                     x->e_mbd.plane[i].subsampling_y);
John Koleszar's avatar
John Koleszar committed
545
546
}

James Zern's avatar
James Zern committed
547
548
static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile,
                        int mi_row, int mi_col, BLOCK_SIZE bsize) {
549
550
551
  MACROBLOCK *const x = &cpi->mb;
  VP9_COMMON *const cm = &cpi->common;
  MACROBLOCKD *const xd = &x->e_mbd;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
552
  MB_MODE_INFO *mbmi;
553
  const int idx_str = xd->mode_info_stride * mi_row + mi_col;
Jim Bankoski's avatar
Jim Bankoski committed
554
555
  const int mi_width = num_8x8_blocks_wide_lookup[bsize];
  const int mi_height = num_8x8_blocks_high_lookup[bsize];
Jingning Han's avatar
Jingning Han committed
556
557
  const int mb_row = mi_row >> 1;
  const int mb_col = mi_col >> 1;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
558
  const int idx_map = mb_row * cm->mb_cols + mb_col;
559
  const struct segmentation *const seg = &cm->seg;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
560

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

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

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

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

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

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

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

Yaowu Xu's avatar
Yaowu Xu committed
581
582
  // Set up limit values for MV components
  // mv beyond the range do not produce new/different prediction block
583
584
  x->mv_row_min = -(((mi_row + mi_height) * MI_SIZE) + VP9_INTERP_EXTEND);
  x->mv_col_min = -(((mi_col + mi_width) * MI_SIZE) + VP9_INTERP_EXTEND);
Yaowu Xu's avatar
Yaowu Xu committed
585
586
  x->mv_row_max = (cm->mi_rows - mi_row) * MI_SIZE + VP9_INTERP_EXTEND;
  x->mv_col_max = (cm->mi_cols - mi_col) * MI_SIZE + VP9_INTERP_EXTEND;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
587
588

  // Set up distance of MB to edge of frame in 1/8th pel units
Jim Bankoski's avatar
Jim Bankoski committed
589
  assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
James Zern's avatar
James Zern committed
590
591
  set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width,
                 cm->mi_rows, cm->mi_cols);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
592
593

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

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

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

609
610
611
    if (seg->enabled && cpi->seg0_cnt > 0 &&
        !vp9_segfeature_active(seg, 0, SEG_LVL_REF_FRAME) &&
        vp9_segfeature_active(seg, 1, SEG_LVL_REF_FRAME)) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
612
613
614
615
      cpi->seg0_progress = (cpi->seg0_idx << 16) / cpi->seg0_cnt;
    } else {
      const int y = mb_row & ~3;
      const int x = mb_col & ~3;
Jim Bankoski's avatar
Jim Bankoski committed
616
      const int p16 = ((mb_row & 1) << 1) + (mb_col & 1);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
617
      const int p32 = ((mb_row & 2) << 2) + ((mb_col & 2) << 1);
James Zern's avatar
James Zern committed
618
619
      const int tile_progress = tile->mi_col_start * cm->mb_rows >> 1;
      const int mb_cols = (tile->mi_col_end - tile->mi_col_start) >> 1;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
620

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

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

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

  vp9_clear_system_state();  // __asm emms;
  rdmult_ratio = 1.0;  // avoid uninitialized warnings
Ronald S. Bultje's avatar
Ronald S. Bultje committed
648

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

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

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

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

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

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

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

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

690
  if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
691
692
    vp9_clear_system_state();  // __asm emms;
    x->rdmult = round(x->rdmult * rdmult_ratio);
693
694
695
696
697
698
699
700
  } else if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
    const int mi_offset = mi_row * cm->mi_cols + mi_col;
    unsigned char complexity = cpi->complexity_map[mi_offset];
    const int is_edge = (mi_row == 0) || (mi_row == (cm->mi_rows - 1)) ||
                        (mi_col == 0) || (mi_col == (cm->mi_cols - 1));

    if (!is_edge && (complexity > 128))
      x->rdmult = x->rdmult  + ((x->rdmult * (complexity - 128)) / 256);
701
  }
702

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

717
  if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
718
719
720
721
722
723
    x->rdmult = orig_rdmult;
    if (*totalrate != INT_MAX) {
      vp9_clear_system_state();  // __asm emms;
      *totalrate = round(*totalrate * rdmult_ratio);
    }
  }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
724
}
Adrian Grange's avatar
Adrian Grange committed
725

726
727
728
729
static void update_stats(VP9_COMP *cpi) {
  VP9_COMMON *const cm = &cpi->common;
  MACROBLOCK *const x = &cpi->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
730
  MODE_INFO *mi = xd->mi_8x8[0];
731
  MB_MODE_INFO *const mbmi = &mi->mbmi;
Adrian Grange's avatar
Adrian Grange committed
732

733
  if (!frame_is_intra_only(cm)) {
734
    const int seg_ref_active = vp9_segfeature_active(&cm->seg, mbmi->segment_id,
735
                                                     SEG_LVL_REF_FRAME);
736
737

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

741
742
743
    // 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
744
    if (is_inter_block(mbmi) && !seg_ref_active) {
745
      if (cm->reference_mode == REFERENCE_MODE_SELECT)
746
        cm->counts.comp_inter[vp9_get_reference_mode_context(cm, xd)]
Dmitry Kovalev's avatar
Dmitry Kovalev committed
747
                             [has_second_ref(mbmi)]++;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
748

Dmitry Kovalev's avatar
Dmitry Kovalev committed
749
      if (has_second_ref(mbmi)) {
750
        cm->counts.comp_ref[vp9_get_pred_context_comp_ref_p(cm, xd)]
Dmitry Kovalev's avatar
Dmitry Kovalev committed
751
                           [mbmi->ref_frame[0] == GOLDEN_FRAME]++;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
752
      } else {
753
        cm->counts.single_ref[vp9_get_pred_context_single_ref_p1(xd)][0]
Dmitry Kovalev's avatar
Dmitry Kovalev committed
754
                             [mbmi->ref_frame[0] != LAST_FRAME]++;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
755
        if (mbmi->ref_frame[0] != LAST_FRAME)
756
          cm->counts.single_ref[vp9_get_pred_context_single_ref_p2(xd)][1]
Dmitry Kovalev's avatar
Dmitry Kovalev committed
757
                               [mbmi->ref_frame[0] != GOLDEN_FRAME]++;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
758
      }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
759
    }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
760
761
  }
}
John Koleszar's avatar
John Koleszar committed
762

763
static BLOCK_SIZE *get_sb_partitioning(MACROBLOCK *x, BLOCK_SIZE bsize) {
764
  switch (bsize) {
765
    case BLOCK_64X64:
766
      return &x->sb64_partitioning;
767
    case BLOCK_32X32:
768
      return &x->sb_partitioning[x->sb_index];
769
    case BLOCK_16X16:
770
      return &x->mb_partitioning[x->sb_index][x->mb_index];
771
    case BLOCK_8X8:
772
      return &x->b_partitioning[x->sb_index][x->mb_index][x->b_index];
773
774
    default:
      assert(0);
775
      return NULL;
776
777
778
779
780
781
  }
}

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
782
                            PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8],
783
                            BLOCK_SIZE bsize) {
Jim Bankoski's avatar
Jim Bankoski committed
784
785
  MACROBLOCK *const x = &cpi->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
786
  int p;
Jim Bankoski's avatar
Jim Bankoski committed
787
788
  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
789
790
  int mi_width = num_8x8_blocks_wide_lookup[bsize];
  int mi_height = num_8x8_blocks_high_lookup[bsize];
791
  for (p = 0; p < MAX_MB_PLANE; p++) {
Jim Bankoski's avatar
Jim Bankoski committed
792
    vpx_memcpy(
793
        cpi->above_context[p] + ((mi_col * 2) >> xd->plane[p].subsampling_x),
Jim Bankoski's avatar
Jim Bankoski committed
794
795
796
        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
797
    vpx_memcpy(
798
        cpi->left_context[p]
Jim Bankoski's avatar
Jim Bankoski committed
799
800
801
802
803
            + ((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);
  }
804
805
806
807
  vpx_memcpy(cpi->above_seg_context + mi_col, sa,
             sizeof(*cpi->above_seg_context) * mi_width);
  vpx_memcpy(cpi->left_seg_context + (mi_row & MI_MASK), sl,
             sizeof(cpi->left_seg_context[0]) * mi_height);
808
}
Jim Bankoski's avatar
Jim Bankoski committed
809
static void save_context(VP9_COMP *cpi, int mi_row, int mi_col,
Jim Bankoski's avatar
Jim Bankoski committed
810
811
812
                         ENTROPY_CONTEXT a[16 * MAX_MB_PLANE],
                         ENTROPY_CONTEXT l[16 * MAX_MB_PLANE],
                         PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8],