vp9_bitstream.c 60.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
26
#include "vp9/common/vp9_seg_common.h"
#include "vp9/common/vp9_pred_common.h"
#include "vp9/common/vp9_entropy.h"
#include "vp9/common/vp9_entropymv.h"
#include "vp9/common/vp9_mvref_common.h"
27
#include "vp9/common/vp9_treecoder.h"
28
29
30
31
32
33
34
35
36
#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"
#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[VP9_INTRA_MODES]
                    [VP9_INTRA_MODES]
                    [VP9_INTRA_MODES];
46
47
48
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];
49
vp9_coeff_stats tree_update_hist_32x32[BLOCK_TYPES];
50

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

54
55
#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)))
56
57
58

static int update_bits[255];

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

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

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
void vp9_encode_unsigned_max(vp9_writer *br, int data, int max) {
  assert(data <= max);
  while (max) {
    vp9_write_bit(br, data & 1);
    data >>= 1;
    max >>= 1;
  }
}

int recenter_nonneg(int v, int m) {
  if (v > (m << 1))
    return v;
  else if (v >= m)
    return ((v - m) << 1);
  else
    return ((m - v) << 1) - 1;
}

static int get_unsigned_bits(unsigned num_values) {
  int cat = 0;
  if ((num_values--) <= 1) return 0;
  while (num_values > 0) {
    cat++;
    num_values >>= 1;
  }
  return cat;
}

void encode_uniform(vp9_writer *w, int v, int n) {
  int l = get_unsigned_bits(n);
  int m;
  if (l == 0)
    return;
  m = (1 << l) - n;
  if (v < m) {
    vp9_write_literal(w, v, l - 1);
  } else {
    vp9_write_literal(w, m + ((v - m) >> 1), l - 1);
    vp9_write_literal(w, (v - m) & 1, 1);
  }
}

int count_uniform(int v, int n) {
  int l = get_unsigned_bits(n);
  int m;
  if (l == 0) return 0;
  m = (1 << l) - n;
  if (v < m)
    return l - 1;
  else
    return l;
}

void encode_term_subexp(vp9_writer *w, int word, int k, int num_syms) {
  int i = 0;
  int mk = 0;
  while (1) {
    int b = (i ? k + i - 1 : k);
    int a = (1 << b);
    if (num_syms <= mk + 3 * a) {
      encode_uniform(w, word - mk, num_syms - mk);
      break;
    } else {
      int t = (word >= mk + a);
      vp9_write_literal(w, t, 1);
      if (t) {
        i = i + 1;
        mk += a;
      } else {
        vp9_write_literal(w, word - mk, b);
        break;
      }
    }
  }
}

int count_term_subexp(int word, int k, int num_syms) {
  int count = 0;
  int i = 0;
  int mk = 0;
  while (1) {
    int b = (i ? k + i - 1 : k);
    int a = (1 << b);
    if (num_syms <= mk + 3 * a) {
      count += count_uniform(word - mk, num_syms - mk);
      break;
    } else {
      int t = (word >= mk + a);
      count++;
      if (t) {
        i = i + 1;
        mk += a;
      } else {
        count += b;
        break;
      }
    }
  }
  return count;
}

John Koleszar's avatar
John Koleszar committed
172
173
174
static void compute_update_table() {
  int i;
  for (i = 0; i < 255; i++)
175
    update_bits[i] = count_term_subexp(i, SUBEXP_PARAM, 255);
176
177
}

John Koleszar's avatar
John Koleszar committed
178
179
180
181
182
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;
183
184
}

John Koleszar's avatar
John Koleszar committed
185
186
187
188
189
static int remap_prob(int v, int m) {
  const int n = 256;
  const int modulus = MODULUS_PARAM;
  int i;
  if ((m << 1) <= n)
190
    i = recenter_nonneg(v, m) - 1;
John Koleszar's avatar
John Koleszar committed
191
  else
192
    i = recenter_nonneg(n - 1 - v, n - 1 - m) - 1;
John Koleszar's avatar
John Koleszar committed
193
194
195

  i = split_index(i, n - 1, modulus);
  return i;
196
}
197

