vp9_bitstream.c 64.2 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
53
54
55
56
extern unsigned int active_section;
#endif

#ifdef MODE_STATS
int count_mb_seg[4] = { 0, 0, 0, 0 };
#endif

57
58
#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)))
59
60
61
62

#define SEARCH_NEWP
static int update_bits[255];

63
64
65
66
67
68
69
70
71
72
73
74
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
75
76
77
static void compute_update_table() {
  int i;
  for (i = 0; i < 255; i++)
78
    update_bits[i] = vp9_count_term_subexp(i, SUBEXP_PARAM, 255);
79
80
}

John Koleszar's avatar
John Koleszar committed
81
82
83
84
85
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;
86
87
}

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

  i = split_index(i, n - 1, modulus);
  return i;
99
}
100

101
102
static void write_prob_diff_update(vp9_writer *const bc,
                                   vp9_prob newp, vp9_prob oldp) {
John Koleszar's avatar
John Koleszar committed
103
  int delp = remap_prob(newp, oldp);
104
  vp9_encode_term_subexp(bc, delp, SUBEXP_PARAM, 255);
105
106
}

107
static int prob_diff_update_cost(vp9_prob newp, vp9_prob oldp) {
John Koleszar's avatar
John Koleszar committed
108
109
  int delp = remap_prob(newp, oldp);
  return update_bits[delp] * 256;
110
}
111

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

125
126
  vp9_tree_probs_from_distribution(tree, Pnew, bct, num_events, 0);
  n--;
John Koleszar's avatar
John Koleszar committed
127
128

  do {
129
130
    new_b += cost_branch(bct[i], Pnew[i]);
    old_b += cost_branch(bct[i], Pcur[i]);
John Koleszar's avatar
John Koleszar committed
131
132
133
  } while (++i < n);

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

136
    vp9_write_bit(bc, 1);
John Koleszar's avatar
John Koleszar committed
137

John Koleszar's avatar
John Koleszar committed
138
    do {
139
      const vp9_prob p = Pnew[i];
John Koleszar's avatar
John Koleszar committed
140

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

147
static void update_mbintra_mode_probs(VP9_COMP* const cpi,
148
                                      vp9_writer* const bc) {
149
  VP9_COMMON *const cm = &cpi->common;
John Koleszar's avatar
John Koleszar committed
150

151
152
153
154
155
156
157
158
159
  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
160
161
}

162
163
void vp9_update_skip_probs(VP9_COMP *cpi) {
  VP9_COMMON *const pc = &cpi->common;
John Koleszar's avatar
John Koleszar committed
164
  int k;
Paul Wilkins's avatar
Paul Wilkins committed
165

166
  for (k = 0; k < MBSKIP_CONTEXTS; ++k)
John Koleszar's avatar
John Koleszar committed
167
168
    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
169
170
}

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

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

  // Set the prediction probability structures to defaults
197
  if (cm->frame_type != KEY_FRAME) {
John Koleszar's avatar
John Koleszar committed
198
199
    // From the prediction counts set the probabilities for each context
    for (i = 0; i < PREDICTION_PROBS; i++) {
200
201
202
203
      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
204
205
206

      // Decide whether or not to update the reference frame probs.
      // Returned costs are in 1/256 bit units.
207
208
      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
209

210
211
      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
212
213
214
215
216
217
218

      // 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;
219
    }
John Koleszar's avatar
John Koleszar committed
220
  }
221
222
}

223
224
225
226
227
228
// 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.
229
230
static void update_inter_mode_probs(VP9_COMMON *cm,
                                    int mode_context[INTER_MODE_CONTEXTS][4]) {
231
  int i, j;
232
  unsigned int (*mv_ref_ct)[4][2] = cm->fc.mv_ref_ct;
233
234
235
236
237
238

  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++) {
239
      int new_prob, old_cost, new_cost;
240
241
242

      // 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]);
243
      new_prob = get_binary_prob(mv_ref_ct[i][j][0], mv_ref_ct[i][j][1]);
244
245
246
247
248
249
250
251
252
253
254
      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;
      }
    }
  }
}
255

