vp9_bitstream.c 50.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 16 17
#include "vpx/vpx_encoder.h"
#include "vpx_mem/vpx_mem.h"

18
#include "vp9/common/vp9_entropymode.h"
19
#include "vp9/common/vp9_entropymv.h"
20
#include "vp9/common/vp9_findnearmv.h"
21
#include "vp9/common/vp9_tile_common.h"
22 23 24 25
#include "vp9/common/vp9_seg_common.h"
#include "vp9/common/vp9_pred_common.h"
#include "vp9/common/vp9_entropy.h"
#include "vp9/common/vp9_mvref_common.h"
26
#include "vp9/common/vp9_treecoder.h"
27 28 29 30 31 32 33
#include "vp9/common/vp9_systemdependent.h"
#include "vp9/common/vp9_pragmas.h"

#include "vp9/encoder/vp9_mcomp.h"
#include "vp9/encoder/vp9_encodemv.h"
#include "vp9/encoder/vp9_bitstream.h"
#include "vp9/encoder/vp9_segmentation.h"
34
#include "vp9/encoder/vp9_subexp.h"
35 36
#include "vp9/encoder/vp9_write_bit_buffer.h"

Paul Wilkins's avatar
Paul Wilkins committed
37

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

#ifdef ENTROPY_STATS
43 44 45
int intra_mode_stats[INTRA_MODES]
                    [INTRA_MODES]
                    [INTRA_MODES];
46
vp9_coeff_stats tree_update_hist[TX_SIZES][BLOCK_TYPES];
47

John Koleszar's avatar
John Koleszar committed
48 49 50
extern unsigned int active_section;
#endif

51

52
#ifdef MODE_STATS
53 54 55
int64_t tx_count_32x32p_stats[TX_SIZE_CONTEXTS][TX_SIZES];
int64_t tx_count_16x16p_stats[TX_SIZE_CONTEXTS][TX_SIZES - 1];
int64_t tx_count_8x8p_stats[TX_SIZE_CONTEXTS][TX_SIZES - 2];
56
int64_t switchable_interp_stats[SWITCHABLE_FILTER_CONTEXTS][SWITCHABLE_FILTERS];
57 58 59 60 61 62 63

void init_tx_count_stats() {
  vp9_zero(tx_count_32x32p_stats);
  vp9_zero(tx_count_16x16p_stats);
  vp9_zero(tx_count_8x8p_stats);
}

64 65 66 67
void init_switchable_interp_stats() {
  vp9_zero(switchable_interp_stats);
}

68 69
static void update_tx_count_stats(VP9_COMMON *cm) {
  int i, j;
70
  for (i = 0; i < TX_SIZE_CONTEXTS; i++) {
71
    for (j = 0; j < TX_SIZES; j++) {
72 73 74
      tx_count_32x32p_stats[i][j] += cm->fc.tx_count_32x32p[i][j];
    }
  }
75
  for (i = 0; i < TX_SIZE_CONTEXTS; i++) {
76
    for (j = 0; j < TX_SIZES - 1; j++) {
77 78 79
      tx_count_16x16p_stats[i][j] += cm->fc.tx_count_16x16p[i][j];
    }
  }
80
  for (i = 0; i < TX_SIZE_CONTEXTS; i++) {
81
    for (j = 0; j < TX_SIZES - 2; j++) {
82 83 84 85 86
      tx_count_8x8p_stats[i][j] += cm->fc.tx_count_8x8p[i][j];
    }
  }
}

87 88
static void update_switchable_interp_stats(VP9_COMMON *cm) {
  int i, j;
89 90
  for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
    for (j = 0; j < SWITCHABLE_FILTERS; ++j)
91 92 93
      switchable_interp_stats[i][j] += cm->fc.switchable_interp_count[i][j];
}

