vp9_encodeframe.c 90.3 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
 */

11
#include "./vpx_config.h"
Jim Bankoski's avatar
Jim Bankoski committed
12
#include "./vp9_rtcd.h"
13
#include "vp9/encoder/vp9_encodeframe.h"
14
15
#include "vp9/encoder/vp9_encodemb.h"
#include "vp9/encoder/vp9_encodemv.h"
16
#include "vp9/common/vp9_common.h"
17
#include "vp9/encoder/vp9_onyx_int.h"
18
#include "vp9/common/vp9_extend.h"
Yaowu Xu's avatar
Yaowu Xu committed
19
#include "vp9/common/vp9_entropy.h"
20
21
#include "vp9/common/vp9_entropymode.h"
#include "vp9/common/vp9_quant_common.h"
22
23
#include "vp9/encoder/vp9_segmentation.h"
#include "vp9/encoder/vp9_encodeintra.h"
24
#include "vp9/common/vp9_reconinter.h"
25
#include "vp9/encoder/vp9_rdopt.h"
26
27
28
#include "vp9/common/vp9_findnearmv.h"
#include "vp9/common/vp9_reconintra.h"
#include "vp9/common/vp9_seg_common.h"
29
#include "vp9/common/vp9_tile_common.h"
30
#include "vp9/encoder/vp9_tokenize.h"
Yaowu Xu's avatar
Yaowu Xu committed
31
#include "./vp9_rtcd.h"
John Koleszar's avatar
John Koleszar committed
32
#include <stdio.h>
33
#include <math.h>
John Koleszar's avatar
John Koleszar committed
34
35
#include <limits.h>
#include "vpx_ports/vpx_timer.h"
36
37
#include "vp9/common/vp9_pred_common.h"
#include "vp9/common/vp9_mvref_common.h"
Paul Wilkins's avatar
Paul Wilkins committed
38

Yaowu Xu's avatar
Yaowu Xu committed
39
#define DBG_PRNT_SEGMAP 0
40

41
// #define ENC_DEBUG
42
#ifdef ENC_DEBUG
John Koleszar's avatar
John Koleszar committed
43
int enc_debug = 0;
44
45
#endif

Jim Bankoski's avatar
Jim Bankoski committed
46
47
static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
                              int mi_row, int mi_col, BLOCK_SIZE_TYPE bsize);
48

49
static void adjust_act_zbin(VP9_COMP *cpi, MACROBLOCK *x);
50

51
52
53
/* 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
54
 *  vp9_activity_masking().
55
 */
56
#define VP9_ACTIVITY_AVG_MIN (64)
57
58
59
60
61
62

/* 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.
 */
Jim Bankoski's avatar
Jim Bankoski committed
63
64
static const uint8_t VP9_VAR_OFFS[16] = {128, 128, 128, 128, 128, 128, 128, 128,
    128, 128, 128, 128, 128, 128, 128, 128};
65
66

// Original activity measure from Tim T's code.
67
static unsigned int tt_activity_measure(VP9_COMP *cpi, MACROBLOCK *x) {
John Koleszar's avatar
John Koleszar committed
68
69
70
71
72
73
74
75
76
  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
77
78
  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
79
  act <<= 4;
John Koleszar's avatar
John Koleszar committed
80
81
82
83
84
85

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

  return act;
86
87
}

88
// Stub for alternative experimental activity measures.
Jim Bankoski's avatar
Jim Bankoski committed
89
90
static unsigned int alt_activity_measure(VP9_COMP *cpi, MACROBLOCK *x,
                                         int use_dc_pred) {
91
  return vp9_encode_intra(cpi, x, use_dc_pred);
92
}
Jim Bankoski's avatar
Jim Bankoski committed
93
DECLARE_ALIGNED(16, static const uint8_t, vp9_64x64_zeros[64*64]) = {0};
94
95
96

// Measure the activity of the current macroblock
// What we measure here is TBD so abstracted to this function
97
#define ALT_ACT_MEASURE 1
98
static unsigned int mb_activity_measure(VP9_COMP *cpi, MACROBLOCK *x,
John Koleszar's avatar
John Koleszar committed
99
100
                                        int mb_row, int mb_col) {
  unsigned int mb_activity;
101

John Koleszar's avatar
John Koleszar committed
102
103
  if (ALT_ACT_MEASURE) {
    int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);
104

John Koleszar's avatar
John Koleszar committed
105
106
107
108
109
110
    // Or use and alternative.
    mb_activity = alt_activity_measure(cpi, x, use_dc_pred);
  } else {
    // Original activity measure from Tim T's code.
    mb_activity = tt_activity_measure(cpi, x);
  }
111

112
113
  if (mb_activity < VP9_ACTIVITY_AVG_MIN)
    mb_activity = VP9_ACTIVITY_AVG_MIN;
114

John Koleszar's avatar
John Koleszar committed
115
  return mb_activity;
116
117
118
}

// Calculate an "average" mb activity value for the frame
119
#define ACT_MEDIAN 0
120
static void calc_av_activity(VP9_COMP *cpi, int64_t activity_sum) {
121
#if ACT_MEDIAN
John Koleszar's avatar
John Koleszar committed
122
123
124
125
126
127
128
129
  // 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
130
131
    CHECK_MEM_ERROR(&cpi->common, sortlist, vpx_calloc(sizeof(unsigned int),
                    cpi->common.MBs));
John Koleszar's avatar
John Koleszar committed
132
133
134

    // Copy map to sort list
    vpx_memcpy(sortlist, cpi->mb_activity_map,
Jim Bankoski's avatar
Jim Bankoski committed
135
        sizeof(unsigned int) * cpi->common.MBs);
John Koleszar's avatar
John Koleszar committed
136
137
138
139
140
141
142
143
144
145

    // 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;
        } else
