vp9_bitstream.c 63.1 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
12
13
#include <assert.h>
#include <stdio.h>
#include <limits.h>
John Koleszar's avatar
John Koleszar committed
14

15
#include "vp9/common/vp9_header.h"
16
#include "vp9/encoder/vp9_encodemv.h"
17
#include "vp9/common/vp9_entropymode.h"
18
#include "vp9/common/vp9_entropymv.h"
19
#include "vp9/common/vp9_findnearmv.h"
20
#include "vp9/common/vp9_tile_common.h"
21
#include "vp9/encoder/vp9_mcomp.h"
22
23
#include "vp9/common/vp9_systemdependent.h"
#include "vp9/common/vp9_pragmas.h"
24
#include "vpx/vpx_encoder.h"
John Koleszar's avatar
John Koleszar committed
25
#include "vpx_mem/vpx_mem.h"
26
27
#include "vp9/encoder/vp9_bitstream.h"
#include "vp9/encoder/vp9_segmentation.h"
28

29
30
31
32
33
34
#include "vp9/common/vp9_seg_common.h"
#include "vp9/common/vp9_pred_common.h"
#include "vp9/common/vp9_entropy.h"
#include "vp9/encoder/vp9_encodemv.h"
#include "vp9/common/vp9_entropymv.h"
#include "vp9/common/vp9_mvref_common.h"
35
#include "vp9/common/vp9_treecoder.h"
Paul Wilkins's avatar
Paul Wilkins committed
36

John Koleszar's avatar
John Koleszar committed
37
38
39
40
41
#if defined(SECTIONBITS_OUTPUT)
unsigned __int64 Sectionbits[500];
#endif

#ifdef ENTROPY_STATS
42
43
44
int intra_mode_stats[VP9_KF_BINTRAMODES]
                    [VP9_KF_BINTRAMODES]
                    [VP9_KF_BINTRAMODES];
45
46
47
vp9_coeff_stats tree_update_hist_4x4[BLOCK_TYPES];
vp9_coeff_stats tree_update_hist_8x8[BLOCK_TYPES];
vp9_coeff_stats tree_update_hist_16x16[BLOCK_TYPES];
48
vp9_coeff_stats tree_update_hist_32x32[BLOCK_TYPES];
49

John Koleszar's avatar
John Koleszar committed
50
51
52
extern unsigned int active_section;
#endif

53
54
#define vp9_cost_upd  ((int)(vp9_cost_one(upd) - vp9_cost_zero(upd)) >> 8)
#define vp9_cost_upd256  ((int)(vp9_cost_one(upd) - vp9_cost_zero(upd)))
55
56
57
58

#define SEARCH_NEWP
static int update_bits[255];

59
60
61
62
63
64
65
66
67
68
69
70
static INLINE void write_le16(uint8_t *p, int value) {
  p[0] = value;
  p[1] = value >> 8;
}

static INLINE void write_le32(uint8_t *p, int value) {
  p[0] = value;
  p[1] = value >> 8;
  p[2] = value >> 16;
  p[3] = value >> 24;
}

John Koleszar's avatar
John Koleszar committed
71
72
73
static void compute_update_table() {
  int i;
  for (i = 0; i < 255; i++)
74
    update_bits[i] = vp9_count_term_subexp(i, SUBEXP_PARAM, 255);
75
76
}

John Koleszar's avatar
John Koleszar committed
77
78
79
80
81
static int split_index(int i, int n, int modulus) {
  int max1 = (n - 1 - modulus / 2) / modulus + 1;
  if (i % modulus == modulus / 2) i = i / modulus;
  else i = max1 + i - (i + modulus - modulus / 2) / modulus;
  return i;
82
83
}

John Koleszar's avatar
John Koleszar committed
84
85
86
87
88
static int remap_prob(int v, int m) {
  const int n = 256;
  const int modulus = MODULUS_PARAM;
  int i;
  if ((m << 1) <= n)
89
    i = vp9_recenter_nonneg(v, m) - 1;
John Koleszar's avatar
John Koleszar committed
90
  else
91
    i = vp9_recenter_nonneg(n - 1 - v, n - 1 - m) - 1;
John Koleszar's avatar
John Koleszar committed
92
93
94

  i = split_index(i, n - 1, modulus);
  return i;
95
}
96

97
98
static void write_prob_diff_update(vp9_writer *const bc,
                                   vp9_prob newp, vp9_prob oldp) {
John Koleszar's avatar
John Koleszar committed
99
  int delp = remap_prob(newp, oldp);
100
  vp9_encode_term_subexp(bc, delp, SUBEXP_PARAM, 255);
101
102
}

103
static int prob_diff_update_cost(vp9_prob newp, vp9_prob oldp) {
John Koleszar's avatar
John Koleszar committed
104
105
  int delp = remap_prob(newp, oldp);
  return update_bits[delp] * 256;
106
}
107

John Koleszar's avatar
John Koleszar committed
108
static void update_mode(
109
  vp9_writer *const bc,
John Koleszar's avatar
John Koleszar committed
110
  int n,
111
  const struct vp9_token tok[/* n */],
112
113
114
  vp9_tree tree,
  vp9_prob Pnew               [/* n-1 */],
  vp9_prob Pcur               [/* n-1 */],
John Koleszar's avatar
John Koleszar committed
115
116
117
118
119
120
  unsigned int bct            [/* n-1 */] [2],
  const unsigned int num_events[/* n */]
) {
  unsigned int new_b = 0, old_b = 0;
  int i = 0;

121
122
  vp9_tree_probs_from_distribution(tree, Pnew, bct, num_events, 0);
  n--;
John Koleszar's avatar
John Koleszar committed
123
124

  do {
125
126
    new_b += cost_branch(bct[i], Pnew[i]);
    old_b += cost_branch(bct[i], Pcur[i]);
John Koleszar's avatar
John Koleszar committed
127
128
129
  } while (++i < n);

  if (new_b + (n << 8) < old_b) {
John Koleszar's avatar
John Koleszar committed
130
131
    int i = 0;

132
    vp9_write_bit(bc, 1);
John Koleszar's avatar
John Koleszar committed
133

John Koleszar's avatar
John Koleszar committed
134
    do {
135
      const vp9_prob p = Pnew[i];
John Koleszar's avatar
John Koleszar committed
136

137
      vp9_write_literal(bc, Pcur[i] = p ? p : 1, 8);
John Koleszar's avatar
John Koleszar committed
138
139
    } while (++i < n);
  } else
140
    vp9_write_bit(bc, 0);
John Koleszar's avatar
John Koleszar committed
141
142
}