94 95 96 97 98 99 100 101
void write_tx_count_stats() {
  int i, j;
  FILE *fp = fopen("tx_count.bin", "wb");
  fwrite(tx_count_32x32p_stats, sizeof(tx_count_32x32p_stats), 1, fp);
  fwrite(tx_count_16x16p_stats, sizeof(tx_count_16x16p_stats), 1, fp);
  fwrite(tx_count_8x8p_stats, sizeof(tx_count_8x8p_stats), 1, fp);
  fclose(fp);

102
  printf(
103
      "vp9_default_tx_count_32x32p[TX_SIZE_CONTEXTS][TX_SIZES] = {\n");
104 105
  for (i = 0; i < TX_SIZE_CONTEXTS; i++) {
    printf("  { ");
106
    for (j = 0; j < TX_SIZES; j++) {
107 108 109 110 111
      printf("%"PRId64", ", tx_count_32x32p_stats[i][j]);
    }
    printf("},\n");
  }
  printf("};\n");
112
  printf(
113
      "vp9_default_tx_count_16x16p[TX_SIZE_CONTEXTS][TX_SIZES-1] = {\n");
114 115
  for (i = 0; i < TX_SIZE_CONTEXTS; i++) {
    printf("  { ");
116
    for (j = 0; j < TX_SIZES - 1; j++) {
117 118 119 120 121
      printf("%"PRId64", ", tx_count_16x16p_stats[i][j]);
    }
    printf("},\n");
  }
  printf("};\n");
122
  printf(
123
      "vp9_default_tx_count_8x8p[TX_SIZE_CONTEXTS][TX_SIZES-2] = {\n");
124 125
  for (i = 0; i < TX_SIZE_CONTEXTS; i++) {
    printf("  { ");
126
    for (j = 0; j < TX_SIZES - 2; j++) {
127 128 129 130 131 132
      printf("%"PRId64", ", tx_count_8x8p_stats[i][j]);
    }
    printf("},\n");
  }
  printf("};\n");
}
133 134 135 136 137 138 139 140

void write_switchable_interp_stats() {
  int i, j;
  FILE *fp = fopen("switchable_interp.bin", "wb");
  fwrite(switchable_interp_stats, sizeof(switchable_interp_stats), 1, fp);
  fclose(fp);

  printf(
141
      "vp9_default_switchable_filter_count[SWITCHABLE_FILTER_CONTEXTS]"
142
      "[SWITCHABLE_FILTERS] = {\n");
143
  for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
144
    printf("  { ");
145
    for (j = 0; j < SWITCHABLE_FILTERS; j++) {
146 147 148 149 150 151
      printf("%"PRId64", ", switchable_interp_stats[i][j]);
    }
    printf("},\n");
  }
  printf("};\n");
}
152 153
#endif

154 155 156 157 158
static INLINE void write_be32(uint8_t *p, int value) {
  p[0] = value >> 24;
  p[1] = value >> 16;
  p[2] = value >> 8;
  p[3] = value;
159 160
}

161 162 163 164 165
void vp9_encode_unsigned_max(struct vp9_write_bit_buffer *wb,
                             int data, int max) {
  vp9_wb_write_literal(wb, data, get_unsigned_bits(max));
}

166 167 168 169
static void update_mode(vp9_writer *w, int n, vp9_tree tree,
                        vp9_prob Pcur[/* n-1 */],
                        unsigned int bct[/* n-1 */][2],
                        const unsigned int num_events[/* n */]) {
170 171
  int i = 0;

172
  vp9_tree_probs_from_distribution(tree, bct, num_events, 0);
173 174
  n--;

175 176
  for (i = 0; i < n; ++i)
    vp9_cond_prob_diff_update(w, &Pcur[i], bct[i]);
177 178 179 180 181
}

static void update_mbintra_mode_probs(VP9_COMP* const cpi,
                                      vp9_writer* const bc) {
  VP9_COMMON *const cm = &cpi->common;
182
  int j;
183
  unsigned int bct[INTRA_MODES - 1][2];
184

185
  for (j = 0; j < BLOCK_SIZE_GROUPS; j++)
186
    update_mode(bc, INTRA_MODES, vp9_intra_mode_tree,
187 188
                cm->fc.y_mode_prob[j], bct,
                (unsigned int *)cpi->y_mode_count[j]);
189 190
}

191 192 193
static void write_selected_tx_size(const VP9_COMP *cpi, MODE_INFO *m,
                                   TX_SIZE tx_size, BLOCK_SIZE bsize,
                                   vp9_writer *w) {
194
  const MACROBLOCKD *const xd = &cpi->mb.e_mbd;
195
  const vp9_prob *tx_probs = get_tx_probs2(xd, &cpi->common.fc.tx_probs, m);
196
  vp9_write(w, tx_size != TX_4X4, tx_probs[0]);
197
  if (bsize >= BLOCK_16X16 && tx_size != TX_4X4) {
198
    vp9_write(w, tx_size != TX_8X8, tx_probs[1]);
199
    if (bsize >= BLOCK_32X32 && tx_size != TX_8X8)
200 201 202 203
      vp9_write(w, tx_size != TX_16X16, tx_probs[2]);
  }
}

204 205 206
static int write_skip_coeff(const VP9_COMP *cpi, int segment_id, MODE_INFO *m,
                            vp9_writer *w) {
  const MACROBLOCKD *const xd = &cpi->mb.e_mbd;
207
  if (vp9_segfeature_active(&cpi->common.seg, segment_id, SEG_LVL_SKIP)) {
208 209
    return 1;
  } else {
Paul Wilkins's avatar
Paul Wilkins committed
210
    const int skip_coeff = m->mbmi.skip_coeff;
211
    vp9_write(w, skip_coeff, vp9_get_pred_prob_mbskip(&cpi->common, xd));
212 213 214 215
    return skip_coeff;
  }
}