198
static void write_prob_diff_update(vp9_writer *w,
199
                                   vp9_prob newp, vp9_prob oldp) {
John Koleszar's avatar
John Koleszar committed
200
  int delp = remap_prob(newp, oldp);
201
  encode_term_subexp(w, delp, SUBEXP_PARAM, 255);
202
203
}

204
static int prob_diff_update_cost(vp9_prob newp, vp9_prob oldp) {
John Koleszar's avatar
John Koleszar committed
205
206
  int delp = remap_prob(newp, oldp);
  return update_bits[delp] * 256;
207
}
208

John Koleszar's avatar
John Koleszar committed
209
static void update_mode(
210
  vp9_writer *w,
John Koleszar's avatar
John Koleszar committed
211
  int n,
212
  const struct vp9_token tok[/* n */],
213
214
215
  vp9_tree tree,
  vp9_prob Pnew               [/* n-1 */],
  vp9_prob Pcur               [/* n-1 */],
John Koleszar's avatar
John Koleszar committed
216
217
218
219
220
221
  unsigned int bct            [/* n-1 */] [2],
  const unsigned int num_events[/* n */]
) {
  unsigned int new_b = 0, old_b = 0;
  int i = 0;

222
223
  vp9_tree_probs_from_distribution(tree, Pnew, bct, num_events, 0);
  n--;
John Koleszar's avatar
John Koleszar committed
224
225

  do {
226
227
    new_b += cost_branch(bct[i], Pnew[i]);
    old_b += cost_branch(bct[i], Pcur[i]);
John Koleszar's avatar
John Koleszar committed
228
229
230
  } while (++i < n);

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

233
    vp9_write_bit(w, 1);
John Koleszar's avatar
John Koleszar committed
234

John Koleszar's avatar
John Koleszar committed
235
    do {
236
      const vp9_prob p = Pnew[i];
John Koleszar's avatar
John Koleszar committed
237

238
      vp9_write_literal(w, Pcur[i] = p ? p : 1, 8);
John Koleszar's avatar
John Koleszar committed
239
240
    } while (++i < n);
  } else
241
    vp9_write_bit(w, 0);
John Koleszar's avatar
John Koleszar committed
242
243
}

244
static void update_mbintra_mode_probs(VP9_COMP* const cpi,
245
                                      vp9_writer* const bc) {
246
  VP9_COMMON *const cm = &cpi->common;
John Koleszar's avatar
John Koleszar committed
247

248
249
  vp9_prob pnew[VP9_INTRA_MODES - 1];
  unsigned int bct[VP9_INTRA_MODES - 1][2];
250

251
  update_mode(bc, VP9_INTRA_MODES, vp9_intra_mode_encodings,
252
253
              vp9_intra_mode_tree, pnew,
              cm->fc.y_mode_prob, bct, (unsigned int *)cpi->y_mode_count);
John Koleszar's avatar
John Koleszar committed
254
255
}

256
257
void vp9_update_skip_probs(VP9_COMP *cpi) {
  VP9_COMMON *const pc = &cpi->common;
John Koleszar's avatar
John Koleszar committed
258
  int k;
Paul Wilkins's avatar
Paul Wilkins committed
259

260
  for (k = 0; k < MBSKIP_CONTEXTS; ++k)
John Koleszar's avatar
John Koleszar committed
261
262
    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
263
264
}

265
static void update_switchable_interp_probs(VP9_COMP *cpi,
266
                                           vp9_writer* const bc) {
267
  VP9_COMMON *const pc = &cpi->common;
268
269
  unsigned int branch_ct[32][2];
  int i, j;
270
  for (j = 0; j <= VP9_SWITCHABLE_FILTERS; ++j) {
271
    vp9_tree_probs_from_distribution(
272
        vp9_switchable_interp_tree,
273
        pc->fc.switchable_interp_prob[j], branch_ct,
274
        cpi->switchable_interp_count[j], 0);
275
    for (i = 0; i < VP9_SWITCHABLE_FILTERS - 1; ++i) {
276
277
      if (pc->fc.switchable_interp_prob[j][i] < 1)
        pc->fc.switchable_interp_prob[j][i] = 1;
278
      vp9_write_prob(bc, pc->fc.switchable_interp_prob[j][i]);
279
280
281
282
    }
  }
}