256
257
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
258
259
}

260
261
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
262
263
}

264
265
266
267
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);
}

268
269
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
270
271
}

272
273
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
274
275
276
}


277
278
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
279
280
}

281
282
283
284
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);
}

285
static int prob_update_savings(const unsigned int *ct,
286
287
288
289
290
                               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;
291
  return old_b - new_b - update_b;
292
293
294
}

static int prob_diff_update_savings_search(const unsigned int *ct,
295
296
297
                                           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
298
  int new_b, update_b, savings, bestsavings, step;
299
  vp9_prob newp, bestnewp;
John Koleszar's avatar
John Koleszar committed
300
301
302
303
304
305

  bestsavings = 0;
  bestnewp = oldp;

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

318
319
320
321
322
#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,
323
                                                 int b, int r, int q) {
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
351
352
353
354
  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

355
356
357
358
359
360
361
362
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);
363
    vp9_write_prob(bc, newp);
364
365
366
367
368
369
    *oldp = newp;
  } else {
    vp9_write(bc, 0, upd);
  }
}

370
static void pack_mb_tokens(vp9_writer* const bc,
371
372
373
                           TOKENEXTRA **tp,
                           const TOKENEXTRA *const stop) {
  TOKENEXTRA *p = *tp;
John Koleszar's avatar
John Koleszar committed
374

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

385
386
387
388
389
    if (t == EOSB_TOKEN)
    {
      ++p;
      break;
    }
390
    assert(pp != 0);
391

John Koleszar's avatar
John Koleszar committed
392
393
394
395
    /* skip one or two nodes */
    if (p->skip_eob_node) {
      n -= p->skip_eob_node;
      i = 2 * p->skip_eob_node;
396
      ncount -= p->skip_eob_node;
John Koleszar's avatar
John Koleszar committed
397
    }
John Koleszar's avatar
John Koleszar committed
398

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


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

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

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

423
      vp9_write_bit(bc, e & 1);
John Koleszar's avatar
John Koleszar committed
424
    }
John Koleszar's avatar
John Koleszar committed
425
426
427
    ++p;
  }

428
  *tp = p;
John Koleszar's avatar
John Koleszar committed
429
430
}

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

440
441
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
442
443
444
#if CONFIG_DEBUG
  assert(NEARESTMV <= m  &&  m < SPLITMV);
#endif
445
446
  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
447
448
}

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

458
459
static void write_nmv(VP9_COMP *cpi, vp9_writer *bc,
                      const MV *mv, const int_mv *ref,
John Koleszar's avatar
John Koleszar committed
460
                      const nmv_context *nmvc, int usehp) {
461
462
463
464
  MV e;
  e.row = mv->row - ref->as_mv.row;
  e.col = mv->col - ref->as_mv.col;

465
466
  vp9_encode_nmv(bc, &e, &ref->as_mv, nmvc);
  vp9_encode_nmv_fp(bc, &e, &ref->as_mv, nmvc, usehp);
467
468
}

Paul Wilkins's avatar
Paul Wilkins committed
469
470
// 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.
471
static void write_mb_segid(vp9_writer *bc,
Paul Wilkins's avatar
Paul Wilkins committed
472
                           const MB_MODE_INFO *mi, const MACROBLOCKD *xd) {
473
474
475
  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
476
477
}

