bitstream.c 92 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
 */


John Koleszar's avatar
John Koleszar committed
12
#include "vp8/common/header.h"
John Koleszar's avatar
John Koleszar committed
13
#include "encodemv.h"
John Koleszar's avatar
John Koleszar committed
14
15
#include "vp8/common/entropymode.h"
#include "vp8/common/findnearmv.h"
John Koleszar's avatar
John Koleszar committed
16
#include "mcomp.h"
John Koleszar's avatar
John Koleszar committed
17
#include "vp8/common/systemdependent.h"
John Koleszar's avatar
John Koleszar committed
18
19
#include <assert.h>
#include <stdio.h>
20
#include <limits.h>
John Koleszar's avatar
John Koleszar committed
21
#include "vp8/common/pragmas.h"
22
#include "vpx/vpx_encoder.h"
John Koleszar's avatar
John Koleszar committed
23
24
#include "vpx_mem/vpx_mem.h"
#include "bitstream.h"
Christian Duvivier's avatar
Christian Duvivier committed
25
#include "segmentation.h"
26

27
#include "vp8/common/seg_common.h"
28
#include "vp8/common/pred_common.h"
29
#include "vp8/common/entropy.h"
30
#include "vp8/encoder/encodemv.h"
31

32
#if CONFIG_NEWBESTREFMV
Paul Wilkins's avatar
Paul Wilkins committed
33
34
35
#include "vp8/common/mvref_common.h"
#endif

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

40
41
//int final_packing = 0;

John Koleszar's avatar
John Koleszar committed
42
#ifdef ENTROPY_STATS
43
int intra_mode_stats [VP8_BINTRAMODES] [VP8_BINTRAMODES] [VP8_BINTRAMODES];
44
unsigned int tree_update_hist [BLOCK_TYPES]
45
46
47
                              [COEF_BANDS]
                              [PREV_COEF_CONTEXTS]
                              [ENTROPY_NODES][2];
48
49
50
51
52
53
#if CONFIG_HYBRIDTRANSFORM
unsigned int hybrid_tree_update_hist [BLOCK_TYPES]
                                     [COEF_BANDS]
                                     [PREV_COEF_CONTEXTS]
                                     [ENTROPY_NODES][2];
#endif
54
unsigned int tree_update_hist_8x8 [BLOCK_TYPES_8X8]
55
56
57
                                  [COEF_BANDS]
                                  [PREV_COEF_CONTEXTS]
                                  [ENTROPY_NODES] [2];
58
59
60
61
62
63
#if CONFIG_HYBRIDTRANSFORM8X8
unsigned int hybrid_tree_update_hist_8x8 [BLOCK_TYPES_8X8]
                                         [COEF_BANDS]
                                         [PREV_COEF_CONTEXTS]
                                         [ENTROPY_NODES] [2];
#endif
Daniel Kang's avatar
Daniel Kang committed
64
65
66
67
unsigned int tree_update_hist_16x16 [BLOCK_TYPES_16X16]
                                    [COEF_BANDS]
                                    [PREV_COEF_CONTEXTS]
                                    [ENTROPY_NODES] [2];
68
69
70
71
72
73
#if CONFIG_HYBRIDTRANSFORM16X16
unsigned int hybrid_tree_update_hist_16x16 [BLOCK_TYPES_16X16]
                                           [COEF_BANDS]
                                           [PREV_COEF_CONTEXTS]
                                           [ENTROPY_NODES] [2];
#endif
74

John Koleszar's avatar
John Koleszar committed
75
76
77
78
79
80
81
extern unsigned int active_section;
#endif

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

82
#define vp8_cost_upd  ((int)(vp8_cost_one(upd) - vp8_cost_zero(upd)) >> 8)
83
84
85
86
87
#define vp8_cost_upd256  ((int)(vp8_cost_one(upd) - vp8_cost_zero(upd)))

#define SEARCH_NEWP
static int update_bits[255];

John Koleszar's avatar
John Koleszar committed
88
89
90
91
static void compute_update_table() {
  int i;
  for (i = 0; i < 255; i++)
    update_bits[i] = vp8_count_term_subexp(i, SUBEXP_PARAM, 255);
92
93
}

John Koleszar's avatar
John Koleszar committed
94
95
96
97
98
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;
99
100
}

John Koleszar's avatar
John Koleszar committed
101
102
103
104
105
106
107
108
109
110
111
static int remap_prob(int v, int m) {
  const int n = 256;
  const int modulus = MODULUS_PARAM;
  int i;
  if ((m << 1) <= n)
    i = recenter_nonneg(v, m) - 1;
  else
    i = recenter_nonneg(n - 1 - v, n - 1 - m) - 1;

  i = split_index(i, n - 1, modulus);
  return i;
112
}
113
114

static void write_prob_diff_update(vp8_writer *const w,
John Koleszar's avatar
John Koleszar committed
115
116
117
                                   vp8_prob newp, vp8_prob oldp) {
  int delp = remap_prob(newp, oldp);
  vp8_encode_term_subexp(w, delp, SUBEXP_PARAM, 255);
118
119
}

John Koleszar's avatar
John Koleszar committed
120
121
122
static int prob_diff_update_cost(vp8_prob newp, vp8_prob oldp) {
  int delp = remap_prob(newp, oldp);
  return update_bits[delp] * 256;
123
}
124

Paul Wilkins's avatar
Paul Wilkins committed
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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#if CONFIG_NEW_MVREF
// Estimate the cost of each coding the vector using each reference candidate
unsigned int pick_best_mv_ref( MACROBLOCK *x,
                               int_mv target_mv,
                               int_mv * mv_ref_list,
                               int_mv * best_ref ) {

  int i;
  int best_index = 0;
  int cost, cost2;
  int index_cost[MAX_MV_REFS];
  MACROBLOCKD *xd = &x->e_mbd;

  /*unsigned int distance, distance2;

  distance = mv_distance(&target_mv, &mv_ref_list[0]);

  for (i = 1; i < MAX_MV_REFS; ++i ) {
    distance2 =
      mv_distance(&target_mv, &mv_ref_list[i]);
    if (distance2 < distance) {
      distance = distance2;
      best_index = i;
    }
  }*/

  // For now estimate the cost of selecting a given ref index
  // as index * 1 bits (but here 1 bit is scaled to 256)
  for (i = 0; i < MAX_MV_REFS; ++i ) {
    index_cost[i] = i << 8;
  }
  index_cost[0] = vp8_cost_zero(205);
  index_cost[1] = vp8_cost_zero(40);
  index_cost[2] = vp8_cost_zero(8);
  index_cost[3] = vp8_cost_zero(2);

  cost = index_cost[0] +
         vp8_mv_bit_cost(&target_mv,
                         &mv_ref_list[0],
                         XMVCOST, 96,
                         xd->allow_high_precision_mv);


  //for (i = 1; i < MAX_MV_REFS; ++i ) {
  for (i = 1; i < 4; ++i ) {
    cost2 = index_cost[i] +
            vp8_mv_bit_cost(&target_mv,
                            &mv_ref_list[i],
                            XMVCOST, 96,
                            xd->allow_high_precision_mv);

    if (cost2 < cost) {
      cost = cost2;
      best_index = i;
    }
  }

  (*best_ref).as_int = mv_ref_list[best_index].as_int;

  return best_index;
}
#endif