Jim Bankoski's avatar
Jim Bankoski committed
146
        break;
John Koleszar's avatar
John Koleszar committed
147
148
      }
    }
149

John Koleszar's avatar
John Koleszar committed
150
151
    // 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
152
        sortlist[(cpi->common.MBs >> 1) + 1]) >> 1;
153

John Koleszar's avatar
John Koleszar committed
154
    cpi->activity_avg = median;
155

John Koleszar's avatar
John Koleszar committed
156
157
    vpx_free(sortlist);
  }
158
#else
John Koleszar's avatar
John Koleszar committed
159
  // Simple mean for now
Jim Bankoski's avatar
Jim Bankoski committed
160
  cpi->activity_avg = (unsigned int) (activity_sum / cpi->common.MBs);
161
162
#endif

163
164
  if (cpi->activity_avg < VP9_ACTIVITY_AVG_MIN)
    cpi->activity_avg = VP9_ACTIVITY_AVG_MIN;
165

John Koleszar's avatar
John Koleszar committed
166
167
168
  // Experimental code: return fixed value normalized for several clips
  if (ALT_ACT_MEASURE)
    cpi->activity_avg = 100000;
169
170
}

171
#define USE_ACT_INDEX   0
172
#define OUTPUT_NORM_ACT_STATS   0
173
174

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

John Koleszar's avatar
John Koleszar committed
180
181
182
  int64_t act;
  int64_t a;
  int64_t b;
183
184

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

John Koleszar's avatar
John Koleszar committed
189
190
  // Reset pointers to start of activity map
  x->mb_activity_ptr = cpi->mb_activity_map;
191

John Koleszar's avatar
John Koleszar committed
192
193
194
195
196
197
  // 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);
198

John Koleszar's avatar
John Koleszar committed
199
200
201
      // Calculate a normalized activity number
      a = act + 4 * cpi->activity_avg;
      b = 4 * act + cpi->activity_avg;
202

John Koleszar's avatar
John Koleszar committed
203
      if (b >= a)
Jim Bankoski's avatar
Jim Bankoski committed
204
      *(x->activity_ptr) = (int)((b + (a >> 1)) / a) - 1;
John Koleszar's avatar
John Koleszar committed
205
      else
Jim Bankoski's avatar
Jim Bankoski committed
206
      *(x->activity_ptr) = 1 - (int)((a + (b >> 1)) / b);
207
208

#if OUTPUT_NORM_ACT_STATS
John Koleszar's avatar
John Koleszar committed
209
      fprintf(f, " %6d", *(x->mb_activity_ptr));
210
#endif
John Koleszar's avatar
John Koleszar committed
211
212
213
      // Increment activity map pointers
      x->mb_activity_ptr++;
    }
214
215

#if OUTPUT_NORM_ACT_STATS
John Koleszar's avatar
John Koleszar committed
216
    fprintf(f, "\n");
217
218
#endif

John Koleszar's avatar
John Koleszar committed
219
  }
220
221

#if OUTPUT_NORM_ACT_STATS
John Koleszar's avatar
John Koleszar committed
222
  fclose(f);
223
224
225
#endif

}
226
#endif
227
228
229

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

235
#if ALT_ACT_MEASURE
John Koleszar's avatar
John Koleszar committed
236
237
238
  YV12_BUFFER_CONFIG *new_yv12 = &cm->yv12_fb[cm->new_fb_idx];
  int recon_yoffset;
  int recon_y_stride = new_yv12->y_stride;
239
240
#endif

John Koleszar's avatar
John Koleszar committed
241
242
243
  int mb_row, mb_col;
  unsigned int mb_activity;
  int64_t activity_sum = 0;
244

245
246
  x->mb_activity_ptr = cpi->mb_activity_map;

John Koleszar's avatar
John Koleszar committed
247
248
  // for each macroblock row in image
  for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) {
249
#if ALT_ACT_MEASURE
John Koleszar's avatar
John Koleszar committed
250
251
252
    // reset above block coeffs
    xd->up_available = (mb_row != 0);
    recon_yoffset = (mb_row * recon_y_stride * 16);
253
#endif
John Koleszar's avatar
John Koleszar committed
254
255
    // for each macroblock col in image
    for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) {
256
#if ALT_ACT_MEASURE
257
      xd->plane[0].dst.buf = new_yv12->y_buffer + recon_yoffset;
John Koleszar's avatar
John Koleszar committed
258
259
      xd->left_available = (mb_col != 0);
      recon_yoffset += 16;
260
#endif
261

John Koleszar's avatar
John Koleszar committed
262
263
      // measure activity
      mb_activity = mb_activity_measure(cpi, x, mb_row, mb_col);
264

John Koleszar's avatar
John Koleszar committed
265
266
      // Keep frame sum
      activity_sum += mb_activity;
267

John Koleszar's avatar
John Koleszar committed
268
269
      // Store MB level activity details.
      *x->mb_activity_ptr = mb_activity;
270

John Koleszar's avatar
John Koleszar committed
271
272
      // Increment activity map pointer
      x->mb_activity_ptr++;
273

John Koleszar's avatar
John Koleszar committed
274
      // adjust to the next column of source macroblocks
John Koleszar's avatar
John Koleszar committed
275
      x->plane[0].src.buf += 16;
John Koleszar's avatar
John Koleszar committed
276
    }
