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

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)) {
365
    for (i = 0; i < TX_MODES; i++)
Ronald S. Bultje's avatar
Ronald S. Bultje committed
366
      cpi->rd_tx_select_diff[i] += ctx->txfm_rd_diff[i];
367
368
  }

John Koleszar's avatar
John Koleszar committed
369
370
  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
371
    // if (mb_mode == I4X4_PRED)
John Koleszar's avatar
John Koleszar committed
372
373
374
375
376
377
    //    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);
    //    }
378
#if CONFIG_INTERNAL_STATS
John Koleszar's avatar
John Koleszar committed
379
380
381
382
383
384
385
386
387
388
389
    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
390
      THR_B_PRED /*I4X4_PRED*/,
John Koleszar's avatar
John Koleszar committed
391
    };
392
    cpi->mode_chosen_counts[kf_mode_index[mi->mbmi.mode]]++;
393
#endif
John Koleszar's avatar
John Koleszar committed
394
395
396
  } else {
    // Note how often each mode chosen as best
    cpi->mode_chosen_counts[mb_mode_index]++;
Jim Bankoski's avatar
Jim Bankoski committed
397
398
    if (mbmi->ref_frame[0] != INTRA_FRAME
        && (mbmi->sb_type < BLOCK_SIZE_SB8X8 || mbmi->mode == NEWMV)) {
Deb Mukherjee's avatar
Deb Mukherjee committed
399
      int_mv best_mv, best_second_mv;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
400
401
      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
402
403
404
      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
405
406
        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
407
408
409
410
      }
      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);
411
    }
Jingning Han's avatar
Jingning Han committed
412

413
414
    if (bsize > BLOCK_SIZE_SB8X8 && mbmi->mode == NEWMV) {
      int i, j;
Jim Bankoski's avatar
Jim Bankoski committed
415
416
417
418
      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)
419
            xd->mode_info_context[mis * j + i].mbmi = *mbmi;
Deb Mukherjee's avatar
Deb Mukherjee committed
420
    }
421

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

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

    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
436
  }
Adrian Grange's avatar
Adrian Grange committed
437
438
}

Jim Bankoski's avatar
Jim Bankoski committed
439
void vp9_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
John Koleszar's avatar
John Koleszar committed
440
                          int mb_row, int mb_col) {
Jim Bankoski's avatar
Jim Bankoski committed
441
442
443
444
  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};
445
446
447
  int i;

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

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

  // entropy context structures
470
  for (i = 0; i < MAX_MB_PLANE; i++) {
Jim Bankoski's avatar
Jim Bankoski committed
471
472
473
474
    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);
475
  }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
476

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

Ronald S. Bultje's avatar
Ronald S. Bultje committed
480
481
482
483
484
  // 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
485
486
  x->partition_info = x->pi + idx_str;
  xd->mode_info_context = cm->mi + idx_str;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
487
  mbmi = &xd->mode_info_context->mbmi;
488
489
  // Special case: if prev_mi is NULL, the previous mode info context
  // cannot be used.
Jim Bankoski's avatar
Jim Bankoski committed
490
  xd->prev_mode_info_context = cm->prev_mi ? cm->prev_mi + idx_str : NULL;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