216
void vp9_update_skip_probs(VP9_COMP *cpi, vp9_writer *w) {
217
  VP9_COMMON *cm = &cpi->common;
218 219
  int k;

220
  for (k = 0; k < MBSKIP_CONTEXTS; ++k)
221
    vp9_cond_prob_diff_update(w, &cm->fc.mbskip_probs[k], cm->counts.mbskip[k]);
222 223 224 225 226 227
}

static void write_intra_mode(vp9_writer *bc, int m, const vp9_prob *p) {
  write_token(bc, vp9_intra_mode_tree, p, vp9_intra_mode_encodings + m);
}

228
static void update_switchable_interp_probs(VP9_COMP *cpi, vp9_writer *w) {
229
  VP9_COMMON *const cm = &cpi->common;
230
  unsigned int branch_ct[SWITCHABLE_FILTERS - 1][2];
231
  int i, j;
232
  for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j) {
233 234 235 236 237 238
    vp9_tree_probs_from_distribution(vp9_switchable_interp_tree, branch_ct,
                                     cm->counts.switchable_interp[j], 0);

    for (i = 0; i < SWITCHABLE_FILTERS - 1; ++i)
      vp9_cond_prob_diff_update(w, &cm->fc.switchable_interp_prob[j][i],
                                branch_ct[i]);
239
  }
240

241 242
#ifdef MODE_STATS
  if (!cpi->dummy_packing)
243
    update_switchable_interp_stats(cm);
244
#endif
245 246
}

247
static void update_inter_mode_probs(VP9_COMMON *cm, vp9_writer *w) {
248 249
  int i, j;

250
  for (i = 0; i < INTER_MODE_CONTEXTS; ++i) {
251
    unsigned int branch_ct[INTER_MODES - 1][2];
252
    vp9_tree_probs_from_distribution(vp9_inter_mode_tree, branch_ct,
253
                                     cm->counts.inter_mode[i], NEARESTMV);
254

255
    for (j = 0; j < INTER_MODES - 1; ++j)
256
      vp9_cond_prob_diff_update(w, &cm->fc.inter_mode_probs[i][j],
257
                                branch_ct[j]);
258 259 260
  }
}

261
static void pack_mb_tokens(vp9_writer* const bc,
262 263 264
                           TOKENEXTRA **tp,
                           const TOKENEXTRA *const stop) {
  TOKENEXTRA *p = *tp;
John Koleszar's avatar
John Koleszar committed
265

266
  while (p < stop && p->token != EOSB_TOKEN) {
267
    const int t = p->token;
268
    const struct vp9_token *const a = vp9_coef_encodings + t;
269
    const vp9_extra_bit *const b = vp9_extra_bits + t;
John Koleszar's avatar
John Koleszar committed
270
    int i = 0;
271
    const vp9_prob *pp;
John Koleszar's avatar
John Koleszar committed
272
    int v = a->value;
273
    int n = a->len;
274
    vp9_prob probs[ENTROPY_NODES];
John Koleszar's avatar
John Koleszar committed
275

276
    if (t >= TWO_TOKEN) {
277
      vp9_model_to_full_probs(p->context_tree, probs);
278 279 280 281
      pp = probs;
    } else {
      pp = p->context_tree;
    }
282
    assert(pp != 0);
283

John Koleszar's avatar
John Koleszar committed
284 285 286 287 288
    /* skip one or two nodes */
    if (p->skip_eob_node) {
      n -= p->skip_eob_node;
      i = 2 * p->skip_eob_node;
    }
John Koleszar's avatar
John Koleszar committed
289

John Koleszar's avatar
John Koleszar committed
290 291
    do {
      const int bb = (v >> --n) & 1;
292
      vp9_write(bc, bb, pp[i >> 1]);
293
      i = vp9_coef_tree[i + bb];
294
    } while (n);
John Koleszar's avatar
John Koleszar committed
295

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

299
      if (l) {
300
        const unsigned char *pb = b->prob;
John Koleszar's avatar
John Koleszar committed
301
        int v = e >> 1;
302
        int n = l;              /* number of bits in v, assumed nonzero */
John Koleszar's avatar
John Koleszar committed
303
        int i = 0;
John Koleszar's avatar
John Koleszar committed
304

John Koleszar's avatar
John Koleszar committed
305 306
        do {
          const int bb = (v >> --n) & 1;
307
          vp9_write(bc, bb, pb[i >> 1]);
John Koleszar's avatar
John Koleszar committed
308 309 310
          i = b->tree[i + bb];
        } while (n);
      }
John Koleszar's avatar
John Koleszar committed
311

312
      vp9_write_bit(bc, e & 1);
John Koleszar's avatar
John Koleszar committed
313
    }
John Koleszar's avatar
John Koleszar committed
314 315 316
    ++p;
  }