277

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

John Koleszar's avatar
John Koleszar committed
282
283
  // Calculate an "average" MB activity
  calc_av_activity(cpi, activity_sum);
284

285
#if USE_ACT_INDEX
John Koleszar's avatar
John Koleszar committed
286
287
  // Calculate an activity index number of each mb
  calc_activity_index(cpi, x);
288
289
#endif

290
291
}

292
// Macroblock activity masking
293
void vp9_activity_masking(VP9_COMP *cpi, MACROBLOCK *x) {
294
#if USE_ACT_INDEX
John Koleszar's avatar
John Koleszar committed
295
296
297
  x->rdmult += *(x->mb_activity_ptr) * (x->rdmult >> 2);
  x->errorperbit = x->rdmult * 100 / (110 * x->rddiv);
  x->errorperbit += (x->errorperbit == 0);
298
#else
John Koleszar's avatar
John Koleszar committed
299
300
301
  int64_t a;
  int64_t b;
  int64_t act = *(x->mb_activity_ptr);
302

John Koleszar's avatar
John Koleszar committed
303
304
305
  // Apply the masking to the RD multiplier.
  a = act + (2 * cpi->activity_avg);
  b = (2 * act) + cpi->activity_avg;
306

Jim Bankoski's avatar
Jim Bankoski committed
307
  x->rdmult = (unsigned int) (((int64_t) x->rdmult * b + (a >> 1)) / a);
John Koleszar's avatar
John Koleszar committed
308
309
  x->errorperbit = x->rdmult * 100 / (110 * x->rddiv);
  x->errorperbit += (x->errorperbit == 0);
310
#endif
311

John Koleszar's avatar
John Koleszar committed
312
313
  // Activity based Zbin adjustment
  adjust_act_zbin(cpi, x);
314
}
John Koleszar's avatar
John Koleszar committed
315

Jim Bankoski's avatar
Jim Bankoski committed
316
317
static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
                         BLOCK_SIZE_TYPE bsize, int output_enabled) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
318
  int i, x_idx, y;
Jim Bankoski's avatar
Jim Bankoski committed
319
320
  MACROBLOCK * const x = &cpi->mb;
  MACROBLOCKD * const xd = &x->e_mbd;
John Koleszar's avatar
John Koleszar committed
321
  MODE_INFO *mi = &ctx->mic;
Jim Bankoski's avatar
Jim Bankoski committed
322
  MB_MODE_INFO * const mbmi = &xd->mode_info_context->mbmi;
323

John Koleszar's avatar
John Koleszar committed
324
  int mb_mode_index = ctx->best_mode_index;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
325
  const int mis = cpi->common.mode_info_stride;
Jim Bankoski's avatar
Jim Bankoski committed
326
327
  const int mi_height = num_8x8_blocks_high_lookup[bsize];
  const int mi_width = num_8x8_blocks_wide_lookup[bsize];
Adrian Grange's avatar
Adrian Grange committed
328

329
  assert(mi->mbmi.mode < MB_MODE_COUNT);
John Koleszar's avatar
John Koleszar committed
330
  assert(mb_mode_index < MAX_MODES);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
331
332
  assert(mi->mbmi.ref_frame[0] < MAX_REF_FRAMES);
  assert(mi->mbmi.ref_frame[1] < MAX_REF_FRAMES);
333
  assert(mi->mbmi.sb_type == bsize);
334

John Koleszar's avatar
John Koleszar committed
335
336
  // Restore the coding context of the MB to that that was in place
  // when the mode was picked for it
Jim Bankoski's avatar
Jim Bankoski committed
337
338
339
340
  for (y = 0; y < mi_height; y++) {
    for (x_idx = 0; x_idx < mi_width; x_idx++) {
      if ((xd->mb_to_right_edge >> (3 + LOG2_MI_SIZE)) + mi_width > x_idx
          && (xd->mb_to_bottom_edge >> (3 + LOG2_MI_SIZE)) + mi_height > y) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
341
        MODE_INFO *mi_addr = xd->mode_info_context + x_idx + y * mis;
342
        *mi_addr = *mi;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
343
      }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
344
    }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
345
  }
346
347
  // FIXME(rbultje) I'm pretty sure this should go to the end of this block
  // (i.e. after the output_enabled)
348
  if (bsize < BLOCK_SIZE_SB32X32) {
349
350
    if (bsize < BLOCK_SIZE_MB16X16)
      ctx->txfm_rd_diff[ALLOW_16X16] = ctx->txfm_rd_diff[ALLOW_8X8];
351
    ctx->txfm_rd_diff[ALLOW_32X32] = ctx->txfm_rd_diff[ALLOW_16X16];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
352
  }
Adrian Grange's avatar
Adrian Grange committed
353

Ronald S. Bultje's avatar
Ronald S. Bultje committed
354
  if (mbmi->ref_frame[0] != INTRA_FRAME && mbmi->sb_type < BLOCK_SIZE_SB8X8) {
355
    *x->partition_info = ctx->partition_info;
356
357
    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
358
359
  }

360
  x->skip = ctx->skip;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
361
362
363
  if (!output_enabled)
    return;