143
static void update_mbintra_mode_probs(VP9_COMP* const cpi,
144
                                      vp9_writer* const bc) {
145
  VP9_COMMON *const cm = &cpi->common;
John Koleszar's avatar
John Koleszar committed
146

147
148
149
150
151
152
153
154
155
  vp9_prob pnew[VP9_YMODES - 1];
  unsigned int bct[VP9_YMODES - 1][2];

  update_mode(bc, VP9_YMODES, vp9_ymode_encodings, vp9_ymode_tree, pnew,
              cm->fc.ymode_prob, bct, (unsigned int *)cpi->ymode_count);

  update_mode(bc, VP9_I32X32_MODES, vp9_sb_ymode_encodings,
              vp9_sb_ymode_tree, pnew, cm->fc.sb_ymode_prob, bct,
              (unsigned int *)cpi->sb_ymode_count);
John Koleszar's avatar
John Koleszar committed
156
157
}

158
159
void vp9_update_skip_probs(VP9_COMP *cpi) {
  VP9_COMMON *const pc = &cpi->common;
John Koleszar's avatar
John Koleszar committed
160
  int k;
Paul Wilkins's avatar
Paul Wilkins committed
161

162
  for (k = 0; k < MBSKIP_CONTEXTS; ++k)
John Koleszar's avatar
John Koleszar committed
163
164
    pc->mbskip_pred_probs[k] = get_binary_prob(cpi->skip_false_count[k],
                                               cpi->skip_true_count[k]);
Paul Wilkins's avatar
Paul Wilkins committed
165
166
}

167
static void update_switchable_interp_probs(VP9_COMP *cpi,
168
                                           vp9_writer* const bc) {
169
  VP9_COMMON *const pc = &cpi->common;
170
171
  unsigned int branch_ct[32][2];
  int i, j;
172
  for (j = 0; j <= VP9_SWITCHABLE_FILTERS; ++j) {
173
    vp9_tree_probs_from_distribution(
174
        vp9_switchable_interp_tree,
175
        pc->fc.switchable_interp_prob[j], branch_ct,
176
        cpi->switchable_interp_count[j], 0);
177
    for (i = 0; i < VP9_SWITCHABLE_FILTERS - 1; ++i) {
178
179
      if (pc->fc.switchable_interp_prob[j][i] < 1)
        pc->fc.switchable_interp_prob[j][i] = 1;
180
      vp9_write_prob(bc, pc->fc.switchable_interp_prob[j][i]);
181
182
183
184
    }
  }
}

185
// This function updates the reference frame prediction stats
186
187
static void update_refpred_stats(VP9_COMP *cpi) {
  VP9_COMMON *const cm = &cpi->common;
John Koleszar's avatar
John Koleszar committed
188
  int i;
189
  vp9_prob new_pred_probs[PREDICTION_PROBS];
John Koleszar's avatar
John Koleszar committed
190
191
192
  int old_cost, new_cost;

  // Set the prediction probability structures to defaults
193
  if (cm->frame_type != KEY_FRAME) {
John Koleszar's avatar
John Koleszar committed
194
195
    // From the prediction counts set the probabilities for each context
    for (i = 0; i < PREDICTION_PROBS; i++) {
196
197
198
199
      const int c0 = cpi->ref_pred_count[i][0];
      const int c1 = cpi->ref_pred_count[i][1];

      new_pred_probs[i] = get_binary_prob(c0, c1);
John Koleszar's avatar
John Koleszar committed
200
201
202

      // Decide whether or not to update the reference frame probs.
      // Returned costs are in 1/256 bit units.
203
204
      old_cost = c0 * vp9_cost_zero(cm->ref_pred_probs[i]) +
                 c1 * vp9_cost_one(cm->ref_pred_probs[i]);
John Koleszar's avatar
John Koleszar committed
205

206
207
      new_cost = c0 * vp9_cost_zero(new_pred_probs[i]) +
                 c1 * vp9_cost_one(new_pred_probs[i]);
John Koleszar's avatar
John Koleszar committed
208
209
210
211
212
213
214

      // Cost saving must be >= 8 bits (2048 in these units)
      if ((old_cost - new_cost) >= 2048) {
        cpi->ref_pred_probs_update[i] = 1;
        cm->ref_pred_probs[i] = new_pred_probs[i];
      } else
        cpi->ref_pred_probs_update[i] = 0;
215
    }
John Koleszar's avatar
John Koleszar committed
216
  }
217
218
}

219
220
221
222
223
224
// This function is called to update the mode probability context used to encode
// inter modes. It assumes the branch counts table has already been populated
// prior to the actual packing of the bitstream (in rd stage or dummy pack)
//
// The branch counts table is re-populated during the actual pack stage and in
// the decoder to facilitate backwards update of the context.
225
226
static void update_inter_mode_probs(VP9_COMMON *cm,
                                    int mode_context[INTER_MODE_CONTEXTS][4]) {
227
  int i, j;
228
  unsigned int (*mv_ref_ct)[4][2] = cm->fc.mv_ref_ct;
229
230
231
232
233
234

  vpx_memcpy(mode_context, cm->fc.vp9_mode_contexts,
             sizeof(cm->fc.vp9_mode_contexts));

  for (i = 0; i < INTER_MODE_CONTEXTS; i++) {
    for (j = 0; j < 4; j++) {
235
      int new_prob, old_cost, new_cost;
236
237
238

      // Work out cost of coding branches with the old and optimal probability
      old_cost = cost_branch256(mv_ref_ct[i][j], mode_context[i][j]);
239
      new_prob = get_binary_prob(mv_ref_ct[i][j][0], mv_ref_ct[i][j][1]);
240
241
242
243
244
245
246
247
248
249
250
      new_cost = cost_branch256(mv_ref_ct[i][j], new_prob);

      // If cost saving is >= 14 bits then update the mode probability.
      // This is the approximate net cost of updating one probability given
      // that the no update case ismuch more common than the update case.
      if (new_cost <= (old_cost - (14 << 8))) {
        mode_context[i][j] = new_prob;
      }
    }
  }
}
251