317
  *tp = p + (p->token == EOSB_TOKEN);
John Koleszar's avatar
John Koleszar committed
318 319
}

320
static void write_sb_mv_ref(vp9_writer *w, MB_PREDICTION_MODE mode,
321
                            const vp9_prob *p) {
322
  assert(is_inter_mode(mode));
323
  write_token(w, vp9_inter_mode_tree, p,
324
              &vp9_inter_mode_encodings[inter_mode_offset(mode)]);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
325 326
}

327

328
static void write_segment_id(vp9_writer *w, const struct segmentation *seg,
329
                             int segment_id) {
330 331
  if (seg->enabled && seg->update_map)
    treed_write(w, vp9_segment_tree, seg->tree_probs, segment_id, 3);
John Koleszar's avatar
John Koleszar committed
332 333
}

Paul Wilkins's avatar
Paul Wilkins committed
334
// This function encodes the reference frame
Ronald S. Bultje's avatar
Ronald S. Bultje committed
335
static void encode_ref_frame(VP9_COMP *cpi, vp9_writer *bc) {
336
  VP9_COMMON *const cm = &cpi->common;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
337 338
  MACROBLOCK *const x = &cpi->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
339
  MB_MODE_INFO *mi = &xd->mi_8x8[0]->mbmi;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
340
  const int segment_id = mi->segment_id;
341
  int seg_ref_active = vp9_segfeature_active(&cm->seg, segment_id,
Ronald S. Bultje's avatar
Ronald S. Bultje committed
342
                                             SEG_LVL_REF_FRAME);
John Koleszar's avatar
John Koleszar committed
343 344
  // If segment level coding of this signal is disabled...
  // or the segment allows multiple reference frame options
345
  if (!seg_ref_active) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
346 347
    // does the feature use compound prediction or not
    // (if not specified at the frame/segment level)
348
    if (cm->comp_pred_mode == HYBRID_PREDICTION) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
349
      vp9_write(bc, mi->ref_frame[1] > INTRA_FRAME,
350
                vp9_get_pred_prob_comp_inter_inter(cm, xd));
Ronald S. Bultje's avatar
Ronald S. Bultje committed
351 352
    } else {
      assert((mi->ref_frame[1] <= INTRA_FRAME) ==
353
                 (cm->comp_pred_mode == SINGLE_PREDICTION_ONLY));
Ronald S. Bultje's avatar
Ronald S. Bultje committed
354
    }
355

Ronald S. Bultje's avatar
Ronald S. Bultje committed
356 357
    if (mi->ref_frame[1] > INTRA_FRAME) {
      vp9_write(bc, mi->ref_frame[0] == GOLDEN_FRAME,
358
                vp9_get_pred_prob_comp_ref_p(cm, xd));
Ronald S. Bultje's avatar
Ronald S. Bultje committed
359 360
    } else {
      vp9_write(bc, mi->ref_frame[0] != LAST_FRAME,
361
                vp9_get_pred_prob_single_ref_p1(cm, xd));
Ronald S. Bultje's avatar
Ronald S. Bultje committed
362 363
      if (mi->ref_frame[0] != LAST_FRAME)
        vp9_write(bc, mi->ref_frame[0] != GOLDEN_FRAME,
364
                  vp9_get_pred_prob_single_ref_p2(cm, xd));
Paul Wilkins's avatar
Paul Wilkins committed
365
    }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
366 367
  } else {
    assert(mi->ref_frame[1] <= INTRA_FRAME);
368
    assert(vp9_get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME) ==
369
           mi->ref_frame[0]);
John Koleszar's avatar
John Koleszar committed
370
  }
Paul Wilkins's avatar
Paul Wilkins committed
371

Jingning Han's avatar
Jingning Han committed
372 373
  // If using the prediction model we have nothing further to do because
  // the reference frame is fully coded by the segment.
Paul Wilkins's avatar
Paul Wilkins committed
374
}
John Koleszar's avatar
John Koleszar committed
375