364
  if (!vp9_segfeature_active(&xd->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
365
366
    for (i = 0; i < NB_TXFM_MODES; i++) {
      cpi->rd_tx_select_diff[i] += ctx->txfm_rd_diff[i];
367
    }
368
369
  }

John Koleszar's avatar
John Koleszar committed
370
371
  if (cpi->common.frame_type == KEY_FRAME) {
    // Restore the coding modes to that held in the coding context
Yaowu Xu's avatar
Yaowu Xu committed
372
    // if (mb_mode == I4X4_PRED)
John Koleszar's avatar
John Koleszar committed
373
374
375
376
377
378
    //    for (i = 0; i < 16; i++)
    //    {
    //        xd->block[i].bmi.as_mode =
    //                          xd->mode_info_context->bmi[i].as_mode;
    //        assert(xd->mode_info_context->bmi[i].as_mode < MB_MODE_COUNT);
    //    }
379
#if CONFIG_INTERNAL_STATS
John Koleszar's avatar
John Koleszar committed
380
381
382
383
384
385
386
387
388
389
390
    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*/,
      THR_D27_PRED /*D27_PRED*/,
      THR_D63_PRED /*D63_PRED*/,
      THR_TM /*TM_PRED*/,
Yaowu Xu's avatar
Yaowu Xu committed
391
      THR_B_PRED /*I4X4_PRED*/,
John Koleszar's avatar
John Koleszar committed
392
    };
393
    cpi->mode_chosen_counts[kf_mode_index[mi->mbmi.mode]]++;
394
#endif
John Koleszar's avatar
John Koleszar committed
395
396
397
  } else {
    // Note how often each mode chosen as best
    cpi->mode_chosen_counts[mb_mode_index]++;
Jim Bankoski's avatar
Jim Bankoski committed
398
399
    if (mbmi->ref_frame[0] != INTRA_FRAME
        && (mbmi->sb_type < BLOCK_SIZE_SB8X8 || mbmi->mode == NEWMV)) {
Deb Mukherjee's avatar
Deb Mukherjee committed
400
      int_mv best_mv, best_second_mv;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
401
402
      const MV_REFERENCE_FRAME rf1 = mbmi->ref_frame[0];
      const MV_REFERENCE_FRAME rf2 = mbmi->ref_frame[1];
Deb Mukherjee's avatar
Deb Mukherjee committed
403
404
405
      best_mv.as_int = ctx->best_ref_mv.as_int;
      best_second_mv.as_int = ctx->second_best_ref_mv.as_int;
      if (mbmi->mode == NEWMV) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
406
407
        best_mv.as_int = mbmi->ref_mvs[rf1][0].as_int;
        best_second_mv.as_int = mbmi->ref_mvs[rf2][0].as_int;
Deb Mukherjee's avatar
Deb Mukherjee committed
408
409
410
411
      }
      mbmi->best_mv.as_int = best_mv.as_int;
      mbmi->best_second_mv.as_int = best_second_mv.as_int;
      vp9_update_nmv_count(cpi, x, &best_mv, &best_second_mv);
412
    }
Jingning Han's avatar
Jingning Han committed
413

414
415
    if (bsize > BLOCK_SIZE_SB8X8 && mbmi->mode == NEWMV) {
      int i, j;
Jim Bankoski's avatar
Jim Bankoski committed
416
417
418
419
      for (j = 0; j < mi_height; ++j)
        for (i = 0; i < mi_width; ++i)
          if ((xd->mb_to_right_edge >> (3 + LOG2_MI_SIZE)) + mi_width > i
              && (xd->mb_to_bottom_edge >> (3 + LOG2_MI_SIZE)) + mi_height > j)
420
            xd->mode_info_context[mis * j + i].mbmi = *mbmi;
Deb Mukherjee's avatar
Deb Mukherjee committed
421
    }
422

Jim Bankoski's avatar
Jim Bankoski committed
423
424
    if (cpi->common.mcomp_filter_type == SWITCHABLE
        && is_inter_mode(mbmi->mode)) {
425
      ++cpi->common.counts.switchable_interp[
426
          vp9_get_pred_context_switchable_interp(xd)]
427
            [vp9_switchable_interp_map[mbmi->interp_filter]];
428
    }
Adrian Grange's avatar
Adrian Grange committed
429

430
    cpi->rd_comp_pred_diff[SINGLE_PREDICTION_ONLY] += ctx->single_pred_diff;
Jim Bankoski's avatar
Jim Bankoski committed
431
432
    cpi->rd_comp_pred_diff[COMP_PREDICTION_ONLY] += ctx->comp_pred_diff;
    cpi->rd_comp_pred_diff[HYBRID_PREDICTION] += ctx->hybrid_pred_diff;
433
434
435
436

    for (i = 0; i <= VP9_SWITCHABLE_FILTERS; i++) {
      cpi->rd_filter_diff[i] += ctx->best_filter_diff[i];
    }
John Koleszar's avatar
John Koleszar committed
437
  }
Adrian Grange's avatar
Adrian Grange committed
438
439
}

Jim Bankoski's avatar
Jim Bankoski committed
440
void vp9_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
John Koleszar's avatar
John Koleszar committed
441
                          int mb_row, int mb_col) {
Jim Bankoski's avatar
Jim Bankoski committed
442
443
444
445
  uint8_t *buffers[4] = {src->y_buffer, src->u_buffer, src->v_buffer, src
      ->alpha_buffer};
  int strides[4] = {src->y_stride, src->uv_stride, src->uv_stride, src
      ->alpha_stride};
446
447
448
  int i;

  for (i = 0; i < MAX_MB_PLANE; i++) {
Jim Bankoski's avatar
Jim Bankoski committed
449
450
    setup_pred_plane(&x->plane[i].src, buffers[i], strides[i], mb_row, mb_col,
                     NULL, x->e_mbd.plane[i].subsampling_x,
451
452
                     x->e_mbd.plane[i].subsampling_y);
  }
John Koleszar's avatar
John Koleszar committed
453
454
}