491
492

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

  /* 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
497
498
499
  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
500
      + (VP9BORDERINPIXELS - MI_SIZE * mi_height - VP9_INTERP_EXTEND));
Jim Bankoski's avatar
Jim Bankoski committed
501
  x->mv_col_max = ((cm->mi_cols - mi_col) * MI_SIZE
Jim Bankoski's avatar
Jim Bankoski committed
502
      + (VP9BORDERINPIXELS - MI_SIZE * mi_width - VP9_INTERP_EXTEND));
Ronald S. Bultje's avatar
Ronald S. Bultje committed
503
504

  // Set up distance of MB to edge of frame in 1/8th pel units
Jim Bankoski's avatar
Jim Bankoski committed
505
506
  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
507
508

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

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

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

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

523
524
525
    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
526
527
528
529
      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
530
      const int p16 = ((mb_row & 1) << 1) + (mb_col & 1);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
531
      const int p32 = ((mb_row & 2) << 2) + ((mb_col & 2) << 1);
Jim Bankoski's avatar
Jim Bankoski committed
532
533
534
      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
535

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

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

547
static void pick_sb_modes(VP9_COMP *cpi, int mi_row, int mi_col,
548
                          int *totalrate, int64_t *totaldist,
549
550
                          BLOCK_SIZE_TYPE bsize, PICK_MODE_CONTEXT *ctx,
                          int64_t best_rd) {
551
552
553
  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
554

555
556
  x->rd_search = 1;

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

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

566
567
568
  // 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)
569
570
    vp9_rd_pick_intra_mode_sb(cpi, x, totalrate, totaldist, bsize, ctx,
                              best_rd);
571
  else
572
    vp9_rd_pick_inter_mode_sb(cpi, x, mi_row, mi_col, totalrate, totaldist,
573
                              bsize, ctx, best_rd);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
574
}
Adrian Grange's avatar
Adrian Grange committed
575

576
static void update_stats(VP9_COMP *cpi, int mi_row, int mi_col) {
Jim Bankoski's avatar
Jim Bankoski committed
577
578
579
  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
580
  MODE_INFO *mi = xd->mode_info_context;
Jim Bankoski's avatar
Jim Bankoski committed
581
  MB_MODE_INFO * const mbmi = &mi->mbmi;
Adrian Grange's avatar
Adrian Grange committed
582

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

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

591
592
593
594
    // 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
595
      if (cm->comp_pred_mode == HYBRID_PREDICTION)
596
597
        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
598
599

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

616
617
618
// 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.
619
620
static PICK_MODE_CONTEXT *get_block_context(MACROBLOCK *x,
                                            BLOCK_SIZE_TYPE bsize) {
Jim Bankoski's avatar
Jim Bankoski committed
621
  MACROBLOCKD * const xd = &x->e_mbd;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
622

623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
  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];
638
639
640
641
642
    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:
643
644
645
646
647
648
649
      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];
650
651
    default:
      assert(0);
Jim Bankoski's avatar
Jim Bankoski committed
652
      return NULL ;
653
654
  }
}
Ronald S. Bultje's avatar
Ronald S. Bultje committed
655

656
657
658
659
660
661
662
663
664
665
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];
666
667
    case BLOCK_SIZE_SB8X8:
      return &x->b_partitioning[xd->sb_index][xd->mb_index][xd->b_index];
668
669
    default:
      assert(0);
Jim Bankoski's avatar
Jim Bankoski committed
670
      return NULL ;
671
672
673
674
675
676
  }
}

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

  // 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
721
    vpx_memcpy(
Jim Bankoski's avatar
Jim Bankoski committed
722
        a + num_4x4_blocks_wide * p,
Jim Bankoski's avatar
Jim Bankoski committed
723
        cm->above_context[p] + (mi_col * 2 >> xd->plane[p].subsampling_x),
Jim Bankoski's avatar
Jim Bankoski committed
724
725
        (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
        xd->plane[p].subsampling_x);
Jim Bankoski's avatar
Jim Bankoski committed
726
    vpx_memcpy(
Jim Bankoski's avatar
Jim Bankoski committed
727
        l + num_4x4_blocks_high * p,
Jim Bankoski's avatar
Jim Bankoski committed
728
        cm->left_context[p]
Jim Bankoski's avatar
Jim Bankoski committed
729
730
731
732
            + ((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
733
  vpx_memcpy(sa, cm->above_seg_context + mi_col,
Jim Bankoski's avatar
Jim Bankoski committed
734
             sizeof(PARTITION_CONTEXT) * mi_width);
Jim Bankoski's avatar
Jim Bankoski committed
735
  vpx_memcpy(sl, cm->left_seg_context + (mi_row & MI_MASK),
Jim Bankoski's avatar
Jim Bankoski committed
736
737
             sizeof(PARTITION_CONTEXT) * mi_height);
}
738

Jim Bankoski's avatar
Jim Bankoski committed
739
740
741
742
743
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
744

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

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

  if (bsize < BLOCK_SIZE_SB8X8)
    if (xd->ab_index > 0)
      return;
754
755
  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
756
  encode_superblock(cpi, tp, output_enabled, mi_row, mi_col, bsize);
John Koleszar's avatar
John Koleszar committed
757

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

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

Jim Bankoski's avatar
Jim Bankoski committed
766
767
768
769
770
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;
771
  BLOCK_SIZE_TYPE c1 = BLOCK_SIZE_SB8X8;
772
  const int bsl = b_width_log2(bsize), bs = (1 << bsl) / 4;
773
  int UNINITIALIZED_IS_SAFE(pl);
Jim Bankoski's avatar
Jim Bankoski committed
774
775
776
  PARTITION_TYPE partition;
  BLOCK_SIZE_TYPE subsize;
  int i;
777

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

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

Jim Bankoski's avatar
Jim Bankoski committed
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
  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);
809

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

Jim Bankoski's avatar
Jim Bankoski committed
813
814
      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
815

Jim Bankoski's avatar
Jim Bankoski committed
816
817
818
819
820
821
822
823
        *(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
824
  }
825

Jim Bankoski's avatar
Jim Bankoski committed
826
  if (partition != PARTITION_SPLIT || bsize == BLOCK_SIZE_SB8X8) {
827
    set_partition_seg_context(cm, xd, mi_row, mi_col);
Jingning Han's avatar