376
static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m, vp9_writer *bc) {
377 378
  VP9_COMMON *const cm = &cpi->common;
  const nmv_context *nmvc = &cm->fc.nmvc;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
379 380
  MACROBLOCK *const x = &cpi->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
381
  struct segmentation *seg = &cm->seg;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
382
  MB_MODE_INFO *const mi = &m->mbmi;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
383
  const MV_REFERENCE_FRAME rf = mi->ref_frame[0];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
384 385 386
  const MB_PREDICTION_MODE mode = mi->mode;
  const int segment_id = mi->segment_id;
  int skip_coeff;
387
  const BLOCK_SIZE bsize = mi->sb_type;
388
  const int allow_hp = cm->allow_high_precision_mv;
Adrian Grange's avatar
Adrian Grange committed
389

Ronald S. Bultje's avatar
Ronald S. Bultje committed
390 391
#ifdef ENTROPY_STATS
  active_section = 9;
392
#endif
393

394 395
  if (seg->update_map) {
    if (seg->temporal_update) {
Scott LaVarnway's avatar
Scott LaVarnway committed
396
      const int pred_flag = mi->seg_id_predicted;
397
      vp9_prob pred_prob = vp9_get_pred_prob_seg_id(seg, xd);
398 399 400
      vp9_write(bc, pred_flag, pred_prob);
      if (!pred_flag)
        write_segment_id(bc, seg, segment_id);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
401
    } else {
402
      write_segment_id(bc, seg, segment_id);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
403 404
    }
  }
405

406
  skip_coeff = write_skip_coeff(cpi, segment_id, m, bc);
John Koleszar's avatar
John Koleszar committed
407

408
  if (!vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
409
    vp9_write(bc, rf != INTRA_FRAME,
410
              vp9_get_pred_prob_intra_inter(cm, xd));
Paul Wilkins's avatar
Paul Wilkins committed
411

412
  if (bsize >= BLOCK_8X8 && cm->tx_mode == TX_MODE_SELECT &&
413
      !(rf != INTRA_FRAME &&
414
        (skip_coeff || vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP)))) {
415
    write_selected_tx_size(cpi, m, mi->tx_size, bsize, bc);
416 417
  }

Ronald S. Bultje's avatar
Ronald S. Bultje committed
418
  if (rf == INTRA_FRAME) {
419
#ifdef ENTROPY_STATS
Ronald S. Bultje's avatar
Ronald S. Bultje committed
420
    active_section = 6;
421
#endif
Paul Wilkins's avatar
Paul Wilkins committed
422

423
    if (bsize >= BLOCK_8X8) {
424
      write_intra_mode(bc, mode, cm->fc.y_mode_prob[size_group_lookup[bsize]]);
425
    } else {
426
      int idx, idy;
Jim Bankoski's avatar
Jim Bankoski committed
427 428 429
      const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
      const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
      for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
Jim Bankoski's avatar
Jim Bankoski committed
430
        for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
431
          const MB_PREDICTION_MODE bm = m->bmi[idy * 2 + idx].as_mode;
432
          write_intra_mode(bc, bm, cm->fc.y_mode_prob[0]);
433
        }
Jim Bankoski's avatar
Jim Bankoski committed
434
      }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
435
    }
436
    write_intra_mode(bc, mi->uv_mode, cm->fc.uv_mode_prob[mode]);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
437
  } else {
438
    vp9_prob *mv_ref_p;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
439
    encode_ref_frame(cpi, bc);
Paul Wilkins's avatar
Paul Wilkins committed
440
    mv_ref_p = cpi->common.fc.inter_mode_probs[mi->mode_context[rf]];
Yaowu Xu's avatar
Yaowu Xu committed
441

John Koleszar's avatar
John Koleszar committed
442
#ifdef ENTROPY_STATS
Ronald S. Bultje's avatar
Ronald S. Bultje committed
443
    active_section = 3;
John Koleszar's avatar
John Koleszar committed
444 445
#endif

446
    // If segment skip is not enabled code the mode.
447
    if (!vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP)) {
448
      if (bsize >= BLOCK_8X8) {
449
        write_sb_mv_ref(bc, mode, mv_ref_p);
450
        ++cm->counts.inter_mode[mi->mode_context[rf]]
451
                               [inter_mode_offset(mode)];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
452
      }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
453
    }
454

455
    if (cm->mcomp_filter_type == SWITCHABLE) {
456
      const int ctx = vp9_get_pred_context_switchable_interp(xd);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
457
      write_token(bc, vp9_switchable_interp_tree,
458
                  cm->fc.switchable_interp_prob[ctx],
459
                  &vp9_switchable_interp_encodings[mi->interp_filter]);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
460
    } else {
461
      assert(mi->interp_filter == cm->mcomp_filter_type);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
462
    }
463