283
// This function updates the reference frame prediction stats
284
285
static void update_refpred_stats(VP9_COMP *cpi) {
  VP9_COMMON *const cm = &cpi->common;
John Koleszar's avatar
John Koleszar committed
286
  int i;
287
  vp9_prob new_pred_probs[PREDICTION_PROBS];
John Koleszar's avatar
John Koleszar committed
288
289
290
  int old_cost, new_cost;

  // Set the prediction probability structures to defaults
291
  if (cm->frame_type != KEY_FRAME) {
John Koleszar's avatar
John Koleszar committed
292
293
    // From the prediction counts set the probabilities for each context
    for (i = 0; i < PREDICTION_PROBS; i++) {
294
295
296
297
      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
298
299
300

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

304
305
      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
306
307
308
309
310
311
312

      // 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;
313
    }
John Koleszar's avatar
John Koleszar committed
314
  }
315
316
}

317
318
319
320
321
322
// 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.
323
static void update_inter_mode_probs(VP9_COMMON *cm,
324
    int mode_context[INTER_MODE_CONTEXTS][VP9_MVREFS - 1]) {
325
  int i, j;
326
  unsigned int (*mv_ref_ct)[VP9_MVREFS - 1][2] = cm->fc.mv_ref_ct;
327
328
329
330
331

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

  for (i = 0; i < INTER_MODE_CONTEXTS; i++) {
332
    for (j = 0; j < VP9_MVREFS - 1; j++) {
333
      int new_prob, old_cost, new_cost;
334
335
336

      // 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]);
337
      new_prob = get_binary_prob(mv_ref_ct[i][j][0], mv_ref_ct[i][j][1]);
338
339
340
341
342
343
344
345
346
347
348
      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;
      }
    }
  }
}
349

350
351
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);
352
353
}

354
static int prob_update_savings(const unsigned int *ct,
355
356
357
358
359
                               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;
360
  return old_b - new_b - update_b;
361
362
363
}

static int prob_diff_update_savings_search(const unsigned int *ct,
364
365
366
                                           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
367
  int new_b, update_b, savings, bestsavings, step;
368
  vp9_prob newp, bestnewp;
John Koleszar's avatar
John Koleszar committed
369
370
371
372
373
374

  bestsavings = 0;
  bestnewp = oldp;

  step = (*bestp > oldp ? -1 : 1);
  for (newp = *bestp; newp != oldp; newp += step) {
375
376
    new_b = cost_branch256(ct, newp);
    update_b = prob_diff_update_cost(newp, oldp) + vp9_cost_upd256;
John Koleszar's avatar
John Koleszar committed
377
378
379
380
    savings = old_b - new_b - update_b;
    if (savings > bestsavings) {
      bestsavings = savings;
      bestnewp = newp;
381
    }
John Koleszar's avatar
John Koleszar committed
382
383
384
  }
  *bestp = bestnewp;
  return bestsavings;
385
386
}

387
388
389
390
static int prob_diff_update_savings_search_model(const unsigned int *ct,
                                                 const vp9_prob *oldp,
                                                 vp9_prob *bestp,
                                                 const vp9_prob upd,
391
                                                 int b, int r) {
392
393
  int i, old_b, new_b, update_b, savings, bestsavings, step;
  int newp;
394
  vp9_prob bestnewp, newplist[ENTROPY_NODES], oldplist[ENTROPY_NODES];
395
396
  vp9_model_to_full_probs(oldp, oldplist);
  vpx_memcpy(newplist, oldp, sizeof(vp9_prob) * UNCONSTRAINED_NODES);
397
398
399
  for (i = UNCONSTRAINED_NODES, old_b = 0; i < ENTROPY_NODES; ++i)
    old_b += cost_branch256(ct + 2 * i, oldplist[i]);
  old_b += cost_branch256(ct + 2 * PIVOT_NODE, oldplist[PIVOT_NODE]);
400
401

  bestsavings = 0;
402
  bestnewp = oldp[PIVOT_NODE];
403

404
  step = (*bestp > oldp[PIVOT_NODE] ? -1 : 1);
405
  newp = *bestp;
406
  for (; newp != oldp[PIVOT_NODE]; newp += step) {
407
    if (newp < 1 || newp > 255) continue;
408
    newplist[PIVOT_NODE] = newp;
409
    vp9_model_to_full_probs(newplist, newplist);
410
    for (i = UNCONSTRAINED_NODES, new_b = 0; i < ENTROPY_NODES; ++i)
411
      new_b += cost_branch256(ct + 2 * i, newplist[i]);
412
413
    new_b += cost_branch256(ct + 2 * PIVOT_NODE, newplist[PIVOT_NODE]);
    update_b = prob_diff_update_cost(newp, oldp[PIVOT_NODE]) +
414
415
416
417
418
419
420
421
422
423
424
        vp9_cost_upd256;
    savings = old_b - new_b - update_b;
    if (savings > bestsavings) {
      bestsavings = savings;
      bestnewp = newp;
    }
  }
  *bestp = bestnewp;
  return bestsavings;
}