John Koleszar's avatar
John Koleszar committed
188
static void update_mode(
John Koleszar's avatar
John Koleszar committed
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
  vp8_writer *const w,
  int n,
  vp8_token tok               [/* n */],
  vp8_tree tree,
  vp8_prob Pnew               [/* n-1 */],
  vp8_prob Pcur               [/* n-1 */],
  unsigned int bct            [/* n-1 */] [2],
  const unsigned int num_events[/* n */]
) {
  unsigned int new_b = 0, old_b = 0;
  int i = 0;

  vp8_tree_probs_from_distribution(
    n--, tok, tree,
    Pnew, bct, num_events,
    256, 1
  );

  do {
    new_b += vp8_cost_branch(bct[i], Pnew[i]);
    old_b += vp8_cost_branch(bct[i], Pcur[i]);
  } while (++i < n);

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

John Koleszar's avatar
John Koleszar committed
215
    vp8_write_bit(w, 1);
John Koleszar's avatar
John Koleszar committed
216

John Koleszar's avatar
John Koleszar committed
217
218
    do {
      const vp8_prob p = Pnew[i];
John Koleszar's avatar
John Koleszar committed
219

John Koleszar's avatar
John Koleszar committed
220
221
222
223
      vp8_write_literal(w, Pcur[i] = p ? p : 1, 8);
    } while (++i < n);
  } else
    vp8_write_bit(w, 0);
John Koleszar's avatar
John Koleszar committed
224
225
}

John Koleszar's avatar
John Koleszar committed
226
static void update_mbintra_mode_probs(VP8_COMP *cpi) {
Paul Wilkins's avatar
Paul Wilkins committed
227
  VP8_COMMON *const cm = & cpi->common;
John Koleszar's avatar
John Koleszar committed
228

229
  vp8_writer *const w = & cpi->bc2;
John Koleszar's avatar
John Koleszar committed
230

John Koleszar's avatar
John Koleszar committed
231
232
233
  {
    vp8_prob Pnew   [VP8_YMODES - 1];
    unsigned int bct [VP8_YMODES - 1] [2];
John Koleszar's avatar
John Koleszar committed
234

John Koleszar's avatar
John Koleszar committed
235
236
    update_mode(
      w, VP8_YMODES, vp8_ymode_encodings, vp8_ymode_tree,
Paul Wilkins's avatar
Paul Wilkins committed
237
      Pnew, cm->fc.ymode_prob, bct, (unsigned int *)cpi->ymode_count
John Koleszar's avatar
John Koleszar committed
238
239
    );
  }
John Koleszar's avatar
John Koleszar committed
240
241
}

242
243
244
245
246
247
248
249
250
251
252
253
static __inline int get_prob(int num, int den) {
  int p;
  if (den <= 0)
    return 128;
  p = (num * 255 + (den >> 1)) / den;
  if (p > 255)
    return 255;
  else if (p < 1)
    return 1;
  return p;
}

John Koleszar's avatar
John Koleszar committed
254
255
256
257
void update_skip_probs(VP8_COMP *cpi) {
  VP8_COMMON *const pc = & cpi->common;
  int prob_skip_false[3] = {0, 0, 0};
  int k;
Paul Wilkins's avatar
Paul Wilkins committed
258

John Koleszar's avatar
John Koleszar committed
259
260
261
262
263
  for (k = 0; k < MBSKIP_CONTEXTS; ++k) {
    if ((cpi->skip_false_count[k] + cpi->skip_true_count[k])) {
      prob_skip_false[k] =
        cpi->skip_false_count[k] * 256 /
        (cpi->skip_false_count[k] + cpi->skip_true_count[k]);
Paul Wilkins's avatar
Paul Wilkins committed
264

John Koleszar's avatar
John Koleszar committed
265
266
      if (prob_skip_false[k] <= 1)
        prob_skip_false[k] = 1;
Paul Wilkins's avatar
Paul Wilkins committed
267

John Koleszar's avatar
John Koleszar committed
268
269
270
271
      if (prob_skip_false[k] > 255)
        prob_skip_false[k] = 255;
    } else
      prob_skip_false[k] = 128;
Paul Wilkins's avatar
Paul Wilkins committed
272

John Koleszar's avatar
John Koleszar committed
273
274
    pc->mbskip_pred_probs[k] = prob_skip_false[k];
  }
Paul Wilkins's avatar
Paul Wilkins committed
275
276
}

277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
#if CONFIG_SWITCHABLE_INTERP
void update_switchable_interp_probs(VP8_COMP *cpi) {
  VP8_COMMON *const pc = & cpi->common;
  vp8_writer *const w = & cpi->bc;
  unsigned int branch_ct[32][2];
  int i, j;
  for (j = 0; j <= VP8_SWITCHABLE_FILTERS; ++j) {
  //for (j = 0; j <= 0; ++j) {
/*
    if (!cpi->dummy_packing)
#if VP8_SWITCHABLE_FILTERS == 3
      printf("HELLO %d %d %d\n", cpi->switchable_interp_count[j][0],
             cpi->switchable_interp_count[j][1], cpi->switchable_interp_count[j][2]);
#else
      printf("HELLO %d %d\n", cpi->switchable_interp_count[j][0],
             cpi->switchable_interp_count[j][1]);
#endif
*/
    vp8_tree_probs_from_distribution(
        VP8_SWITCHABLE_FILTERS,
        vp8_switchable_interp_encodings, vp8_switchable_interp_tree,
        pc->fc.switchable_interp_prob[j], branch_ct, cpi->switchable_interp_count[j],
        256, 1
        );
    for (i = 0; i < VP8_SWITCHABLE_FILTERS - 1; ++i) {
      if (pc->fc.switchable_interp_prob[j][i] < 1)
        pc->fc.switchable_interp_prob[j][i] = 1;
      vp8_write_literal(w, pc->fc.switchable_interp_prob[j][i], 8);
/*
      if (!cpi->dummy_packing)
#if VP8_SWITCHABLE_FILTERS == 3
        printf("Probs %d %d [%d]\n",
               pc->fc.switchable_interp_prob[j][0],
               pc->fc.switchable_interp_prob[j][1], pc->frame_type);
#else
        printf("Probs %d [%d]\n", pc->fc.switchable_interp_prob[j][0],
               pc->frame_type);
#endif
*/
    }
  }
  /*
  if (!cpi->dummy_packing)
#if VP8_SWITCHABLE_FILTERS == 3
    printf("Probs %d %d [%d]\n",
           pc->fc.switchable_interp_prob[0], pc->fc.switchable_interp_prob[1], pc->frame_type);
#else
    printf("Probs %d [%d]\n", pc->fc.switchable_interp_prob[0], pc->frame_type);
#endif
  */
}
#endif

330
// This function updates the reference frame prediction stats
John Koleszar's avatar
John Koleszar committed
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
static void update_refpred_stats(VP8_COMP *cpi) {
  VP8_COMMON *const cm = & cpi->common;
  int i;
  int tot_count;
  vp8_prob new_pred_probs[PREDICTION_PROBS];
  int old_cost, new_cost;

  // Set the prediction probability structures to defaults
  if (cm->frame_type == KEY_FRAME) {
    // Set the prediction probabilities to defaults
    cm->ref_pred_probs[0] = 120;
    cm->ref_pred_probs[1] = 80;
    cm->ref_pred_probs[2] = 40;

    vpx_memset(cpi->ref_pred_probs_update, 0,
               sizeof(cpi->ref_pred_probs_update));
  } else {
    // From the prediction counts set the probabilities for each context
    for (i = 0; i < PREDICTION_PROBS; i++) {
      tot_count = cpi->ref_pred_count[i][0] + cpi->ref_pred_count[i][1];
      if (tot_count) {
        new_pred_probs[i] =
          (cpi->ref_pred_count[i][0] * 255 + (tot_count >> 1)) / tot_count;

        // Clamp to minimum allowed value
        new_pred_probs[i] += !new_pred_probs[i];
      } else
        new_pred_probs[i] = 128;

      // Decide whether or not to update the reference frame probs.
      // Returned costs are in 1/256 bit units.
      old_cost =
        (cpi->ref_pred_count[i][0] * vp8_cost_zero(cm->ref_pred_probs[i])) +
        (cpi->ref_pred_count[i][1] * vp8_cost_one(cm->ref_pred_probs[i]));

      new_cost =
        (cpi->ref_pred_count[i][0] * vp8_cost_zero(new_pred_probs[i])) +
        (cpi->ref_pred_count[i][1] * vp8_cost_one(new_pred_probs[i]));

      // 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;
376
377

    }
John Koleszar's avatar
John Koleszar committed
378
  }
379
380
}