Paul Wilkins's avatar
Paul Wilkins committed
478
// This function encodes the reference frame
479
static void encode_ref_frame(vp9_writer *const bc,
480
                             VP9_COMMON *const cm,
John Koleszar's avatar
John Koleszar committed
481
482
483
484
485
                             MACROBLOCKD *xd,
                             int segment_id,
                             MV_REFERENCE_FRAME rf) {
  int seg_ref_active;
  int seg_ref_count = 0;
486
487
488
  seg_ref_active = vp9_segfeature_active(xd,
                                         segment_id,
                                         SEG_LVL_REF_FRAME);
John Koleszar's avatar
John Koleszar committed
489
490

  if (seg_ref_active) {
491
492
493
494
    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
495
496
497
498
499
500
501
  }

  // 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;
502
    vp9_prob pred_prob;
John Koleszar's avatar
John Koleszar committed
503
504
505
    MV_REFERENCE_FRAME pred_rf;

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

    // Get the predicted value.
Paul Wilkins's avatar
Paul Wilkins committed
509
    pred_rf = vp9_get_pred_ref(cm, xd);
John Koleszar's avatar
John Koleszar committed
510
511
512
513
514

    // 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
515
    vp9_set_pred_flag(xd, PRED_REF, prediction_flag);
516
    vp9_write(bc, prediction_flag, pred_prob);
John Koleszar's avatar
John Koleszar committed
517
518
519

    // If not predicted correctly then code value explicitly
    if (!prediction_flag) {
520
      vp9_prob mod_refprobs[PREDICTION_PROBS];
John Koleszar's avatar
John Koleszar committed
521
522
523
524
525
526
527
528

      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] *=
529
          vp9_check_segref(xd, segment_id, INTRA_FRAME);
John Koleszar's avatar
John Koleszar committed
530
        mod_refprobs[LAST_FRAME] *=
531
          vp9_check_segref(xd, segment_id, LAST_FRAME);
John Koleszar's avatar
John Koleszar committed
532
        mod_refprobs[GOLDEN_FRAME] *=
533
534
          (vp9_check_segref(xd, segment_id, GOLDEN_FRAME) *
           vp9_check_segref(xd, segment_id, ALTREF_FRAME));
John Koleszar's avatar
John Koleszar committed
535
536
537
      }

      if (mod_refprobs[0]) {
538
        vp9_write(bc, (rf != INTRA_FRAME), mod_refprobs[0]);
John Koleszar's avatar
John Koleszar committed
539
540
541
542
543
      }

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

John Koleszar's avatar
John Koleszar committed
547
548
        if (rf != LAST_FRAME) {
          if (mod_refprobs[2]) {
549
            vp9_write(bc, (rf != GOLDEN_FRAME), mod_refprobs[2]);
John Koleszar's avatar
John Koleszar committed
550
          }
551
        }
John Koleszar's avatar
John Koleszar committed
552
      }
Paul Wilkins's avatar
Paul Wilkins committed
553
    }
John Koleszar's avatar
John Koleszar committed
554
  }
Paul Wilkins's avatar
Paul Wilkins committed
555

John Koleszar's avatar
John Koleszar committed
556
557
  // 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
558
}
John Koleszar's avatar
John Koleszar committed
559

560
// Update the probabilities used to encode reference frame data
561
562
static void update_ref_probs(VP9_COMP *const cpi) {
  VP9_COMMON *const cm = &cpi->common;
563

John Koleszar's avatar
John Koleszar committed
564
565
566
567
  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];
568

John Koleszar's avatar
John Koleszar committed
569
570
571
  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]);
572

John Koleszar's avatar
John Koleszar committed
573
574
  // Compute a modified set of probabilities to use when prediction of the
  // reference frame fails
Paul Wilkins's avatar
Paul Wilkins committed
575
  vp9_compute_mod_refprobs(cm);
576
577
}

Ronald S. Bultje's avatar
Ronald S. Bultje committed
578
static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m,
579
                                vp9_writer *bc, int mi_row, int mi_col) {
580
  VP9_COMMON *const pc = &cpi->common;
581
  const nmv_context *nmvc = &pc->fc.nmvc;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
582
583
  MACROBLOCK *const x = &cpi->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
John Koleszar's avatar
John Koleszar committed
584
  const int mis = pc->mode_info_stride;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
585
586
587
588
589
  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
590

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

Ronald S. Bultje's avatar
Ronald S. Bultje committed
594
595
#ifdef ENTROPY_STATS
  active_section = 9;
596
#endif
597

Ronald S. Bultje's avatar
Ronald S. Bultje committed
598
599
600
601
602
  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
603

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

Ronald S. Bultje's avatar
Ronald S. Bultje committed
607
608
      // If the mb segment id wasn't predicted code explicitly
      if (!prediction_flag)
Paul Wilkins's avatar
Paul Wilkins committed
609
        write_mb_segid(bc, mi, &cpi->mb.e_mbd);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
610
611
612
613
614
    } else {
      // Normal unpredicted coding
      write_mb_segid(bc, mi, &cpi->mb.e_mbd);
    }
  }