425
426
427
428
429
430
431
432
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);
433
    vp9_write_prob(bc, newp);
434
435
436
437
438
439
    *oldp = newp;
  } else {
    vp9_write(bc, 0, upd);
  }
}

440
static void pack_mb_tokens(vp9_writer* const bc,
441
442
443
                           TOKENEXTRA **tp,
                           const TOKENEXTRA *const stop) {
  TOKENEXTRA *p = *tp;
John Koleszar's avatar
John Koleszar committed
444

John Koleszar's avatar
John Koleszar committed
445
  while (p < stop) {
446
    const int t = p->token;
447
    const struct vp9_token *const a = vp9_coef_encodings + t;
448
    const vp9_extra_bit *const b = vp9_extra_bits + t;
John Koleszar's avatar
John Koleszar committed
449
    int i = 0;
450
    const vp9_prob *pp;
John Koleszar's avatar
John Koleszar committed
451
    int v = a->value;
452
    int n = a->len;
453
    vp9_prob probs[ENTROPY_NODES];
John Koleszar's avatar
John Koleszar committed
454

455
    if (t == EOSB_TOKEN) {
456
457
458
      ++p;
      break;
    }
459
    if (t >= TWO_TOKEN) {
460
      vp9_model_to_full_probs(p->context_tree, probs);
461
462
463
464
      pp = probs;
    } else {
      pp = p->context_tree;
    }
465
    assert(pp != 0);
466

John Koleszar's avatar
John Koleszar committed
467
    /* skip one or two nodes */
468
#if !CONFIG_BALANCED_COEFTREE
John Koleszar's avatar
John Koleszar committed
469
470
471
472
    if (p->skip_eob_node) {
      n -= p->skip_eob_node;
      i = 2 * p->skip_eob_node;
    }
473
#endif
John Koleszar's avatar
John Koleszar committed
474

John Koleszar's avatar
John Koleszar committed
475
476
    do {
      const int bb = (v >> --n) & 1;
477
478
479
480
481
482
483
#if CONFIG_BALANCED_COEFTREE
      if (i == 2 && p->skip_eob_node) {
        i += 2;
        assert(bb == 1);
        continue;
      }
#endif
484
      vp9_write(bc, bb, pp[i >> 1]);
485
      i = vp9_coef_tree[i + bb];
486
    } while (n);
John Koleszar's avatar
John Koleszar committed
487

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

491
      if (l) {
492
        const unsigned char *pb = b->prob;
John Koleszar's avatar
John Koleszar committed
493
        int v = e >> 1;
494
        int n = l;              /* number of bits in v, assumed nonzero */
John Koleszar's avatar
John Koleszar committed
495
        int i = 0;
John Koleszar's avatar
John Koleszar committed
496

John Koleszar's avatar
John Koleszar committed
497
498
        do {
          const int bb = (v >> --n) & 1;
499
          vp9_write(bc, bb, pb[i >> 1]);
John Koleszar's avatar
John Koleszar committed
500
501
502
          i = b->tree[i + bb];
        } while (n);
      }
John Koleszar's avatar
John Koleszar committed
503

504
      vp9_write_bit(bc, e & 1);
John Koleszar's avatar
John Koleszar committed
505
    }
John Koleszar's avatar
John Koleszar committed
506
507
508
    ++p;
  }

509
  *tp = p;
John Koleszar's avatar
John Koleszar committed
510
511
}

512
513
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
514
#if CONFIG_DEBUG
Ronald S. Bultje's avatar
Ronald S. Bultje committed
515
  assert(NEARESTMV <= m && m <= NEWMV);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
516
#endif
517
518
  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