252
253
static void write_ymode(vp9_writer *bc, int m, const vp9_prob *p) {
  write_token(bc, vp9_ymode_tree, p, vp9_ymode_encodings + m);
John Koleszar's avatar
John Koleszar committed
254
255
}

256
257
static void kfwrite_ymode(vp9_writer *bc, int m, const vp9_prob *p) {
  write_token(bc, vp9_kf_ymode_tree, p, vp9_kf_ymode_encodings + m);
John Koleszar's avatar
John Koleszar committed
258
259
}

260
261
262
263
static void write_sb_ymode(vp9_writer *bc, int m, const vp9_prob *p) {
  write_token(bc, vp9_sb_ymode_tree, p, vp9_sb_ymode_encodings + m);
}

264
265
static void sb_kfwrite_ymode(vp9_writer *bc, int m, const vp9_prob *p) {
  write_token(bc, vp9_uv_mode_tree, p, vp9_sb_kf_ymode_encodings + m);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
266
267
}

268
269
static void write_uv_mode(vp9_writer *bc, int m, const vp9_prob *p) {
  write_token(bc, vp9_uv_mode_tree, p, vp9_uv_mode_encodings + m);
John Koleszar's avatar
John Koleszar committed
270
271
272
}


273
274
static void write_bmode(vp9_writer *bc, int m, const vp9_prob *p) {
  write_token(bc, vp9_bmode_tree, p, vp9_bmode_encodings + m);
John Koleszar's avatar
John Koleszar committed
275
276
}

277
278
279
280
static void write_kf_bmode(vp9_writer *bc, int m, const vp9_prob *p) {
  write_token(bc, vp9_kf_bmode_tree, p, vp9_kf_bmode_encodings + m);
}

281
static int prob_update_savings(const unsigned int *ct,
282
283
284
285
286
                               const vp9_prob oldp, const vp9_prob newp,
                               const vp9_prob upd) {
  const int old_b = cost_branch256(ct, oldp);
  const int new_b = cost_branch256(ct, newp);
  const int update_b = 2048 + vp9_cost_upd256;
287
  return old_b - new_b - update_b;
288
289
290
}

static int prob_diff_update_savings_search(const unsigned int *ct,
291
292
293
                                           const vp9_prob oldp, vp9_prob *bestp,
                                           const vp9_prob upd) {
  const int old_b = cost_branch256(ct, oldp);
John Koleszar's avatar
John Koleszar committed
294
  int new_b, update_b, savings, bestsavings, step;
295
  vp9_prob newp, bestnewp;
John Koleszar's avatar
John Koleszar committed
296
297
298
299
300
301

  bestsavings = 0;
  bestnewp = oldp;

  step = (*bestp > oldp ? -1 : 1);
  for (newp = *bestp; newp != oldp; newp += step) {
302
303
    new_b = cost_branch256(ct, newp);
    update_b = prob_diff_update_cost(newp, oldp) + vp9_cost_upd256;
John Koleszar's avatar
John Koleszar committed
304
305
306
307
    savings = old_b - new_b - update_b;
    if (savings > bestsavings) {
      bestsavings = savings;
      bestnewp = newp;
308
    }
John Koleszar's avatar
John Koleszar committed
309
310
311
  }
  *bestp = bestnewp;
  return bestsavings;
312
313
}

314
315
316
317
318
#if CONFIG_MODELCOEFPROB && MODEL_BASED_UPDATE
static int prob_diff_update_savings_search_model(const unsigned int *ct,
                                                 const vp9_prob *oldp,
                                                 vp9_prob *bestp,
                                                 const vp9_prob upd,
319
                                                 int b, int r, int q) {
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
  int i, old_b, new_b, update_b, savings, bestsavings, step;
  int newp;
  vp9_prob bestnewp, newplist[ENTROPY_NODES];
  for (i = UNCONSTRAINED_NODES - 1, old_b = 0; i < ENTROPY_NODES; ++i)
    old_b += cost_branch256(ct + 2 * i, oldp[i]);

  bestsavings = 0;
  bestnewp = oldp[UNCONSTRAINED_NODES - 1];

  step = (*bestp > oldp[UNCONSTRAINED_NODES - 1] ? -1 : 1);
  newp = *bestp;
  // newp = *bestp - step * (abs(*bestp - oldp[UNCONSTRAINED_NODES - 1]) >> 1);
  for (; newp != oldp[UNCONSTRAINED_NODES - 1]; newp += step) {
    if (newp < 1 || newp > 255) continue;
    newplist[UNCONSTRAINED_NODES - 1] = newp;
    vp9_get_model_distribution(newp, newplist, b, r);
    for (i = UNCONSTRAINED_NODES - 1, new_b = 0; i < ENTROPY_NODES; ++i)
      new_b += cost_branch256(ct + 2 * i, newplist[i]);
    update_b = prob_diff_update_cost(newp, oldp[UNCONSTRAINED_NODES - 1]) +
        vp9_cost_upd256;
    savings = old_b - new_b - update_b;
    if (savings > bestsavings) {
      bestsavings = savings;
      bestnewp = newp;
    }
  }
  *bestp = bestnewp;
  return bestsavings;
}
#endif

351
352
353
354
355
356
357
358
static void vp9_cond_prob_update(vp9_writer *bc, vp9_prob *oldp, vp9_prob upd,
                                 unsigned int *ct) {
  vp9_prob newp;
  int savings;
  newp = get_binary_prob(ct[0], ct[1]);
  savings = prob_update_savings(ct, *oldp, newp, upd);
  if (savings > 0) {
    vp9_write(bc, 1, upd);
359
    vp9_write_prob(bc, newp);
360
361
362
363
364
365
    *oldp = newp;
  } else {
    vp9_write(bc, 0, upd);
  }
}

