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

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.fc.switchable_interp_count[
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
542
543
544
    }
  } else {
    mbmi->segment_id = 0;
  }
}

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

553
554
  x->rd_search = 1;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

756
757
  if (output_enabled) {
    update_stats(cpi, mi_row, mi_col);
758

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

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

776
777
  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
    return;
778

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

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

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

Jim Bankoski's avatar
Jim Bankoski committed
811
812
      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
813

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

Jim Bankoski's avatar
Jim Bankoski committed
824
  if (partition != PARTITION_SPLIT || bsize == BLOCK_SIZE_SB8X8) {
825
    set_partition_seg_context(cm, xd, mi_row, mi_col);
826
    update_partition_context(xd, c1, bsize);
827
  }
Adrian Grange's avatar
Adrian Grange committed
828
}
John Koleszar's avatar
John Koleszar committed
829

830
831
832