519
520
}

Paul Wilkins's avatar
Paul Wilkins committed
521
522
// 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.
523
static void write_mb_segid(vp9_writer *bc,
Paul Wilkins's avatar
Paul Wilkins committed
524
                           const MB_MODE_INFO *mi, const MACROBLOCKD *xd) {
525
526
527
  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
528
529
}

Paul Wilkins's avatar
Paul Wilkins committed
530
// This function encodes the reference frame
531
static void encode_ref_frame(vp9_writer *const bc,
532
                             VP9_COMMON *const cm,
John Koleszar's avatar
John Koleszar committed
533
534
535
536
537
                             MACROBLOCKD *xd,
                             int segment_id,
                             MV_REFERENCE_FRAME rf) {
  int seg_ref_active;
  int seg_ref_count = 0;
538
539
540
  seg_ref_active = vp9_segfeature_active(xd,
                                         segment_id,
                                         SEG_LVL_REF_FRAME);
John Koleszar's avatar
John Koleszar committed
541
542

  if (seg_ref_active) {
543
544
545
546
    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
547
548
549
550
551
552
553
  }

  // 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;
554
    vp9_prob pred_prob;
John Koleszar's avatar
John Koleszar committed
555
556
557
    MV_REFERENCE_FRAME pred_rf;

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

    // Get the predicted value.
Paul Wilkins's avatar
Paul Wilkins committed
561
    pred_rf = vp9_get_pred_ref(cm, xd);
John Koleszar's avatar
John Koleszar committed
562
563
564
565
566

    // 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
567
    vp9_set_pred_flag(xd, PRED_REF, prediction_flag);
568
    vp9_write(bc, prediction_flag, pred_prob);
John Koleszar's avatar
John Koleszar committed
569
570
571

    // If not predicted correctly then code value explicitly
    if (!prediction_flag) {
572
      vp9_prob mod_refprobs[PREDICTION_PROBS];
John Koleszar's avatar
John Koleszar committed
573
574
575
576
577
578
579
580

      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] *=
581
          vp9_check_segref(xd, segment_id, INTRA_FRAME);
John Koleszar's avatar
John Koleszar committed
582
        mod_refprobs[LAST_FRAME] *=
583
          vp9_check_segref(xd, segment_id, LAST_FRAME);
John Koleszar's avatar
John Koleszar committed
584
        mod_refprobs[GOLDEN_FRAME] *=
585
586
          (vp9_check_segref(xd, segment_id, GOLDEN_FRAME) *
           vp9_check_segref(xd, segment_id, ALTREF_FRAME));
John Koleszar's avatar
John Koleszar committed
587
588
589
      }

      if (mod_refprobs[0]) {
590
        vp9_write(bc, (rf != INTRA_FRAME), mod_refprobs[0]);
John Koleszar's avatar
John Koleszar committed
591
592
593
594
595
      }

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

John Koleszar's avatar
John Koleszar committed
599
600
        if (rf != LAST_FRAME) {
          if (mod_refprobs[2]) {
601
            vp9_write(bc, (rf != GOLDEN_FRAME), mod_refprobs[2]);
John Koleszar's avatar
John Koleszar committed
602
          }
603
        }
John Koleszar's avatar
John Koleszar committed
604
      }
Paul Wilkins's avatar
Paul Wilkins committed
605
    }
John Koleszar's avatar
John Koleszar committed
606
  }
Paul Wilkins's avatar
Paul Wilkins committed
607

John Koleszar's avatar
John Koleszar committed
608
609
  // 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
610
}
John Koleszar's avatar
John Koleszar committed
611

612
// Update the probabilities used to encode reference frame data
613
614
static void update_ref_probs(VP9_COMP *const cpi) {
  VP9_COMMON *const cm = &cpi->common;
615

John Koleszar's avatar
John Koleszar committed
616
617
618
619
  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];
620

John Koleszar's avatar
John Koleszar committed
621
622
623
  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]);
624

John Koleszar's avatar
John Koleszar committed
625
626
  // Compute a modified set of probabilities to use when prediction of the
  // reference frame fails
Paul Wilkins's avatar
Paul Wilkins committed
627
  vp9_compute_mod_refprobs(cm);
628
629
}

