vp9_encodeframe.c 96.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
#include "vp9/encoder/vp9_onyx_int.h"
37
#include "vp9/encoder/vp9_pickmode.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
38
39
#include "vp9/encoder/vp9_rdopt.h"
#include "vp9/encoder/vp9_segmentation.h"
40
#include "vp9/encoder/vp9_tokenize.h"
41
42
#include "vp9/encoder/vp9_vaq.h"

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

45

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

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

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

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

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

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

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

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

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

  return act;
131
132
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  unsigned char segment;

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

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

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

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

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

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

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

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

425
426
  *mi_addr = *mi;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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
783
                            PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8],