John Koleszar's avatar
John Koleszar committed
381
382
static void write_ymode(vp8_writer *bc, int m, const vp8_prob *p) {
  vp8_write_token(bc, vp8_ymode_tree, p, vp8_ymode_encodings + m);
John Koleszar's avatar
John Koleszar committed
383
384
}

John Koleszar's avatar
John Koleszar committed
385
386
static void kfwrite_ymode(vp8_writer *bc, int m, const vp8_prob *p) {
  vp8_write_token(bc, vp8_kf_ymode_tree, p, vp8_kf_ymode_encodings + m);
John Koleszar's avatar
John Koleszar committed
387
388
}

Ronald S. Bultje's avatar
Ronald S. Bultje committed
389
390
391
392
393
394
#if CONFIG_SUPERBLOCKS
static void sb_kfwrite_ymode(vp8_writer *bc, int m, const vp8_prob *p) {
  vp8_write_token(bc, vp8_uv_mode_tree, p, vp8_sb_kf_ymode_encodings + m);
}
#endif

John Koleszar's avatar
John Koleszar committed
395
396
static void write_i8x8_mode(vp8_writer *bc, int m, const vp8_prob *p) {
  vp8_write_token(bc, vp8_i8x8_mode_tree, p, vp8_i8x8_mode_encodings + m);
Yaowu Xu's avatar
Yaowu Xu committed
397
}
Yaowu Xu's avatar
Yaowu Xu committed
398

John Koleszar's avatar
John Koleszar committed
399
400
static void write_uv_mode(vp8_writer *bc, int m, const vp8_prob *p) {
  vp8_write_token(bc, vp8_uv_mode_tree, p, vp8_uv_mode_encodings + m);
John Koleszar's avatar
John Koleszar committed
401
402
403
}


John Koleszar's avatar
John Koleszar committed
404
405
static void write_bmode(vp8_writer *bc, int m, const vp8_prob *p) {
  vp8_write_token(bc, vp8_bmode_tree, p, vp8_bmode_encodings + m);
John Koleszar's avatar
John Koleszar committed
406
407
}

John Koleszar's avatar
John Koleszar committed
408
409
410
411
static void write_split(vp8_writer *bc, int x, const vp8_prob *p) {
  vp8_write_token(
    bc, vp8_mbsplit_tree, p, vp8_mbsplit_encodings + x
  );
John Koleszar's avatar
John Koleszar committed
412
413
}

414
415
static int prob_update_savings(const unsigned int *ct,
                               const vp8_prob oldp, const vp8_prob newp,
John Koleszar's avatar
John Koleszar committed
416
417
418
419
420
                               const vp8_prob upd) {
  const int old_b = vp8_cost_branch256(ct, oldp);
  const int new_b = vp8_cost_branch256(ct, newp);
  const int update_b = 2048 + vp8_cost_upd256;
  return (old_b - new_b - update_b);
421
422
}

423
static int prob_diff_update_savings(const unsigned int *ct,
John Koleszar's avatar
John Koleszar committed
424
425
426
427
428
429
430
                                    const vp8_prob oldp, const vp8_prob newp,
                                    const vp8_prob upd) {
  const int old_b = vp8_cost_branch256(ct, oldp);
  const int new_b = vp8_cost_branch256(ct, newp);
  const int update_b = (newp == oldp ? 0 :
                        prob_diff_update_cost(newp, oldp) + vp8_cost_upd256);
  return (old_b - new_b - update_b);
431
432
433
}

static int prob_diff_update_savings_search(const unsigned int *ct,
John Koleszar's avatar
John Koleszar committed
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
                                           const vp8_prob oldp, vp8_prob *bestp,
                                           const vp8_prob upd) {
  const int old_b = vp8_cost_branch256(ct, oldp);
  int new_b, update_b, savings, bestsavings, step;
  vp8_prob newp, bestnewp;

  bestsavings = 0;
  bestnewp = oldp;

  step = (*bestp > oldp ? -1 : 1);
  for (newp = *bestp; newp != oldp; newp += step) {
    new_b = vp8_cost_branch256(ct, newp);
    update_b = prob_diff_update_cost(newp, oldp) + vp8_cost_upd256;
    savings = old_b - new_b - update_b;
    if (savings > bestsavings) {
      bestsavings = savings;
      bestnewp = newp;
451
    }
John Koleszar's avatar
John Koleszar committed
452
453
454
  }
  *bestp = bestnewp;
  return bestsavings;
455
456
}