Ronald S. Bultje's avatar
Ronald S. Bultje committed
630
static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m,
631
                                vp9_writer *bc, int mi_row, int mi_col) {
632
  VP9_COMMON *const pc = &cpi->common;
633
  const nmv_context *nmvc = &pc->fc.nmvc;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
634
635
636
637
638
639
640
  MACROBLOCK *const x = &cpi->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
  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
641

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

Ronald S. Bultje's avatar
Ronald S. Bultje committed
645
646
#ifdef ENTROPY_STATS
  active_section = 9;
647
#endif
648

Ronald S. Bultje's avatar
Ronald S. Bultje committed
649
650
651
652
653
  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
654

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

Ronald S. Bultje's avatar
Ronald S. Bultje committed
658
659
      // If the mb segment id wasn't predicted code explicitly
      if (!prediction_flag)
Paul Wilkins's avatar
Paul Wilkins committed
660
        write_mb_segid(bc, mi, &cpi->mb.e_mbd);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
661
662
663
664
665
    } else {
      // Normal unpredicted coding
      write_mb_segid(bc, mi, &cpi->mb.e_mbd);
    }
  }
666

667
  if (vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
668
669
    skip_coeff = 1;
  } else {
670
    skip_coeff = m->mbmi.mb_skip_coeff;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
671
672
673
    vp9_write(bc, skip_coeff,
              vp9_get_pred_prob(pc, xd, PRED_MBSKIP));
  }
John Koleszar's avatar
John Koleszar committed
674

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

678
679
680
681
682
683
684
685
686
687
688
689
690
  if (mi->sb_type >= BLOCK_SIZE_SB8X8 && pc->txfm_mode == TX_MODE_SELECT &&
      !(rf != INTRA_FRAME &&
        (skip_coeff || vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)))) {
    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]);
    }
  }

Ronald S. Bultje's avatar
Ronald S. Bultje committed
691
  if (rf == INTRA_FRAME) {
692
#ifdef ENTROPY_STATS
Ronald S. Bultje's avatar
Ronald S. Bultje committed
693
    active_section = 6;
694
#endif
Paul Wilkins's avatar
Paul Wilkins committed
695

696
697
698
    if (m->mbmi.sb_type >= BLOCK_SIZE_SB8X8) {
      write_intra_mode(bc, mode, pc->fc.y_mode_prob);
    } else {
699
700
701
702
703
      int idx, idy;
      int bw = 1 << b_width_log2(mi->sb_type);
      int bh = 1 << b_height_log2(mi->sb_type);
      for (idy = 0; idy < 2; idy += bh)
        for (idx = 0; idx < 2; idx += bw)
704
705
          write_intra_mode(bc, m->bmi[idy * 2 + idx].as_mode.first,
                           pc->fc.y_mode_prob);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
706
    }
707
708
    write_intra_mode(bc, mi->uv_mode,
                     pc->fc.uv_mode_prob[mode]);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
709
710
  } else {
    vp9_prob mv_ref_p[VP9_MVREFS - 1];
711

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

John Koleszar's avatar
John Koleszar committed
714
#ifdef ENTROPY_STATS
Ronald S. Bultje's avatar
Ronald S. Bultje committed
715
    active_section = 3;
John Koleszar's avatar
John Koleszar committed
716
717
#endif

718
    // If segment skip is not enabled code the mode.
Paul Wilkins's avatar
Paul Wilkins committed
719
    if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
720
      if (mi->sb_type >= BLOCK_SIZE_SB8X8) {
721
        write_sb_mv_ref(bc, mode, mv_ref_p);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
722
723
        vp9_accum_mv_refs(&cpi->common, mode, mi->mb_mode_context[rf]);
      }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
724
    }
725

Ronald S. Bultje's avatar
Ronald S. Bultje committed
726
727
728
729
730
731
732
733
    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);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
734
    }
735

Ronald S. Bultje's avatar
Ronald S. Bultje committed
736
737
738
739
740
741
    // 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
742