366
static void pack_mb_tokens(vp9_writer* const bc,
367
368
369
                           TOKENEXTRA **tp,
                           const TOKENEXTRA *const stop) {
  TOKENEXTRA *p = *tp;
John Koleszar's avatar
John Koleszar committed
370

John Koleszar's avatar
John Koleszar committed
371
  while (p < stop) {
372
    const int t = p->token;
373
    const struct vp9_token *const a = vp9_coef_encodings + t;
374
    const vp9_extra_bit *const b = vp9_extra_bits + t;
John Koleszar's avatar
John Koleszar committed
375
376
377
    int i = 0;
    const unsigned char *pp = p->context_tree;
    int v = a->value;
378
    int n = a->len;
379
    int ncount = n;
John Koleszar's avatar
John Koleszar committed
380

381
382
383
384
385
    if (t == EOSB_TOKEN)
    {
      ++p;
      break;
    }
386
    assert(pp != 0);
387

John Koleszar's avatar
John Koleszar committed
388
389
390
391
    /* skip one or two nodes */
    if (p->skip_eob_node) {
      n -= p->skip_eob_node;
      i = 2 * p->skip_eob_node;
392
      ncount -= p->skip_eob_node;
John Koleszar's avatar
John Koleszar committed
393
    }
John Koleszar's avatar
John Koleszar committed
394

John Koleszar's avatar
John Koleszar committed
395
396
    do {
      const int bb = (v >> --n) & 1;
397
      vp9_write(bc, bb, pp[i >> 1]);
398
      i = vp9_coef_tree[i + bb];
399
400
      ncount--;
    } while (n && ncount);
John Koleszar's avatar
John Koleszar committed
401
402


John Koleszar's avatar
John Koleszar committed
403
    if (b->base_val) {
404
      const int e = p->extra, l = b->len;
John Koleszar's avatar
John Koleszar committed
405

406
      if (l) {
John Koleszar's avatar
John Koleszar committed
407
408
        const unsigned char *pp = b->prob;
        int v = e >> 1;
409
        int n = l;              /* number of bits in v, assumed nonzero */
John Koleszar's avatar
John Koleszar committed
410
        int i = 0;
John Koleszar's avatar
John Koleszar committed
411

John Koleszar's avatar
John Koleszar committed
412
413
        do {
          const int bb = (v >> --n) & 1;
414
          vp9_write(bc, bb, pp[i >> 1]);
John Koleszar's avatar
John Koleszar committed
415
416
417
          i = b->tree[i + bb];
        } while (n);
      }
John Koleszar's avatar
John Koleszar committed
418

419
      vp9_write_bit(bc, e & 1);
John Koleszar's avatar
John Koleszar committed
420
    }
John Koleszar's avatar
John Koleszar committed
421
422
423
    ++p;
  }

424
  *tp = p;
John Koleszar's avatar
John Koleszar committed
425
426
}

427
428
static void write_mv_ref(vp9_writer *bc, MB_PREDICTION_MODE m,
                         const vp9_prob *p) {
429
#if CONFIG_DEBUG
John Koleszar's avatar
John Koleszar committed
430
  assert(NEARESTMV <= m  &&  m <= SPLITMV);
431
#endif
432
433
  write_token(bc, vp9_mv_ref_tree, p,
              vp9_mv_ref_encoding_array - NEARESTMV + m);
John Koleszar's avatar
John Koleszar committed
434
435
}

436
437
static void write_sb_mv_ref(vp9_writer *bc, MB_PREDICTION_MODE m,
                            const vp9_prob *p) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
438
439
440
#if CONFIG_DEBUG
  assert(NEARESTMV <= m  &&  m < SPLITMV);
#endif
441
442
  write_token(bc, vp9_sb_mv_ref_tree, p,
              vp9_sb_mv_ref_encoding_array - NEARESTMV + m);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
443
444
}

445
446
static void write_sub_mv_ref(vp9_writer *bc, B_PREDICTION_MODE m,
                             const vp9_prob *p) {
447
#if CONFIG_DEBUG
John Koleszar's avatar
John Koleszar committed
448
  assert(LEFT4X4 <= m  &&  m <= NEW4X4);
449
#endif
450
451
  write_token(bc, vp9_sub_mv_ref_tree, p,
              vp9_sub_mv_ref_encoding_array - LEFT4X4 + m);
John Koleszar's avatar
John Koleszar committed
452
453
}

454

Paul Wilkins's avatar
Paul Wilkins committed
455
456
// This function writes the current macro block's segnment id to the bitstream
// It should only be called if a segment map update is indicated.
457
static void write_mb_segid(vp9_writer *bc,
Paul Wilkins's avatar
Paul Wilkins committed
458
                           const MB_MODE_INFO *mi, const MACROBLOCKD *xd) {
459
460
461
  if (xd->segmentation_enabled && xd->update_mb_segmentation_map)
    treed_write(bc, vp9_segment_tree, xd->mb_segment_tree_probs,
                mi->segment_id, 3);
John Koleszar's avatar
John Koleszar committed
462
463
}