457
458
459
static void pack_mb_tokens(vp8_writer *w,
                           TOKENEXTRA **tp,
                           const TOKENEXTRA *const stop) {
John Koleszar's avatar
John Koleszar committed
460
461
462
463
464
  unsigned int split;
  unsigned int shift;
  int count = w->count;
  unsigned int range = w->range;
  unsigned int lowvalue = w->lowvalue;
465
  TOKENEXTRA *p = *tp;
John Koleszar's avatar
John Koleszar committed
466

John Koleszar's avatar
John Koleszar committed
467
468
469
470
471
472
473
474
475
  while (p < stop) {
    const int t = p->Token;
    vp8_token *const a = vp8_coef_encodings + t;
    const vp8_extra_bit_struct *const b = vp8_extra_bits + t;
    int i = 0;
    const unsigned char *pp = p->context_tree;
    int v = a->value;
    int n = a->Len;

476
477
478
479
480
481
    if (t == EOSB_TOKEN)
    {
      ++p;
      break;
    }

John Koleszar's avatar
John Koleszar committed
482
483
484
485
486
    /* 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
487

John Koleszar's avatar
John Koleszar committed
488
489
490
491
    do {
      const int bb = (v >> --n) & 1;
      split = 1 + (((range - 1) * pp[i >> 1]) >> 8);
      i = vp8_coef_tree[i + bb];
John Koleszar's avatar
John Koleszar committed
492

John Koleszar's avatar
John Koleszar committed
493
494
495
496
497
498
      if (bb) {
        lowvalue += split;
        range = range - split;
      } else {
        range = split;
      }
John Koleszar's avatar
John Koleszar committed
499

John Koleszar's avatar
John Koleszar committed
500
501
502
      shift = vp8_norm[range];
      range <<= shift;
      count += shift;
John Koleszar's avatar
John Koleszar committed
503

John Koleszar's avatar
John Koleszar committed
504
505
      if (count >= 0) {
        int offset = shift - count;
John Koleszar's avatar
John Koleszar committed
506

John Koleszar's avatar
John Koleszar committed
507
508
        if ((lowvalue << (offset - 1)) & 0x80000000) {
          int x = w->pos - 1;
John Koleszar's avatar
John Koleszar committed
509

John Koleszar's avatar
John Koleszar committed
510
511
512
513
          while (x >= 0 && w->buffer[x] == 0xff) {
            w->buffer[x] = (unsigned char)0;
            x--;
          }
John Koleszar's avatar
John Koleszar committed
514

John Koleszar's avatar
John Koleszar committed
515
516
          w->buffer[x] += 1;
        }
John Koleszar's avatar
John Koleszar committed
517

John Koleszar's avatar
John Koleszar committed
518
519
520
521
522
523
        w->buffer[w->pos++] = (lowvalue >> (24 - offset));
        lowvalue <<= offset;
        shift = count;
        lowvalue &= 0xffffff;
        count -= 8;
      }
John Koleszar's avatar
John Koleszar committed
524

John Koleszar's avatar
John Koleszar committed
525
526
      lowvalue <<= shift;
    } while (n);
John Koleszar's avatar
John Koleszar committed
527
528


John Koleszar's avatar
John Koleszar committed
529
530
    if (b->base_val) {
      const int e = p->Extra, L = b->Len;
John Koleszar's avatar
John Koleszar committed
531

John Koleszar's avatar
John Koleszar committed
532
533
534
535
536
      if (L) {
        const unsigned char *pp = b->prob;
        int v = e >> 1;
        int n = L;              /* number of bits in v, assumed nonzero */
        int i = 0;
John Koleszar's avatar
John Koleszar committed
537

John Koleszar's avatar
John Koleszar committed
538
539
540
541
        do {
          const int bb = (v >> --n) & 1;
          split = 1 + (((range - 1) * pp[i >> 1]) >> 8);
          i = b->tree[i + bb];
John Koleszar's avatar
John Koleszar committed
542

John Koleszar's avatar
John Koleszar committed
543
544
545
546
547
548
          if (bb) {
            lowvalue += split;
            range = range - split;
          } else {
            range = split;
          }
John Koleszar's avatar
John Koleszar committed
549

John Koleszar's avatar
John Koleszar committed
550
551
552
          shift = vp8_norm[range];
          range <<= shift;
          count += shift;
John Koleszar's avatar
John Koleszar committed
553

John Koleszar's avatar
John Koleszar committed
554
555
          if (count >= 0) {
            int offset = shift - count;
John Koleszar's avatar
John Koleszar committed
556

John Koleszar's avatar
John Koleszar committed
557
558
559
560
561
562
563
564
565
            if ((lowvalue << (offset - 1)) & 0x80000000) {
              int x = w->pos - 1;

              while (x >= 0 && w->buffer[x] == 0xff) {
                w->buffer[x] = (unsigned char)0;
                x--;
              }

              w->buffer[x] += 1;
John Koleszar's avatar
John Koleszar committed
566
567
            }

John Koleszar's avatar
John Koleszar committed
568
569
570
571
572
573
            w->buffer[w->pos++] = (lowvalue >> (24 - offset));
            lowvalue <<= offset;
            shift = count;
            lowvalue &= 0xffffff;
            count -= 8;
          }
John Koleszar's avatar
John Koleszar committed
574

John Koleszar's avatar
John Koleszar committed
575
576
577
          lowvalue <<= shift;
        } while (n);
      }
John Koleszar's avatar
John Koleszar committed
578
579


John Koleszar's avatar
John Koleszar committed
580
      {
John Koleszar's avatar
John Koleszar committed
581

John Koleszar's avatar
John Koleszar committed
582
        split = (range + 1) >> 1;
John Koleszar's avatar
John Koleszar committed
583

John Koleszar's avatar
John Koleszar committed
584
585
586
587
588
589
        if (e & 1) {
          lowvalue += split;
          range = range - split;
        } else {
          range = split;
        }
John Koleszar's avatar
John Koleszar committed
590

John Koleszar's avatar
John Koleszar committed
591
        range <<= 1;
John Koleszar's avatar
John Koleszar committed
592

John Koleszar's avatar
John Koleszar committed
593
594
        if ((lowvalue & 0x80000000)) {
          int x = w->pos - 1;
John Koleszar's avatar
John Koleszar committed
595

John Koleszar's avatar
John Koleszar committed
596
597
598
599
          while (x >= 0 && w->buffer[x] == 0xff) {
            w->buffer[x] = (unsigned char)0;
            x--;
          }
John Koleszar's avatar
John Koleszar committed
600

John Koleszar's avatar
John Koleszar committed
601
          w->buffer[x] += 1;
John Koleszar's avatar
John Koleszar committed
602

John Koleszar's avatar
John Koleszar committed
603
        }
John Koleszar's avatar
John Koleszar committed
604

John Koleszar's avatar
John Koleszar committed
605
606
607
608
609
610
        lowvalue  <<= 1;

        if (!++count) {
          count = -8;
          w->buffer[w->pos++] = (lowvalue >> 24);
          lowvalue &= 0xffffff;
John Koleszar's avatar
John Koleszar committed
611
        }
John Koleszar's avatar
John Koleszar committed
612
      }
John Koleszar's avatar
John Koleszar committed
613
614

    }
John Koleszar's avatar
John Koleszar committed
615
616
617
618
619
620
    ++p;
  }

  w->count = count;
  w->lowvalue = lowvalue;
  w->range = range;
621
  *tp = p;
John Koleszar's avatar
John Koleszar committed
622
623
}

John Koleszar's avatar
John Koleszar committed
624
625
static void write_partition_size(unsigned char *cx_data, int size) {
  signed char csize;
John Koleszar's avatar
John Koleszar committed
626

John Koleszar's avatar
John Koleszar committed
627
628
629
630
631
632
  csize = size & 0xff;
  *cx_data = csize;
  csize = (size >> 8) & 0xff;
  *(cx_data + 1) = csize;
  csize = (size >> 16) & 0xff;
  *(cx_data + 2) = csize;
John Koleszar's avatar
John Koleszar committed
633
634
635
636
637

}

static void write_mv_ref
(
John Koleszar's avatar
John Koleszar committed
638
639
  vp8_writer *w, MB_PREDICTION_MODE m, const vp8_prob *p
) {
640
#if CONFIG_DEBUG
John Koleszar's avatar
John Koleszar committed
641
  assert(NEARESTMV <= m  &&  m <= SPLITMV);
642
#endif
John Koleszar's avatar
John Koleszar committed
643
644
  vp8_write_token(w, vp8_mv_ref_tree, p,
                  vp8_mv_ref_encoding_array - NEARESTMV + m);
John Koleszar's avatar
John Koleszar committed
645
646
}

Ronald S. Bultje's avatar
Ronald S. Bultje committed
647
648
649
650
651
652
653
654
655
656
#if CONFIG_SUPERBLOCKS
static void write_sb_mv_ref(vp8_writer *w, MB_PREDICTION_MODE m, const vp8_prob *p) {
#if CONFIG_DEBUG
  assert(NEARESTMV <= m  &&  m < SPLITMV);
#endif
  vp8_write_token(w, vp8_sb_mv_ref_tree, p,
                  vp8_sb_mv_ref_encoding_array - NEARESTMV + m);
}
#endif

John Koleszar's avatar
John Koleszar committed
657
658
static void write_sub_mv_ref
(
John Koleszar's avatar
John Koleszar committed
659
660
  vp8_writer *w, B_PREDICTION_MODE m, const vp8_prob *p
) {
661
#if CONFIG_DEBUG
John Koleszar's avatar
John Koleszar committed
662
  assert(LEFT4X4 <= m  &&  m <= NEW4X4);
663
#endif
John Koleszar's avatar
John Koleszar committed
664
665
  vp8_write_token(w, vp8_sub_mv_ref_tree, p,
                  vp8_sub_mv_ref_encoding_array - LEFT4X4 + m);
John Koleszar's avatar
John Koleszar committed
666
667
}