Ronald S. Bultje's avatar
Ronald S. Bultje committed
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
    if (xd->mode_info_context->mbmi.sb_type < BLOCK_SIZE_SB8X8) {
      int j;
      MB_PREDICTION_MODE blockmode;
      int_mv blockmv;
      int bwl = b_width_log2(mi->sb_type), bw = 1 << bwl;
      int bhl = b_height_log2(mi->sb_type), bh = 1 << bhl;
      int idx, idy;
      for (idy = 0; idy < 2; idy += bh) {
        for (idx = 0; idx < 2; idx += bw) {
          j = idy * 2 + idx;
          blockmode = cpi->mb.partition_info->bmi[j].mode;
          blockmv = cpi->mb.partition_info->bmi[j].mv;
          write_sb_mv_ref(bc, blockmode, mv_ref_p);
          vp9_accum_mv_refs(&cpi->common, blockmode, mi->mb_mode_context[rf]);
          if (blockmode == NEWMV) {
758
#ifdef ENTROPY_STATS
Ronald S. Bultje's avatar
Ronald S. Bultje committed
759
            active_section = 11;
760
#endif
Ronald S. Bultje's avatar
Ronald S. Bultje committed
761
762
            vp9_encode_mv(bc, &blockmv.as_mv, &mi->best_mv.as_mv,
                          nmvc, xd->allow_high_precision_mv);
763

Ronald S. Bultje's avatar
Ronald S. Bultje committed
764
765
766
767
            if (mi->second_ref_frame > 0)
              vp9_encode_mv(bc,
                            &cpi->mb.partition_info->bmi[j].second_mv.as_mv,
                            &mi->best_second_mv.as_mv,
768
                            nmvc, xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
769
          }
770
        }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
771
      }
772
773

#ifdef MODE_STATS
Ronald S. Bultje's avatar
Ronald S. Bultje committed
774
      ++count_mb_seg[mi->partitioning];
775
#endif
Ronald S. Bultje's avatar
Ronald S. Bultje committed
776
777
778
779
780
781
782
783
784
785
786
787
    } else if (mode == NEWMV) {
#ifdef ENTROPY_STATS
      active_section = 5;
#endif
      vp9_encode_mv(bc,
                    &mi->mv[0].as_mv, &mi->best_mv.as_mv,
                    nmvc, xd->allow_high_precision_mv);

      if (mi->second_ref_frame > 0)
        vp9_encode_mv(bc,
                      &mi->mv[1].as_mv, &mi->best_second_mv.as_mv,
                      nmvc, xd->allow_high_precision_mv);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
788
789
    }
  }
John Koleszar's avatar
John Koleszar committed
790
}
791

Ronald S. Bultje's avatar
Ronald S. Bultje committed
792
static void write_mb_modes_kf(const VP9_COMP *cpi,
793
                              MODE_INFO *m,
794
                              vp9_writer *bc, int mi_row, int mi_col) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
795
796
797
  const VP9_COMMON *const c = &cpi->common;
  const MACROBLOCKD *const xd = &cpi->mb.e_mbd;
  const int ym = m->mbmi.mode;
798
  const int mis = c->mode_info_stride;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
799
800
  const int segment_id = m->mbmi.segment_id;
  int skip_coeff;
801

802
  if (xd->update_mb_segmentation_map)
803
804
    write_mb_segid(bc, &m->mbmi, xd);

805
  if (vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
806
807
    skip_coeff = 1;
  } else {
808
    skip_coeff = m->mbmi.mb_skip_coeff;
809
    vp9_write(bc, skip_coeff, vp9_get_pred_prob(c, xd, PRED_MBSKIP));
810
811
  }

812
813
814
815
816
817
818
819
820
821
822
  if (m->mbmi.sb_type >= BLOCK_SIZE_SB8X8 && c->txfm_mode == TX_MODE_SELECT) {
    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]);
    }
  }

823
  if (m->mbmi.sb_type >= BLOCK_SIZE_SB8X8) {
Yaowu Xu's avatar
Yaowu Xu committed
824
825
    const MB_PREDICTION_MODE A = above_block_mode(m, 0, mis);
    const MB_PREDICTION_MODE L = xd->left_available ?
826
                                 left_block_mode(m, 0) : DC_PRED;
827
828
    write_intra_mode(bc, ym, c->kf_y_mode_prob[A][L]);
  } else {
829
830
831
    int idx, idy;
    int bw = 1 << b_width_log2(m->mbmi.sb_type);
    int bh = 1 << b_height_log2(m->mbmi.sb_type);
832
833
834
    for (idy = 0; idy < 2; idy += bh) {
      for (idx = 0; idx < 2; idx += bw) {
        int i = idy * 2 + idx;
Yaowu Xu's avatar
Yaowu Xu committed
835
836
        const MB_PREDICTION_MODE A = above_block_mode(m, i, mis);
        const MB_PREDICTION_MODE L = (xd->left_available || idx) ?
837
                                     left_block_mode(m, i) : DC_PRED;
838
839
840
841
        const int bm = m->bmi[i].as_mode.first;
#ifdef ENTROPY_STATS
        ++intra_mode_stats[A][L][bm];
#endif
842
        write_intra_mode(bc, bm, c->kf_y_mode_prob[A][L]);
843
844
      }
    }
845
846
  }