Paul Wilkins's avatar
Paul Wilkins committed
464
// This function encodes the reference frame
465
static void encode_ref_frame(vp9_writer *const bc,
466
                             VP9_COMMON *const cm,
John Koleszar's avatar
John Koleszar committed
467
468
469
470
471
                             MACROBLOCKD *xd,
                             int segment_id,
                             MV_REFERENCE_FRAME rf) {
  int seg_ref_active;
  int seg_ref_count = 0;
472
473
474
  seg_ref_active = vp9_segfeature_active(xd,
                                         segment_id,
                                         SEG_LVL_REF_FRAME);
John Koleszar's avatar
John Koleszar committed
475
476

  if (seg_ref_active) {
477
478
479
480
    seg_ref_count = vp9_check_segref(xd, segment_id, INTRA_FRAME) +
                    vp9_check_segref(xd, segment_id, LAST_FRAME) +
                    vp9_check_segref(xd, segment_id, GOLDEN_FRAME) +
                    vp9_check_segref(xd, segment_id, ALTREF_FRAME);
John Koleszar's avatar
John Koleszar committed
481
482
483
484
485
486
487
  }

  // If segment level coding of this signal is disabled...
  // or the segment allows multiple reference frame options
  if (!seg_ref_active || (seg_ref_count > 1)) {
    // Values used in prediction model coding
    unsigned char prediction_flag;
488
    vp9_prob pred_prob;
John Koleszar's avatar
John Koleszar committed
489
490
491
    MV_REFERENCE_FRAME pred_rf;

    // Get the context probability the prediction flag
Paul Wilkins's avatar
Paul Wilkins committed
492
    pred_prob = vp9_get_pred_prob(cm, xd, PRED_REF);
John Koleszar's avatar
John Koleszar committed
493
494

    // Get the predicted value.
Paul Wilkins's avatar
Paul Wilkins committed
495
    pred_rf = vp9_get_pred_ref(cm, xd);
John Koleszar's avatar
John Koleszar committed
496
497
498
499
500

    // Did the chosen reference frame match its predicted value.
    prediction_flag =
      (xd->mode_info_context->mbmi.ref_frame == pred_rf);

Paul Wilkins's avatar
Paul Wilkins committed
501
    vp9_set_pred_flag(xd, PRED_REF, prediction_flag);
502
    vp9_write(bc, prediction_flag, pred_prob);
John Koleszar's avatar
John Koleszar committed
503
504
505

    // If not predicted correctly then code value explicitly
    if (!prediction_flag) {
506
      vp9_prob mod_refprobs[PREDICTION_PROBS];
John Koleszar's avatar
John Koleszar committed
507
508
509
510
511
512
513
514

      vpx_memcpy(mod_refprobs,
                 cm->mod_refprobs[pred_rf], sizeof(mod_refprobs));

      // If segment coding enabled blank out options that cant occur by
      // setting the branch probability to 0.
      if (seg_ref_active) {
        mod_refprobs[INTRA_FRAME] *=
515
          vp9_check_segref(xd, segment_id, INTRA_FRAME);
John Koleszar's avatar
John Koleszar committed
516
        mod_refprobs[LAST_FRAME] *=
517
          vp9_check_segref(xd, segment_id, LAST_FRAME);
John Koleszar's avatar
John Koleszar committed
518
        mod_refprobs[GOLDEN_FRAME] *=
519
520
          (vp9_check_segref(xd, segment_id, GOLDEN_FRAME) *
           vp9_check_segref(xd, segment_id, ALTREF_FRAME));
John Koleszar's avatar
John Koleszar committed
521
522
523
      }

      if (mod_refprobs[0]) {
524
        vp9_write(bc, (rf != INTRA_FRAME), mod_refprobs[0]);
John Koleszar's avatar
John Koleszar committed
525
526
527
528
529
      }

      // Inter coded
      if (rf != INTRA_FRAME) {
        if (mod_refprobs[1]) {
530
          vp9_write(bc, (rf != LAST_FRAME), mod_refprobs[1]);
John Koleszar's avatar
John Koleszar committed
531
        }
532

John Koleszar's avatar
John Koleszar committed
533
534
        if (rf != LAST_FRAME) {
          if (mod_refprobs[2]) {
535
            vp9_write(bc, (rf != GOLDEN_FRAME), mod_refprobs[2]);
John Koleszar's avatar
John Koleszar committed
536
          }
537
        }
John Koleszar's avatar
John Koleszar committed
538
      }
Paul Wilkins's avatar
Paul Wilkins committed
539
    }
John Koleszar's avatar
John Koleszar committed
540
  }
Paul Wilkins's avatar
Paul Wilkins committed
541

John Koleszar's avatar
John Koleszar committed
542
543
  // if using the prediction mdoel we have nothing further to do because
  // the reference frame is fully coded by the segment
Paul Wilkins's avatar
Paul Wilkins committed
544
}
John Koleszar's avatar
John Koleszar committed
545

546
// Update the probabilities used to encode reference frame data
547
548
static void update_ref_probs(VP9_COMP *const cpi) {
  VP9_COMMON *const cm = &cpi->common;
549

John Koleszar's avatar
John Koleszar committed
550
551
552
553
  const int *const rfct = cpi->count_mb_ref_frame_usage;
  const int rf_intra = rfct[INTRA_FRAME];
  const int rf_inter = rfct[LAST_FRAME] +
                       rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];
554

John Koleszar's avatar
John Koleszar committed
555
556
557
  cm->prob_intra_coded = get_binary_prob(rf_intra, rf_inter);
  cm->prob_last_coded = get_prob(rfct[LAST_FRAME], rf_inter);
  cm->prob_gf_coded = get_binary_prob(rfct[GOLDEN_FRAME], rfct[ALTREF_FRAME]);
558

John Koleszar's avatar
John Koleszar committed
559
560
  // Compute a modified set of probabilities to use when prediction of the
  // reference frame fails
Paul Wilkins's avatar
Paul Wilkins committed
561
  vp9_compute_mod_refprobs(cm);
562
563
}