464
    if (bsize < BLOCK_8X8) {
Jim Bankoski's avatar
Jim Bankoski committed
465 466
      const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
      const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
467
      int idx, idy;
Jim Bankoski's avatar
Jim Bankoski committed
468 469
      for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
        for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
470
          const int j = idy * 2 + idx;
471
          const MB_PREDICTION_MODE blockmode = m->bmi[j].as_mode;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
472
          write_sb_mv_ref(bc, blockmode, mv_ref_p);
473
          ++cm->counts.inter_mode[mi->mode_context[rf]]
474 475
                                 [inter_mode_offset(blockmode)];

Ronald S. Bultje's avatar
Ronald S. Bultje committed
476
          if (blockmode == NEWMV) {
477
#ifdef ENTROPY_STATS
Ronald S. Bultje's avatar
Ronald S. Bultje committed
478
            active_section = 11;
479
#endif
480 481 482 483 484 485
            vp9_encode_mv(cpi, bc, &m->bmi[j].as_mv[0].as_mv,
                          &mi->best_mv[0].as_mv, nmvc, allow_hp);

            if (has_second_ref(mi))
              vp9_encode_mv(cpi, bc, &m->bmi[j].as_mv[1].as_mv,
                            &mi->best_mv[1].as_mv, nmvc, allow_hp);
John Koleszar's avatar
John Koleszar committed
486
          }
487
        }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
488 489 490 491 492
      }
    } else if (mode == NEWMV) {
#ifdef ENTROPY_STATS
      active_section = 5;
#endif
493 494
      vp9_encode_mv(cpi, bc, &mi->mv[0].as_mv,
                    &mi->best_mv[0].as_mv, nmvc, allow_hp);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
495

496 497 498
      if (has_second_ref(mi))
        vp9_encode_mv(cpi, bc, &mi->mv[1].as_mv,
                      &mi->best_mv[1].as_mv, nmvc, allow_hp);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
499 500
    }
  }
John Koleszar's avatar
John Koleszar committed
501
}
502

503
static void write_mb_modes_kf(const VP9_COMP *cpi, MODE_INFO **mi_8x8,
504
                              vp9_writer *bc) {
505
  const VP9_COMMON *const cm = &cpi->common;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
506
  const MACROBLOCKD *const xd = &cpi->mb.e_mbd;
507
  const struct segmentation *const seg = &cm->seg;
508
  MODE_INFO *m = mi_8x8[0];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
509 510
  const int ym = m->mbmi.mode;
  const int segment_id = m->mbmi.segment_id;
511
  MODE_INFO *above_mi = mi_8x8[-xd->mode_info_stride];
512
  MODE_INFO *left_mi = xd->left_available ? mi_8x8[-1] : NULL;
513

514 515
  if (seg->update_map)
    write_segment_id(bc, seg, m->mbmi.segment_id);
516

517
  write_skip_coeff(cpi, segment_id, m, bc);
518

519
  if (m->mbmi.sb_type >= BLOCK_8X8 && cm->tx_mode == TX_MODE_SELECT)
520
    write_selected_tx_size(cpi, m, m->mbmi.tx_size, m->mbmi.sb_type, bc);
521

522
  if (m->mbmi.sb_type >= BLOCK_8X8) {
523
    const MB_PREDICTION_MODE A = above_block_mode(m, above_mi, 0);
524
    const MB_PREDICTION_MODE L = left_block_mode(m, left_mi, 0);
525
    write_intra_mode(bc, ym, vp9_kf_y_mode_prob[A][L]);
526
  } else {
527
    int idx, idy;
Jim Bankoski's avatar
Jim Bankoski committed
528 529
    const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[m->mbmi.sb_type];
    const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[m->mbmi.sb_type];
Jim Bankoski's avatar
Jim Bankoski committed
530 531
    for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
      for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
532 533
        int i = idy * 2 + idx;
        const MB_PREDICTION_MODE A = above_block_mode(m, above_mi, i);
534
        const MB_PREDICTION_MODE L = left_block_mode(m, left_mi, i);
535
        const int bm = m->bmi[i].as_mode;
536 537 538
#ifdef ENTROPY_STATS
        ++intra_mode_stats[A][L][bm];
#endif
539
        write_intra_mode(bc, bm, vp9_kf_y_mode_prob[A][L]);
540 541
      }
    }
542 543
  }

544
  write_intra_mode(bc, m->mbmi.uv_mode, vp9_kf_uv_mode_prob[ym]);
545 546
}