847
  write_intra_mode(bc, m->mbmi.uv_mode, c->kf_uv_mode_prob[ym]);
848
849
}

Ronald S. Bultje's avatar
Ronald S. Bultje committed
850
851
static void write_modes_b(VP9_COMP *cpi, MODE_INFO *m, vp9_writer *bc,
                          TOKENEXTRA **tok, TOKENEXTRA *tok_end,
852
                          int mi_row, int mi_col) {
853
  VP9_COMMON *const cm = &cpi->common;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
854
855
  MACROBLOCKD *const xd = &cpi->mb.e_mbd;

856
857
858
  if (m->mbmi.sb_type < BLOCK_SIZE_SB8X8)
    if (xd->ab_index > 0)
      return;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
859
  xd->mode_info_context = m;
860
861
862
  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));
863
  if (cm->frame_type == KEY_FRAME) {
864
    write_mb_modes_kf(cpi, m, bc, mi_row, mi_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
865
866
867
868
#ifdef ENTROPY_STATS
    active_section = 8;
#endif
  } else {
869
    pack_inter_mode_mvs(cpi, m, bc, mi_row, mi_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
870
871
872
873
874
875
876
877
878
#ifdef ENTROPY_STATS
    active_section = 1;
#endif
  }

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

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

893
  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
894
895
    return;

896
897
  bwl = b_width_log2(m->mbmi.sb_type);
  bhl = b_height_log2(m->mbmi.sb_type);
898
899
900
901
902
903
904
905
906
907
908
909
910

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

911
  if (bsize < BLOCK_SIZE_SB8X8)
912
    if (xd->ab_index > 0)
913
914
915
      return;

  if (bsize >= BLOCK_SIZE_SB8X8) {
916
    int pl;
917
918
    xd->left_seg_context = cm->left_seg_context + (mi_row & MI_MASK);
    xd->above_seg_context = cm->above_seg_context + mi_col;
919
    pl = partition_plane_context(xd, bsize);
920
    // encode the partition information
921
    write_token(bc, vp9_partition_tree, cm->fc.partition_prob[pl],
922
                vp9_partition_encodings + partition);
923
  }
924

925
  subsize = get_subsize(bsize, partition);
926
  *(get_sb_index(xd, subsize)) = 0;
927

928
929
  switch (partition) {
    case PARTITION_NONE:
930
      write_modes_b(cpi, m, bc, tok, tok_end, mi_row, mi_col);
931
932
      break;
    case PARTITION_HORZ:
933
      write_modes_b(cpi, m, bc, tok, tok_end, mi_row, mi_col);
934
      *(get_sb_index(xd, subsize)) = 1;
935
936
      if ((mi_row + bs) < cm->mi_rows)
        write_modes_b(cpi, m + bs * mis, bc, tok, tok_end, mi_row + bs, mi_col);
937
938
      break;
    case PARTITION_VERT:
939
      write_modes_b(cpi, m, bc, tok, tok_end, mi_row, mi_col);
940
      *(get_sb_index(xd, subsize)) = 1;
941
942
      if ((mi_col + bs) < cm->mi_cols)
        write_modes_b(cpi, m + bs, bc, tok, tok_end, mi_row, mi_col + bs);
943
944
945
946
      break;
    case PARTITION_SPLIT:
      for (n = 0; n < 4; n++) {
        int j = n >> 1, i = n & 0x01;
947
        *(get_sb_index(xd, subsize)) = n;
948
        write_modes_sb(cpi, m + j * bs * mis + i * bs, bc, tok, tok_end,
949
                       mi_row + j * bs, mi_col + i * bs, subsize);