Ronald S. Bultje's avatar
Ronald S. Bultje committed
564
static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m,
565
                                vp9_writer *bc, int mi_row, int mi_col) {
566
  VP9_COMMON *const pc = &cpi->common;
567
  const nmv_context *nmvc = &pc->fc.nmvc;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
568
569
  MACROBLOCK *const x = &cpi->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
John Koleszar's avatar
John Koleszar committed
570
  const int mis = pc->mode_info_stride;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
571
572
573
574
575
  MB_MODE_INFO *const mi = &m->mbmi;
  const MV_REFERENCE_FRAME rf = mi->ref_frame;
  const MB_PREDICTION_MODE mode = mi->mode;
  const int segment_id = mi->segment_id;
  int skip_coeff;
Adrian Grange's avatar
Adrian Grange committed
576

Ronald S. Bultje's avatar
Ronald S. Bultje committed
577
578
  xd->prev_mode_info_context = pc->prev_mi + (m - pc->mi);
  x->partition_info = x->pi + (m - pc->mi);
579

Ronald S. Bultje's avatar
Ronald S. Bultje committed
580
581
#ifdef ENTROPY_STATS
  active_section = 9;
582
#endif
583

Ronald S. Bultje's avatar
Ronald S. Bultje committed
584
585
586
587
588
  if (cpi->mb.e_mbd.update_mb_segmentation_map) {
    // Is temporal coding of the segment map enabled
    if (pc->temporal_update) {
      unsigned char prediction_flag = vp9_get_pred_flag(xd, PRED_SEG_ID);
      vp9_prob pred_prob = vp9_get_pred_prob(pc, xd, PRED_SEG_ID);
Paul Wilkins's avatar
Paul Wilkins committed
589

Ronald S. Bultje's avatar
Ronald S. Bultje committed
590
591
      // Code the segment id prediction flag for this mb
      vp9_write(bc, prediction_flag, pred_prob);
592

Ronald S. Bultje's avatar
Ronald S. Bultje committed
593
594
      // If the mb segment id wasn't predicted code explicitly
      if (!prediction_flag)
Paul Wilkins's avatar
Paul Wilkins committed
595
        write_mb_segid(bc, mi, &cpi->mb.e_mbd);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
596
597
598
599
600
    } else {
      // Normal unpredicted coding
      write_mb_segid(bc, mi, &cpi->mb.e_mbd);
    }
  }
601

602
  if (vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
603
604
    skip_coeff = 1;
  } else {
605
    skip_coeff = m->mbmi.mb_skip_coeff;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
606
607
608
    vp9_write(bc, skip_coeff,
              vp9_get_pred_prob(pc, xd, PRED_MBSKIP));
  }
John Koleszar's avatar
John Koleszar committed
609

Ronald S. Bultje's avatar
Ronald S. Bultje committed
610
  // Encode the reference frame.
Paul Wilkins's avatar
Paul Wilkins committed
611
  encode_ref_frame(bc, pc, xd, segment_id, rf);
Paul Wilkins's avatar
Paul Wilkins committed
612

Ronald S. Bultje's avatar
Ronald S. Bultje committed
613
  if (rf == INTRA_FRAME) {
614
#ifdef ENTROPY_STATS
Ronald S. Bultje's avatar
Ronald S. Bultje committed
615
    active_section = 6;
616
#endif
Paul Wilkins's avatar
Paul Wilkins committed
617

618
619
620
621
#if CONFIG_AB4X4
    if (m->mbmi.sb_type >= BLOCK_SIZE_SB8X8)
      write_sb_ymode(bc, mode, pc->fc.sb_ymode_prob);
#else
622
    if (m->mbmi.sb_type > BLOCK_SIZE_SB8X8)
Paul Wilkins's avatar
Paul Wilkins committed
623
624
625
      write_sb_ymode(bc, mode, pc->fc.sb_ymode_prob);
    else
      write_ymode(bc, mode, pc->fc.ymode_prob);
626
#endif
Paul Wilkins's avatar
Paul Wilkins committed
627

628
629
630
#if CONFIG_AB4X4
    if (m->mbmi.sb_type < BLOCK_SIZE_SB8X8) {
#else
Yaowu Xu's avatar
Yaowu Xu committed
631
    if (mode == I4X4_PRED) {
632
#endif
Ronald S. Bultje's avatar
Ronald S. Bultje committed
633
634
635
636
      int j = 0;
      do {
        write_bmode(bc, m->bmi[j].as_mode.first,
                    pc->fc.bmode_prob);
Jingning Han's avatar
Jingning Han committed
637
      } while (++j < 4);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
638
    }
Jingning Han's avatar
Jingning Han committed
639
640
    write_uv_mode(bc, mi->uv_mode,
                  pc->fc.uv_mode_prob[mode]);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
641
642
  } else {
    vp9_prob mv_ref_p[VP9_MVREFS - 1];
643

Ronald S. Bultje's avatar
Ronald S. Bultje committed
644
    vp9_mv_ref_probs(&cpi->common, mv_ref_p, mi->mb_mode_context[rf]);
Yaowu Xu's avatar
Yaowu Xu committed
645

John Koleszar's avatar
John Koleszar committed
646
#ifdef ENTROPY_STATS
Ronald S. Bultje's avatar
Ronald S. Bultje committed
647
    active_section = 3;
John Koleszar's avatar
John Koleszar committed
648
649
#endif

650
    // If segment skip is not enabled code the mode.
Paul Wilkins's avatar
Paul Wilkins committed
651
    if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) {
652
653
654
655
#if CONFIG_AB4X4
      if (mi->sb_type >= BLOCK_SIZE_SB8X8)
        write_sb_mv_ref(bc, mode, mv_ref_p);
#else
656
      if (mi->sb_type > BLOCK_SIZE_SB8X8) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
657
        write_sb_mv_ref(bc, mode, mv_ref_p);
658
      } else {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
659
660
        write_mv_ref(bc, mode, mv_ref_p);
      }
661
#endif
Ronald S. Bultje's avatar
Ronald S. Bultje committed
662
663
      vp9_accum_mv_refs(&cpi->common, mode, mi->mb_mode_context[rf]);
    }
664

665
    if (is_inter_mode(mode)) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
666
667
668
669
670
671
672
673
674
675
      if (cpi->common.mcomp_filter_type == SWITCHABLE) {
        write_token(bc, vp9_switchable_interp_tree,
                    vp9_get_pred_probs(&cpi->common, xd,
                                       PRED_SWITCHABLE_INTERP),
                    vp9_switchable_interp_encodings +
                    vp9_switchable_interp_map[mi->interp_filter]);
      } else {
        assert(mi->interp_filter == cpi->common.mcomp_filter_type);
      }
    }
676

Ronald S. Bultje's avatar
Ronald S. Bultje committed
677
678
679
680
681
682
    // does the feature use compound prediction or not
    // (if not specified at the frame/segment level)
    if (cpi->common.comp_pred_mode == HYBRID_PREDICTION) {
      vp9_write(bc, mi->second_ref_frame > INTRA_FRAME,
                vp9_get_pred_prob(pc, xd, PRED_COMP));
    }
John Koleszar's avatar
John Koleszar committed
683