James Zern's avatar
James Zern committed
547 548
static void write_modes_b(VP9_COMP *cpi, const TileInfo *const tile,
                          MODE_INFO **mi_8x8, vp9_writer *bc,
Ronald S. Bultje's avatar
Ronald S. Bultje committed
549
                          TOKENEXTRA **tok, TOKENEXTRA *tok_end,
550
                          int mi_row, int mi_col, int index) {
551
  VP9_COMMON *const cm = &cpi->common;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
552
  MACROBLOCKD *const xd = &cpi->mb.e_mbd;
553
  MODE_INFO *m = mi_8x8[0];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
554

555
  if (m->mbmi.sb_type < BLOCK_8X8)
556
    if (index > 0)
557
      return;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
558

559 560
  xd->mi_8x8 = mi_8x8;

James Zern's avatar
James Zern committed
561
  set_mi_row_col(xd, tile,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
562
                 mi_row, num_8x8_blocks_high_lookup[m->mbmi.sb_type],
James Zern's avatar
James Zern committed
563 564
                 mi_col, num_8x8_blocks_wide_lookup[m->mbmi.sb_type],
                 cm->mi_rows, cm->mi_cols);
565
  if (frame_is_intra_only(cm)) {
566
    write_mb_modes_kf(cpi, mi_8x8, bc);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
567 568 569 570
#ifdef ENTROPY_STATS
    active_section = 8;
#endif
  } else {
571
    pack_inter_mode_mvs(cpi, m, bc);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
572 573 574 575 576 577 578 579 580
#ifdef ENTROPY_STATS
    active_section = 1;
#endif
  }

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

581 582 583 584 585 586 587 588 589
static void write_partition(VP9_COMP *cpi, int hbs, int mi_row, int mi_col,
                            PARTITION_TYPE p, BLOCK_SIZE bsize, vp9_writer *w) {
  VP9_COMMON *const cm = &cpi->common;
  const int ctx = partition_plane_context(cpi->above_seg_context,
                                          cpi->left_seg_context,
                                          mi_row, mi_col, bsize);
  const vp9_prob *const probs = get_partition_probs(cm, ctx);
  const int has_rows = (mi_row + hbs) < cm->mi_rows;
  const int has_cols = (mi_col + hbs) < cm->mi_cols;
590 591

  if (has_rows && has_cols) {
592
    write_token(w, vp9_partition_tree, probs, &vp9_partition_encodings[p]);
593
  } else if (!has_rows && has_cols) {
594 595
    assert(p == PARTITION_SPLIT || p == PARTITION_HORZ);
    vp9_write(w, p == PARTITION_SPLIT, probs[1]);
596
  } else if (has_rows && !has_cols) {
597 598
    assert(p == PARTITION_SPLIT || p == PARTITION_VERT);
    vp9_write(w, p == PARTITION_SPLIT, probs[2]);
599
  } else {
600
    assert(p == PARTITION_SPLIT);
601 602 603
  }
}

James Zern's avatar
James Zern committed
604 605
static void write_modes_sb(VP9_COMP *cpi, const TileInfo *const tile,
                           MODE_INFO **mi_8x8, vp9_writer *bc,
606
                           TOKENEXTRA **tok, TOKENEXTRA *tok_end,
607 608
                           int mi_row, int mi_col, BLOCK_SIZE bsize,
                           int index) {
609 610
  VP9_COMMON *const cm = &cpi->common;
  const int mis = cm->mode_info_stride;
611 612
  int bsl = b_width_log2(bsize);
  int bs = (1 << bsl) / 4;  // mode_info step for subsize
613
  int n;
614
  PARTITION_TYPE partition = PARTITION_NONE;
615
  BLOCK_SIZE subsize;
616
  MODE_INFO *m = mi_8x8[0];
617

618
  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
619 620
    return;

Jim Bankoski's avatar
Jim Bankoski committed
621
  partition = partition_lookup[bsl][m->mbmi.sb_type];
622

623 624
  if (bsize < BLOCK_8X8) {
    if (index > 0)
625
      return;
626
  } else {
627
    write_partition(cpi, bs, mi_row, mi_col, partition, bsize, bc);
628
  }
629

630 631
  subsize = get_subsize(bsize, partition);

632 633
  switch (partition) {
    case PARTITION_NONE:
James Zern's avatar
James Zern committed
634
      write_modes_b(cpi, tile, mi_8x8, bc, tok, tok_end, mi_row, mi_col, 0);
635 636
      break;
    case PARTITION_HORZ:
James Zern's avatar
James Zern committed
637
      write_modes_b(cpi, tile, mi_8x8, bc, tok, tok_end, mi_row, mi_col, 0);
638
      if ((mi_row + bs) < cm->mi_rows)
James Zern's avatar
James Zern committed
639 640
        write_modes_b(cpi, tile, mi_8x8 + bs * mis, bc, tok, tok_end,
                      mi_row + bs, mi_col, 1);
641 642
      break;
    case PARTITION_VERT:
James Zern's avatar
James Zern committed
643
      write_modes_b(cpi, tile, mi_8x8, bc, tok, tok_end, mi_row, mi_col, 0);
644
      if ((mi_col + bs) < cm->mi_cols)
James Zern's avatar
James Zern committed
645 646
        write_modes_b(cpi, tile, mi_8x8 + bs, bc, tok, tok_end,
                      mi_row, mi_col + bs, 1);
647 648 649
      break;
    case PARTITION_SPLIT:
      for (n = 0; n < 4; n++) {
650
        const int j = n >> 1, i = n & 1;
James Zern's avatar
James Zern committed
651 652
        write_modes_sb(cpi, tile, mi_8x8 + j * bs * mis + i * bs, bc,
                       tok, tok_end,
653
                       mi_row + j * bs, mi_col + i * bs, subsize, n);
654 655 656 657 658
      }
      break;
    default:
      assert(0);
  }
659 660

  // update partition context
661
  if (bsize >= BLOCK_8X8 &&
662
      (bsize == BLOCK_8X8 || partition != PARTITION_SPLIT))
663
    update_partition_context(cpi->above_seg_context, cpi->left_seg_context,
664
                             mi_row, mi_col, subsize, bsize);
665 666
}

James Zern's avatar
James Zern committed
667 668
static void write_modes(VP9_COMP *cpi, const TileInfo *const tile,
                        vp9_writer* const bc,
Ronald S. Bultje's avatar
Ronald S. Bultje committed
669
                        TOKENEXTRA **tok, TOKENEXTRA *tok_end) {
670 671
  VP9_COMMON *const cm = &cpi->common;
  const int mis = cm->mode_info_stride;
672
  int mi_row, mi_col;
673 674
  MODE_INFO **mi_8x8 = cm->mi_grid_visible;
  MODE_INFO **m_8x8;
John Koleszar's avatar
John Koleszar committed
675

James Zern's avatar
James Zern committed
676
  mi_8x8 += tile->mi_col_start + tile->mi_row_start * mis;
677

James Zern's avatar
James Zern committed
678
  for (mi_row = tile->mi_row_start; mi_row < tile->mi_row_end;
679 680
       mi_row += 8, mi_8x8 += 8 * mis) {
    m_8x8 = mi_8x8;
681
    vp9_zero(cpi->left_seg_context);
James Zern's avatar
James Zern committed
682
    for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end;
683
         mi_col += MI_BLOCK_SIZE, m_8x8 += MI_BLOCK_SIZE) {
James Zern's avatar
James Zern committed
684
      write_modes_sb(cpi, tile, m_8x8, bc, tok, tok_end, mi_row, mi_col,
685
                     BLOCK_64X64, 0);
686
    }
John Koleszar's avatar
John Koleszar committed
687
  }
John Koleszar's avatar
John Koleszar committed
688
}
689