Jim Bankoski's avatar
Jim Bankoski committed
455
456
457
458
459
static void set_offsets(VP9_COMP *cpi, int mi_row, int mi_col,
                        BLOCK_SIZE_TYPE bsize) {
  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
460
461
  MB_MODE_INFO *mbmi;
  const int dst_fb_idx = cm->new_fb_idx;
462
  const int idx_str = xd->mode_info_stride * mi_row + mi_col;
Jim Bankoski's avatar
Jim Bankoski committed
463
464
  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
465
466
  const int mb_row = mi_row >> 1;
  const int mb_col = mi_col >> 1;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
467
  const int idx_map = mb_row * cm->mb_cols + mb_col;
468
  int i;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
469
470

  // entropy context structures
471
  for (i = 0; i < MAX_MB_PLANE; i++) {
Jim Bankoski's avatar
Jim Bankoski committed
472
473
474
475
    xd->plane[i].above_context = cm->above_context[i]
        + (mi_col * 2 >> xd->plane[i].subsampling_x);
    xd->plane[i].left_context = cm->left_context[i]
        + (((mi_row * 2) & 15) >> xd->plane[i].subsampling_y);
476
  }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
477

478
  // partition contexts
479
  set_partition_seg_context(cm, xd, mi_row, mi_col);
480

Ronald S. Bultje's avatar
Ronald S. Bultje committed
481
482
483
484
485
  // Activity map pointer
  x->mb_activity_ptr = &cpi->mb_activity_map[idx_map];
  x->active_ptr = cpi->active_map + idx_map;

  /* pointers to mode info contexts */
Jim Bankoski's avatar
Jim Bankoski committed
486
487
  x->partition_info = x->pi + idx_str;
  xd->mode_info_context = cm->mi + idx_str;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
488
  mbmi = &xd->mode_info_context->mbmi;
489
490
  // Special case: if prev_mi is NULL, the previous mode info context
  // cannot be used.
Jim Bankoski's avatar
Jim Bankoski committed
491
  xd->prev_mode_info_context = cm->prev_mi ? cm->prev_mi + idx_str : NULL;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
492
493

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

  /* Set up limit values for MV components to prevent them from
   * extending beyond the UMV borders assuming 16x16 block size */
Jim Bankoski's avatar
Jim Bankoski committed
498
499
500
  x->mv_row_min = -((mi_row * MI_SIZE)+ VP9BORDERINPIXELS - VP9_INTERP_EXTEND);
  x->mv_col_min = -((mi_col * MI_SIZE)+ VP9BORDERINPIXELS - VP9_INTERP_EXTEND);
  x->mv_row_max = ((cm->mi_rows - mi_row) * MI_SIZE
Jim Bankoski's avatar
Jim Bankoski committed
501
      + (VP9BORDERINPIXELS - MI_SIZE * mi_height - VP9_INTERP_EXTEND));
Jim Bankoski's avatar
Jim Bankoski committed
502
  x->mv_col_max = ((cm->mi_cols - mi_col) * MI_SIZE
Jim Bankoski's avatar
Jim Bankoski committed
503
      + (VP9BORDERINPIXELS - MI_SIZE * mi_width - VP9_INTERP_EXTEND));
Ronald S. Bultje's avatar
Ronald S. Bultje committed
504
505

  // Set up distance of MB to edge of frame in 1/8th pel units
Jim Bankoski's avatar
Jim Bankoski committed
506
507
  assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
  set_mi_row_col(cm, xd, mi_row, mi_height, mi_col, mi_width);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
508
509

  /* set up source buffers */
510
  vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
511
512
513
514
515
516

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

  /* segment ID */
517
518
519
  if (xd->seg.enabled) {
    uint8_t *map = xd->seg.update_map ? cpi->segmentation_map
                                      : cm->last_frame_seg_map;
520
    mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
521

Ronald S. Bultje's avatar
Ronald S. Bultje committed
522
523
    vp9_mb_init_quantizer(cpi, x);

524
525
526
    if (xd->seg.enabled && cpi->seg0_cnt > 0
        && !vp9_segfeature_active(&xd->seg, 0, SEG_LVL_REF_FRAME)
        && vp9_segfeature_active(&xd->seg, 1, SEG_LVL_REF_FRAME)) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
527
528
529
530
      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
531
      const int p16 = ((mb_row & 1) << 1) + (mb_col & 1);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
532
      const int p32 = ((mb_row & 2) << 2) + ((mb_col & 2) << 1);
Jim Bankoski's avatar
Jim Bankoski committed
533
534
535
      const int tile_progress = cm->cur_tile_mi_col_start * cm->mb_rows >> 1;
      const int mb_cols = (cm->cur_tile_mi_col_end - cm->cur_tile_mi_col_start)
          >> 1;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
536

Jim Bankoski's avatar
Jim Bankoski committed
537
538
      cpi->seg0_progress = ((y * mb_cols + x * 4 + p32 + p16 + tile_progress)
          << 16) / cm->MBs;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
539
    }
540
541

    x->encode_breakout = cpi->segment_encode_breakout[mbmi->segment_id];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
542
543
  } else {
    mbmi->segment_id = 0;
544
    x->encode_breakout = cpi->oxcf.encode_breakout;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
545
546
547
  }
}