Ronald S. Bultje's avatar
Ronald S. Bultje committed
684
685
    switch (mode) { /* new, split require MVs */
      case NEWMV:
686
#ifdef ENTROPY_STATS
Ronald S. Bultje's avatar
Ronald S. Bultje committed
687
        active_section = 5;
688
#endif
689
690
691
692
693
694
695
696
        vp9_encode_mv(bc,
                      &mi->mv[0].as_mv, &mi->best_mv.as_mv,
                      nmvc, xd->allow_high_precision_mv);

        if (mi->second_ref_frame > 0)
          vp9_encode_mv(bc,
                        &mi->mv[1].as_mv, &mi->best_second_mv.as_mv,
                        nmvc, xd->allow_high_precision_mv);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
697
698
699
        break;
      case SPLITMV: {
        int j = 0;
John Koleszar's avatar
John Koleszar committed
700

Ronald S. Bultje's avatar
Ronald S. Bultje committed
701
702
703
704
705
706
707
708
709
        do {
          B_PREDICTION_MODE blockmode;
          int_mv blockmv;
          int k = -1;  /* first block in subset j */
          int mv_contz;
          int_mv leftmv, abovemv;

          blockmode = cpi->mb.partition_info->bmi[j].mode;
          blockmv = cpi->mb.partition_info->bmi[j].mv;
710
          k = j;
711
          leftmv.as_int = left_block_mv(xd, m, k);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
712
713
          abovemv.as_int = above_block_mv(m, k, mis);
          mv_contz = vp9_mv_cont(&leftmv, &abovemv);
714

Ronald S. Bultje's avatar
Ronald S. Bultje committed
715
716
717
718
          write_sub_mv_ref(bc, blockmode,
                           cpi->common.fc.sub_mv_ref_prob[mv_contz]);
          cpi->sub_mv_ref_count[mv_contz][blockmode - LEFT4X4]++;
          if (blockmode == NEW4X4) {
719
#ifdef ENTROPY_STATS
Ronald S. Bultje's avatar
Ronald S. Bultje committed
720
721
            active_section = 11;
#endif
722
723
724
725
726
727
728
729
            vp9_encode_mv(bc, &blockmv.as_mv, &mi->best_mv.as_mv,
                          nmvc, xd->allow_high_precision_mv);

            if (mi->second_ref_frame > 0)
              vp9_encode_mv(bc,
                            &cpi->mb.partition_info->bmi[j].second_mv.as_mv,
                            &mi->best_second_mv.as_mv,
                            nmvc, xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
730
          }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
731
732
733
734
735
736
737
        } while (++j < cpi->mb.partition_info->count);
        break;
      }
      default:
        break;
    }
  }
John Koleszar's avatar
John Koleszar committed
738

739
740
741
742
743
744
745
#if CONFIG_AB4X4
  if (((rf == INTRA_FRAME && mi->sb_type >= BLOCK_SIZE_SB8X8) ||
       (rf != INTRA_FRAME && mi->sb_type >= BLOCK_SIZE_SB8X8)) &&
      pc->txfm_mode == TX_MODE_SELECT &&
      !(skip_coeff || vp9_segfeature_active(xd, segment_id,
                                            SEG_LVL_SKIP)))
#else
746
747
748
749
  if (((rf == INTRA_FRAME && mode != I4X4_PRED) ||
       (rf != INTRA_FRAME && mode != SPLITMV)) &&
      pc->txfm_mode == TX_MODE_SELECT &&
      !(skip_coeff || vp9_segfeature_active(xd, segment_id,
750
751
752
                                            SEG_LVL_SKIP)))
#endif
  {
753
754
755
756
757
758
759
760
761
    TX_SIZE sz = mi->txfm_size;
    // FIXME(rbultje) code ternary symbol once all experiments are merged
    vp9_write(bc, sz != TX_4X4, pc->prob_tx[0]);
    if (mi->sb_type >= BLOCK_SIZE_MB16X16 && sz != TX_4X4) {
      vp9_write(bc, sz != TX_8X8, pc->prob_tx[1]);
      if (mi->sb_type >= BLOCK_SIZE_SB32X32 && sz != TX_8X8)
        vp9_write(bc, sz != TX_16X16, pc->prob_tx[2]);
    }
  }
John Koleszar's avatar
John Koleszar committed
762
}
763

Ronald S. Bultje's avatar
Ronald S. Bultje committed
764
static void write_mb_modes_kf(const VP9_COMP *cpi,
765
                              MODE_INFO *m,
766
                              vp9_writer *bc, int mi_row, int mi_col) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
767
768
769
770
771
772
  const VP9_COMMON *const c = &cpi->common;
  const MACROBLOCKD *const xd = &cpi->mb.e_mbd;
  const int mis = c->mode_info_stride;
  const int ym = m->mbmi.mode;
  const int segment_id = m->mbmi.segment_id;
  int skip_coeff;
773

774
  if (xd->update_mb_segmentation_map)
775
776
    write_mb_segid(bc, &m->mbmi, xd);

777
  if (vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
778
779
    skip_coeff = 1;
  } else {
780
    skip_coeff = m->mbmi.mb_skip_coeff;
781
    vp9_write(bc, skip_coeff, vp9_get_pred_prob(c, xd, PRED_MBSKIP));
782
783
  }

784
785
786
787
#if CONFIG_AB4X4
  if (m->mbmi.sb_type >= BLOCK_SIZE_SB8X8)
    sb_kfwrite_ymode(bc, ym, c->sb_kf_ymode_prob[c->kf_ymode_probs_index]);
#else
788
  if (m->mbmi.sb_type > BLOCK_SIZE_SB8X8)
789
790
791
    sb_kfwrite_ymode(bc, ym, c->sb_kf_ymode_prob[c->kf_ymode_probs_index]);
  else
    kfwrite_ymode(bc, ym, c->kf_ymode_prob[c->kf_ymode_probs_index]);
792
#endif
793