668
669
670
671
672
673
674
675
676
677
678
679
680
#if CONFIG_NEWMVENTROPY
static void write_nmv (vp8_writer *w, const MV *mv, const int_mv *ref,
                       const nmv_context *nmvc, int usehp) {
  MV e;
  e.row = mv->row - ref->as_mv.row;
  e.col = mv->col - ref->as_mv.col;

  vp8_encode_nmv(w, &e, &ref->as_mv, nmvc);
  vp8_encode_nmv_fp(w, &e, &ref->as_mv, nmvc, usehp);
}

#else

John Koleszar's avatar
John Koleszar committed
681
682
static void write_mv
(
John Koleszar's avatar
John Koleszar committed
683
684
685
686
687
688
689
  vp8_writer *w, const MV *mv, const int_mv *ref, const MV_CONTEXT *mvc
) {
  MV e;
  e.row = mv->row - ref->as_mv.row;
  e.col = mv->col - ref->as_mv.col;

  vp8_encode_motion_vector(w, &e, mvc);
John Koleszar's avatar
John Koleszar committed
690
691
}

692
693
static void write_mv_hp
(
John Koleszar's avatar
John Koleszar committed
694
695
696
697
698
699
700
  vp8_writer *w, const MV *mv, const int_mv *ref, const MV_CONTEXT_HP *mvc
) {
  MV e;
  e.row = mv->row - ref->as_mv.row;
  e.col = mv->col - ref->as_mv.col;

  vp8_encode_motion_vector_hp(w, &e, mvc);
701
}
702
#endif  /* CONFIG_NEWMVENTROPY */
703

Paul Wilkins's avatar
Paul Wilkins committed
704
705
706
// 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.
static void write_mb_segid(vp8_writer *w,
Paul Wilkins's avatar
Paul Wilkins committed
707
                           const MB_MODE_INFO *mi, const MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
708
  // Encode the MB segment id.
Paul Wilkins's avatar
Paul Wilkins committed
709
  if (xd->segmentation_enabled && xd->update_mb_segmentation_map) {
John Koleszar's avatar
John Koleszar committed
710
711
    switch (mi->segment_id) {
      case 0:
Paul Wilkins's avatar
Paul Wilkins committed
712
713
        vp8_write(w, 0, xd->mb_segment_tree_probs[0]);
        vp8_write(w, 0, xd->mb_segment_tree_probs[1]);
John Koleszar's avatar
John Koleszar committed
714
715
        break;
      case 1:
Paul Wilkins's avatar
Paul Wilkins committed
716
717
        vp8_write(w, 0, xd->mb_segment_tree_probs[0]);
        vp8_write(w, 1, xd->mb_segment_tree_probs[1]);
John Koleszar's avatar
John Koleszar committed
718
719
        break;
      case 2:
Paul Wilkins's avatar
Paul Wilkins committed
720
721
        vp8_write(w, 1, xd->mb_segment_tree_probs[0]);
        vp8_write(w, 0, xd->mb_segment_tree_probs[2]);
John Koleszar's avatar
John Koleszar committed
722
723
        break;
      case 3:
Paul Wilkins's avatar
Paul Wilkins committed
724
725
        vp8_write(w, 1, xd->mb_segment_tree_probs[0]);
        vp8_write(w, 1, xd->mb_segment_tree_probs[2]);
John Koleszar's avatar
John Koleszar committed
726
727
728
729
        break;

        // TRAP.. This should not happen
      default:
Paul Wilkins's avatar
Paul Wilkins committed
730
731
        vp8_write(w, 0, xd->mb_segment_tree_probs[0]);
        vp8_write(w, 0, xd->mb_segment_tree_probs[1]);
John Koleszar's avatar
John Koleszar committed
732
        break;
John Koleszar's avatar
John Koleszar committed
733
    }
John Koleszar's avatar
John Koleszar committed
734
  }
John Koleszar's avatar
John Koleszar committed
735
736
}

Paul Wilkins's avatar
Paul Wilkins committed
737
// This function encodes the reference frame
John Koleszar's avatar
John Koleszar committed
738
739
740
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
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
static void encode_ref_frame(vp8_writer *const w,
                             VP8_COMMON *const cm,
                             MACROBLOCKD *xd,
                             int segment_id,
                             MV_REFERENCE_FRAME rf) {
  int seg_ref_active;
  int seg_ref_count = 0;
  seg_ref_active = segfeature_active(xd,
                                     segment_id,
                                     SEG_LVL_REF_FRAME);

  if (seg_ref_active) {
    seg_ref_count = check_segref(xd, segment_id, INTRA_FRAME) +
                    check_segref(xd, segment_id, LAST_FRAME) +
                    check_segref(xd, segment_id, GOLDEN_FRAME) +
                    check_segref(xd, segment_id, ALTREF_FRAME);
  }

  // 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;
    vp8_prob pred_prob;
    MV_REFERENCE_FRAME pred_rf;

    // Get the context probability the prediction flag
    pred_prob = get_pred_prob(cm, xd, PRED_REF);

    // Get the predicted value.
    pred_rf = get_pred_ref(cm, xd);

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

    set_pred_flag(xd, PRED_REF, prediction_flag);
    vp8_write(w, prediction_flag, pred_prob);

    // If not predicted correctly then code value explicitly
    if (!prediction_flag) {
      vp8_prob mod_refprobs[PREDICTION_PROBS];

      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] *=
          check_segref(xd, segment_id, INTRA_FRAME);
        mod_refprobs[LAST_FRAME] *=
          check_segref(xd, segment_id, LAST_FRAME);
        mod_refprobs[GOLDEN_FRAME] *=
          (check_segref(xd, segment_id, GOLDEN_FRAME) *
           check_segref(xd, segment_id, ALTREF_FRAME));
      }

      if (mod_refprobs[0]) {
        vp8_write(w, (rf != INTRA_FRAME), mod_refprobs[0]);
      }

      // Inter coded
      if (rf != INTRA_FRAME) {
        if (mod_refprobs[1]) {
          vp8_write(w, (rf != LAST_FRAME), mod_refprobs[1]);
        }
805

John Koleszar's avatar
John Koleszar committed
806
807
808
809
        if (rf != LAST_FRAME) {
          if (mod_refprobs[2]) {
            vp8_write(w, (rf != GOLDEN_FRAME), mod_refprobs[2]);
          }
810
        }
John Koleszar's avatar
John Koleszar committed
811
      }
Paul Wilkins's avatar
Paul Wilkins committed
812
    }
John Koleszar's avatar
John Koleszar committed
813
  }
Paul Wilkins's avatar
Paul Wilkins committed
814

John Koleszar's avatar
John Koleszar committed
815
816
  // 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
817
}
John Koleszar's avatar
John Koleszar committed
818

819
// Update the probabilities used to encode reference frame data
John Koleszar's avatar
John Koleszar committed
820
821
static void update_ref_probs(VP8_COMP *const cpi) {
  VP8_COMMON *const cm = & cpi->common;
822

John Koleszar's avatar
John Koleszar committed
823
824
825
826
  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];
827

John Koleszar's avatar
John Koleszar committed
828
829
  cm->prob_intra_coded = (rf_intra + rf_inter)
                         ? rf_intra * 255 / (rf_intra + rf_inter) : 1;
830

John Koleszar's avatar
John Koleszar committed
831
832
  if (!cm->prob_intra_coded)
    cm->prob_intra_coded = 1;