615

616
  if (vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
617
618
    skip_coeff = 1;
  } else {
619
    skip_coeff = m->mbmi.mb_skip_coeff;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
620
621
622
    vp9_write(bc, skip_coeff,
              vp9_get_pred_prob(pc, xd, PRED_MBSKIP));
  }
John Koleszar's avatar
John Koleszar committed
623

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

Ronald S. Bultje's avatar
Ronald S. Bultje committed
627
  if (rf == INTRA_FRAME) {
628
#ifdef ENTROPY_STATS
Ronald S. Bultje's avatar
Ronald S. Bultje committed
629
    active_section = 6;
630
#endif
Paul Wilkins's avatar
Paul Wilkins committed
631

632
633
634
635
#if CONFIG_AB4X4
    if (m->mbmi.sb_type >= BLOCK_SIZE_SB8X8)
      write_sb_ymode(bc, mode, pc->fc.sb_ymode_prob);
#else
636
    if (m->mbmi.sb_type > BLOCK_SIZE_SB8X8)
Paul Wilkins's avatar
Paul Wilkins committed
637
638
639
      write_sb_ymode(bc, mode, pc->fc.sb_ymode_prob);
    else
      write_ymode(bc, mode, pc->fc.ymode_prob);
640
#endif
Paul Wilkins's avatar
Paul Wilkins committed
641

642
643
644
#if CONFIG_AB4X4
    if (m->mbmi.sb_type < BLOCK_SIZE_SB8X8) {
#else
Yaowu Xu's avatar
Yaowu Xu committed
645
    if (mode == I4X4_PRED) {
646
#endif
Ronald S. Bultje's avatar
Ronald S. Bultje committed
647
648
649
650
      int j = 0;
      do {
        write_bmode(bc, m->bmi[j].as_mode.first,
                    pc->fc.bmode_prob);
Jingning Han's avatar
Jingning Han committed
651
      } while (++j < 4);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
652
    }
Jingning Han's avatar
Jingning Han committed
653
654
    write_uv_mode(bc, mi->uv_mode,
                  pc->fc.uv_mode_prob[mode]);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
655
656
  } else {
    vp9_prob mv_ref_p[VP9_MVREFS - 1];
657

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

John Koleszar's avatar
John Koleszar committed
660
#ifdef ENTROPY_STATS
Ronald S. Bultje's avatar
Ronald S. Bultje committed
661
    active_section = 3;
John Koleszar's avatar
John Koleszar committed
662
663
#endif

664
    // If segment skip is not enabled code the mode.
Paul Wilkins's avatar
Paul Wilkins committed
665
    if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) {
666
667
668
669
#if CONFIG_AB4X4
      if (mi->sb_type >= BLOCK_SIZE_SB8X8)
        write_sb_mv_ref(bc, mode, mv_ref_p);
#else
670
      if (mi->sb_type > BLOCK_SIZE_SB8X8) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
671
        write_sb_mv_ref(bc, mode, mv_ref_p);
672
      } else {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
673
674
        write_mv_ref(bc, mode, mv_ref_p);
      }
675
#endif
Ronald S. Bultje's avatar
Ronald S. Bultje committed
676
677
      vp9_accum_mv_refs(&cpi->common, mode, mi->mb_mode_context[rf]);
    }
678

679
    if (is_inter_mode(mode)) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
680
681
682
683
684
685
686
687
688
689
      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);
      }
    }
690

Ronald S. Bultje's avatar
Ronald S. Bultje committed
691
692
693
694
695
696
    // 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
697