548
static void pick_sb_modes(VP9_COMP *cpi, int mi_row, int mi_col,
549
                          int *totalrate, int64_t *totaldist,
550
551
                          BLOCK_SIZE_TYPE bsize, PICK_MODE_CONTEXT *ctx,
                          int64_t best_rd) {
552
553
554
  VP9_COMMON *const cm = &cpi->common;
  MACROBLOCK *const x = &cpi->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
555

556
557
  x->rd_search = 1;

558
559
560
561
  if (bsize < BLOCK_SIZE_SB8X8)
    if (xd->ab_index != 0)
      return;

562
  set_offsets(cpi, mi_row, mi_col, bsize);
563
  xd->mode_info_context->mbmi.sb_type = bsize;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
564
  if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
565
    vp9_activity_masking(cpi, x);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
566

567
568
569
  // Find best coding mode & reconstruct the MB so it is available
  // as a predictor for MBs that follow in the SB
  if (cm->frame_type == KEY_FRAME)
570
571
    vp9_rd_pick_intra_mode_sb(cpi, x, totalrate, totaldist, bsize, ctx,
                              best_rd);
572
  else
573
    vp9_rd_pick_inter_mode_sb(cpi, x, mi_row, mi_col, totalrate, totaldist,
574
                              bsize, ctx, best_rd);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
575
}
Adrian Grange's avatar
Adrian Grange committed
576

577
static void update_stats(VP9_COMP *cpi, int mi_row, int mi_col) {
Jim Bankoski's avatar
Jim Bankoski committed
578
579
580
  VP9_COMMON * const cm = &cpi->common;
  MACROBLOCK * const x = &cpi->mb;
  MACROBLOCKD * const xd = &x->e_mbd;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
581
  MODE_INFO *mi = xd->mode_info_context;
Jim Bankoski's avatar
Jim Bankoski committed
582
  MB_MODE_INFO * const mbmi = &mi->mbmi;
Adrian Grange's avatar
Adrian Grange committed
583

Paul Wilkins's avatar
Paul Wilkins committed
584
  if (cm->frame_type != KEY_FRAME) {
585
586
    const int seg_ref_active = vp9_segfeature_active(&xd->seg, mbmi->segment_id,
                                                     SEG_LVL_REF_FRAME);
587
588

    if (!seg_ref_active)
589
      cpi->intra_inter_count[vp9_get_pred_context_intra_inter(xd)][mbmi
Jim Bankoski's avatar
Jim Bankoski committed
590
          ->ref_frame[0] > INTRA_FRAME]++;
Adrian Grange's avatar
Adrian Grange committed
591

592
593
594
595
    // 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.
    if ((mbmi->ref_frame[0] > INTRA_FRAME) && !seg_ref_active) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
596
      if (cm->comp_pred_mode == HYBRID_PREDICTION)
597
598
        cpi->comp_inter_count[vp9_get_pred_context_comp_inter_inter(cm, xd)]
                              [mbmi->ref_frame[1] > INTRA_FRAME]++;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
599
600

      if (mbmi->ref_frame[1] > INTRA_FRAME) {
601
        cpi->comp_ref_count[vp9_get_pred_context_comp_ref_p(cm, xd)][mbmi
Jim Bankoski's avatar
Jim Bankoski committed
602
            ->ref_frame[0] == GOLDEN_FRAME]++;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
603
      } else {
604
        cpi->single_ref_count[vp9_get_pred_context_single_ref_p1(xd)]
605
                              [0][mbmi->ref_frame[0] != LAST_FRAME]++;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
606
        if (mbmi->ref_frame[0] != LAST_FRAME)
607
          cpi->single_ref_count[vp9_get_pred_context_single_ref_p2(xd)][1]
608
              [mbmi->ref_frame[0] != GOLDEN_FRAME]++;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
609
      }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
610
    }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
611
    // Count of last ref frame 0,0 usage
Ronald S. Bultje's avatar
Ronald S. Bultje committed
612
    if ((mbmi->mode == ZEROMV) && (mbmi->ref_frame[0] == LAST_FRAME))
Ronald S. Bultje's avatar
Ronald S. Bultje committed
613
614
615
      cpi->inter_zz_count++;
  }
}
John Koleszar's avatar
John Koleszar committed
616

617
618
619
// TODO(jingning): the variables used here are little complicated. need further
// refactoring on organizing the the temporary buffers, when recursive
// partition down to 4x4 block size is enabled.
620
621
static PICK_MODE_CONTEXT *get_block_context(MACROBLOCK *x,
                                            BLOCK_SIZE_TYPE bsize) {
Jim Bankoski's avatar
Jim Bankoski committed
622
  MACROBLOCKD * const xd = &x->e_mbd;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
623

624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
  switch (bsize) {
    case BLOCK_SIZE_SB64X64:
      return &x->sb64_context;
    case BLOCK_SIZE_SB64X32:
      return &x->sb64x32_context[xd->sb_index];
    case BLOCK_SIZE_SB32X64:
      return &x->sb32x64_context[xd->sb_index];
    case BLOCK_SIZE_SB32X32:
      return &x->sb32_context[xd->sb_index];
    case BLOCK_SIZE_SB32X16:
      return &x->sb32x16_context[xd->sb_index][xd->mb_index];
    case BLOCK_SIZE_SB16X32:
      return &x->sb16x32_context[xd->sb_index][xd->mb_index];
    case BLOCK_SIZE_MB16X16:
      return &x->mb_context[xd->sb_index][xd->mb_index];
639
640
641
642
643
    case BLOCK_SIZE_SB16X8:
      return &x->sb16x8_context[xd->sb_index][xd->mb_index][xd->b_index];
    case BLOCK_SIZE_SB8X16:
      return &x->sb8x16_context[xd->sb_index][xd->mb_index][xd->b_index];
    case BLOCK_SIZE_SB8X8:
644
645
646
647
648
649
650
      return &x->sb8x8_context[xd->sb_index][xd->mb_index][xd->b_index];
    case BLOCK_SIZE_SB8X4:
      return &x->sb8x4_context[xd->sb_index][xd->mb_index][xd->b_index];
    case BLOCK_SIZE_SB4X8:
      return &x->sb4x8_context[xd->sb_index][xd->mb_index][xd->b_index];
    case BLOCK_SIZE_AB4X4:
      return &x->ab4x4_context[xd->sb_index][xd->mb_index][xd->b_index];
651
652
    default:
      assert(0);
Jim Bankoski's avatar
Jim Bankoski committed
653
      return NULL ;
654
655
  }
}
Ronald S. Bultje's avatar
Ronald S. Bultje committed
656