833

John Koleszar's avatar
John Koleszar committed
834
  cm->prob_last_coded = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;
835

John Koleszar's avatar
John Koleszar committed
836
837
  if (!cm->prob_last_coded)
    cm->prob_last_coded = 1;
838

John Koleszar's avatar
John Koleszar committed
839
840
841
  cm->prob_gf_coded = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
                      ? (rfct[GOLDEN_FRAME] * 255) /
                      (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]) : 128;
842

John Koleszar's avatar
John Koleszar committed
843
844
  if (!cm->prob_gf_coded)
    cm->prob_gf_coded = 1;
845

John Koleszar's avatar
John Koleszar committed
846
847
848
  // Compute a modified set of probabilities to use when prediction of the
  // reference frame fails
  compute_mod_refprobs(cm);
849
850
}

John Koleszar's avatar
John Koleszar committed
851
852
853
static void pack_inter_mode_mvs(VP8_COMP *const cpi) {
  int i;
  VP8_COMMON *const pc = & cpi->common;
854
  vp8_writer *const w = & cpi->bc2;
855
856
857
#if CONFIG_NEWMVENTROPY
  const nmv_context *nmvc = &pc->fc.nmvc;
#else
John Koleszar's avatar
John Koleszar committed
858
859
  const MV_CONTEXT *mvc = pc->fc.mvc;
  const MV_CONTEXT_HP *mvc_hp = pc->fc.mvc_hp;
860
#endif
Paul Wilkins's avatar
Paul Wilkins committed
861
  MACROBLOCK *x = &cpi->mb;
John Koleszar's avatar
John Koleszar committed
862
863
864
  MACROBLOCKD *xd = &cpi->mb.e_mbd;
  MODE_INFO *m;
  MODE_INFO *prev_m;
865
866
  TOKENEXTRA *tok = cpi->tok;
  TOKENEXTRA *tok_end = tok + cpi->tok_count;
867

John Koleszar's avatar
John Koleszar committed
868
869
870
  const int mis = pc->mode_info_stride;
  int mb_row, mb_col;
  int row, col;
John Koleszar's avatar
John Koleszar committed
871

John Koleszar's avatar
John Koleszar committed
872
873
874
  // Values used in prediction model coding
  vp8_prob pred_prob;
  unsigned char prediction_flag;
875

John Koleszar's avatar
John Koleszar committed
876
877
  int row_delta[4] = { 0, +1,  0, -1};
  int col_delta[4] = { +1, -1, +1, +1};
Adrian Grange's avatar
Adrian Grange committed
878

879
880
  //final_packing = !cpi->dummy_packing;

John Koleszar's avatar
John Koleszar committed
881
  cpi->mb.partition_info = cpi->mb.pi;
882

John Koleszar's avatar
John Koleszar committed
883
884
  // Update the probabilities used to encode reference frame data
  update_ref_probs(cpi);
John Koleszar's avatar
John Koleszar committed
885
886

#ifdef ENTROPY_STATS
John Koleszar's avatar
John Koleszar committed
887
  active_section = 1;
John Koleszar's avatar
John Koleszar committed
888
889
#endif

John Koleszar's avatar
John Koleszar committed
890
891
  if (pc->mb_no_coeff_skip) {
    int k;
892

John Koleszar's avatar
John Koleszar committed
893
894
895
896
    update_skip_probs(cpi);
    for (k = 0; k < MBSKIP_CONTEXTS; ++k)
      vp8_write_literal(w, pc->mbskip_pred_probs[k], 8);
  }
John Koleszar's avatar
John Koleszar committed
897

898
#if CONFIG_PRED_FILTER
John Koleszar's avatar
John Koleszar committed
899
900
901
902
903
904
905
906
907
908
  // Write the prediction filter mode used for this frame
  vp8_write_literal(w, pc->pred_filter_mode, 2);

  // Write prediction filter on/off probability if signaling at MB level
  if (pc->pred_filter_mode == 2)
    vp8_write_literal(w, pc->prob_pred_filter_off, 8);

  // printf("pred_filter_mode:%d  prob_pred_filter_off:%d\n",
  //       pc->pred_filter_mode, pc->prob_pred_filter_off);
#endif
909
910
911
912
#if CONFIG_SWITCHABLE_INTERP
  if (pc->mcomp_filter_type == SWITCHABLE)
    update_switchable_interp_probs(cpi);
#endif
John Koleszar's avatar
John Koleszar committed
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930

  vp8_write_literal(w, pc->prob_intra_coded, 8);
  vp8_write_literal(w, pc->prob_last_coded, 8);
  vp8_write_literal(w, pc->prob_gf_coded, 8);

  if (cpi->common.comp_pred_mode == HYBRID_PREDICTION) {
    vp8_write(w, 1, 128);
    vp8_write(w, 1, 128);
    for (i = 0; i < COMP_PRED_CONTEXTS; i++) {
      if (cpi->single_pred_count[i] + cpi->comp_pred_count[i]) {
        pc->prob_comppred[i] = cpi->single_pred_count[i] * 255 /
                               (cpi->single_pred_count[i] + cpi->comp_pred_count[i]);
        if (pc->prob_comppred[i] < 1)
          pc->prob_comppred[i] = 1;
      } else {
        pc->prob_comppred[i] = 128;
      }
      vp8_write_literal(w, pc->prob_comppred[i], 8);
931
    }
John Koleszar's avatar
John Koleszar committed
932
933
934
935
936
937
  } else if (cpi->common.comp_pred_mode == SINGLE_PREDICTION_ONLY) {
    vp8_write(w, 0, 128);
  } else { /* compound prediction only */
    vp8_write(w, 1, 128);
    vp8_write(w, 0, 128);
  }
938

John Koleszar's avatar
John Koleszar committed
939
  update_mbintra_mode_probs(cpi);
John Koleszar's avatar
John Koleszar committed
940

941
942
943
#if CONFIG_NEWMVENTROPY
  vp8_write_nmvprobs(cpi, xd->allow_high_precision_mv);
#else
John Koleszar's avatar
John Koleszar committed
944
945
946
947
  if (xd->allow_high_precision_mv)
    vp8_write_mvprobs_hp(cpi);
  else
    vp8_write_mvprobs(cpi);
948
#endif
John Koleszar's avatar
John Koleszar committed
949
950
951
952
953
954
955
956
957
958
959
960

  mb_row = 0;
  for (row = 0; row < pc->mb_rows; row += 2) {
    m = pc->mi + row * mis;
    prev_m = pc->prev_mi + row * mis;

    mb_col = 0;
    for (col = 0; col < pc->mb_cols; col += 2) {
      int i;

      // Process the 4 MBs in the order:
      // top-left, top-right, bottom-left, bottom-right
Ronald S. Bultje's avatar
Ronald S. Bultje committed
961
962
963
#if CONFIG_SUPERBLOCKS
      vp8_write(w, m->mbmi.encoded_as_sb, pc->sb_coded);
#endif
John Koleszar's avatar
John Koleszar committed
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
      for (i = 0; i < 4; i++) {
        MB_MODE_INFO *mi;
        MV_REFERENCE_FRAME rf;
        MB_PREDICTION_MODE mode;
        int segment_id;

        int dy = row_delta[i];
        int dx = col_delta[i];
        int offset_extended = dy * mis + dx;

        if ((mb_row >= pc->mb_rows) || (mb_col >= pc->mb_cols)) {
          // MB lies outside frame, move on
          mb_row += dy;
          mb_col += dx;
          m += offset_extended;
          prev_m += offset_extended;
          cpi->mb.partition_info += offset_extended;
          continue;
        }
Adrian Grange's avatar
Adrian Grange committed
983

John Koleszar's avatar
John Koleszar committed
984
985
986
987
        mi = & m->mbmi;
        rf = mi->ref_frame;
        mode = mi->mode;
        segment_id = mi->segment_id;
988

John Koleszar's avatar
John Koleszar committed
989
990
991
992
993
994
995
        // Distance of Mb to the various image edges.
        // These specified to 8th pel as they are always compared to MV
        // values that are in 1/8th pel units
        xd->mb_to_left_edge = -((mb_col * 16) << 3);
        xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
        xd->mb_to_top_edge = -((mb_row * 16)) << 3;
        xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
996

John Koleszar's avatar
John Koleszar committed
997
998
999
        // Make sure the MacroBlockD mode info pointer is set correctly
        xd->mode_info_context = m;
        xd->prev_mode_info_context = prev_m;
Paul Wilkins's avatar
Paul Wilkins committed
1000

John Koleszar's avatar
John Koleszar committed
1001
#ifdef ENTROPY_STATS
John Koleszar's avatar
John Koleszar committed
1002
        active_section = 9;
John Koleszar's avatar
John Koleszar committed
1003
1004
#endif

John Koleszar's avatar
John Koleszar committed
1005
1006
1007
1008
1009
        if (cpi->mb.e_mbd.update_mb_segmentation_map) {
          // Is temporal coding of the segment map enabled
          if (pc->temporal_update) {
            prediction_flag = get_pred_flag(xd, PRED_SEG_ID);
            pred_prob = get_pred_prob(pc, xd, PRED_SEG_ID);
1010

John Koleszar's avatar
John Koleszar committed
1011
1012
            // Code the segment id prediction flag for this mb
            vp8_write(w, prediction_flag, pred_prob);
1013

John Koleszar's avatar
John Koleszar committed
1014
1015
1016
1017
1018
1019
1020
1021
            // If the mb segment id wasn't predicted code explicitly
            if (!prediction_flag)
              write_mb_segid(w, mi, &cpi->mb.e_mbd);
          } else {
            // Normal unpredicted coding
            write_mb_segid(w, mi, &cpi->mb.e_mbd);
          }
        }
John Koleszar's avatar
John Koleszar committed
1022

John Koleszar's avatar
John Koleszar committed
1023
1024
1025
        if (pc->mb_no_coeff_skip &&
            (!segfeature_active(xd, segment_id, SEG_LVL_EOB) ||
             (get_segdata(xd, segment_id, SEG_LVL_EOB) != 0))) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
1026
1027
1028
1029
1030
1031
1032
1033
1034
          int skip_coeff = mi->mb_skip_coeff;
#if CONFIG_SUPERBLOCKS
          if (mi->encoded_as_sb) {
            skip_coeff &= m[1].mbmi.mb_skip_coeff;
            skip_coeff &= m[mis].mbmi.mb_skip_coeff;
            skip_coeff &= m[mis + 1].mbmi.mb_skip_coeff;
          }
#endif
          vp8_encode_bool(w, skip_coeff,
John Koleszar's avatar
John Koleszar committed
1035
1036
                          get_pred_prob(pc, xd, PRED_MBSKIP));
        }
John Koleszar's avatar
John Koleszar committed
1037

John Koleszar's avatar
John Koleszar committed
1038
1039
        // Encode the reference frame.
        encode_ref_frame(w, pc, xd, segment_id, rf);
Paul Wilkins's avatar
Paul Wilkins committed
1040

John Koleszar's avatar
John Koleszar committed
1041
        if (rf == INTRA_FRAME) {
1042
#ifdef ENTROPY_STATS
John Koleszar's avatar
John Koleszar committed
1043
          active_section = 6;
1044
#endif
Paul Wilkins's avatar
Paul Wilkins committed
1045

Ronald S. Bultje's avatar
Ronald S. Bultje committed
1046
1047
          // TODO(rbultje) write using SB tree structure

John Koleszar's avatar
John Koleszar committed
1048
1049
1050
          if (!segfeature_active(xd, segment_id, SEG_LVL_MODE)) {
            write_ymode(w, mode, pc->fc.ymode_prob);
          }
John Koleszar's avatar
John Koleszar committed
1051

John Koleszar's avatar
John Koleszar committed
1052
1053
          if (mode == B_PRED) {
            int j = 0;
1054
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
1055
1056
1057
1058
            int uses_second =
              m->bmi[0].as_mode.second !=
              (B_PREDICTION_MODE)(B_DC_PRED - 1);
            vp8_write(w, uses_second, 128);
1059
#endif
John Koleszar's avatar
John Koleszar committed
1060
            do {
1061
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
1062
              B_PREDICTION_MODE mode2 = m->bmi[j].as_mode.second;
1063
#endif
John Koleszar's avatar
John Koleszar committed
1064
1065
              write_bmode(w, m->bmi[j].as_mode.first,
                          pc->fc.bmode_prob);
1066
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
              if (uses_second) {
                write_bmode(w, mode2, pc->fc.bmode_prob);
              }
#endif
            } while (++j < 16);
          }
          if (mode == I8X8_PRED) {
            write_i8x8_mode(w, m->bmi[0].as_mode.first,
                            pc->fc.i8x8_mode_prob);
            write_i8x8_mode(w, m->bmi[2].as_mode.first,
                            pc->fc.i8x8_mode_prob);
            write_i8x8_mode(w, m->bmi[8].as_mode.first,
                            pc->fc.i8x8_mode_prob);
            write_i8x8_mode(w, m->bmi[10].as_mode.first,
                            pc->fc.i8x8_mode_prob);
          } else {
            write_uv_mode(w, mi->uv_mode,
                          pc->fc.uv_mode_prob[mode]);
          }
        } else {
          int_mv best_mv, best_second_mv;
          int ct[4];

          vp8_prob mv_ref_p [VP8_MVREFS - 1];

          {
            int_mv n1, n2;

            vp8_find_near_mvs(xd, m, prev_m, &n1, &n2, &best_mv, ct,
                              rf, cpi->common.ref_frame_sign_bias);
1097
1098
1099
#if CONFIG_NEWBESTREFMV
            best_mv.as_int = mi->ref_mv.as_int;
#endif
John Koleszar's avatar
John Koleszar committed
1100
            vp8_mv_ref_probs(&cpi->common, mv_ref_p, ct);
Yaowu Xu's avatar
Yaowu Xu committed
1101

John Koleszar's avatar
John Koleszar committed
1102
#ifdef ENTROPY_STATS
John Koleszar's avatar
John Koleszar committed
1103
            accum_mv_refs(mode, ct);
John Koleszar's avatar
John Koleszar committed
1104
#endif
John Koleszar's avatar
John Koleszar committed
1105
          }
John Koleszar's avatar
John Koleszar committed
1106
1107

#ifdef ENTROPY_STATS
John Koleszar's avatar
John Koleszar committed
1108
          active_section = 3;
John Koleszar's avatar
John Koleszar committed
1109
1110
#endif

John Koleszar's avatar
John Koleszar committed
1111
1112
          // Is the segment coding of mode enabled
          if (!segfeature_active(xd, segment_id, SEG_LVL_MODE)) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
1113
1114
1115
1116
1117
1118
1119
1120
#if CONFIG_SUPERBLOCKS
            if (mi->encoded_as_sb) {
              write_sb_mv_ref(w, mode, mv_ref_p);
            } else
#endif
            {
              write_mv_ref(w, mode, mv_ref_p);
            }
John Koleszar's avatar
John Koleszar committed
1121
1122
            vp8_accum_mv_refs(&cpi->common, mode, ct);
          }
1123

1124
#if CONFIG_PRED_FILTER
John Koleszar's avatar
John Koleszar committed
1125
1126
1127
1128
1129
1130
1131
1132
1133
          // Is the prediction filter enabled
          if (mode >= NEARESTMV && mode < SPLITMV) {
            if (cpi->common.pred_filter_mode == 2)
              vp8_write(w, mi->pred_filter_enabled,
                        pc->prob_pred_filter_off);
            else
              assert(mi->pred_filter_enabled ==
                     cpi->common.pred_filter_mode);
          }
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
#endif
#if CONFIG_SWITCHABLE_INTERP
          if (mode >= NEARESTMV && mode <= SPLITMV)
          {
            if (cpi->common.mcomp_filter_type == SWITCHABLE) {
              vp8_write_token(w, vp8_switchable_interp_tree,
                              get_pred_probs(&cpi->common, xd, PRED_SWITCHABLE_INTERP),
                              vp8_switchable_interp_encodings +
                              vp8_switchable_interp_map[mi->interp_filter]);
              //if (!cpi->dummy_packing) printf("Reading: %d\n", mi->interp_filter);
            } else {
              assert (mi->interp_filter ==
                      cpi->common.mcomp_filter_type);
            }
          }
John Koleszar's avatar
John Koleszar committed
1149
1150
1151
1152
1153
1154
1155
1156
#endif
          if (mi->second_ref_frame &&
              (mode == NEWMV || mode == SPLITMV)) {
            int_mv n1, n2;

            vp8_find_near_mvs(xd, m,
                              prev_m,
                              &n1, &n2, &best_second_mv, ct,
1157
1158
1159
1160
1161
                              mi->second_ref_frame,
                              cpi->common.ref_frame_sign_bias);
#if CONFIG_NEWBESTREFMV
            best_second_mv.as_int = mi->second_ref_mv.as_int;
#endif
John Koleszar's avatar
John Koleszar committed
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
          }

          // does the feature use compound prediction or not
          // (if not specified at the frame/segment level)
          if (cpi->common.comp_pred_mode == HYBRID_PREDICTION) {
            vp8_write(w, mi->second_ref_frame != INTRA_FRAME,
                      get_pred_prob(pc, xd, PRED_COMP));
          }

          {
            switch (mode) { /* new, split require MVs */
              case NEWMV:
1174
#ifdef ENTROPY_STATS
John Koleszar's avatar
John Koleszar committed
1175
                active_section = 5;
1176
#endif
John Koleszar's avatar
John Koleszar committed
1177

Paul Wilkins's avatar
Paul Wilkins committed
1178
#if 0 //CONFIG_NEW_MVREF
Paul Wilkins's avatar
Paul Wilkins committed
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
                {
                  unsigned int best_index;
                  /*find_mv_refs(xd, m, prev_m,
                               m->mbmi.ref_frame,
                               mi->ref_mvs[rf],
                               cpi->common.ref_frame_sign_bias );*/

                  best_index = pick_best_mv_ref(x, mi->mv[0],
                                                mi->ref_mvs[rf], &best_mv);
                  cpi->best_ref_index_counts[best_index]++;
Paul Wilkins's avatar
Paul Wilkins committed
1189

Paul Wilkins's avatar
Paul Wilkins committed
1190
                }
Paul Wilkins's avatar
Paul Wilkins committed
1191
#endif
1192
1193
1194
1195
1196
1197
#if CONFIG_NEWMVENTROPY
                write_nmv(w, &mi->mv[0].as_mv, &best_mv,
                          (const nmv_context*) nmvc,
                          xd->allow_high_precision_mv);
#else
                if (xd->allow_high_precision_mv) {
1198
                  write_mv_hp(w, &mi->mv[0].as_mv, &best_mv, mvc_hp);
1199
                } else {
1200
                  write_mv(w, &mi->mv[0].as_mv, &best_mv, mvc);
1201
1202
                }
#endif
John Koleszar's avatar
John Koleszar committed
1203
1204

                if (mi->second_ref_frame) {
Paul Wilkins's avatar
Paul Wilkins committed
1205
#if 0 //CONFIG_NEW_MVREF
Paul Wilkins's avatar
Paul Wilkins committed
1206
1207
1208
                  unsigned int best_index;

                  /*find_mv_refs(xd, m, prev_m,
Paul Wilkins's avatar
Paul Wilkins committed
1209
1210
                               m->mbmi.second_ref_frame,
                               mi->ref_mvs[mi->second_ref_frame],
Paul Wilkins's avatar
Paul Wilkins committed
1211
                               cpi->common.ref_frame_sign_bias );*/
Paul Wilkins's avatar
Paul Wilkins committed
1212

Paul Wilkins's avatar
Paul Wilkins committed
1213
1214
1215
1216
1217
                  best_index =
                    pick_best_mv_ref(x, mi->mv[1],
                                     mi->ref_mvs[mi->second_ref_frame],
                                     &best_second_mv);
                  cpi->best_ref_index_counts[best_index]++;
Paul Wilkins's avatar
Paul Wilkins committed
1218
#endif
1219
1220
1221
1222
1223
1224
#if CONFIG_NEWMVENTROPY
                  write_nmv(w, &mi->mv[1].as_mv, &best_second_mv,
                            (const nmv_context*) nmvc,
                            xd->allow_high_precision_mv);
#else
                  if (xd->allow_high_precision_mv) {
1225
                    write_mv_hp(w, &mi->mv[1].as_mv, &best_second_mv, mvc_hp);
1226
                  } else {
1227
                    write_mv(w, &mi->mv[1].as_mv, &best_second_mv, mvc);
1228
1229
                  }
#endif
John Koleszar's avatar
John Koleszar committed
1230
1231
1232
1233
                }
                break;
              case SPLITMV: {
                int j = 0;
John Koleszar's avatar
John Koleszar committed
1234

1235
#ifdef MODE_STATS
John Koleszar's avatar
John Koleszar committed
1236
                ++count_mb_seg [mi->partitioning];
1237
#endif
John Koleszar's avatar
John Koleszar committed
1238

John Koleszar's avatar
John Koleszar committed
1239
1240
                write_split(w, mi->partitioning, cpi->common.fc.mbsplit_prob);
                cpi->mbsplit_count[mi->partitioning]++;
1241

John Koleszar's avatar
John Koleszar committed
1242
1243
1244
1245
1246
1247
1248
1249
                do {
                  B_PREDICTION_MODE blockmode;
                  int_mv blockmv;
                  const int *const  L =
                    vp8_mbsplits [mi->partitioning];
                  int k = -1;  /* first block in subset j */
                  int mv_contz;
                  int_mv leftmv, abovemv;
Adrian Grange's avatar
Adrian Grange committed
1250

John Koleszar's avatar
John Koleszar committed
1251
1252
                  blockmode = cpi->mb.partition_info->bmi[j].mode;
                  blockmv = cpi->mb.partition_info->bmi[j].mv;
1253
#if CONFIG_DEBUG
John Koleszar's avatar
John Koleszar committed
1254
1255
1256
                  while (j != L[++k])
                    if (k >= 16)
                      assert(0);
1257
#else
John Koleszar's avatar
John Koleszar committed
1258
                  while (j != L[++k]);
1259
#endif
John Koleszar's avatar
John Koleszar committed
1260
1261
1262
                  leftmv.as_int = left_block_mv(m, k);
                  abovemv.as_int