Ronald S. Bultje's avatar
Ronald S. Bultje committed
698
699
    switch (mode) { /* new, split require MVs */
      case NEWMV:
700
#ifdef ENTROPY_STATS
Ronald S. Bultje's avatar
Ronald S. Bultje committed
701
        active_section = 5;
702
#endif
703
        write_nmv(cpi, bc, &mi->mv[0].as_mv, &mi->best_mv,
Ronald S. Bultje's avatar
Ronald S. Bultje committed
704
705
                  (const nmv_context*) nmvc,
                  xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
706

Ronald S. Bultje's avatar
Ronald S. Bultje committed
707
        if (mi->second_ref_frame > 0) {
708
          write_nmv(cpi, bc, &mi->mv[1].as_mv, &mi->best_second_mv,
Ronald S. Bultje's avatar
Ronald S. Bultje committed
709
710
711
712
713
714
                    (const nmv_context*) nmvc,
                    xd->allow_high_precision_mv);
        }
        break;
      case SPLITMV: {
        int j = 0;
John Koleszar's avatar
John Koleszar committed
715

716
#ifdef MODE_STATS
Ronald S. Bultje's avatar
Ronald S. Bultje committed
717
        ++count_mb_seg[mi->partitioning];
718
#endif
John Koleszar's avatar
John Koleszar committed
719

Ronald S. Bultje's avatar
Ronald S. Bultje committed
720
721
722
723
724
725
726
727
728
        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;
729
          k = j;
730
          leftmv.as_int = left_block_mv(xd, m, k);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
731
732
          abovemv.as_int = above_block_mv(m, k, mis);
          mv_contz = vp9_mv_cont(&leftmv, &abovemv);
733

Ronald S. Bultje's avatar
Ronald S. Bultje committed
734
735
736
737
          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) {
738
#ifdef ENTROPY_STATS
Ronald S. Bultje's avatar
Ronald S. Bultje committed
739
740
            active_section = 11;
#endif
741
            write_nmv(cpi, bc, &blockmv.as_mv, &mi->best_mv,
Ronald S. Bultje's avatar
Ronald S. Bultje committed
742
743
744
745
                      (const nmv_context*) nmvc,
                      xd->allow_high_precision_mv);

            if (mi->second_ref_frame > 0) {
746
              write_nmv(cpi, bc,
Ronald S. Bultje's avatar
Ronald S. Bultje committed
747
748
749
750
                        &cpi->mb.partition_info->bmi[j].second_mv.as_mv,
                        &mi->best_second_mv,
                        (const nmv_context*) nmvc,
                        xd->allow_high_precision_mv);
Adrian Grange's avatar
Adrian Grange committed
751
            }
John Koleszar's avatar
John Koleszar committed
752
          }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
753
754
755
756
757
758
759
        } while (++j < cpi->mb.partition_info->count);
        break;
      }
      default:
        break;
    }
  }
John Koleszar's avatar
John Koleszar committed
760

761
762
763
764
765
766
767
#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
768
769
770
771
  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,
772
773
774
                                            SEG_LVL_SKIP)))
#endif
  {
775
776
777
778
779
780
781
782
783
    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
784
}
785

Ronald S. Bultje's avatar
Ronald S. Bultje committed
786
static void write_mb_modes_kf(const VP9_COMP *cpi,
787
                              MODE_INFO *m,
788
                              vp9_writer *bc, int mi_row, int mi_col) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
789
790
791
792
793
794
  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;
795

796
  if (xd->update_mb_segmentation_map)
797
798
    write_mb_segid(bc, &m->mbmi, xd);

799
  if (vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
800
801
    skip_coeff = 1;
  } else {
802
    skip_coeff = m->mbmi.mb_skip_coeff;
803
    vp9_write(bc, skip_coeff, vp9_get_pred_prob(c, xd, PRED_MBSKIP));
804
805
  }

806
807
808
809
#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
810
  if (m->mbmi.sb_type > BLOCK_SIZE_SB8X8)
811
812
813
    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]);
814
#endif
815