794
795
796
#if CONFIG_AB4X4
  if (m->mbmi.sb_type < BLOCK_SIZE_SB8X8) {
#else
Yaowu Xu's avatar
Yaowu Xu committed
797
  if (ym == I4X4_PRED) {
798
#endif
799
800
    int i = 0;
    do {
801
      const B_PREDICTION_MODE a = above_block_mode(m, i, mis);
802
      const B_PREDICTION_MODE l = (xd->left_available ||
Jingning Han's avatar
Jingning Han committed
803
                                  (i & 1)) ?
804
                                  left_block_mode(m, i) : B_DC_PRED;
805
806
      const int bm = m->bmi[i].as_mode.first;

Paul Wilkins's avatar
Paul Wilkins committed
807
/*#ifdef ENTROPY_STATS
808
      ++intra_mode_stats [A] [L] [bm];
Paul Wilkins's avatar
Paul Wilkins committed
809
#endif*/
810
      write_kf_bmode(bc, bm, c->kf_bmode_prob[a][l]);
Jingning Han's avatar
Jingning Han committed
811
    } while (++i < 4);
812
813
  }

Jingning Han's avatar
Jingning Han committed
814
815
  write_uv_mode(bc, m->mbmi.uv_mode, c->kf_uv_mode_prob[ym]);

816
817
818
819
#if CONFIG_AB4X4
  if (m->mbmi.sb_type >= BLOCK_SIZE_SB8X8 && c->txfm_mode == TX_MODE_SELECT &&
      !(skip_coeff || vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))) {
#else
820
821
  if (ym != I4X4_PRED && c->txfm_mode == TX_MODE_SELECT &&
      !(skip_coeff || vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))) {
822
#endif
823
824
825
826
827
828
829
830
831
    TX_SIZE sz = m->mbmi.txfm_size;
    // FIXME(rbultje) code ternary symbol once all experiments are merged
    vp9_write(bc, sz != TX_4X4, c->prob_tx[0]);
    if (m->mbmi.sb_type >= BLOCK_SIZE_MB16X16 && sz != TX_4X4) {
      vp9_write(bc, sz != TX_8X8, c->prob_tx[1]);
      if (m->mbmi.sb_type >= BLOCK_SIZE_SB32X32 && sz != TX_8X8)
        vp9_write(bc, sz != TX_16X16, c->prob_tx[2]);
    }
  }
832
833
}

Ronald S. Bultje's avatar
Ronald S. Bultje committed
834
835
static void write_modes_b(VP9_COMP *cpi, MODE_INFO *m, vp9_writer *bc,
                          TOKENEXTRA **tok, TOKENEXTRA *tok_end,
836
                          int mi_row, int mi_col) {
837
  VP9_COMMON *const cm = &cpi->common;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
838
839
840
  MACROBLOCKD *const xd = &cpi->mb.e_mbd;

  xd->mode_info_context = m;
841
842
843
  set_mi_row_col(&cpi->common, xd, mi_row,
                 1 << mi_height_log2(m->mbmi.sb_type),
                 mi_col, 1 << mi_width_log2(m->mbmi.sb_type));
844
  if (cm->frame_type == KEY_FRAME) {
845
    write_mb_modes_kf(cpi, m, bc, mi_row, mi_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
846
847
848
849
#ifdef ENTROPY_STATS
    active_section = 8;
#endif
  } else {
850
    pack_inter_mode_mvs(cpi, m, bc, mi_row, mi_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
851
852
853
854
855
856
857
858
859
#ifdef ENTROPY_STATS
    active_section = 1;
#endif
  }

  assert(*tok < tok_end);
  pack_mb_tokens(bc, tok, tok_end);
}

860
861
static void write_modes_sb(VP9_COMP *cpi, MODE_INFO *m, vp9_writer *bc,
                           TOKENEXTRA **tok, TOKENEXTRA *tok_end,
862
                           int mi_row, int mi_col,
863
864
                           BLOCK_SIZE_TYPE bsize) {
  VP9_COMMON *const cm = &cpi->common;
865
  MACROBLOCKD *xd = &cpi->mb.e_mbd;
866
867
  const int mis = cm->mode_info_stride;
  int bwl, bhl;
868
869
  int bsl = b_width_log2(bsize);
  int bs = (1 << bsl) / 4;  // mode_info step for subsize
870
871
872
873
  int n;
  PARTITION_TYPE partition;
  BLOCK_SIZE_TYPE subsize;

874
  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
875
876
    return;

877
878
  bwl = b_width_log2(m->mbmi.sb_type);
  bhl = b_height_log2(m->mbmi.sb_type);
879
880
881
882
883
884
885
886
887
888
889
890
891

  // parse the partition type
  if ((bwl == bsl) && (bhl == bsl))
    partition = PARTITION_NONE;
  else if ((bwl == bsl) && (bhl < bsl))
    partition = PARTITION_HORZ;
  else if ((bwl < bsl) && (bhl == bsl))
    partition = PARTITION_VERT;
  else if ((bwl < bsl) && (bhl < bsl))
    partition = PARTITION_SPLIT;
  else
    assert(0);

892
893
894
895
896
897
898
899
900
#if CONFIG_AB4X4
  if (bsize < BLOCK_SIZE_SB8X8)
    if (xd->ab_index != 0)
      return;
#endif

#if CONFIG_AB4X4
  if (bsize >= BLOCK_SIZE_SB8X8) {
#else
901
  if (bsize > BLOCK_SIZE_SB8X8) {
902
#endif
903
    int pl;
904
905
    xd->left_seg_context = cm->left_seg_context + (mi_row & MI_MASK);
    xd->above_seg_context = cm->above_seg_context + mi_col;
906
    pl = partition_plane_context(xd, bsize);
907
    // encode the partition information
908
    write_token(bc, vp9_partition_tree, cm->fc.partition_prob[pl],
909
                vp9_partition_encodings + partition);
910
  }
911

912
913
  subsize = get_subsize(bsize, partition);

914
915
  switch (partition) {
    case PARTITION_NONE:
916
      write_modes_b(cpi, m, bc, tok, tok_end, mi_row, mi_col);
917
918
      break;
    case PARTITION_HORZ:
919
      write_modes_b(cpi, m, bc, tok, tok_end, mi_row, mi_col);
920
921
      if ((mi_row + bs) < cm->mi_rows)
        write_modes_b(cpi, m + bs * mis, bc, tok, tok_end, mi_row + bs, mi_col);
922
923
      break;
    case PARTITION_VERT:
924
      write_modes_b(cpi, m, bc