657
658
659
660
661
662
663
664
665
666
static BLOCK_SIZE_TYPE *get_sb_partitioning(MACROBLOCK *x,
                                            BLOCK_SIZE_TYPE bsize) {
  MACROBLOCKD *xd = &x->e_mbd;
  switch (bsize) {
    case BLOCK_SIZE_SB64X64:
      return &x->sb64_partitioning;
    case BLOCK_SIZE_SB32X32:
      return &x->sb_partitioning[xd->sb_index];
    case BLOCK_SIZE_MB16X16:
      return &x->mb_partitioning[xd->sb_index][xd->mb_index];
667
668
    case BLOCK_SIZE_SB8X8:
      return &x->b_partitioning[xd->sb_index][xd->mb_index][xd->b_index];
669
670
    default:
      assert(0);
Jim Bankoski's avatar
Jim Bankoski committed
671
      return NULL ;
672
673
674
675
676
677
  }
}

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
678
                            PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8],
679
                            BLOCK_SIZE_TYPE bsize) {
Jim Bankoski's avatar
Jim Bankoski committed
680
681
682
  VP9_COMMON * const cm = &cpi->common;
  MACROBLOCK * const x = &cpi->mb;
  MACROBLOCKD * const xd = &x->e_mbd;
683
  int p;
Jim Bankoski's avatar
Jim Bankoski committed
684
685
686
687
  int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
  int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
  int mi_width = num_8x8_blocks_wide_lookup[bsize];
  int mi_height = num_8x8_blocks_high_lookup[bsize];
688
  for (p = 0; p < MAX_MB_PLANE; p++) {
Jim Bankoski's avatar
Jim Bankoski committed
689
690
    vpx_memcpy(
        cm->above_context[p] + ((mi_col * 2) >> xd->plane[p].subsampling_x),
Jim Bankoski's avatar
Jim Bankoski committed
691
692
693
        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
694
695
    vpx_memcpy(
        cm->left_context[p]
Jim Bankoski's avatar
Jim Bankoski committed
696
697
698
699
700
            + ((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);
  }
701
  vpx_memcpy(cm->above_seg_context + mi_col, sa,
Jim Bankoski's avatar
Jim Bankoski committed
702
             sizeof(PARTITION_CONTEXT) * mi_width);
703
  vpx_memcpy(cm->left_seg_context + (mi_row & MI_MASK), sl,
Jim Bankoski's avatar
Jim Bankoski committed
704
             sizeof(PARTITION_CONTEXT) * mi_height);
705
}
Jim Bankoski's avatar
Jim Bankoski committed
706
static void save_context(VP9_COMP *cpi, int mi_row, int mi_col,
Jim Bankoski's avatar
Jim Bankoski committed
707
708
709
710
711
712
713
                         ENTROPY_CONTEXT a[16 * MAX_MB_PLANE],
                         ENTROPY_CONTEXT l[16 * MAX_MB_PLANE],
                         PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8],
                         BLOCK_SIZE_TYPE bsize) {
  VP9_COMMON * const cm = &cpi->common;
  MACROBLOCK * const x = &cpi->mb;
  MACROBLOCKD * const xd = &x->e_mbd;
Jim Bankoski's avatar
Jim Bankoski committed
714
  int p;
Jim Bankoski's avatar
Jim Bankoski committed
715
716
717
718
  int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
  int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
  int mi_width = num_8x8_blocks_wide_lookup[bsize];
  int mi_height = num_8x8_blocks_high_lookup[bsize];
Jim Bankoski's avatar
Jim Bankoski committed
719
720
721

  // buffer the above/left context information of the block in search.
  for (p = 0; p < MAX_MB_PLANE; ++p) {
Jim Bankoski's avatar
Jim Bankoski committed
722
    vpx_memcpy(
Jim Bankoski's avatar
Jim Bankoski committed
723
        a + num_4x4_blocks_wide * p,
Jim Bankoski's avatar
Jim Bankoski committed
724
        cm->above_context[p] + (mi_col * 2 >> xd->plane[p].subsampling_x),
Jim Bankoski's avatar
Jim Bankoski committed
725
726
        (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
        xd->plane[p].subsampling_x);
Jim Bankoski's avatar
Jim Bankoski committed
727
    vpx_memcpy(
Jim Bankoski's avatar
Jim Bankoski committed
728
        l + num_4x4_blocks_high * p,
Jim Bankoski's avatar
Jim Bankoski committed
729
        cm->left_context[p]
Jim Bankoski's avatar
Jim Bankoski committed
730
731
732
733
            + ((mi_row & MI_MASK) * 2 >> xd->plane[p].subsampling_y),
        (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
        xd->plane[p].subsampling_y);
  }
Jim Bankoski's avatar
Jim Bankoski committed
734
  vpx_memcpy(sa, cm->above_seg_context + mi_col,
Jim Bankoski's avatar
Jim Bankoski committed
735
             sizeof(PARTITION_CONTEXT) * mi_width);
Jim Bankoski's avatar
Jim Bankoski committed
736
  vpx_memcpy(sl, cm->left_seg_context + (mi_row & MI_MASK),
Jim Bankoski's avatar
Jim Bankoski committed
737
738
             sizeof(PARTITION_CONTEXT) * mi_height);
}
739

Jim Bankoski's avatar
Jim Bankoski committed
740
741
742
743
744
static void encode_b(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, int mi_col,
                     int output_enabled, BLOCK_SIZE_TYPE bsize, int sub_index) {
  VP9_COMMON * const cm = &cpi->common;
  MACROBLOCK * const x = &cpi->mb;
  MACROBLOCKD * const xd = &x->e_mbd;
John Koleszar's avatar
John Koleszar committed
745

746
747
  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
    return;
John Koleszar's avatar
John Koleszar committed
748

749
  if (sub_index != -1)
750
    *(get_sb_index(xd, bsize)) = sub_index;
751
752
753
754

  if (bsize < BLOCK_SIZE_SB8X8)
    if (xd->ab_index > 0)
      return;
755
756
  set_offsets(cpi, mi_row, mi_col, bsize);
  update_state(cpi, get_block_context(x, bsize), bsize, output_enabled);
Jingning Han's avatar
Jingning Han committed
757
  encode_superblock(cpi, tp, output_enabled, mi_row, mi_col, bsize);
John Koleszar's avatar
John Koleszar committed
758

759
760
  if (output_enabled) {
    update_stats(cpi, mi_row, mi_col);
761

762
763
    (*tp)->token = EOSB_TOKEN;
    (*tp)++;
John Koleszar's avatar
John Koleszar committed
764
  }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
765
766
}

Jim Bankoski's avatar
Jim Bankoski committed
767
768
769
770
771
static void encode_sb(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, int mi_col,
                      int output_enabled, BLOCK_SIZE_TYPE bsize) {
  VP9_COMMON * const cm = &cpi->common;
  MACROBLOCK * const x = &cpi->mb;
  MACROBLOCKD * const xd = &x->e_mbd;
772
  BLOCK_SIZE_TYPE c1 = BLOCK_SIZE_SB8X8;
773
  const int bsl = b_width_log2(bsize), bs = (1 << bsl) / 4;
774
  int UNINITIALIZED_IS_SAFE(pl);
Jim Bankoski's avatar
Jim Bankoski committed
775
776
777
  PARTITION_TYPE partition;
  BLOCK_SIZE_TYPE subsize;
  int i;
778

779
780
  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
    return;
781

782
  c1 = BLOCK_SIZE_AB4X4;
783
  if (bsize >= BLOCK_SIZE_SB8X8) {
784
    set_partition_seg_context(cm, xd, mi_row, mi_col);
785
786
    pl = partition_plane_context(xd, bsize);
    c1 = *(get_sb_partitioning(x, bsize));
787
  }
Jim Bankoski's avatar
Jim Bankoski committed
788
  partition = partition_lookup[bsl][c1];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
789

Jim Bankoski's avatar
Jim Bankoski committed
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
  switch (partition) {
    case PARTITION_NONE:
      if (output_enabled && bsize >= BLOCK_SIZE_SB8X8)
        cpi->partition_count[pl][PARTITION_NONE]++;
      encode_b(cpi, tp, mi_row, mi_col, output_enabled, c1, -1);
      break;
    case PARTITION_VERT:
      if (output_enabled)
        cpi->partition_count[pl][PARTITION_VERT]++;
      encode_b(cpi, tp, mi_row, mi_col, output_enabled, c1, 0);
      encode_b(cpi, tp, mi_row, mi_col + bs, output_enabled, c1, 1);
      break;
    case PARTITION_HORZ:
      if (output_enabled)
        cpi->partition_count[pl][PARTITION_HORZ]++;
      encode_b(cpi, tp, mi_row, mi_col, output_enabled, c1, 0);
      encode_b(cpi, tp, mi_row + bs, mi_col, output_enabled, c1, 1);
      break;
    case PARTITION_SPLIT:
      subsize = get_subsize(bsize, PARTITION_SPLIT);
810

Jim Bankoski's avatar
Jim Bankoski committed
811
812
      if (output_enabled)
        cpi->partition_count[pl][PARTITION_SPLIT]++;
813

Jim Bankoski's avatar
Jim Bankoski committed
814
815
      for (i = 0; i < 4; i++) {
        const int x_idx = i & 1, y_idx = i >> 1;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
816

Jim Bankoski's avatar
Jim Bankoski committed
817
818
819
820
821
822
823
824
        *(get_sb_index(xd, subsize)) = i;
        encode_sb(cpi, tp, mi_row + y_idx * bs, mi_col + x_idx * bs,
                  output_enabled, subsize);
      }
      break;
    default:
      assert(0);
      break;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
825
  }
826

Jim Bankoski's avatar
Jim Bankoski committed
827
  if (partition != PARTITION_SPLIT || bsize == BLOCK_SIZE_SB8X8) {
828