690 691 692
static void build_tree_distribution(VP9_COMP *cpi, TX_SIZE tx_size) {
  vp9_coeff_probs_model *coef_probs = cpi->frame_coef_probs[tx_size];
  vp9_coeff_count *coef_counts = cpi->coef_counts[tx_size];
693
  unsigned int (*eob_branch_ct)[REF_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS] =
694 695
      cpi->common.counts.eob_branch[tx_size];
  vp9_coeff_stats *coef_branch_ct = cpi->frame_branch_ct[tx_size];
696
  int i, j, k, l, m;
697

698
  for (i = 0; i < BLOCK_TYPES; ++i) {
699 700 701 702 703
    for (j = 0; j < REF_TYPES; ++j) {
      for (k = 0; k < COEF_BANDS; ++k) {
        for (l = 0; l < PREV_COEF_CONTEXTS; ++l) {
          if (l >= 3 && k == 0)
            continue;
704
          vp9_tree_probs_from_distribution(vp9_coef_tree,
705
                                           coef_branch_ct[i][j][k][l],
706
                                           coef_counts[i][j][k][l], 0);
707 708
          coef_branch_ct[i][j][k][l][0][1] = eob_branch_ct[i][j][k][l] -
                                             coef_branch_ct[i][j][k][l][0][0];
709 710 711 712
          for (m = 0; m < UNCONSTRAINED_NODES; ++m)
            coef_probs[i][j][k][l][m] = get_binary_prob(
                                            coef_branch_ct[i][j][k][l][m][0],
                                            coef_branch_ct[i][j][k][l][m][1]);
713
#ifdef ENTROPY_STATS
714
          if (!cpi->dummy_packing) {
715
            int t;
716
            for (t = 0; t < MAX_ENTROPY_TOKENS; ++t)
717
              context_counters[tx_size][i][j][k][l][t] +=
718
                  coef_counts[i][j][k][l][t];
719
            context_counters[tx_size][i][j][k][l][MAX_ENTROPY_TOKENS] +=
720 721
                eob_branch_ct[i][j][k][l];
          }
John Koleszar's avatar
John Koleszar committed
722
#endif