vp9_bitstream.c 50 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
173
  vp9_tree_probs_from_distribution(tree, bct, num_events);
  for (i = 0; i < n - 1; ++i)
174
    vp9_cond_prob_diff_update(w, &Pcur[i], bct[i]);
175
176
177
178
179
}

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

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

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

202
203
204
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;
205
  if (vp9_segfeature_active(&cpi->common.seg, segment_id, SEG_LVL_SKIP)) {
206
207
    return 1;
  } else {
Paul Wilkins's avatar
Paul Wilkins committed
208
    const int skip_coeff = m->mbmi.skip_coeff;
209
    vp9_write(w, skip_coeff, vp9_get_pred_prob_mbskip(&cpi->common, xd));
210
211
212
213
    return skip_coeff;
  }
}

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

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

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

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

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

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

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

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

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

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

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

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

John Koleszar's avatar
John Koleszar committed
282
283
284
285
286
    /* 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
287

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

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

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

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

310
      vp9_write_bit(w, e & 1);
John Koleszar's avatar
John Koleszar committed
311
    }
John Koleszar's avatar
John Koleszar committed
312
313
314
    ++p;
  }

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

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

325

326
static void write_segment_id(vp9_writer *w, const struct segmentation *seg,
327
                             int segment_id) {
328
329
  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
330
331
}

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

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

Jingning Han's avatar
Jingning Han committed
370
371
  // 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
372
}
John Koleszar's avatar
John Koleszar committed
373

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

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

392
393
  if (seg->update_map) {
    if (seg->temporal_update) {
Scott LaVarnway's avatar
Scott LaVarnway committed
394
      const int pred_flag = mi->seg_id_predicted;
395
      vp9_prob pred_prob = vp9_get_pred_prob_seg_id(seg, xd);
396
397
398
      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
399
    } else {
400
      write_segment_id(bc, seg, segment_id);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
401
402
    }
  }
403

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

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

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

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

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

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

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

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

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

Ronald S. Bultje's avatar
Ronald S. Bultje committed
474
          if (blockmode == NEWMV) {
475
#ifdef ENTROPY_STATS
Ronald S. Bultje's avatar
Ronald S. Bultje committed
476
            active_section = 11;
477
#endif
478
479
480
481
482
483
            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
484
          }
485
        }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
486
487
488
489
490
      }
    } else if (mode == NEWMV) {
#ifdef ENTROPY_STATS
      active_section = 5;
#endif
491
492
      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
493

494
495
496
      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
497
498
    }
  }
John Koleszar's avatar
John Koleszar committed
499
}
500

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

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

515
  write_skip_coeff(cpi, segment_id, m, bc);
516

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

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

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

James Zern's avatar
James Zern committed
545
546
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
547
                          TOKENEXTRA **tok, TOKENEXTRA *tok_end,
548
                          int mi_row, int mi_col, int index) {
549
  VP9_COMMON *const cm = &cpi->common;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
550
  MACROBLOCKD *const xd = &cpi->mb.e_mbd;
551
  MODE_INFO *m = mi_8x8[0];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
552

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

557
558
  xd->mi_8x8 = mi_8x8;

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

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

579
580
581
582
583
584
585
586
587
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;
588
589

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

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

616
  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
617
618
    return;

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

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

628
629
  subsize = get_subsize(bsize, partition);

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

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

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

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

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

688
689
690
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];
691
  unsigned int (*eob_branch_ct)[REF_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS] =
692
693
      cpi->common.counts.eob_branch[tx_size];
  vp9_coeff_stats *coef_branch_ct = cpi->frame_branch_ct[tx_size];
694
  int i, j, k, l, m;
695

696
  for (i = 0; i < BLOCK_TYPES; ++i) {
697
698
699
700
701
    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;
702
          vp9_tree_probs_from_distribution(vp9_coef_tree,
703
                                           coef_branch_ct[i][j][k][l],
704
                                           coef_counts[i][j][k][l]);
705
706
          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];
707
708
709
710
          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]);
711
#ifdef ENTROPY_STATS
712
          if (!cpi->dummy_packing) {
713
            int t;
714
            for (t = 0; t < MAX_ENTROPY_TOKENS; ++t)
715
              context_counters[tx_size][i][j][k][l][t] +=
716
                  coef_counts[i][j][k][l][t];
717
            context_counters[tx_size][i][j][k][l][MAX_ENTROPY_TOKENS] +=
718
719
                eob_branch_ct[i][j][k][l];
          }
John Koleszar's avatar
John Koleszar committed
720
#endif
721
        }
Daniel Kang's avatar
Daniel Kang committed
722
723
724
      }
    }
  }
725
726
727
}

static void build_coeff_contexts(VP9_COMP *cpi) {
728
729
730
  TX_SIZE t;
  for (t = TX_4X4; t <= TX_32X32; t++)
    build_tree_distribution(cpi, t);
John Koleszar's avatar
John Koleszar committed
731
732
}

733
734
735
736
737
738
static void update_coef_probs_common(vp9_writer* const bc, VP9_COMP *cpi,
                                     TX_SIZE tx_size) {
  vp9_coeff_probs_model *new_frame_coef_probs = cpi->frame_coef_probs[tx_size];
  vp9_coeff_probs_model *old_frame_coef_probs =
      cpi->common.fc.coef_probs[tx_size];
  vp9_coeff_stats *frame_branch_ct = cpi->frame_branch_ct[tx_size];
739
  const vp9_prob upd = DIFF_UPDATE_PROB;
740
  const int entropy_nodes_update = UNCONSTRAINED_NODES;
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
  int i, j, k, l, t;
  switch (cpi->sf.use_fast_coef_updates) {
    case 0: {
      /* dry run to see if there is any udpate at all needed */
      int savings = 0;
      int update[2] = {0, 0};
      for (i = 0; i < BLOCK_TYPES; ++i) {
        for (j = 0; j < REF_TYPES; ++j) {
          for (k = 0; k < COEF_BANDS; ++k) {
            for (l = 0; l < PREV_COEF_CONTEXTS; ++l) {
              for (t = 0; t < entropy_nodes_update; ++t) {
                vp9_prob newp = new_frame_coef_probs[i][j][k][l][t];
                const vp9_prob oldp = old_frame_coef_probs[i][j][k][l][t];
                int s;
                int u = 0;

                if (l >= 3 && k == 0)
                  continue;
                if (t == PIVOT_NODE)
                  s = vp9_prob_diff_update_savings_search_model(
                      frame_branch_ct[i][j][k][l][0],
                      old_frame_coef_probs[i][j][k][l], &newp, upd, i, j);
                else
                  s = vp9_prob_diff_update_savings_search(
                      frame_branch_ct[i][j][k][l][t], oldp, &newp, upd);
                if (s > 0 && newp != oldp)
                  u = 1;
                if (u)
                  savings += s - (int)(vp9_cost_zero(upd));
                else
                  savings -= (int)(vp9_cost_zero(upd));
                update[u]++;
              }
            }
          }
        }
      }
778

779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
      // printf("Update %d %d, savings %d\n", update[0], update[1], savings);
      /* Is coef updated at all */
      if (update[1] == 0 || savings < 0) {
        vp9_write_bit(bc, 0);
        return;
      }
      vp9_write_bit(bc, 1);
      for (i = 0; i < BLOCK_TYPES; ++i) {
        for (j = 0; j < REF_TYPES; ++j) {
          for (k = 0; k < COEF_BANDS; ++k) {
            for (l = 0; l < PREV_COEF_CONTEXTS; ++l) {
              // calc probs and branch cts for this frame only
              for (t = 0; t < entropy_nodes_update; ++t) {
                vp9_prob newp = new_frame_coef_probs[i][j][k][l][t];
                vp9_prob *oldp = old_frame_coef_probs[i][j][k][l] + t;
794
                const vp9_prob upd = DIFF_UPDATE_PROB;
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820