816
817
818
#if CONFIG_AB4X4
  if (m->mbmi.sb_type < BLOCK_SIZE_SB8X8) {
#else
Yaowu Xu's avatar
Yaowu Xu committed
819
  if (ym == I4X4_PRED) {
820
#endif
821
822
    int i = 0;
    do {
823
      const B_PREDICTION_MODE a = above_block_mode(m, i, mis);
824
      const B_PREDICTION_MODE l = (xd->left_available ||
Jingning Han's avatar
Jingning Han committed
825
                                  (i & 1)) ?
826
                                  left_block_mode(m, i) : B_DC_PRED;
827
828
829
830
831
      const int bm = m->bmi[i].as_mode.first;

#ifdef ENTROPY_STATS
      ++intra_mode_stats [A] [L] [bm];
#endif
832
      write_kf_bmode(bc, bm, c->kf_bmode_prob[a][l]);
Jingning Han's avatar
Jingning Han committed
833
    } while (++i < 4);
834
835
  }

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

838
839
840
841
#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
842
843
  if (ym != I4X4_PRED && c->txfm_mode == TX_MODE_SELECT &&
      !(skip_coeff || vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))) {
844
#endif
845
846
847
848
849
850
851
852
853
    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]);
    }
  }
854
855
}

Ronald S. Bultje's avatar
Ronald S. Bultje committed
856
857
static void write_modes_b(VP9_COMP *cpi, MODE_INFO *m, vp9_writer *bc,
                          TOKENEXTRA **tok, TOKENEXTRA *tok_end,
858
                          int mi_row, int mi_col) {
859
  VP9_COMMON *const cm = &cpi->common;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
860
861
862
  MACROBLOCKD *const xd = &cpi->mb.e_mbd;

  xd->mode_info_context = m;
863
864
865
  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));
866
  if (cm->frame_type == KEY_FRAME) {
867
    write_mb_modes_kf(cpi, m, bc, mi_row, mi_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
868
869
870
871
#ifdef ENTROPY_STATS
    active_section = 8;
#endif
  } else {
872
    pack_inter_mode_mvs(cpi, m, bc, mi_row, mi_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
873
874
875
876
877
878
879
880
881
#ifdef ENTROPY_STATS
    active_section = 1;
#endif
  }

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

882
883
static void write_modes_sb(VP9_COMP *cpi, MODE_INFO *m, vp9_writer *bc,
                           TOKENEXTRA **tok, TOKENEXTRA *tok_end,
884
                           int mi_row, int mi_col,
885
886
                           BLOCK_SIZE_TYPE bsize) {
  VP9_COMMON *const cm = &cpi->common;
887
  MACROBLOCKD *xd = &cpi->mb.e_mbd;
888
889
890
  const int mis = cm->mode_info_stride;
  int bwl, bhl;
  int bw, bh;
891
  int bsl = mi_width_log2(bsize), bs = (1 << bsl) / 2;
892
893
894
895
  int n;
  PARTITION_TYPE partition;
  BLOCK_SIZE_TYPE subsize;

896
  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
897
898
    return;

899
900
  bwl = mi_width_log2(m->mbmi.sb_type);
  bhl = mi_height_log2(m->mbmi.sb_type);
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
  bw = 1 << bwl;
  bh = 1 << bhl;

  // 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);

916
917
918
919
920
921
922
923
924
925
926
#if CONFIG_AB4X4
  if (bsize == BLOCK_SIZE_SB8X8 && m->mbmi.sb_type < BLOCK_SIZE_SB8X8)
    partition = PARTITION_SPLIT;
  if (bsize < BLOCK_SIZE_SB8X8)
    if (xd->ab_index != 0)
      return;
#endif

#if CONFIG_AB4X4
  if (bsize >= BLOCK_SIZE_SB8X8) {
#else
927
  if (bsize > BLOCK_SIZE_SB8X8) {
928
#endif
929
    int pl;
930
931
    xd->left_seg_context = cm->left_seg_context + (mi_row & MI_MASK);
    xd->above_seg_context = cm->above_seg_context + mi_col;
932