190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/*
2f71323e297a928af368937089d3ed71239786f86Andreas Huber *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
4f71323e297a928af368937089d3ed71239786f86Andreas Huber *  Use of this source code is governed by a BSD-style license
5f71323e297a928af368937089d3ed71239786f86Andreas Huber *  that can be found in the LICENSE file in the root of the source
6f71323e297a928af368937089d3ed71239786f86Andreas Huber *  tree. An additional intellectual property rights grant can be found
7f71323e297a928af368937089d3ed71239786f86Andreas Huber *  in the file PATENTS.  All contributing project authors may
8f71323e297a928af368937089d3ed71239786f86Andreas Huber *  be found in the AUTHORS file in the root of the source tree.
990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber */
1090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1179f15823c34ae1e423108295e416213200bb280fAndreas Huber#include "vp8/common/header.h"
1290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include "encodemv.h"
1379f15823c34ae1e423108295e416213200bb280fAndreas Huber#include "vp8/common/entropymode.h"
1479f15823c34ae1e423108295e416213200bb280fAndreas Huber#include "vp8/common/findnearmv.h"
1590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include "mcomp.h"
1679f15823c34ae1e423108295e416213200bb280fAndreas Huber#include "vp8/common/systemdependent.h"
1790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <assert.h>
1890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <stdio.h>
191b362b15af34006e6a11974088a46d42b903418eJohann#include <limits.h>
201b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx/vpx_encoder.h"
2190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include "vpx_mem/vpx_mem.h"
227bc9febe8749e98a3812a0dc4380ceae75c29450Johann#include "vpx_ports/system_state.h"
2390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include "bitstream.h"
2490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
251b362b15af34006e6a11974088a46d42b903418eJohann#include "defaultcoefcounts.h"
261b362b15af34006e6a11974088a46d42b903418eJohann#include "vp8/common/common.h"
271b362b15af34006e6a11974088a46d42b903418eJohann
287bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst int vp8cx_base_skip_false_prob[128] = {
297bc9febe8749e98a3812a0dc4380ceae75c29450Johann  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
307bc9febe8749e98a3812a0dc4380ceae75c29450Johann  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
317bc9febe8749e98a3812a0dc4380ceae75c29450Johann  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
327bc9febe8749e98a3812a0dc4380ceae75c29450Johann  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 251, 248, 244, 240,
337bc9febe8749e98a3812a0dc4380ceae75c29450Johann  236, 232, 229, 225, 221, 217, 213, 208, 204, 199, 194, 190, 187, 183, 179,
347bc9febe8749e98a3812a0dc4380ceae75c29450Johann  175, 172, 168, 164, 160, 157, 153, 149, 145, 142, 138, 134, 130, 127, 124,
357bc9febe8749e98a3812a0dc4380ceae75c29450Johann  120, 117, 114, 110, 107, 104, 101, 98,  95,  92,  89,  86,  83,  80,  77,
367bc9febe8749e98a3812a0dc4380ceae75c29450Johann  74,  71,  68,  65,  62,  59,  56,  53,  50,  47,  44,  41,  38,  35,  32,
377bc9febe8749e98a3812a0dc4380ceae75c29450Johann  30,  28,  26,  24,  22,  20,  18,  16,
3890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber};
3990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if defined(SECTIONBITS_OUTPUT)
4190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberunsigned __int64 Sectionbits[500];
4290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
4390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
44ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#ifdef VP8_ENTROPY_STATS
4590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberint intra_mode_stats[10][10][10];
467bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic unsigned int tree_update_hist[BLOCK_TYPES][COEF_BANDS]
477bc9febe8749e98a3812a0dc4380ceae75c29450Johann                                    [PREV_COEF_CONTEXTS][ENTROPY_NODES][2];
4890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberextern unsigned int active_section;
4990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
5090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#ifdef MODE_STATS
5290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberint count_mb_seg[4] = { 0, 0, 0, 0 };
5390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
5490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
557bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void update_mode(vp8_writer *const w, int n, vp8_token tok[/* n */],
567bc9febe8749e98a3812a0dc4380ceae75c29450Johann                        vp8_tree tree, vp8_prob Pnew[/* n-1 */],
577bc9febe8749e98a3812a0dc4380ceae75c29450Johann                        vp8_prob Pcur[/* n-1 */],
587bc9febe8749e98a3812a0dc4380ceae75c29450Johann                        unsigned int bct[/* n-1 */][2],
597bc9febe8749e98a3812a0dc4380ceae75c29450Johann                        const unsigned int num_events[/* n */]) {
607bc9febe8749e98a3812a0dc4380ceae75c29450Johann  unsigned int new_b = 0, old_b = 0;
617bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int i = 0;
6290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
637bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_tree_probs_from_distribution(n--, tok, tree, Pnew, bct, num_events, 256,
647bc9febe8749e98a3812a0dc4380ceae75c29450Johann                                   1);
6590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
667bc9febe8749e98a3812a0dc4380ceae75c29450Johann  do {
677bc9febe8749e98a3812a0dc4380ceae75c29450Johann    new_b += vp8_cost_branch(bct[i], Pnew[i]);
687bc9febe8749e98a3812a0dc4380ceae75c29450Johann    old_b += vp8_cost_branch(bct[i], Pcur[i]);
697bc9febe8749e98a3812a0dc4380ceae75c29450Johann  } while (++i < n);
7090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
717bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (new_b + (n << 8) < old_b) {
727bc9febe8749e98a3812a0dc4380ceae75c29450Johann    int j = 0;
7390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
747bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_write_bit(w, 1);
7590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
767bc9febe8749e98a3812a0dc4380ceae75c29450Johann    do {
777bc9febe8749e98a3812a0dc4380ceae75c29450Johann      const vp8_prob p = Pnew[j];
7890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
797bc9febe8749e98a3812a0dc4380ceae75c29450Johann      vp8_write_literal(w, Pcur[j] = p ? p : 1, 8);
807bc9febe8749e98a3812a0dc4380ceae75c29450Johann    } while (++j < n);
817bc9febe8749e98a3812a0dc4380ceae75c29450Johann  } else
827bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_write_bit(w, 0);
8390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
8490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
857bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void update_mbintra_mode_probs(VP8_COMP *cpi) {
867bc9febe8749e98a3812a0dc4380ceae75c29450Johann  VP8_COMMON *const x = &cpi->common;
8790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
887bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_writer *const w = cpi->bc;
8990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
907bc9febe8749e98a3812a0dc4380ceae75c29450Johann  {
917bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_prob Pnew[VP8_YMODES - 1];
927bc9febe8749e98a3812a0dc4380ceae75c29450Johann    unsigned int bct[VP8_YMODES - 1][2];
9390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
947bc9febe8749e98a3812a0dc4380ceae75c29450Johann    update_mode(w, VP8_YMODES, vp8_ymode_encodings, vp8_ymode_tree, Pnew,
957bc9febe8749e98a3812a0dc4380ceae75c29450Johann                x->fc.ymode_prob, bct, (unsigned int *)cpi->mb.ymode_count);
967bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
977bc9febe8749e98a3812a0dc4380ceae75c29450Johann  {
987bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_prob Pnew[VP8_UV_MODES - 1];
997bc9febe8749e98a3812a0dc4380ceae75c29450Johann    unsigned int bct[VP8_UV_MODES - 1][2];
10090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1017bc9febe8749e98a3812a0dc4380ceae75c29450Johann    update_mode(w, VP8_UV_MODES, vp8_uv_mode_encodings, vp8_uv_mode_tree, Pnew,
1027bc9febe8749e98a3812a0dc4380ceae75c29450Johann                x->fc.uv_mode_prob, bct, (unsigned int *)cpi->mb.uv_mode_count);
1037bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
10490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
10590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1067bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void write_ymode(vp8_writer *bc, int m, const vp8_prob *p) {
1077bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_write_token(bc, vp8_ymode_tree, p, vp8_ymode_encodings + m);
10890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
10990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1107bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void kfwrite_ymode(vp8_writer *bc, int m, const vp8_prob *p) {
1117bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_write_token(bc, vp8_kf_ymode_tree, p, vp8_kf_ymode_encodings + m);
11290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
11390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1147bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void write_uv_mode(vp8_writer *bc, int m, const vp8_prob *p) {
1157bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_write_token(bc, vp8_uv_mode_tree, p, vp8_uv_mode_encodings + m);
11690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
11790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1187bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void write_bmode(vp8_writer *bc, int m, const vp8_prob *p) {
1197bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_write_token(bc, vp8_bmode_tree, p, vp8_bmode_encodings + m);
12090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
12190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1227bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void write_split(vp8_writer *bc, int x) {
1237bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_write_token(bc, vp8_mbsplit_tree, vp8_mbsplit_probs,
1247bc9febe8749e98a3812a0dc4380ceae75c29450Johann                  vp8_mbsplit_encodings + x);
12590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
12690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1277bc9febe8749e98a3812a0dc4380ceae75c29450Johannvoid vp8_pack_tokens(vp8_writer *w, const TOKENEXTRA *p, int xcount) {
1287bc9febe8749e98a3812a0dc4380ceae75c29450Johann  const TOKENEXTRA *stop = p + xcount;
1297bc9febe8749e98a3812a0dc4380ceae75c29450Johann  unsigned int split;
1307bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int shift;
1317bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int count = w->count;
1327bc9febe8749e98a3812a0dc4380ceae75c29450Johann  unsigned int range = w->range;
1337bc9febe8749e98a3812a0dc4380ceae75c29450Johann  unsigned int lowvalue = w->lowvalue;
1347bc9febe8749e98a3812a0dc4380ceae75c29450Johann
1357bc9febe8749e98a3812a0dc4380ceae75c29450Johann  while (p < stop) {
1367bc9febe8749e98a3812a0dc4380ceae75c29450Johann    const int t = p->Token;
1377bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_token *a = vp8_coef_encodings + t;
1387bc9febe8749e98a3812a0dc4380ceae75c29450Johann    const vp8_extra_bit_struct *b = vp8_extra_bits + t;
1397bc9febe8749e98a3812a0dc4380ceae75c29450Johann    int i = 0;
1407bc9febe8749e98a3812a0dc4380ceae75c29450Johann    const unsigned char *pp = p->context_tree;
1417bc9febe8749e98a3812a0dc4380ceae75c29450Johann    int v = a->value;
1427bc9febe8749e98a3812a0dc4380ceae75c29450Johann    int n = a->Len;
14390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1447bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (p->skip_eob_node) {
1457bc9febe8749e98a3812a0dc4380ceae75c29450Johann      n--;
1467bc9febe8749e98a3812a0dc4380ceae75c29450Johann      i = 2;
1477bc9febe8749e98a3812a0dc4380ceae75c29450Johann    }
14890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1497bc9febe8749e98a3812a0dc4380ceae75c29450Johann    do {
1507bc9febe8749e98a3812a0dc4380ceae75c29450Johann      const int bb = (v >> --n) & 1;
1517bc9febe8749e98a3812a0dc4380ceae75c29450Johann      split = 1 + (((range - 1) * pp[i >> 1]) >> 8);
1527bc9febe8749e98a3812a0dc4380ceae75c29450Johann      i = vp8_coef_tree[i + bb];
15390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1547bc9febe8749e98a3812a0dc4380ceae75c29450Johann      if (bb) {
1557bc9febe8749e98a3812a0dc4380ceae75c29450Johann        lowvalue += split;
1567bc9febe8749e98a3812a0dc4380ceae75c29450Johann        range = range - split;
1577bc9febe8749e98a3812a0dc4380ceae75c29450Johann      } else {
1587bc9febe8749e98a3812a0dc4380ceae75c29450Johann        range = split;
1597bc9febe8749e98a3812a0dc4380ceae75c29450Johann      }
16090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1617bc9febe8749e98a3812a0dc4380ceae75c29450Johann      shift = vp8_norm[range];
1627bc9febe8749e98a3812a0dc4380ceae75c29450Johann      range <<= shift;
1637bc9febe8749e98a3812a0dc4380ceae75c29450Johann      count += shift;
16490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1657bc9febe8749e98a3812a0dc4380ceae75c29450Johann      if (count >= 0) {
1667bc9febe8749e98a3812a0dc4380ceae75c29450Johann        int offset = shift - count;
16790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1687bc9febe8749e98a3812a0dc4380ceae75c29450Johann        if ((lowvalue << (offset - 1)) & 0x80000000) {
1697bc9febe8749e98a3812a0dc4380ceae75c29450Johann          int x = w->pos - 1;
17090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1717bc9febe8749e98a3812a0dc4380ceae75c29450Johann          while (x >= 0 && w->buffer[x] == 0xff) {
1727bc9febe8749e98a3812a0dc4380ceae75c29450Johann            w->buffer[x] = (unsigned char)0;
1737bc9febe8749e98a3812a0dc4380ceae75c29450Johann            x--;
1747bc9febe8749e98a3812a0dc4380ceae75c29450Johann          }
17590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1767bc9febe8749e98a3812a0dc4380ceae75c29450Johann          w->buffer[x] += 1;
1777bc9febe8749e98a3812a0dc4380ceae75c29450Johann        }
17890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1797bc9febe8749e98a3812a0dc4380ceae75c29450Johann        validate_buffer(w->buffer + w->pos, 1, w->buffer_end, w->error);
1801b362b15af34006e6a11974088a46d42b903418eJohann
1817bc9febe8749e98a3812a0dc4380ceae75c29450Johann        w->buffer[w->pos++] = (lowvalue >> (24 - offset));
1827bc9febe8749e98a3812a0dc4380ceae75c29450Johann        lowvalue <<= offset;
1837bc9febe8749e98a3812a0dc4380ceae75c29450Johann        shift = count;
1847bc9febe8749e98a3812a0dc4380ceae75c29450Johann        lowvalue &= 0xffffff;
1857bc9febe8749e98a3812a0dc4380ceae75c29450Johann        count -= 8;
1867bc9febe8749e98a3812a0dc4380ceae75c29450Johann      }
18790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1887bc9febe8749e98a3812a0dc4380ceae75c29450Johann      lowvalue <<= shift;
1897bc9febe8749e98a3812a0dc4380ceae75c29450Johann    } while (n);
19090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1917bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (b->base_val) {
1927bc9febe8749e98a3812a0dc4380ceae75c29450Johann      const int e = p->Extra, L = b->Len;
19390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1947bc9febe8749e98a3812a0dc4380ceae75c29450Johann      if (L) {
1957bc9febe8749e98a3812a0dc4380ceae75c29450Johann        const unsigned char *proba = b->prob;
1967bc9febe8749e98a3812a0dc4380ceae75c29450Johann        const int v2 = e >> 1;
1977bc9febe8749e98a3812a0dc4380ceae75c29450Johann        int n2 = L; /* number of bits in v2, assumed nonzero */
1987bc9febe8749e98a3812a0dc4380ceae75c29450Johann        i = 0;
19990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2007bc9febe8749e98a3812a0dc4380ceae75c29450Johann        do {
2017bc9febe8749e98a3812a0dc4380ceae75c29450Johann          const int bb = (v2 >> --n2) & 1;
2027bc9febe8749e98a3812a0dc4380ceae75c29450Johann          split = 1 + (((range - 1) * proba[i >> 1]) >> 8);
2037bc9febe8749e98a3812a0dc4380ceae75c29450Johann          i = b->tree[i + bb];
20490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2057bc9febe8749e98a3812a0dc4380ceae75c29450Johann          if (bb) {
2067bc9febe8749e98a3812a0dc4380ceae75c29450Johann            lowvalue += split;
2077bc9febe8749e98a3812a0dc4380ceae75c29450Johann            range = range - split;
2087bc9febe8749e98a3812a0dc4380ceae75c29450Johann          } else {
2097bc9febe8749e98a3812a0dc4380ceae75c29450Johann            range = split;
2107bc9febe8749e98a3812a0dc4380ceae75c29450Johann          }
21190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2127bc9febe8749e98a3812a0dc4380ceae75c29450Johann          shift = vp8_norm[range];
2137bc9febe8749e98a3812a0dc4380ceae75c29450Johann          range <<= shift;
2147bc9febe8749e98a3812a0dc4380ceae75c29450Johann          count += shift;
21590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2167bc9febe8749e98a3812a0dc4380ceae75c29450Johann          if (count >= 0) {
2177bc9febe8749e98a3812a0dc4380ceae75c29450Johann            int offset = shift - count;
21890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2197bc9febe8749e98a3812a0dc4380ceae75c29450Johann            if ((lowvalue << (offset - 1)) & 0x80000000) {
2207bc9febe8749e98a3812a0dc4380ceae75c29450Johann              int x = w->pos - 1;
22190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2227bc9febe8749e98a3812a0dc4380ceae75c29450Johann              while (x >= 0 && w->buffer[x] == 0xff) {
2237bc9febe8749e98a3812a0dc4380ceae75c29450Johann                w->buffer[x] = (unsigned char)0;
2247bc9febe8749e98a3812a0dc4380ceae75c29450Johann                x--;
2257bc9febe8749e98a3812a0dc4380ceae75c29450Johann              }
22690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2277bc9febe8749e98a3812a0dc4380ceae75c29450Johann              w->buffer[x] += 1;
2287bc9febe8749e98a3812a0dc4380ceae75c29450Johann            }
22990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2307bc9febe8749e98a3812a0dc4380ceae75c29450Johann            validate_buffer(w->buffer + w->pos, 1, w->buffer_end, w->error);
23190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2327bc9febe8749e98a3812a0dc4380ceae75c29450Johann            w->buffer[w->pos++] = (lowvalue >> (24 - offset));
2337bc9febe8749e98a3812a0dc4380ceae75c29450Johann            lowvalue <<= offset;
2347bc9febe8749e98a3812a0dc4380ceae75c29450Johann            shift = count;
2357bc9febe8749e98a3812a0dc4380ceae75c29450Johann            lowvalue &= 0xffffff;
2367bc9febe8749e98a3812a0dc4380ceae75c29450Johann            count -= 8;
2377bc9febe8749e98a3812a0dc4380ceae75c29450Johann          }
23890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2397bc9febe8749e98a3812a0dc4380ceae75c29450Johann          lowvalue <<= shift;
2407bc9febe8749e98a3812a0dc4380ceae75c29450Johann        } while (n2);
2417bc9febe8749e98a3812a0dc4380ceae75c29450Johann      }
24290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2437bc9febe8749e98a3812a0dc4380ceae75c29450Johann      {
2447bc9febe8749e98a3812a0dc4380ceae75c29450Johann        split = (range + 1) >> 1;
24590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2467bc9febe8749e98a3812a0dc4380ceae75c29450Johann        if (e & 1) {
2477bc9febe8749e98a3812a0dc4380ceae75c29450Johann          lowvalue += split;
2487bc9febe8749e98a3812a0dc4380ceae75c29450Johann          range = range - split;
2497bc9febe8749e98a3812a0dc4380ceae75c29450Johann        } else {
2507bc9febe8749e98a3812a0dc4380ceae75c29450Johann          range = split;
2517bc9febe8749e98a3812a0dc4380ceae75c29450Johann        }
25290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2537bc9febe8749e98a3812a0dc4380ceae75c29450Johann        range <<= 1;
2541b362b15af34006e6a11974088a46d42b903418eJohann
2557bc9febe8749e98a3812a0dc4380ceae75c29450Johann        if ((lowvalue & 0x80000000)) {
2567bc9febe8749e98a3812a0dc4380ceae75c29450Johann          int x = w->pos - 1;
2571b362b15af34006e6a11974088a46d42b903418eJohann
2587bc9febe8749e98a3812a0dc4380ceae75c29450Johann          while (x >= 0 && w->buffer[x] == 0xff) {
2597bc9febe8749e98a3812a0dc4380ceae75c29450Johann            w->buffer[x] = (unsigned char)0;
2607bc9febe8749e98a3812a0dc4380ceae75c29450Johann            x--;
2617bc9febe8749e98a3812a0dc4380ceae75c29450Johann          }
26290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2637bc9febe8749e98a3812a0dc4380ceae75c29450Johann          w->buffer[x] += 1;
26490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
26590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2667bc9febe8749e98a3812a0dc4380ceae75c29450Johann        lowvalue <<= 1;
26790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2687bc9febe8749e98a3812a0dc4380ceae75c29450Johann        if (!++count) {
2697bc9febe8749e98a3812a0dc4380ceae75c29450Johann          count = -8;
27090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2717bc9febe8749e98a3812a0dc4380ceae75c29450Johann          validate_buffer(w->buffer + w->pos, 1, w->buffer_end, w->error);
27290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2737bc9febe8749e98a3812a0dc4380ceae75c29450Johann          w->buffer[w->pos++] = (lowvalue >> 24);
2747bc9febe8749e98a3812a0dc4380ceae75c29450Johann          lowvalue &= 0xffffff;
2757bc9febe8749e98a3812a0dc4380ceae75c29450Johann        }
2767bc9febe8749e98a3812a0dc4380ceae75c29450Johann      }
2777bc9febe8749e98a3812a0dc4380ceae75c29450Johann    }
27890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2797bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ++p;
2807bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
28190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2827bc9febe8749e98a3812a0dc4380ceae75c29450Johann  w->count = count;
2837bc9febe8749e98a3812a0dc4380ceae75c29450Johann  w->lowvalue = lowvalue;
2847bc9febe8749e98a3812a0dc4380ceae75c29450Johann  w->range = range;
28590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
28690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2877bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void write_partition_size(unsigned char *cx_data, int size) {
2887bc9febe8749e98a3812a0dc4380ceae75c29450Johann  signed char csize;
28990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2907bc9febe8749e98a3812a0dc4380ceae75c29450Johann  csize = size & 0xff;
2917bc9febe8749e98a3812a0dc4380ceae75c29450Johann  *cx_data = csize;
2927bc9febe8749e98a3812a0dc4380ceae75c29450Johann  csize = (size >> 8) & 0xff;
2937bc9febe8749e98a3812a0dc4380ceae75c29450Johann  *(cx_data + 1) = csize;
2947bc9febe8749e98a3812a0dc4380ceae75c29450Johann  csize = (size >> 16) & 0xff;
2957bc9febe8749e98a3812a0dc4380ceae75c29450Johann  *(cx_data + 2) = csize;
2967bc9febe8749e98a3812a0dc4380ceae75c29450Johann}
29790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2987bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void pack_tokens_into_partitions(VP8_COMP *cpi, unsigned char *cx_data,
2997bc9febe8749e98a3812a0dc4380ceae75c29450Johann                                        unsigned char *cx_data_end,
3007bc9febe8749e98a3812a0dc4380ceae75c29450Johann                                        int num_part) {
3017bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int i;
3027bc9febe8749e98a3812a0dc4380ceae75c29450Johann  unsigned char *ptr = cx_data;
3037bc9febe8749e98a3812a0dc4380ceae75c29450Johann  unsigned char *ptr_end = cx_data_end;
3047bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_writer *w;
3057bc9febe8749e98a3812a0dc4380ceae75c29450Johann
3067bc9febe8749e98a3812a0dc4380ceae75c29450Johann  for (i = 0; i < num_part; ++i) {
3077bc9febe8749e98a3812a0dc4380ceae75c29450Johann    int mb_row;
30890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
3097bc9febe8749e98a3812a0dc4380ceae75c29450Johann    w = cpi->bc + i + 1;
31090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
3117bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_start_encode(w, ptr, ptr_end);
31290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
3137bc9febe8749e98a3812a0dc4380ceae75c29450Johann    for (mb_row = i; mb_row < cpi->common.mb_rows; mb_row += num_part) {
3147bc9febe8749e98a3812a0dc4380ceae75c29450Johann      const TOKENEXTRA *p = cpi->tplist[mb_row].start;
3157bc9febe8749e98a3812a0dc4380ceae75c29450Johann      const TOKENEXTRA *stop = cpi->tplist[mb_row].stop;
3167bc9febe8749e98a3812a0dc4380ceae75c29450Johann      int tokens = (int)(stop - p);
31790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
3187bc9febe8749e98a3812a0dc4380ceae75c29450Johann      vp8_pack_tokens(w, p, tokens);
31990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
32090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
3217bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_stop_encode(w);
3227bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ptr += w->pos;
3237bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
3247bc9febe8749e98a3812a0dc4380ceae75c29450Johann}
32590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
326c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann#if CONFIG_MULTITHREAD
3277bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void pack_mb_row_tokens(VP8_COMP *cpi, vp8_writer *w) {
3287bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int mb_row;
32990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
3307bc9febe8749e98a3812a0dc4380ceae75c29450Johann  for (mb_row = 0; mb_row < cpi->common.mb_rows; ++mb_row) {
3317bc9febe8749e98a3812a0dc4380ceae75c29450Johann    const TOKENEXTRA *p = cpi->tplist[mb_row].start;
3327bc9febe8749e98a3812a0dc4380ceae75c29450Johann    const TOKENEXTRA *stop = cpi->tplist[mb_row].stop;
3337bc9febe8749e98a3812a0dc4380ceae75c29450Johann    int tokens = (int)(stop - p);
33490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
3357bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_pack_tokens(w, p, tokens);
3367bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
33790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
338c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann#endif  // CONFIG_MULTITHREAD
33990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
3407bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void write_mv_ref(vp8_writer *w, MB_PREDICTION_MODE m,
3417bc9febe8749e98a3812a0dc4380ceae75c29450Johann                         const vp8_prob *p) {
3427bc9febe8749e98a3812a0dc4380ceae75c29450Johann  assert(NEARESTMV <= m && m <= SPLITMV);
3437bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_write_token(w, vp8_mv_ref_tree, p,
3447bc9febe8749e98a3812a0dc4380ceae75c29450Johann                  vp8_mv_ref_encoding_array + (m - NEARESTMV));
34590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
34690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
3477bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void write_sub_mv_ref(vp8_writer *w, B_PREDICTION_MODE m,
3487bc9febe8749e98a3812a0dc4380ceae75c29450Johann                             const vp8_prob *p) {
3497bc9febe8749e98a3812a0dc4380ceae75c29450Johann  assert(LEFT4X4 <= m && m <= NEW4X4);
3507bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_write_token(w, vp8_sub_mv_ref_tree, p,
3517bc9febe8749e98a3812a0dc4380ceae75c29450Johann                  vp8_sub_mv_ref_encoding_array + (m - LEFT4X4));
35290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
35390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
3547bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void write_mv(vp8_writer *w, const MV *mv, const int_mv *ref,
3557bc9febe8749e98a3812a0dc4380ceae75c29450Johann                     const MV_CONTEXT *mvc) {
3567bc9febe8749e98a3812a0dc4380ceae75c29450Johann  MV e;
3577bc9febe8749e98a3812a0dc4380ceae75c29450Johann  e.row = mv->row - ref->as_mv.row;
3587bc9febe8749e98a3812a0dc4380ceae75c29450Johann  e.col = mv->col - ref->as_mv.col;
35990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
3607bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_encode_motion_vector(w, &e, mvc);
36190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
36290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
3637bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void write_mb_features(vp8_writer *w, const MB_MODE_INFO *mi,
3647bc9febe8749e98a3812a0dc4380ceae75c29450Johann                              const MACROBLOCKD *x) {
3657bc9febe8749e98a3812a0dc4380ceae75c29450Johann  /* Encode the MB segment id. */
3667bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (x->segmentation_enabled && x->update_mb_segmentation_map) {
3677bc9febe8749e98a3812a0dc4380ceae75c29450Johann    switch (mi->segment_id) {
3687bc9febe8749e98a3812a0dc4380ceae75c29450Johann      case 0:
3697bc9febe8749e98a3812a0dc4380ceae75c29450Johann        vp8_write(w, 0, x->mb_segment_tree_probs[0]);
3707bc9febe8749e98a3812a0dc4380ceae75c29450Johann        vp8_write(w, 0, x->mb_segment_tree_probs[1]);
3717bc9febe8749e98a3812a0dc4380ceae75c29450Johann        break;
3727bc9febe8749e98a3812a0dc4380ceae75c29450Johann      case 1:
3737bc9febe8749e98a3812a0dc4380ceae75c29450Johann        vp8_write(w, 0, x->mb_segment_tree_probs[0]);
3747bc9febe8749e98a3812a0dc4380ceae75c29450Johann        vp8_write(w, 1, x->mb_segment_tree_probs[1]);
3757bc9febe8749e98a3812a0dc4380ceae75c29450Johann        break;
3767bc9febe8749e98a3812a0dc4380ceae75c29450Johann      case 2:
3777bc9febe8749e98a3812a0dc4380ceae75c29450Johann        vp8_write(w, 1, x->mb_segment_tree_probs[0]);
3787bc9febe8749e98a3812a0dc4380ceae75c29450Johann        vp8_write(w, 0, x->mb_segment_tree_probs[2]);
3797bc9febe8749e98a3812a0dc4380ceae75c29450Johann        break;
3807bc9febe8749e98a3812a0dc4380ceae75c29450Johann      case 3:
3817bc9febe8749e98a3812a0dc4380ceae75c29450Johann        vp8_write(w, 1, x->mb_segment_tree_probs[0]);
3827bc9febe8749e98a3812a0dc4380ceae75c29450Johann        vp8_write(w, 1, x->mb_segment_tree_probs[2]);
3837bc9febe8749e98a3812a0dc4380ceae75c29450Johann        break;
3847bc9febe8749e98a3812a0dc4380ceae75c29450Johann
3857bc9febe8749e98a3812a0dc4380ceae75c29450Johann      /* TRAP.. This should not happen */
3867bc9febe8749e98a3812a0dc4380ceae75c29450Johann      default:
3877bc9febe8749e98a3812a0dc4380ceae75c29450Johann        vp8_write(w, 0, x->mb_segment_tree_probs[0]);
3887bc9febe8749e98a3812a0dc4380ceae75c29450Johann        vp8_write(w, 0, x->mb_segment_tree_probs[1]);
3897bc9febe8749e98a3812a0dc4380ceae75c29450Johann        break;
39090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
3917bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
39290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
3937bc9febe8749e98a3812a0dc4380ceae75c29450Johannvoid vp8_convert_rfct_to_prob(VP8_COMP *const cpi) {
3947bc9febe8749e98a3812a0dc4380ceae75c29450Johann  const int *const rfct = cpi->mb.count_mb_ref_frame_usage;
3957bc9febe8749e98a3812a0dc4380ceae75c29450Johann  const int rf_intra = rfct[INTRA_FRAME];
3967bc9febe8749e98a3812a0dc4380ceae75c29450Johann  const int rf_inter =
3977bc9febe8749e98a3812a0dc4380ceae75c29450Johann      rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];
39890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
3997bc9febe8749e98a3812a0dc4380ceae75c29450Johann  /* Calculate the probabilities used to code the ref frame based on usage */
4007bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (!(cpi->prob_intra_coded = rf_intra * 255 / (rf_intra + rf_inter))) {
4017bc9febe8749e98a3812a0dc4380ceae75c29450Johann    cpi->prob_intra_coded = 1;
4027bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
4031b362b15af34006e6a11974088a46d42b903418eJohann
4047bc9febe8749e98a3812a0dc4380ceae75c29450Johann  cpi->prob_last_coded = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;
4051b362b15af34006e6a11974088a46d42b903418eJohann
4067bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (!cpi->prob_last_coded) cpi->prob_last_coded = 1;
4071b362b15af34006e6a11974088a46d42b903418eJohann
4087bc9febe8749e98a3812a0dc4380ceae75c29450Johann  cpi->prob_gf_coded = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
4097bc9febe8749e98a3812a0dc4380ceae75c29450Johann                           ? (rfct[GOLDEN_FRAME] * 255) /
4107bc9febe8749e98a3812a0dc4380ceae75c29450Johann                                 (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
4117bc9febe8749e98a3812a0dc4380ceae75c29450Johann                           : 128;
4121b362b15af34006e6a11974088a46d42b903418eJohann
4137bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (!cpi->prob_gf_coded) cpi->prob_gf_coded = 1;
4141b362b15af34006e6a11974088a46d42b903418eJohann}
41590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4167bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void pack_inter_mode_mvs(VP8_COMP *const cpi) {
4177bc9febe8749e98a3812a0dc4380ceae75c29450Johann  VP8_COMMON *const pc = &cpi->common;
4187bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_writer *const w = cpi->bc;
4197bc9febe8749e98a3812a0dc4380ceae75c29450Johann  const MV_CONTEXT *mvc = pc->fc.mvc;
42090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4217bc9febe8749e98a3812a0dc4380ceae75c29450Johann  MODE_INFO *m = pc->mi;
4227bc9febe8749e98a3812a0dc4380ceae75c29450Johann  const int mis = pc->mode_info_stride;
4237bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int mb_row = -1;
42490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4257bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int prob_skip_false = 0;
42690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4277bc9febe8749e98a3812a0dc4380ceae75c29450Johann  cpi->mb.partition_info = cpi->mb.pi;
428f71323e297a928af368937089d3ed71239786f86Andreas Huber
4297bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_convert_rfct_to_prob(cpi);
43090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
431ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#ifdef VP8_ENTROPY_STATS
4327bc9febe8749e98a3812a0dc4380ceae75c29450Johann  active_section = 1;
43390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
43490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4357bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (pc->mb_no_coeff_skip) {
4367bc9febe8749e98a3812a0dc4380ceae75c29450Johann    int total_mbs = pc->mb_rows * pc->mb_cols;
4371b362b15af34006e6a11974088a46d42b903418eJohann
4387bc9febe8749e98a3812a0dc4380ceae75c29450Johann    prob_skip_false = (total_mbs - cpi->mb.skip_true_count) * 256 / total_mbs;
43990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4407bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (prob_skip_false <= 1) prob_skip_false = 1;
44190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4427bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (prob_skip_false > 255) prob_skip_false = 255;
44390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4447bc9febe8749e98a3812a0dc4380ceae75c29450Johann    cpi->prob_skip_false = prob_skip_false;
4457bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_write_literal(w, prob_skip_false, 8);
4467bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
44790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4487bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_write_literal(w, cpi->prob_intra_coded, 8);
4497bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_write_literal(w, cpi->prob_last_coded, 8);
4507bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_write_literal(w, cpi->prob_gf_coded, 8);
45190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4527bc9febe8749e98a3812a0dc4380ceae75c29450Johann  update_mbintra_mode_probs(cpi);
45390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4547bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_write_mvprobs(cpi);
45590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4567bc9febe8749e98a3812a0dc4380ceae75c29450Johann  while (++mb_row < pc->mb_rows) {
4577bc9febe8749e98a3812a0dc4380ceae75c29450Johann    int mb_col = -1;
45890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4597bc9febe8749e98a3812a0dc4380ceae75c29450Johann    while (++mb_col < pc->mb_cols) {
4607bc9febe8749e98a3812a0dc4380ceae75c29450Johann      const MB_MODE_INFO *const mi = &m->mbmi;
4617bc9febe8749e98a3812a0dc4380ceae75c29450Johann      const MV_REFERENCE_FRAME rf = mi->ref_frame;
4627bc9febe8749e98a3812a0dc4380ceae75c29450Johann      const MB_PREDICTION_MODE mode = mi->mode;
46390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4647bc9febe8749e98a3812a0dc4380ceae75c29450Johann      MACROBLOCKD *xd = &cpi->mb.e_mbd;
46590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4667bc9febe8749e98a3812a0dc4380ceae75c29450Johann      /* Distance of Mb to the various image edges.
4677bc9febe8749e98a3812a0dc4380ceae75c29450Johann       * These specified to 8th pel as they are always compared to MV
4687bc9febe8749e98a3812a0dc4380ceae75c29450Johann       * values that are in 1/8th pel units
4697bc9febe8749e98a3812a0dc4380ceae75c29450Johann       */
4707bc9febe8749e98a3812a0dc4380ceae75c29450Johann      xd->mb_to_left_edge = -((mb_col * 16) << 3);
4717bc9febe8749e98a3812a0dc4380ceae75c29450Johann      xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
4727bc9febe8749e98a3812a0dc4380ceae75c29450Johann      xd->mb_to_top_edge = -((mb_row * 16) << 3);
4737bc9febe8749e98a3812a0dc4380ceae75c29450Johann      xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
47490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
475ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#ifdef VP8_ENTROPY_STATS
4767bc9febe8749e98a3812a0dc4380ceae75c29450Johann      active_section = 9;
47790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
47890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4797bc9febe8749e98a3812a0dc4380ceae75c29450Johann      if (cpi->mb.e_mbd.update_mb_segmentation_map) {
4807bc9febe8749e98a3812a0dc4380ceae75c29450Johann        write_mb_features(w, mi, &cpi->mb.e_mbd);
4817bc9febe8749e98a3812a0dc4380ceae75c29450Johann      }
48290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4837bc9febe8749e98a3812a0dc4380ceae75c29450Johann      if (pc->mb_no_coeff_skip) {
4847bc9febe8749e98a3812a0dc4380ceae75c29450Johann        vp8_encode_bool(w, m->mbmi.mb_skip_coeff, prob_skip_false);
4857bc9febe8749e98a3812a0dc4380ceae75c29450Johann      }
48690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4877bc9febe8749e98a3812a0dc4380ceae75c29450Johann      if (rf == INTRA_FRAME) {
4887bc9febe8749e98a3812a0dc4380ceae75c29450Johann        vp8_write(w, 0, cpi->prob_intra_coded);
489ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#ifdef VP8_ENTROPY_STATS
4907bc9febe8749e98a3812a0dc4380ceae75c29450Johann        active_section = 6;
49190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
4927bc9febe8749e98a3812a0dc4380ceae75c29450Johann        write_ymode(w, mode, pc->fc.ymode_prob);
49390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4947bc9febe8749e98a3812a0dc4380ceae75c29450Johann        if (mode == B_PRED) {
4957bc9febe8749e98a3812a0dc4380ceae75c29450Johann          int j = 0;
49690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4977bc9febe8749e98a3812a0dc4380ceae75c29450Johann          do {
4987bc9febe8749e98a3812a0dc4380ceae75c29450Johann            write_bmode(w, m->bmi[j].as_mode, pc->fc.bmode_prob);
4997bc9febe8749e98a3812a0dc4380ceae75c29450Johann          } while (++j < 16);
5007bc9febe8749e98a3812a0dc4380ceae75c29450Johann        }
50190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5027bc9febe8749e98a3812a0dc4380ceae75c29450Johann        write_uv_mode(w, mi->uv_mode, pc->fc.uv_mode_prob);
503df37111358d02836cb29bbcb9c6e4c95dff90a16Johann      } else { /* inter coded */
5047bc9febe8749e98a3812a0dc4380ceae75c29450Johann        int_mv best_mv;
5057bc9febe8749e98a3812a0dc4380ceae75c29450Johann        vp8_prob mv_ref_p[VP8_MVREFS - 1];
50690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5077bc9febe8749e98a3812a0dc4380ceae75c29450Johann        vp8_write(w, 1, cpi->prob_intra_coded);
50890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5097bc9febe8749e98a3812a0dc4380ceae75c29450Johann        if (rf == LAST_FRAME)
5107bc9febe8749e98a3812a0dc4380ceae75c29450Johann          vp8_write(w, 0, cpi->prob_last_coded);
5117bc9febe8749e98a3812a0dc4380ceae75c29450Johann        else {
5127bc9febe8749e98a3812a0dc4380ceae75c29450Johann          vp8_write(w, 1, cpi->prob_last_coded);
5137bc9febe8749e98a3812a0dc4380ceae75c29450Johann          vp8_write(w, (rf == GOLDEN_FRAME) ? 0 : 1, cpi->prob_gf_coded);
5147bc9febe8749e98a3812a0dc4380ceae75c29450Johann        }
51590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5167bc9febe8749e98a3812a0dc4380ceae75c29450Johann        {
5177bc9febe8749e98a3812a0dc4380ceae75c29450Johann          int_mv n1, n2;
5187bc9febe8749e98a3812a0dc4380ceae75c29450Johann          int ct[4];
51990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5207bc9febe8749e98a3812a0dc4380ceae75c29450Johann          vp8_find_near_mvs(xd, m, &n1, &n2, &best_mv, ct, rf,
5217bc9febe8749e98a3812a0dc4380ceae75c29450Johann                            cpi->common.ref_frame_sign_bias);
5227bc9febe8749e98a3812a0dc4380ceae75c29450Johann          vp8_clamp_mv2(&best_mv, xd);
5231b362b15af34006e6a11974088a46d42b903418eJohann
5247bc9febe8749e98a3812a0dc4380ceae75c29450Johann          vp8_mv_ref_probs(mv_ref_p, ct);
52590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
526ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#ifdef VP8_ENTROPY_STATS
5277bc9febe8749e98a3812a0dc4380ceae75c29450Johann          accum_mv_refs(mode, ct);
52890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
5297bc9febe8749e98a3812a0dc4380ceae75c29450Johann        }
53090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
531ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#ifdef VP8_ENTROPY_STATS
5327bc9febe8749e98a3812a0dc4380ceae75c29450Johann        active_section = 3;
53390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
53490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5357bc9febe8749e98a3812a0dc4380ceae75c29450Johann        write_mv_ref(w, mode, mv_ref_p);
53690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5377bc9febe8749e98a3812a0dc4380ceae75c29450Johann        switch (mode) /* new, split require MVs */
5387bc9febe8749e98a3812a0dc4380ceae75c29450Johann        {
5397bc9febe8749e98a3812a0dc4380ceae75c29450Johann          case NEWMV:
54090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
541ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#ifdef VP8_ENTROPY_STATS
5427bc9febe8749e98a3812a0dc4380ceae75c29450Johann            active_section = 5;
54390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
54490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5457bc9febe8749e98a3812a0dc4380ceae75c29450Johann            write_mv(w, &mi->mv.as_mv, &best_mv, mvc);
5467bc9febe8749e98a3812a0dc4380ceae75c29450Johann            break;
54790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5487bc9febe8749e98a3812a0dc4380ceae75c29450Johann          case SPLITMV: {
5497bc9febe8749e98a3812a0dc4380ceae75c29450Johann            int j = 0;
55090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
55190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#ifdef MODE_STATS
5527bc9febe8749e98a3812a0dc4380ceae75c29450Johann            ++count_mb_seg[mi->partitioning];
55390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
55490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5557bc9febe8749e98a3812a0dc4380ceae75c29450Johann            write_split(w, mi->partitioning);
5567bc9febe8749e98a3812a0dc4380ceae75c29450Johann
5577bc9febe8749e98a3812a0dc4380ceae75c29450Johann            do {
5587bc9febe8749e98a3812a0dc4380ceae75c29450Johann              B_PREDICTION_MODE blockmode;
5597bc9febe8749e98a3812a0dc4380ceae75c29450Johann              int_mv blockmv;
5607bc9febe8749e98a3812a0dc4380ceae75c29450Johann              const int *const L = vp8_mbsplits[mi->partitioning];
5617bc9febe8749e98a3812a0dc4380ceae75c29450Johann              int k = -1; /* first block in subset j */
5627bc9febe8749e98a3812a0dc4380ceae75c29450Johann              int mv_contz;
5637bc9febe8749e98a3812a0dc4380ceae75c29450Johann              int_mv leftmv, abovemv;
56490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5657bc9febe8749e98a3812a0dc4380ceae75c29450Johann              blockmode = cpi->mb.partition_info->bmi[j].mode;
5667bc9febe8749e98a3812a0dc4380ceae75c29450Johann              blockmv = cpi->mb.partition_info->bmi[j].mv;
5677bc9febe8749e98a3812a0dc4380ceae75c29450Johann              while (j != L[++k]) {
5687bc9febe8749e98a3812a0dc4380ceae75c29450Johann                assert(k < 16);
5697bc9febe8749e98a3812a0dc4380ceae75c29450Johann              }
5707bc9febe8749e98a3812a0dc4380ceae75c29450Johann              leftmv.as_int = left_block_mv(m, k);
5717bc9febe8749e98a3812a0dc4380ceae75c29450Johann              abovemv.as_int = above_block_mv(m, k, mis);
5727bc9febe8749e98a3812a0dc4380ceae75c29450Johann              mv_contz = vp8_mv_cont(&leftmv, &abovemv);
57390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5747bc9febe8749e98a3812a0dc4380ceae75c29450Johann              write_sub_mv_ref(w, blockmode, vp8_sub_mv_ref_prob2[mv_contz]);
5757bc9febe8749e98a3812a0dc4380ceae75c29450Johann
5767bc9febe8749e98a3812a0dc4380ceae75c29450Johann              if (blockmode == NEW4X4) {
577ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#ifdef VP8_ENTROPY_STATS
5787bc9febe8749e98a3812a0dc4380ceae75c29450Johann                active_section = 11;
57990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
5807bc9febe8749e98a3812a0dc4380ceae75c29450Johann                write_mv(w, &blockmv.as_mv, &best_mv, (const MV_CONTEXT *)mvc);
5817bc9febe8749e98a3812a0dc4380ceae75c29450Johann              }
5827bc9febe8749e98a3812a0dc4380ceae75c29450Johann            } while (++j < cpi->mb.partition_info->count);
5837bc9febe8749e98a3812a0dc4380ceae75c29450Johann            break;
5847bc9febe8749e98a3812a0dc4380ceae75c29450Johann          }
5857bc9febe8749e98a3812a0dc4380ceae75c29450Johann          default: break;
58690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
5877bc9febe8749e98a3812a0dc4380ceae75c29450Johann      }
58890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5897bc9febe8749e98a3812a0dc4380ceae75c29450Johann      ++m;
5907bc9febe8749e98a3812a0dc4380ceae75c29450Johann      cpi->mb.partition_info++;
59190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
5927bc9febe8749e98a3812a0dc4380ceae75c29450Johann
5937bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ++m; /* skip L prediction border */
5947bc9febe8749e98a3812a0dc4380ceae75c29450Johann    cpi->mb.partition_info++;
5957bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
59690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
59790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5987bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void write_kfmodes(VP8_COMP *cpi) {
5997bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_writer *const bc = cpi->bc;
6007bc9febe8749e98a3812a0dc4380ceae75c29450Johann  const VP8_COMMON *const c = &cpi->common;
6017bc9febe8749e98a3812a0dc4380ceae75c29450Johann  /* const */
6027bc9febe8749e98a3812a0dc4380ceae75c29450Johann  MODE_INFO *m = c->mi;
60390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6047bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int mb_row = -1;
6057bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int prob_skip_false = 0;
60690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6077bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (c->mb_no_coeff_skip) {
6087bc9febe8749e98a3812a0dc4380ceae75c29450Johann    int total_mbs = c->mb_rows * c->mb_cols;
60990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6107bc9febe8749e98a3812a0dc4380ceae75c29450Johann    prob_skip_false = (total_mbs - cpi->mb.skip_true_count) * 256 / total_mbs;
6111b362b15af34006e6a11974088a46d42b903418eJohann
6127bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (prob_skip_false <= 1) prob_skip_false = 1;
61390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6147bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (prob_skip_false >= 255) prob_skip_false = 255;
61590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6167bc9febe8749e98a3812a0dc4380ceae75c29450Johann    cpi->prob_skip_false = prob_skip_false;
6177bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_write_literal(bc, prob_skip_false, 8);
6187bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
61990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6207bc9febe8749e98a3812a0dc4380ceae75c29450Johann  while (++mb_row < c->mb_rows) {
6217bc9febe8749e98a3812a0dc4380ceae75c29450Johann    int mb_col = -1;
62290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6237bc9febe8749e98a3812a0dc4380ceae75c29450Johann    while (++mb_col < c->mb_cols) {
6247bc9febe8749e98a3812a0dc4380ceae75c29450Johann      const int ym = m->mbmi.mode;
62590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6267bc9febe8749e98a3812a0dc4380ceae75c29450Johann      if (cpi->mb.e_mbd.update_mb_segmentation_map) {
6277bc9febe8749e98a3812a0dc4380ceae75c29450Johann        write_mb_features(bc, &m->mbmi, &cpi->mb.e_mbd);
6287bc9febe8749e98a3812a0dc4380ceae75c29450Johann      }
62990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6307bc9febe8749e98a3812a0dc4380ceae75c29450Johann      if (c->mb_no_coeff_skip) {
6317bc9febe8749e98a3812a0dc4380ceae75c29450Johann        vp8_encode_bool(bc, m->mbmi.mb_skip_coeff, prob_skip_false);
6327bc9febe8749e98a3812a0dc4380ceae75c29450Johann      }
63390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6347bc9febe8749e98a3812a0dc4380ceae75c29450Johann      kfwrite_ymode(bc, ym, vp8_kf_ymode_prob);
63590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6367bc9febe8749e98a3812a0dc4380ceae75c29450Johann      if (ym == B_PRED) {
6377bc9febe8749e98a3812a0dc4380ceae75c29450Johann        const int mis = c->mode_info_stride;
6387bc9febe8749e98a3812a0dc4380ceae75c29450Johann        int i = 0;
63990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6407bc9febe8749e98a3812a0dc4380ceae75c29450Johann        do {
6417bc9febe8749e98a3812a0dc4380ceae75c29450Johann          const B_PREDICTION_MODE A = above_block_mode(m, i, mis);
6427bc9febe8749e98a3812a0dc4380ceae75c29450Johann          const B_PREDICTION_MODE L = left_block_mode(m, i);
6437bc9febe8749e98a3812a0dc4380ceae75c29450Johann          const int bm = m->bmi[i].as_mode;
64490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
645ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#ifdef VP8_ENTROPY_STATS
6467bc9febe8749e98a3812a0dc4380ceae75c29450Johann          ++intra_mode_stats[A][L][bm];
64790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
64890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6497bc9febe8749e98a3812a0dc4380ceae75c29450Johann          write_bmode(bc, bm, vp8_kf_bmode_prob[A][L]);
6507bc9febe8749e98a3812a0dc4380ceae75c29450Johann        } while (++i < 16);
6517bc9febe8749e98a3812a0dc4380ceae75c29450Johann      }
65290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6537bc9febe8749e98a3812a0dc4380ceae75c29450Johann      write_uv_mode(bc, (m++)->mbmi.uv_mode, vp8_kf_uv_mode_prob);
65490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
6557bc9febe8749e98a3812a0dc4380ceae75c29450Johann
6567bc9febe8749e98a3812a0dc4380ceae75c29450Johann    m++; /* skip L prediction border */
6577bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
65890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
6591b362b15af34006e6a11974088a46d42b903418eJohann
6601b362b15af34006e6a11974088a46d42b903418eJohann#if 0
6611b362b15af34006e6a11974088a46d42b903418eJohann/* This function is used for debugging probability trees. */
6621b362b15af34006e6a11974088a46d42b903418eJohannstatic void print_prob_tree(vp8_prob
6631b362b15af34006e6a11974088a46d42b903418eJohann     coef_probs[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES])
66490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
6651b362b15af34006e6a11974088a46d42b903418eJohann    /* print coef probability tree */
6661b362b15af34006e6a11974088a46d42b903418eJohann    int i,j,k,l;
6671b362b15af34006e6a11974088a46d42b903418eJohann    FILE* f = fopen("enc_tree_probs.txt", "a");
6681b362b15af34006e6a11974088a46d42b903418eJohann    fprintf(f, "{\n");
6697bc9febe8749e98a3812a0dc4380ceae75c29450Johann    for (i = 0; i < BLOCK_TYPES; ++i)
6701b362b15af34006e6a11974088a46d42b903418eJohann    {
6711b362b15af34006e6a11974088a46d42b903418eJohann        fprintf(f, "  {\n");
6727bc9febe8749e98a3812a0dc4380ceae75c29450Johann        for (j = 0; j < COEF_BANDS; ++j)
6731b362b15af34006e6a11974088a46d42b903418eJohann        {
6741b362b15af34006e6a11974088a46d42b903418eJohann            fprintf(f, "    {\n");
6757bc9febe8749e98a3812a0dc4380ceae75c29450Johann            for (k = 0; k < PREV_COEF_CONTEXTS; ++k)
6761b362b15af34006e6a11974088a46d42b903418eJohann            {
6771b362b15af34006e6a11974088a46d42b903418eJohann                fprintf(f, "      {");
6787bc9febe8749e98a3812a0dc4380ceae75c29450Johann                for (l = 0; l < ENTROPY_NODES; ++l)
6791b362b15af34006e6a11974088a46d42b903418eJohann                {
6801b362b15af34006e6a11974088a46d42b903418eJohann                    fprintf(f, "%3u, ",
6811b362b15af34006e6a11974088a46d42b903418eJohann                            (unsigned int)(coef_probs [i][j][k][l]));
6821b362b15af34006e6a11974088a46d42b903418eJohann                }
6831b362b15af34006e6a11974088a46d42b903418eJohann                fprintf(f, " }\n");
6841b362b15af34006e6a11974088a46d42b903418eJohann            }
6851b362b15af34006e6a11974088a46d42b903418eJohann            fprintf(f, "    }\n");
6861b362b15af34006e6a11974088a46d42b903418eJohann        }
6871b362b15af34006e6a11974088a46d42b903418eJohann        fprintf(f, "  }\n");
6881b362b15af34006e6a11974088a46d42b903418eJohann    }
6891b362b15af34006e6a11974088a46d42b903418eJohann    fprintf(f, "}\n");
6901b362b15af34006e6a11974088a46d42b903418eJohann    fclose(f);
6911b362b15af34006e6a11974088a46d42b903418eJohann}
6921b362b15af34006e6a11974088a46d42b903418eJohann#endif
69390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6941b362b15af34006e6a11974088a46d42b903418eJohannstatic void sum_probs_over_prev_coef_context(
6957bc9febe8749e98a3812a0dc4380ceae75c29450Johann    const unsigned int probs[PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS],
6967bc9febe8749e98a3812a0dc4380ceae75c29450Johann    unsigned int *out) {
6977bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int i, j;
6987bc9febe8749e98a3812a0dc4380ceae75c29450Johann  for (i = 0; i < MAX_ENTROPY_TOKENS; ++i) {
6997bc9febe8749e98a3812a0dc4380ceae75c29450Johann    for (j = 0; j < PREV_COEF_CONTEXTS; ++j) {
7007bc9febe8749e98a3812a0dc4380ceae75c29450Johann      const unsigned int tmp = out[i];
7017bc9febe8749e98a3812a0dc4380ceae75c29450Johann      out[i] += probs[j][i];
7027bc9febe8749e98a3812a0dc4380ceae75c29450Johann      /* check for wrap */
7037bc9febe8749e98a3812a0dc4380ceae75c29450Johann      if (out[i] < tmp) out[i] = UINT_MAX;
7041b362b15af34006e6a11974088a46d42b903418eJohann    }
7057bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
7061b362b15af34006e6a11974088a46d42b903418eJohann}
70790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
7087bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic int prob_update_savings(const unsigned int *ct, const vp8_prob oldp,
7097bc9febe8749e98a3812a0dc4380ceae75c29450Johann                               const vp8_prob newp, const vp8_prob upd) {
7107bc9febe8749e98a3812a0dc4380ceae75c29450Johann  const int old_b = vp8_cost_branch(ct, oldp);
7117bc9febe8749e98a3812a0dc4380ceae75c29450Johann  const int new_b = vp8_cost_branch(ct, newp);
7127bc9febe8749e98a3812a0dc4380ceae75c29450Johann  const int update_b = 8 + ((vp8_cost_one(upd) - vp8_cost_zero(upd)) >> 8);
71390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
7147bc9febe8749e98a3812a0dc4380ceae75c29450Johann  return old_b - new_b - update_b;
7151b362b15af34006e6a11974088a46d42b903418eJohann}
7161b362b15af34006e6a11974088a46d42b903418eJohann
7177bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic int independent_coef_context_savings(VP8_COMP *cpi) {
7187bc9febe8749e98a3812a0dc4380ceae75c29450Johann  MACROBLOCK *const x = &cpi->mb;
7197bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int savings = 0;
7207bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int i = 0;
7217bc9febe8749e98a3812a0dc4380ceae75c29450Johann  do {
7227bc9febe8749e98a3812a0dc4380ceae75c29450Johann    int j = 0;
7237bc9febe8749e98a3812a0dc4380ceae75c29450Johann    do {
7247bc9febe8749e98a3812a0dc4380ceae75c29450Johann      int k = 0;
7257bc9febe8749e98a3812a0dc4380ceae75c29450Johann      unsigned int prev_coef_count_sum[MAX_ENTROPY_TOKENS] = { 0 };
7267bc9febe8749e98a3812a0dc4380ceae75c29450Johann      int prev_coef_savings[MAX_ENTROPY_TOKENS] = { 0 };
7277bc9febe8749e98a3812a0dc4380ceae75c29450Johann      const unsigned int(*probs)[MAX_ENTROPY_TOKENS];
7287bc9febe8749e98a3812a0dc4380ceae75c29450Johann      /* Calculate new probabilities given the constraint that
7297bc9febe8749e98a3812a0dc4380ceae75c29450Johann       * they must be equal over the prev coef contexts
7307bc9febe8749e98a3812a0dc4380ceae75c29450Johann       */
7317bc9febe8749e98a3812a0dc4380ceae75c29450Johann
7327bc9febe8749e98a3812a0dc4380ceae75c29450Johann      probs = (const unsigned int(*)[MAX_ENTROPY_TOKENS])x->coef_counts[i][j];
7337bc9febe8749e98a3812a0dc4380ceae75c29450Johann
7347bc9febe8749e98a3812a0dc4380ceae75c29450Johann      /* Reset to default probabilities at key frames */
7357bc9febe8749e98a3812a0dc4380ceae75c29450Johann      if (cpi->common.frame_type == KEY_FRAME) {
7367bc9febe8749e98a3812a0dc4380ceae75c29450Johann        probs = default_coef_counts[i][j];
7377bc9febe8749e98a3812a0dc4380ceae75c29450Johann      }
7387bc9febe8749e98a3812a0dc4380ceae75c29450Johann
7397bc9febe8749e98a3812a0dc4380ceae75c29450Johann      sum_probs_over_prev_coef_context(probs, prev_coef_count_sum);
7407bc9febe8749e98a3812a0dc4380ceae75c29450Johann
7417bc9febe8749e98a3812a0dc4380ceae75c29450Johann      do {
7427bc9febe8749e98a3812a0dc4380ceae75c29450Johann        /* at every context */
7437bc9febe8749e98a3812a0dc4380ceae75c29450Johann
7447bc9febe8749e98a3812a0dc4380ceae75c29450Johann        /* calc probs and branch cts for this frame only */
7457bc9febe8749e98a3812a0dc4380ceae75c29450Johann        int t = 0; /* token/prob index */
7467bc9febe8749e98a3812a0dc4380ceae75c29450Johann
7477bc9febe8749e98a3812a0dc4380ceae75c29450Johann        vp8_tree_probs_from_distribution(
7487bc9febe8749e98a3812a0dc4380ceae75c29450Johann            MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
7497bc9febe8749e98a3812a0dc4380ceae75c29450Johann            cpi->frame_coef_probs[i][j][k], cpi->frame_branch_ct[i][j][k],
7507bc9febe8749e98a3812a0dc4380ceae75c29450Johann            prev_coef_count_sum, 256, 1);
7517bc9febe8749e98a3812a0dc4380ceae75c29450Johann
7527bc9febe8749e98a3812a0dc4380ceae75c29450Johann        do {
7537bc9febe8749e98a3812a0dc4380ceae75c29450Johann          const unsigned int *ct = cpi->frame_branch_ct[i][j][k][t];
7547bc9febe8749e98a3812a0dc4380ceae75c29450Johann          const vp8_prob newp = cpi->frame_coef_probs[i][j][k][t];
7557bc9febe8749e98a3812a0dc4380ceae75c29450Johann          const vp8_prob oldp = cpi->common.fc.coef_probs[i][j][k][t];
7567bc9febe8749e98a3812a0dc4380ceae75c29450Johann          const vp8_prob upd = vp8_coef_update_probs[i][j][k][t];
7577bc9febe8749e98a3812a0dc4380ceae75c29450Johann          const int s = prob_update_savings(ct, oldp, newp, upd);
7587bc9febe8749e98a3812a0dc4380ceae75c29450Johann
7597bc9febe8749e98a3812a0dc4380ceae75c29450Johann          if (cpi->common.frame_type != KEY_FRAME ||
7607bc9febe8749e98a3812a0dc4380ceae75c29450Johann              (cpi->common.frame_type == KEY_FRAME && newp != oldp)) {
7617bc9febe8749e98a3812a0dc4380ceae75c29450Johann            prev_coef_savings[t] += s;
7627bc9febe8749e98a3812a0dc4380ceae75c29450Johann          }
7637bc9febe8749e98a3812a0dc4380ceae75c29450Johann        } while (++t < ENTROPY_NODES);
7647bc9febe8749e98a3812a0dc4380ceae75c29450Johann      } while (++k < PREV_COEF_CONTEXTS);
7657bc9febe8749e98a3812a0dc4380ceae75c29450Johann      k = 0;
7667bc9febe8749e98a3812a0dc4380ceae75c29450Johann      do {
7677bc9febe8749e98a3812a0dc4380ceae75c29450Johann        /* We only update probabilities if we can save bits, except
7687bc9febe8749e98a3812a0dc4380ceae75c29450Johann         * for key frames where we have to update all probabilities
7697bc9febe8749e98a3812a0dc4380ceae75c29450Johann         * to get the equal probabilities across the prev coef
7707bc9febe8749e98a3812a0dc4380ceae75c29450Johann         * contexts.
7717bc9febe8749e98a3812a0dc4380ceae75c29450Johann         */
7727bc9febe8749e98a3812a0dc4380ceae75c29450Johann        if (prev_coef_savings[k] > 0 || cpi->common.frame_type == KEY_FRAME) {
7737bc9febe8749e98a3812a0dc4380ceae75c29450Johann          savings += prev_coef_savings[k];
7741b362b15af34006e6a11974088a46d42b903418eJohann        }
7757bc9febe8749e98a3812a0dc4380ceae75c29450Johann      } while (++k < ENTROPY_NODES);
7767bc9febe8749e98a3812a0dc4380ceae75c29450Johann    } while (++j < COEF_BANDS);
7777bc9febe8749e98a3812a0dc4380ceae75c29450Johann  } while (++i < BLOCK_TYPES);
7787bc9febe8749e98a3812a0dc4380ceae75c29450Johann  return savings;
7791b362b15af34006e6a11974088a46d42b903418eJohann}
78090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
7817bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic int default_coef_context_savings(VP8_COMP *cpi) {
7827bc9febe8749e98a3812a0dc4380ceae75c29450Johann  MACROBLOCK *const x = &cpi->mb;
7837bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int savings = 0;
7847bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int i = 0;
7857bc9febe8749e98a3812a0dc4380ceae75c29450Johann  do {
7867bc9febe8749e98a3812a0dc4380ceae75c29450Johann    int j = 0;
7877bc9febe8749e98a3812a0dc4380ceae75c29450Johann    do {
7887bc9febe8749e98a3812a0dc4380ceae75c29450Johann      int k = 0;
7897bc9febe8749e98a3812a0dc4380ceae75c29450Johann      do {
7907bc9febe8749e98a3812a0dc4380ceae75c29450Johann        /* at every context */
7917bc9febe8749e98a3812a0dc4380ceae75c29450Johann
7927bc9febe8749e98a3812a0dc4380ceae75c29450Johann        /* calc probs and branch cts for this frame only */
7937bc9febe8749e98a3812a0dc4380ceae75c29450Johann        int t = 0; /* token/prob index */
7947bc9febe8749e98a3812a0dc4380ceae75c29450Johann
7957bc9febe8749e98a3812a0dc4380ceae75c29450Johann        vp8_tree_probs_from_distribution(
7967bc9febe8749e98a3812a0dc4380ceae75c29450Johann            MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
7977bc9febe8749e98a3812a0dc4380ceae75c29450Johann            cpi->frame_coef_probs[i][j][k], cpi->frame_branch_ct[i][j][k],
7987bc9febe8749e98a3812a0dc4380ceae75c29450Johann            x->coef_counts[i][j][k], 256, 1);
7997bc9febe8749e98a3812a0dc4380ceae75c29450Johann
8007bc9febe8749e98a3812a0dc4380ceae75c29450Johann        do {
8017bc9febe8749e98a3812a0dc4380ceae75c29450Johann          const unsigned int *ct = cpi->frame_branch_ct[i][j][k][t];
8027bc9febe8749e98a3812a0dc4380ceae75c29450Johann          const vp8_prob newp = cpi->frame_coef_probs[i][j][k][t];
8037bc9febe8749e98a3812a0dc4380ceae75c29450Johann          const vp8_prob oldp = cpi->common.fc.coef_probs[i][j][k][t];
8047bc9febe8749e98a3812a0dc4380ceae75c29450Johann          const vp8_prob upd = vp8_coef_update_probs[i][j][k][t];
8057bc9febe8749e98a3812a0dc4380ceae75c29450Johann          const int s = prob_update_savings(ct, oldp, newp, upd);
8067bc9febe8749e98a3812a0dc4380ceae75c29450Johann
8077bc9febe8749e98a3812a0dc4380ceae75c29450Johann          if (s > 0) {
8087bc9febe8749e98a3812a0dc4380ceae75c29450Johann            savings += s;
8097bc9febe8749e98a3812a0dc4380ceae75c29450Johann          }
8107bc9febe8749e98a3812a0dc4380ceae75c29450Johann        } while (++t < ENTROPY_NODES);
8117bc9febe8749e98a3812a0dc4380ceae75c29450Johann      } while (++k < PREV_COEF_CONTEXTS);
8127bc9febe8749e98a3812a0dc4380ceae75c29450Johann    } while (++j < COEF_BANDS);
8137bc9febe8749e98a3812a0dc4380ceae75c29450Johann  } while (++i < BLOCK_TYPES);
8147bc9febe8749e98a3812a0dc4380ceae75c29450Johann  return savings;
8151b362b15af34006e6a11974088a46d42b903418eJohann}
8161b362b15af34006e6a11974088a46d42b903418eJohann
8177bc9febe8749e98a3812a0dc4380ceae75c29450Johannvoid vp8_calc_ref_frame_costs(int *ref_frame_cost, int prob_intra,
8187bc9febe8749e98a3812a0dc4380ceae75c29450Johann                              int prob_last, int prob_garf) {
8197bc9febe8749e98a3812a0dc4380ceae75c29450Johann  assert(prob_intra >= 0);
8207bc9febe8749e98a3812a0dc4380ceae75c29450Johann  assert(prob_intra <= 255);
8217bc9febe8749e98a3812a0dc4380ceae75c29450Johann  assert(prob_last >= 0);
8227bc9febe8749e98a3812a0dc4380ceae75c29450Johann  assert(prob_last <= 255);
8237bc9febe8749e98a3812a0dc4380ceae75c29450Johann  assert(prob_garf >= 0);
8247bc9febe8749e98a3812a0dc4380ceae75c29450Johann  assert(prob_garf <= 255);
8257bc9febe8749e98a3812a0dc4380ceae75c29450Johann  ref_frame_cost[INTRA_FRAME] = vp8_cost_zero(prob_intra);
8267bc9febe8749e98a3812a0dc4380ceae75c29450Johann  ref_frame_cost[LAST_FRAME] =
8277bc9febe8749e98a3812a0dc4380ceae75c29450Johann      vp8_cost_one(prob_intra) + vp8_cost_zero(prob_last);
8287bc9febe8749e98a3812a0dc4380ceae75c29450Johann  ref_frame_cost[GOLDEN_FRAME] = vp8_cost_one(prob_intra) +
8297bc9febe8749e98a3812a0dc4380ceae75c29450Johann                                 vp8_cost_one(prob_last) +
8307bc9febe8749e98a3812a0dc4380ceae75c29450Johann                                 vp8_cost_zero(prob_garf);
8317bc9febe8749e98a3812a0dc4380ceae75c29450Johann  ref_frame_cost[ALTREF_FRAME] = vp8_cost_one(prob_intra) +
8327bc9febe8749e98a3812a0dc4380ceae75c29450Johann                                 vp8_cost_one(prob_last) +
8337bc9febe8749e98a3812a0dc4380ceae75c29450Johann                                 vp8_cost_one(prob_garf);
8341b362b15af34006e6a11974088a46d42b903418eJohann}
8351b362b15af34006e6a11974088a46d42b903418eJohann
8367bc9febe8749e98a3812a0dc4380ceae75c29450Johannint vp8_estimate_entropy_savings(VP8_COMP *cpi) {
8377bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int savings = 0;
8381b362b15af34006e6a11974088a46d42b903418eJohann
8397bc9febe8749e98a3812a0dc4380ceae75c29450Johann  const int *const rfct = cpi->mb.count_mb_ref_frame_usage;
8407bc9febe8749e98a3812a0dc4380ceae75c29450Johann  const int rf_intra = rfct[INTRA_FRAME];
8417bc9febe8749e98a3812a0dc4380ceae75c29450Johann  const int rf_inter =
8427bc9febe8749e98a3812a0dc4380ceae75c29450Johann      rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];
8437bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int new_intra, new_last, new_garf, oldtotal, newtotal;
8447bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int ref_frame_cost[MAX_REF_FRAMES];
8451b362b15af34006e6a11974088a46d42b903418eJohann
8467bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vpx_clear_system_state();
8471b362b15af34006e6a11974088a46d42b903418eJohann
8487bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (cpi->common.frame_type != KEY_FRAME) {
8497bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (!(new_intra = rf_intra * 255 / (rf_intra + rf_inter))) new_intra = 1;
8501b362b15af34006e6a11974088a46d42b903418eJohann
8517bc9febe8749e98a3812a0dc4380ceae75c29450Johann    new_last = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;
8521b362b15af34006e6a11974088a46d42b903418eJohann
8537bc9febe8749e98a3812a0dc4380ceae75c29450Johann    new_garf = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
8547bc9febe8749e98a3812a0dc4380ceae75c29450Johann                   ? (rfct[GOLDEN_FRAME] * 255) /
8557bc9febe8749e98a3812a0dc4380ceae75c29450Johann                         (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
8567bc9febe8749e98a3812a0dc4380ceae75c29450Johann                   : 128;
8571b362b15af34006e6a11974088a46d42b903418eJohann
8587bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_calc_ref_frame_costs(ref_frame_cost, new_intra, new_last, new_garf);
8591b362b15af34006e6a11974088a46d42b903418eJohann
8607bc9febe8749e98a3812a0dc4380ceae75c29450Johann    newtotal = rfct[INTRA_FRAME] * ref_frame_cost[INTRA_FRAME] +
8617bc9febe8749e98a3812a0dc4380ceae75c29450Johann               rfct[LAST_FRAME] * ref_frame_cost[LAST_FRAME] +
8627bc9febe8749e98a3812a0dc4380ceae75c29450Johann               rfct[GOLDEN_FRAME] * ref_frame_cost[GOLDEN_FRAME] +
8637bc9febe8749e98a3812a0dc4380ceae75c29450Johann               rfct[ALTREF_FRAME] * ref_frame_cost[ALTREF_FRAME];
8641b362b15af34006e6a11974088a46d42b903418eJohann
8657bc9febe8749e98a3812a0dc4380ceae75c29450Johann    /* old costs */
8667bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_calc_ref_frame_costs(ref_frame_cost, cpi->prob_intra_coded,
8677bc9febe8749e98a3812a0dc4380ceae75c29450Johann                             cpi->prob_last_coded, cpi->prob_gf_coded);
8681b362b15af34006e6a11974088a46d42b903418eJohann
8697bc9febe8749e98a3812a0dc4380ceae75c29450Johann    oldtotal = rfct[INTRA_FRAME] * ref_frame_cost[INTRA_FRAME] +
8707bc9febe8749e98a3812a0dc4380ceae75c29450Johann               rfct[LAST_FRAME] * ref_frame_cost[LAST_FRAME] +
8717bc9febe8749e98a3812a0dc4380ceae75c29450Johann               rfct[GOLDEN_FRAME] * ref_frame_cost[GOLDEN_FRAME] +
8727bc9febe8749e98a3812a0dc4380ceae75c29450Johann               rfct[ALTREF_FRAME] * ref_frame_cost[ALTREF_FRAME];
8731b362b15af34006e6a11974088a46d42b903418eJohann
8747bc9febe8749e98a3812a0dc4380ceae75c29450Johann    savings += (oldtotal - newtotal) / 256;
8757bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
8761b362b15af34006e6a11974088a46d42b903418eJohann
8777bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS) {
8787bc9febe8749e98a3812a0dc4380ceae75c29450Johann    savings += independent_coef_context_savings(cpi);
8797bc9febe8749e98a3812a0dc4380ceae75c29450Johann  } else {
8807bc9febe8749e98a3812a0dc4380ceae75c29450Johann    savings += default_coef_context_savings(cpi);
8817bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
8821b362b15af34006e6a11974088a46d42b903418eJohann
8837bc9febe8749e98a3812a0dc4380ceae75c29450Johann  return savings;
88490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
88590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
8861b362b15af34006e6a11974088a46d42b903418eJohann#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
8877bc9febe8749e98a3812a0dc4380ceae75c29450Johannint vp8_update_coef_context(VP8_COMP *cpi) {
8887bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int savings = 0;
88990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
8907bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (cpi->common.frame_type == KEY_FRAME) {
8917bc9febe8749e98a3812a0dc4380ceae75c29450Johann    /* Reset to default counts/probabilities at key frames */
8927bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_copy(cpi->mb.coef_counts, default_coef_counts);
8937bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
89490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
8957bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS)
8967bc9febe8749e98a3812a0dc4380ceae75c29450Johann    savings += independent_coef_context_savings(cpi);
8977bc9febe8749e98a3812a0dc4380ceae75c29450Johann  else
8987bc9febe8749e98a3812a0dc4380ceae75c29450Johann    savings += default_coef_context_savings(cpi);
8991b362b15af34006e6a11974088a46d42b903418eJohann
9007bc9febe8749e98a3812a0dc4380ceae75c29450Johann  return savings;
9011b362b15af34006e6a11974088a46d42b903418eJohann}
9021b362b15af34006e6a11974088a46d42b903418eJohann#endif
9031b362b15af34006e6a11974088a46d42b903418eJohann
9047bc9febe8749e98a3812a0dc4380ceae75c29450Johannvoid vp8_update_coef_probs(VP8_COMP *cpi) {
9057bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int i = 0;
9061b362b15af34006e6a11974088a46d42b903418eJohann#if !(CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING)
9077bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_writer *const w = cpi->bc;
9081b362b15af34006e6a11974088a46d42b903418eJohann#endif
9097bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int savings = 0;
9107bc9febe8749e98a3812a0dc4380ceae75c29450Johann
9117bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vpx_clear_system_state();
9127bc9febe8749e98a3812a0dc4380ceae75c29450Johann
9137bc9febe8749e98a3812a0dc4380ceae75c29450Johann  do {
9147bc9febe8749e98a3812a0dc4380ceae75c29450Johann    int j = 0;
9157bc9febe8749e98a3812a0dc4380ceae75c29450Johann
9167bc9febe8749e98a3812a0dc4380ceae75c29450Johann    do {
9177bc9febe8749e98a3812a0dc4380ceae75c29450Johann      int k = 0;
9187bc9febe8749e98a3812a0dc4380ceae75c29450Johann      int prev_coef_savings[ENTROPY_NODES] = { 0 };
9197bc9febe8749e98a3812a0dc4380ceae75c29450Johann      if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS) {
9207bc9febe8749e98a3812a0dc4380ceae75c29450Johann        for (k = 0; k < PREV_COEF_CONTEXTS; ++k) {
9217bc9febe8749e98a3812a0dc4380ceae75c29450Johann          int t; /* token/prob index */
9227bc9febe8749e98a3812a0dc4380ceae75c29450Johann          for (t = 0; t < ENTROPY_NODES; ++t) {
9237bc9febe8749e98a3812a0dc4380ceae75c29450Johann            const unsigned int *ct = cpi->frame_branch_ct[i][j][k][t];
9247bc9febe8749e98a3812a0dc4380ceae75c29450Johann            const vp8_prob newp = cpi->frame_coef_probs[i][j][k][t];
9257bc9febe8749e98a3812a0dc4380ceae75c29450Johann            const vp8_prob oldp = cpi->common.fc.coef_probs[i][j][k][t];
9267bc9febe8749e98a3812a0dc4380ceae75c29450Johann            const vp8_prob upd = vp8_coef_update_probs[i][j][k][t];
9277bc9febe8749e98a3812a0dc4380ceae75c29450Johann
9287bc9febe8749e98a3812a0dc4380ceae75c29450Johann            prev_coef_savings[t] += prob_update_savings(ct, oldp, newp, upd);
9297bc9febe8749e98a3812a0dc4380ceae75c29450Johann          }
9307bc9febe8749e98a3812a0dc4380ceae75c29450Johann        }
9317bc9febe8749e98a3812a0dc4380ceae75c29450Johann        k = 0;
9327bc9febe8749e98a3812a0dc4380ceae75c29450Johann      }
9337bc9febe8749e98a3812a0dc4380ceae75c29450Johann      do {
9347bc9febe8749e98a3812a0dc4380ceae75c29450Johann        /* note: use result from vp8_estimate_entropy_savings, so no
9357bc9febe8749e98a3812a0dc4380ceae75c29450Johann         * need to call vp8_tree_probs_from_distribution here.
9367bc9febe8749e98a3812a0dc4380ceae75c29450Johann         */
9371b362b15af34006e6a11974088a46d42b903418eJohann
9387bc9febe8749e98a3812a0dc4380ceae75c29450Johann        /* at every context */
93990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
9407bc9febe8749e98a3812a0dc4380ceae75c29450Johann        /* calc probs and branch cts for this frame only */
9417bc9febe8749e98a3812a0dc4380ceae75c29450Johann        int t = 0; /* token/prob index */
94290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
9437bc9febe8749e98a3812a0dc4380ceae75c29450Johann        do {
9447bc9febe8749e98a3812a0dc4380ceae75c29450Johann          const vp8_prob newp = cpi->frame_coef_probs[i][j][k][t];
9451b362b15af34006e6a11974088a46d42b903418eJohann
9467bc9febe8749e98a3812a0dc4380ceae75c29450Johann          vp8_prob *Pold = cpi->common.fc.coef_probs[i][j][k] + t;
9477bc9febe8749e98a3812a0dc4380ceae75c29450Johann          const vp8_prob upd = vp8_coef_update_probs[i][j][k][t];
94890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
9497bc9febe8749e98a3812a0dc4380ceae75c29450Johann          int s = prev_coef_savings[t];
9507bc9febe8749e98a3812a0dc4380ceae75c29450Johann          int u = 0;
95190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
9527bc9febe8749e98a3812a0dc4380ceae75c29450Johann          if (!(cpi->oxcf.error_resilient_mode &
9537bc9febe8749e98a3812a0dc4380ceae75c29450Johann                VPX_ERROR_RESILIENT_PARTITIONS)) {
9547bc9febe8749e98a3812a0dc4380ceae75c29450Johann            s = prob_update_savings(cpi->frame_branch_ct[i][j][k][t], *Pold,
9557bc9febe8749e98a3812a0dc4380ceae75c29450Johann                                    newp, upd);
9567bc9febe8749e98a3812a0dc4380ceae75c29450Johann          }
9577bc9febe8749e98a3812a0dc4380ceae75c29450Johann
9587bc9febe8749e98a3812a0dc4380ceae75c29450Johann          if (s > 0) u = 1;
9597bc9febe8749e98a3812a0dc4380ceae75c29450Johann
9607bc9febe8749e98a3812a0dc4380ceae75c29450Johann          /* Force updates on key frames if the new is different,
9617bc9febe8749e98a3812a0dc4380ceae75c29450Johann           * so that we can be sure we end up with equal probabilities
9627bc9febe8749e98a3812a0dc4380ceae75c29450Johann           * over the prev coef contexts.
9637bc9febe8749e98a3812a0dc4380ceae75c29450Johann           */
9647bc9febe8749e98a3812a0dc4380ceae75c29450Johann          if ((cpi->oxcf.error_resilient_mode &
9657bc9febe8749e98a3812a0dc4380ceae75c29450Johann               VPX_ERROR_RESILIENT_PARTITIONS) &&
9667bc9febe8749e98a3812a0dc4380ceae75c29450Johann              cpi->common.frame_type == KEY_FRAME && newp != *Pold) {
9677bc9febe8749e98a3812a0dc4380ceae75c29450Johann            u = 1;
9687bc9febe8749e98a3812a0dc4380ceae75c29450Johann          }
9691b362b15af34006e6a11974088a46d42b903418eJohann
9701b362b15af34006e6a11974088a46d42b903418eJohann#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
9717bc9febe8749e98a3812a0dc4380ceae75c29450Johann          cpi->update_probs[i][j][k][t] = u;
9721b362b15af34006e6a11974088a46d42b903418eJohann#else
9737bc9febe8749e98a3812a0dc4380ceae75c29450Johann          vp8_write(w, u, upd);
9741b362b15af34006e6a11974088a46d42b903418eJohann#endif
97590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
976ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#ifdef VP8_ENTROPY_STATS
9777bc9febe8749e98a3812a0dc4380ceae75c29450Johann          ++tree_update_hist[i][j][k][t][u];
97890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
97990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
9807bc9febe8749e98a3812a0dc4380ceae75c29450Johann          if (u) {
9817bc9febe8749e98a3812a0dc4380ceae75c29450Johann            /* send/use new probability */
98290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
9837bc9febe8749e98a3812a0dc4380ceae75c29450Johann            *Pold = newp;
9841b362b15af34006e6a11974088a46d42b903418eJohann#if !(CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING)
9857bc9febe8749e98a3812a0dc4380ceae75c29450Johann            vp8_write_literal(w, newp, 8);
9861b362b15af34006e6a11974088a46d42b903418eJohann#endif
98790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
9887bc9febe8749e98a3812a0dc4380ceae75c29450Johann            savings += s;
9897bc9febe8749e98a3812a0dc4380ceae75c29450Johann          }
99090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
9917bc9febe8749e98a3812a0dc4380ceae75c29450Johann        } while (++t < ENTROPY_NODES);
99290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
9937bc9febe8749e98a3812a0dc4380ceae75c29450Johann/* Accum token counts for generation of default statistics */
994ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#ifdef VP8_ENTROPY_STATS
9957bc9febe8749e98a3812a0dc4380ceae75c29450Johann        t = 0;
99690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
9977bc9febe8749e98a3812a0dc4380ceae75c29450Johann        do {
9987bc9febe8749e98a3812a0dc4380ceae75c29450Johann          context_counters[i][j][k][t] += cpi->coef_counts[i][j][k][t];
9997bc9febe8749e98a3812a0dc4380ceae75c29450Johann        } while (++t < MAX_ENTROPY_TOKENS);
100090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
100190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
100290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
10037bc9febe8749e98a3812a0dc4380ceae75c29450Johann      } while (++k < PREV_COEF_CONTEXTS);
10047bc9febe8749e98a3812a0dc4380ceae75c29450Johann    } while (++j < COEF_BANDS);
10057bc9febe8749e98a3812a0dc4380ceae75c29450Johann  } while (++i < BLOCK_TYPES);
100690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
10071b362b15af34006e6a11974088a46d42b903418eJohann
10081b362b15af34006e6a11974088a46d42b903418eJohann#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
10097bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void pack_coef_probs(VP8_COMP *cpi) {
10107bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int i = 0;
10117bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_writer *const w = cpi->bc;
10121b362b15af34006e6a11974088a46d42b903418eJohann
10137bc9febe8749e98a3812a0dc4380ceae75c29450Johann  do {
10147bc9febe8749e98a3812a0dc4380ceae75c29450Johann    int j = 0;
10151b362b15af34006e6a11974088a46d42b903418eJohann
10167bc9febe8749e98a3812a0dc4380ceae75c29450Johann    do {
10177bc9febe8749e98a3812a0dc4380ceae75c29450Johann      int k = 0;
10181b362b15af34006e6a11974088a46d42b903418eJohann
10197bc9febe8749e98a3812a0dc4380ceae75c29450Johann      do {
10207bc9febe8749e98a3812a0dc4380ceae75c29450Johann        int t = 0; /* token/prob index */
10211b362b15af34006e6a11974088a46d42b903418eJohann
10227bc9febe8749e98a3812a0dc4380ceae75c29450Johann        do {
10237bc9febe8749e98a3812a0dc4380ceae75c29450Johann          const vp8_prob newp = cpi->common.fc.coef_probs[i][j][k][t];
10247bc9febe8749e98a3812a0dc4380ceae75c29450Johann          const vp8_prob upd = vp8_coef_update_probs[i][j][k][t];
10251b362b15af34006e6a11974088a46d42b903418eJohann
10267bc9febe8749e98a3812a0dc4380ceae75c29450Johann          const char u = cpi->update_probs[i][j][k][t];
10271b362b15af34006e6a11974088a46d42b903418eJohann
10287bc9febe8749e98a3812a0dc4380ceae75c29450Johann          vp8_write(w, u, upd);
10291b362b15af34006e6a11974088a46d42b903418eJohann
10307bc9febe8749e98a3812a0dc4380ceae75c29450Johann          if (u) {
10317bc9febe8749e98a3812a0dc4380ceae75c29450Johann            /* send/use new probability */
10327bc9febe8749e98a3812a0dc4380ceae75c29450Johann            vp8_write_literal(w, newp, 8);
10337bc9febe8749e98a3812a0dc4380ceae75c29450Johann          }
10347bc9febe8749e98a3812a0dc4380ceae75c29450Johann        } while (++t < ENTROPY_NODES);
10357bc9febe8749e98a3812a0dc4380ceae75c29450Johann      } while (++k < PREV_COEF_CONTEXTS);
10367bc9febe8749e98a3812a0dc4380ceae75c29450Johann    } while (++j < COEF_BANDS);
10377bc9febe8749e98a3812a0dc4380ceae75c29450Johann  } while (++i < BLOCK_TYPES);
10381b362b15af34006e6a11974088a46d42b903418eJohann}
10391b362b15af34006e6a11974088a46d42b903418eJohann#endif
10401b362b15af34006e6a11974088a46d42b903418eJohann
104190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#ifdef PACKET_TESTING
104290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas HuberFILE *vpxlogc = 0;
104390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
104490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
10457bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void put_delta_q(vp8_writer *bc, int delta_q) {
10467bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (delta_q != 0) {
10477bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_write_bit(bc, 1);
10487bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_write_literal(bc, abs(delta_q), 4);
104990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
10507bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (delta_q < 0)
10517bc9febe8749e98a3812a0dc4380ceae75c29450Johann      vp8_write_bit(bc, 1);
105290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    else
10537bc9febe8749e98a3812a0dc4380ceae75c29450Johann      vp8_write_bit(bc, 0);
10547bc9febe8749e98a3812a0dc4380ceae75c29450Johann  } else
10557bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_write_bit(bc, 0);
105690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
105790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
10587bc9febe8749e98a3812a0dc4380ceae75c29450Johannvoid vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest,
10597bc9febe8749e98a3812a0dc4380ceae75c29450Johann                        unsigned char *dest_end, size_t *size) {
10607bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int i, j;
10617bc9febe8749e98a3812a0dc4380ceae75c29450Johann  VP8_HEADER oh;
10627bc9febe8749e98a3812a0dc4380ceae75c29450Johann  VP8_COMMON *const pc = &cpi->common;
10637bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_writer *const bc = cpi->bc;
10647bc9febe8749e98a3812a0dc4380ceae75c29450Johann  MACROBLOCKD *const xd = &cpi->mb.e_mbd;
10657bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int extra_bytes_packed = 0;
106690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
10677bc9febe8749e98a3812a0dc4380ceae75c29450Johann  unsigned char *cx_data = dest;
10687bc9febe8749e98a3812a0dc4380ceae75c29450Johann  unsigned char *cx_data_end = dest_end;
10697bc9febe8749e98a3812a0dc4380ceae75c29450Johann  const int *mb_feature_data_bits;
107090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
10717bc9febe8749e98a3812a0dc4380ceae75c29450Johann  oh.show_frame = (int)pc->show_frame;
10727bc9febe8749e98a3812a0dc4380ceae75c29450Johann  oh.type = (int)pc->frame_type;
10737bc9febe8749e98a3812a0dc4380ceae75c29450Johann  oh.version = pc->version;
10747bc9febe8749e98a3812a0dc4380ceae75c29450Johann  oh.first_partition_length_in_bytes = 0;
107590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
10767bc9febe8749e98a3812a0dc4380ceae75c29450Johann  mb_feature_data_bits = vp8_mb_feature_data_bits;
10771b362b15af34006e6a11974088a46d42b903418eJohann
10787bc9febe8749e98a3812a0dc4380ceae75c29450Johann  bc[0].error = &pc->error;
10791b362b15af34006e6a11974088a46d42b903418eJohann
10807bc9febe8749e98a3812a0dc4380ceae75c29450Johann  validate_buffer(cx_data, 3, cx_data_end, &cpi->common.error);
10817bc9febe8749e98a3812a0dc4380ceae75c29450Johann  cx_data += 3;
108290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
108390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if defined(SECTIONBITS_OUTPUT)
10847bc9febe8749e98a3812a0dc4380ceae75c29450Johann  Sectionbits[active_section = 1] += sizeof(VP8_HEADER) * 8 * 256;
108590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
108690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
10877bc9febe8749e98a3812a0dc4380ceae75c29450Johann  /* every keyframe send startcode, width, height, scale factor, clamp
10887bc9febe8749e98a3812a0dc4380ceae75c29450Johann   * and color type
10897bc9febe8749e98a3812a0dc4380ceae75c29450Johann   */
10907bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (oh.type == KEY_FRAME) {
10917bc9febe8749e98a3812a0dc4380ceae75c29450Johann    int v;
10921b362b15af34006e6a11974088a46d42b903418eJohann
10937bc9febe8749e98a3812a0dc4380ceae75c29450Johann    validate_buffer(cx_data, 7, cx_data_end, &cpi->common.error);
109490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
10957bc9febe8749e98a3812a0dc4380ceae75c29450Johann    /* Start / synch code */
10967bc9febe8749e98a3812a0dc4380ceae75c29450Johann    cx_data[0] = 0x9D;
10977bc9febe8749e98a3812a0dc4380ceae75c29450Johann    cx_data[1] = 0x01;
10987bc9febe8749e98a3812a0dc4380ceae75c29450Johann    cx_data[2] = 0x2a;
109979f15823c34ae1e423108295e416213200bb280fAndreas Huber
11007bc9febe8749e98a3812a0dc4380ceae75c29450Johann    v = (pc->horiz_scale << 14) | pc->Width;
11017bc9febe8749e98a3812a0dc4380ceae75c29450Johann    cx_data[3] = v;
11027bc9febe8749e98a3812a0dc4380ceae75c29450Johann    cx_data[4] = v >> 8;
110390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
11047bc9febe8749e98a3812a0dc4380ceae75c29450Johann    v = (pc->vert_scale << 14) | pc->Height;
11057bc9febe8749e98a3812a0dc4380ceae75c29450Johann    cx_data[5] = v;
11067bc9febe8749e98a3812a0dc4380ceae75c29450Johann    cx_data[6] = v >> 8;
11071b362b15af34006e6a11974088a46d42b903418eJohann
11087bc9febe8749e98a3812a0dc4380ceae75c29450Johann    extra_bytes_packed = 7;
11097bc9febe8749e98a3812a0dc4380ceae75c29450Johann    cx_data += extra_bytes_packed;
111090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
11117bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_start_encode(bc, cx_data, cx_data_end);
111290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
11137bc9febe8749e98a3812a0dc4380ceae75c29450Johann    /* signal clr type */
11147bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_write_bit(bc, 0);
11157bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_write_bit(bc, pc->clamp_type);
111690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
11177bc9febe8749e98a3812a0dc4380ceae75c29450Johann  } else {
11187bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_start_encode(bc, cx_data, cx_data_end);
11197bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
112090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
11217bc9febe8749e98a3812a0dc4380ceae75c29450Johann  /* Signal whether or not Segmentation is enabled */
11227bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_write_bit(bc, xd->segmentation_enabled);
112390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
11247bc9febe8749e98a3812a0dc4380ceae75c29450Johann  /*  Indicate which features are enabled */
11257bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (xd->segmentation_enabled) {
11267bc9febe8749e98a3812a0dc4380ceae75c29450Johann    /* Signal whether or not the segmentation map is being updated. */
11277bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_write_bit(bc, xd->update_mb_segmentation_map);
11287bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_write_bit(bc, xd->update_mb_segmentation_data);
112990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
11307bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (xd->update_mb_segmentation_data) {
11317bc9febe8749e98a3812a0dc4380ceae75c29450Johann      signed char Data;
113290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
11337bc9febe8749e98a3812a0dc4380ceae75c29450Johann      vp8_write_bit(bc, xd->mb_segement_abs_delta);
113490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
11357bc9febe8749e98a3812a0dc4380ceae75c29450Johann      /* For each segmentation feature (Quant and loop filter level) */
11367bc9febe8749e98a3812a0dc4380ceae75c29450Johann      for (i = 0; i < MB_LVL_MAX; ++i) {
11377bc9febe8749e98a3812a0dc4380ceae75c29450Johann        /* For each of the segments */
11387bc9febe8749e98a3812a0dc4380ceae75c29450Johann        for (j = 0; j < MAX_MB_SEGMENTS; ++j) {
11397bc9febe8749e98a3812a0dc4380ceae75c29450Johann          Data = xd->segment_feature_data[i][j];
114090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
11417bc9febe8749e98a3812a0dc4380ceae75c29450Johann          /* Frame level data */
11427bc9febe8749e98a3812a0dc4380ceae75c29450Johann          if (Data) {
11437bc9febe8749e98a3812a0dc4380ceae75c29450Johann            vp8_write_bit(bc, 1);
114490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
11457bc9febe8749e98a3812a0dc4380ceae75c29450Johann            if (Data < 0) {
11467bc9febe8749e98a3812a0dc4380ceae75c29450Johann              Data = -Data;
11477bc9febe8749e98a3812a0dc4380ceae75c29450Johann              vp8_write_literal(bc, Data, mb_feature_data_bits[i]);
11487bc9febe8749e98a3812a0dc4380ceae75c29450Johann              vp8_write_bit(bc, 1);
11497bc9febe8749e98a3812a0dc4380ceae75c29450Johann            } else {
11507bc9febe8749e98a3812a0dc4380ceae75c29450Johann              vp8_write_literal(bc, Data, mb_feature_data_bits[i]);
11517bc9febe8749e98a3812a0dc4380ceae75c29450Johann              vp8_write_bit(bc, 0);
115290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
11537bc9febe8749e98a3812a0dc4380ceae75c29450Johann          } else
11547bc9febe8749e98a3812a0dc4380ceae75c29450Johann            vp8_write_bit(bc, 0);
115590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
11567bc9febe8749e98a3812a0dc4380ceae75c29450Johann      }
115790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
115890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
11597bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (xd->update_mb_segmentation_map) {
11607bc9febe8749e98a3812a0dc4380ceae75c29450Johann      /* Write the probs used to decode the segment id for each mb */
11617bc9febe8749e98a3812a0dc4380ceae75c29450Johann      for (i = 0; i < MB_FEATURE_TREE_PROBS; ++i) {
11627bc9febe8749e98a3812a0dc4380ceae75c29450Johann        int Data = xd->mb_segment_tree_probs[i];
11637bc9febe8749e98a3812a0dc4380ceae75c29450Johann
11647bc9febe8749e98a3812a0dc4380ceae75c29450Johann        if (Data != 255) {
11657bc9febe8749e98a3812a0dc4380ceae75c29450Johann          vp8_write_bit(bc, 1);
11667bc9febe8749e98a3812a0dc4380ceae75c29450Johann          vp8_write_literal(bc, Data, 8);
11677bc9febe8749e98a3812a0dc4380ceae75c29450Johann        } else
11687bc9febe8749e98a3812a0dc4380ceae75c29450Johann          vp8_write_bit(bc, 0);
11697bc9febe8749e98a3812a0dc4380ceae75c29450Johann      }
117090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
11717bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
11727bc9febe8749e98a3812a0dc4380ceae75c29450Johann
11737bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_write_bit(bc, pc->filter_type);
11747bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_write_literal(bc, pc->filter_level, 6);
11757bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_write_literal(bc, pc->sharpness_level, 3);
11767bc9febe8749e98a3812a0dc4380ceae75c29450Johann
11777bc9febe8749e98a3812a0dc4380ceae75c29450Johann  /* Write out loop filter deltas applied at the MB level based on mode
11787bc9febe8749e98a3812a0dc4380ceae75c29450Johann   * or ref frame (if they are enabled).
11797bc9febe8749e98a3812a0dc4380ceae75c29450Johann   */
11807bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_write_bit(bc, xd->mode_ref_lf_delta_enabled);
11817bc9febe8749e98a3812a0dc4380ceae75c29450Johann
11827bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (xd->mode_ref_lf_delta_enabled) {
11837bc9febe8749e98a3812a0dc4380ceae75c29450Johann    /* Do the deltas need to be updated */
11847bc9febe8749e98a3812a0dc4380ceae75c29450Johann    int send_update =
11857bc9febe8749e98a3812a0dc4380ceae75c29450Johann        xd->mode_ref_lf_delta_update || cpi->oxcf.error_resilient_mode;
11867bc9febe8749e98a3812a0dc4380ceae75c29450Johann
11877bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_write_bit(bc, send_update);
11887bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (send_update) {
11897bc9febe8749e98a3812a0dc4380ceae75c29450Johann      int Data;
11907bc9febe8749e98a3812a0dc4380ceae75c29450Johann
11917bc9febe8749e98a3812a0dc4380ceae75c29450Johann      /* Send update */
11927bc9febe8749e98a3812a0dc4380ceae75c29450Johann      for (i = 0; i < MAX_REF_LF_DELTAS; ++i) {
11937bc9febe8749e98a3812a0dc4380ceae75c29450Johann        Data = xd->ref_lf_deltas[i];
11947bc9febe8749e98a3812a0dc4380ceae75c29450Johann
11957bc9febe8749e98a3812a0dc4380ceae75c29450Johann        /* Frame level data */
11967bc9febe8749e98a3812a0dc4380ceae75c29450Johann        if (xd->ref_lf_deltas[i] != xd->last_ref_lf_deltas[i] ||
11977bc9febe8749e98a3812a0dc4380ceae75c29450Johann            cpi->oxcf.error_resilient_mode) {
11987bc9febe8749e98a3812a0dc4380ceae75c29450Johann          xd->last_ref_lf_deltas[i] = xd->ref_lf_deltas[i];
11997bc9febe8749e98a3812a0dc4380ceae75c29450Johann          vp8_write_bit(bc, 1);
12007bc9febe8749e98a3812a0dc4380ceae75c29450Johann
12017bc9febe8749e98a3812a0dc4380ceae75c29450Johann          if (Data > 0) {
12027bc9febe8749e98a3812a0dc4380ceae75c29450Johann            vp8_write_literal(bc, (Data & 0x3F), 6);
12037bc9febe8749e98a3812a0dc4380ceae75c29450Johann            vp8_write_bit(bc, 0); /* sign */
12047bc9febe8749e98a3812a0dc4380ceae75c29450Johann          } else {
12057bc9febe8749e98a3812a0dc4380ceae75c29450Johann            Data = -Data;
12067bc9febe8749e98a3812a0dc4380ceae75c29450Johann            vp8_write_literal(bc, (Data & 0x3F), 6);
12077bc9febe8749e98a3812a0dc4380ceae75c29450Johann            vp8_write_bit(bc, 1); /* sign */
12087bc9febe8749e98a3812a0dc4380ceae75c29450Johann          }
12097bc9febe8749e98a3812a0dc4380ceae75c29450Johann        } else
12107bc9febe8749e98a3812a0dc4380ceae75c29450Johann          vp8_write_bit(bc, 0);
12117bc9febe8749e98a3812a0dc4380ceae75c29450Johann      }
12127bc9febe8749e98a3812a0dc4380ceae75c29450Johann
12137bc9febe8749e98a3812a0dc4380ceae75c29450Johann      /* Send update */
12147bc9febe8749e98a3812a0dc4380ceae75c29450Johann      for (i = 0; i < MAX_MODE_LF_DELTAS; ++i) {
12157bc9febe8749e98a3812a0dc4380ceae75c29450Johann        Data = xd->mode_lf_deltas[i];
12167bc9febe8749e98a3812a0dc4380ceae75c29450Johann
12177bc9febe8749e98a3812a0dc4380ceae75c29450Johann        if (xd->mode_lf_deltas[i] != xd->last_mode_lf_deltas[i] ||
12187bc9febe8749e98a3812a0dc4380ceae75c29450Johann            cpi->oxcf.error_resilient_mode) {
12197bc9febe8749e98a3812a0dc4380ceae75c29450Johann          xd->last_mode_lf_deltas[i] = xd->mode_lf_deltas[i];
12207bc9febe8749e98a3812a0dc4380ceae75c29450Johann          vp8_write_bit(bc, 1);
12217bc9febe8749e98a3812a0dc4380ceae75c29450Johann
12227bc9febe8749e98a3812a0dc4380ceae75c29450Johann          if (Data > 0) {
12237bc9febe8749e98a3812a0dc4380ceae75c29450Johann            vp8_write_literal(bc, (Data & 0x3F), 6);
12247bc9febe8749e98a3812a0dc4380ceae75c29450Johann            vp8_write_bit(bc, 0); /* sign */
12257bc9febe8749e98a3812a0dc4380ceae75c29450Johann          } else {
12267bc9febe8749e98a3812a0dc4380ceae75c29450Johann            Data = -Data;
12277bc9febe8749e98a3812a0dc4380ceae75c29450Johann            vp8_write_literal(bc, (Data & 0x3F), 6);
12287bc9febe8749e98a3812a0dc4380ceae75c29450Johann            vp8_write_bit(bc, 1); /* sign */
12297bc9febe8749e98a3812a0dc4380ceae75c29450Johann          }
12307bc9febe8749e98a3812a0dc4380ceae75c29450Johann        } else
12317bc9febe8749e98a3812a0dc4380ceae75c29450Johann          vp8_write_bit(bc, 0);
12327bc9febe8749e98a3812a0dc4380ceae75c29450Johann      }
12337bc9febe8749e98a3812a0dc4380ceae75c29450Johann    }
12347bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
12357bc9febe8749e98a3812a0dc4380ceae75c29450Johann
12367bc9febe8749e98a3812a0dc4380ceae75c29450Johann  /* signal here is multi token partition is enabled */
12377bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_write_literal(bc, pc->multi_token_partition, 2);
12387bc9febe8749e98a3812a0dc4380ceae75c29450Johann
12397bc9febe8749e98a3812a0dc4380ceae75c29450Johann  /* Frame Qbaseline quantizer index */
12407bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_write_literal(bc, pc->base_qindex, 7);
12417bc9febe8749e98a3812a0dc4380ceae75c29450Johann
12427bc9febe8749e98a3812a0dc4380ceae75c29450Johann  /* Transmit Dc, Second order and Uv quantizer delta information */
12437bc9febe8749e98a3812a0dc4380ceae75c29450Johann  put_delta_q(bc, pc->y1dc_delta_q);
12447bc9febe8749e98a3812a0dc4380ceae75c29450Johann  put_delta_q(bc, pc->y2dc_delta_q);
12457bc9febe8749e98a3812a0dc4380ceae75c29450Johann  put_delta_q(bc, pc->y2ac_delta_q);
12467bc9febe8749e98a3812a0dc4380ceae75c29450Johann  put_delta_q(bc, pc->uvdc_delta_q);
12477bc9febe8749e98a3812a0dc4380ceae75c29450Johann  put_delta_q(bc, pc->uvac_delta_q);
12487bc9febe8749e98a3812a0dc4380ceae75c29450Johann
12497bc9febe8749e98a3812a0dc4380ceae75c29450Johann  /* When there is a key frame all reference buffers are updated using
12507bc9febe8749e98a3812a0dc4380ceae75c29450Johann   * the new key frame
12517bc9febe8749e98a3812a0dc4380ceae75c29450Johann   */
12527bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (pc->frame_type != KEY_FRAME) {
12537bc9febe8749e98a3812a0dc4380ceae75c29450Johann    /* Should the GF or ARF be updated using the transmitted frame
12547bc9febe8749e98a3812a0dc4380ceae75c29450Johann     * or buffer
12551b362b15af34006e6a11974088a46d42b903418eJohann     */
12567bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_write_bit(bc, pc->refresh_golden_frame);
12577bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_write_bit(bc, pc->refresh_alt_ref_frame);
125890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
12597bc9febe8749e98a3812a0dc4380ceae75c29450Johann    /* If not being updated from current frame should either GF or ARF
12607bc9febe8749e98a3812a0dc4380ceae75c29450Johann     * be updated from another buffer
12617bc9febe8749e98a3812a0dc4380ceae75c29450Johann     */
12627bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (!pc->refresh_golden_frame)
12637bc9febe8749e98a3812a0dc4380ceae75c29450Johann      vp8_write_literal(bc, pc->copy_buffer_to_gf, 2);
126490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
12657bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (!pc->refresh_alt_ref_frame)
12667bc9febe8749e98a3812a0dc4380ceae75c29450Johann      vp8_write_literal(bc, pc->copy_buffer_to_arf, 2);
126790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
12687bc9febe8749e98a3812a0dc4380ceae75c29450Johann    /* Indicate reference frame sign bias for Golden and ARF frames
12697bc9febe8749e98a3812a0dc4380ceae75c29450Johann     * (always 0 for last frame buffer)
12707bc9febe8749e98a3812a0dc4380ceae75c29450Johann     */
12717bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_write_bit(bc, pc->ref_frame_sign_bias[GOLDEN_FRAME]);
12727bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_write_bit(bc, pc->ref_frame_sign_bias[ALTREF_FRAME]);
12737bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
127490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
12751b362b15af34006e6a11974088a46d42b903418eJohann#if !(CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING)
12767bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS) {
12777bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (pc->frame_type == KEY_FRAME) {
12787bc9febe8749e98a3812a0dc4380ceae75c29450Johann      pc->refresh_entropy_probs = 1;
12797bc9febe8749e98a3812a0dc4380ceae75c29450Johann    } else {
12807bc9febe8749e98a3812a0dc4380ceae75c29450Johann      pc->refresh_entropy_probs = 0;
12811b362b15af34006e6a11974088a46d42b903418eJohann    }
12827bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
12831b362b15af34006e6a11974088a46d42b903418eJohann#endif
12841b362b15af34006e6a11974088a46d42b903418eJohann
12857bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_write_bit(bc, pc->refresh_entropy_probs);
128690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
12877bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (pc->frame_type != KEY_FRAME) vp8_write_bit(bc, pc->refresh_last_frame);
128890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1289ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#ifdef VP8_ENTROPY_STATS
129090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
12917bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (pc->frame_type == INTER_FRAME)
12927bc9febe8749e98a3812a0dc4380ceae75c29450Johann    active_section = 0;
12937bc9febe8749e98a3812a0dc4380ceae75c29450Johann  else
12947bc9febe8749e98a3812a0dc4380ceae75c29450Johann    active_section = 7;
129590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
129690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
129790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
12987bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vpx_clear_system_state();
129990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
13001b362b15af34006e6a11974088a46d42b903418eJohann#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
13017bc9febe8749e98a3812a0dc4380ceae75c29450Johann  pack_coef_probs(cpi);
13021b362b15af34006e6a11974088a46d42b903418eJohann#else
13037bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (pc->refresh_entropy_probs == 0) {
13047bc9febe8749e98a3812a0dc4380ceae75c29450Johann    /* save a copy for later refresh */
13057bc9febe8749e98a3812a0dc4380ceae75c29450Johann    memcpy(&cpi->common.lfc, &cpi->common.fc, sizeof(cpi->common.fc));
13067bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
130790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
13087bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_update_coef_probs(cpi);
13091b362b15af34006e6a11974088a46d42b903418eJohann#endif
131090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1311ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#ifdef VP8_ENTROPY_STATS
13127bc9febe8749e98a3812a0dc4380ceae75c29450Johann  active_section = 2;
131390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
131490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
13157bc9febe8749e98a3812a0dc4380ceae75c29450Johann  /* Write out the mb_no_coeff_skip flag */
13167bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_write_bit(bc, pc->mb_no_coeff_skip);
131790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
13187bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (pc->frame_type == KEY_FRAME) {
13197bc9febe8749e98a3812a0dc4380ceae75c29450Johann    write_kfmodes(cpi);
132090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1321ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#ifdef VP8_ENTROPY_STATS
13227bc9febe8749e98a3812a0dc4380ceae75c29450Johann    active_section = 8;
132390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
13247bc9febe8749e98a3812a0dc4380ceae75c29450Johann  } else {
13257bc9febe8749e98a3812a0dc4380ceae75c29450Johann    pack_inter_mode_mvs(cpi);
132690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1327ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#ifdef VP8_ENTROPY_STATS
13287bc9febe8749e98a3812a0dc4380ceae75c29450Johann    active_section = 1;
132990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
13307bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
133190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
13327bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_stop_encode(bc);
133390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
13347bc9febe8749e98a3812a0dc4380ceae75c29450Johann  cx_data += bc->pos;
13351b362b15af34006e6a11974088a46d42b903418eJohann
13367bc9febe8749e98a3812a0dc4380ceae75c29450Johann  oh.first_partition_length_in_bytes = cpi->bc->pos;
133779f15823c34ae1e423108295e416213200bb280fAndreas Huber
13387bc9febe8749e98a3812a0dc4380ceae75c29450Johann  /* update frame tag */
13397bc9febe8749e98a3812a0dc4380ceae75c29450Johann  {
13407bc9febe8749e98a3812a0dc4380ceae75c29450Johann    int v = (oh.first_partition_length_in_bytes << 5) | (oh.show_frame << 4) |
13417bc9febe8749e98a3812a0dc4380ceae75c29450Johann            (oh.version << 1) | oh.type;
13427bc9febe8749e98a3812a0dc4380ceae75c29450Johann
13437bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dest[0] = v;
13447bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dest[1] = v >> 8;
13457bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dest[2] = v >> 16;
13467bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
134779f15823c34ae1e423108295e416213200bb280fAndreas Huber
13487bc9febe8749e98a3812a0dc4380ceae75c29450Johann  *size = VP8_HEADER_SIZE + extra_bytes_packed + cpi->bc->pos;
13491b362b15af34006e6a11974088a46d42b903418eJohann
13507bc9febe8749e98a3812a0dc4380ceae75c29450Johann  cpi->partition_sz[0] = (unsigned int)*size;
135190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
13521b362b15af34006e6a11974088a46d42b903418eJohann#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
13537bc9febe8749e98a3812a0dc4380ceae75c29450Johann  {
13547bc9febe8749e98a3812a0dc4380ceae75c29450Johann    const int num_part = (1 << pc->multi_token_partition);
13557bc9febe8749e98a3812a0dc4380ceae75c29450Johann    unsigned char *dp = cpi->partition_d[0] + cpi->partition_sz[0];
13561b362b15af34006e6a11974088a46d42b903418eJohann
13577bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (num_part > 1) {
13587bc9febe8749e98a3812a0dc4380ceae75c29450Johann      /* write token part sizes (all but last) if more than 1 */
13597bc9febe8749e98a3812a0dc4380ceae75c29450Johann      validate_buffer(dp, 3 * (num_part - 1), cpi->partition_d_end[0],
13607bc9febe8749e98a3812a0dc4380ceae75c29450Johann                      &pc->error);
13611b362b15af34006e6a11974088a46d42b903418eJohann
13627bc9febe8749e98a3812a0dc4380ceae75c29450Johann      cpi->partition_sz[0] += 3 * (num_part - 1);
13631b362b15af34006e6a11974088a46d42b903418eJohann
13647bc9febe8749e98a3812a0dc4380ceae75c29450Johann      for (i = 1; i < num_part; ++i) {
13657bc9febe8749e98a3812a0dc4380ceae75c29450Johann        write_partition_size(dp, cpi->partition_sz[i]);
13667bc9febe8749e98a3812a0dc4380ceae75c29450Johann        dp += 3;
13677bc9febe8749e98a3812a0dc4380ceae75c29450Johann      }
13687bc9febe8749e98a3812a0dc4380ceae75c29450Johann    }
13691b362b15af34006e6a11974088a46d42b903418eJohann
13707bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (!cpi->output_partition) {
13717bc9febe8749e98a3812a0dc4380ceae75c29450Johann      /* concatenate partition buffers */
13727bc9febe8749e98a3812a0dc4380ceae75c29450Johann      for (i = 0; i < num_part; ++i) {
13737bc9febe8749e98a3812a0dc4380ceae75c29450Johann        memmove(dp, cpi->partition_d[i + 1], cpi->partition_sz[i + 1]);
13747bc9febe8749e98a3812a0dc4380ceae75c29450Johann        cpi->partition_d[i + 1] = dp;
13757bc9febe8749e98a3812a0dc4380ceae75c29450Johann        dp += cpi->partition_sz[i + 1];
13767bc9febe8749e98a3812a0dc4380ceae75c29450Johann      }
13777bc9febe8749e98a3812a0dc4380ceae75c29450Johann    }
13781b362b15af34006e6a11974088a46d42b903418eJohann
13797bc9febe8749e98a3812a0dc4380ceae75c29450Johann    /* update total size */
13807bc9febe8749e98a3812a0dc4380ceae75c29450Johann    *size = 0;
13817bc9febe8749e98a3812a0dc4380ceae75c29450Johann    for (i = 0; i < num_part + 1; ++i) {
13827bc9febe8749e98a3812a0dc4380ceae75c29450Johann      *size += cpi->partition_sz[i];
13831b362b15af34006e6a11974088a46d42b903418eJohann    }
13847bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
13851b362b15af34006e6a11974088a46d42b903418eJohann#else
13867bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (pc->multi_token_partition != ONE_PARTITION) {
13877bc9febe8749e98a3812a0dc4380ceae75c29450Johann    int num_part = 1 << pc->multi_token_partition;
13881b362b15af34006e6a11974088a46d42b903418eJohann
13897bc9febe8749e98a3812a0dc4380ceae75c29450Johann    /* partition size table at the end of first partition */
13907bc9febe8749e98a3812a0dc4380ceae75c29450Johann    cpi->partition_sz[0] += 3 * (num_part - 1);
13917bc9febe8749e98a3812a0dc4380ceae75c29450Johann    *size += 3 * (num_part - 1);
13921b362b15af34006e6a11974088a46d42b903418eJohann
13937bc9febe8749e98a3812a0dc4380ceae75c29450Johann    validate_buffer(cx_data, 3 * (num_part - 1), cx_data_end, &pc->error);
13941b362b15af34006e6a11974088a46d42b903418eJohann
13957bc9febe8749e98a3812a0dc4380ceae75c29450Johann    for (i = 1; i < num_part + 1; ++i) {
13967bc9febe8749e98a3812a0dc4380ceae75c29450Johann      cpi->bc[i].error = &pc->error;
13977bc9febe8749e98a3812a0dc4380ceae75c29450Johann    }
139890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
13997bc9febe8749e98a3812a0dc4380ceae75c29450Johann    pack_tokens_into_partitions(cpi, cx_data + 3 * (num_part - 1), cx_data_end,
14007bc9febe8749e98a3812a0dc4380ceae75c29450Johann                                num_part);
140190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
14027bc9febe8749e98a3812a0dc4380ceae75c29450Johann    for (i = 1; i < num_part; ++i) {
14037bc9febe8749e98a3812a0dc4380ceae75c29450Johann      cpi->partition_sz[i] = cpi->bc[i].pos;
14047bc9febe8749e98a3812a0dc4380ceae75c29450Johann      write_partition_size(cx_data, cpi->partition_sz[i]);
14057bc9febe8749e98a3812a0dc4380ceae75c29450Johann      cx_data += 3;
14067bc9febe8749e98a3812a0dc4380ceae75c29450Johann      *size += cpi->partition_sz[i]; /* add to total */
140790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
14081b362b15af34006e6a11974088a46d42b903418eJohann
14097bc9febe8749e98a3812a0dc4380ceae75c29450Johann    /* add last partition to total size */
14107bc9febe8749e98a3812a0dc4380ceae75c29450Johann    cpi->partition_sz[i] = cpi->bc[i].pos;
14117bc9febe8749e98a3812a0dc4380ceae75c29450Johann    *size += cpi->partition_sz[i];
14127bc9febe8749e98a3812a0dc4380ceae75c29450Johann  } else {
14137bc9febe8749e98a3812a0dc4380ceae75c29450Johann    bc[1].error = &pc->error;
14147bc9febe8749e98a3812a0dc4380ceae75c29450Johann
14157bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_start_encode(&cpi->bc[1], cx_data, cx_data_end);
141690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
141779f15823c34ae1e423108295e416213200bb280fAndreas Huber#if CONFIG_MULTITHREAD
1418df37111358d02836cb29bbcb9c6e4c95dff90a16Johann    if (vpx_atomic_load_acquire(&cpi->b_multi_threaded)) {
14197bc9febe8749e98a3812a0dc4380ceae75c29450Johann      pack_mb_row_tokens(cpi, &cpi->bc[1]);
14207bc9febe8749e98a3812a0dc4380ceae75c29450Johann    } else {
14217bc9febe8749e98a3812a0dc4380ceae75c29450Johann      vp8_pack_tokens(&cpi->bc[1], cpi->tok, cpi->tok_count);
14227bc9febe8749e98a3812a0dc4380ceae75c29450Johann    }
14237bc9febe8749e98a3812a0dc4380ceae75c29450Johann#else
14247bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_pack_tokens(&cpi->bc[1], cpi->tok, cpi->tok_count);
1425c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann#endif  // CONFIG_MULTITHREAD
142690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
14277bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_stop_encode(&cpi->bc[1]);
142890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
14297bc9febe8749e98a3812a0dc4380ceae75c29450Johann    *size += cpi->bc[1].pos;
14307bc9febe8749e98a3812a0dc4380ceae75c29450Johann    cpi->partition_sz[1] = cpi->bc[1].pos;
14317bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
14321b362b15af34006e6a11974088a46d42b903418eJohann#endif
143390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
143490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1435ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#ifdef VP8_ENTROPY_STATS
14367bc9febe8749e98a3812a0dc4380ceae75c29450Johannvoid print_tree_update_probs() {
14377bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int i, j, k, l;
14387bc9febe8749e98a3812a0dc4380ceae75c29450Johann  FILE *f = fopen("context.c", "a");
14397bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int Sum;
14407bc9febe8749e98a3812a0dc4380ceae75c29450Johann  fprintf(f, "\n/* Update probabilities for token entropy tree. */\n\n");
14417bc9febe8749e98a3812a0dc4380ceae75c29450Johann  fprintf(f,
14427bc9febe8749e98a3812a0dc4380ceae75c29450Johann          "const vp8_prob tree_update_probs[BLOCK_TYPES] [COEF_BANDS] "
14437bc9febe8749e98a3812a0dc4380ceae75c29450Johann          "[PREV_COEF_CONTEXTS] [ENTROPY_NODES] = {\n");
14447bc9febe8749e98a3812a0dc4380ceae75c29450Johann
14457bc9febe8749e98a3812a0dc4380ceae75c29450Johann  for (i = 0; i < BLOCK_TYPES; ++i) {
14467bc9febe8749e98a3812a0dc4380ceae75c29450Johann    fprintf(f, "  { \n");
14477bc9febe8749e98a3812a0dc4380ceae75c29450Johann
14487bc9febe8749e98a3812a0dc4380ceae75c29450Johann    for (j = 0; j < COEF_BANDS; ++j) {
14497bc9febe8749e98a3812a0dc4380ceae75c29450Johann      fprintf(f, "    {\n");
14507bc9febe8749e98a3812a0dc4380ceae75c29450Johann
14517bc9febe8749e98a3812a0dc4380ceae75c29450Johann      for (k = 0; k < PREV_COEF_CONTEXTS; ++k) {
14527bc9febe8749e98a3812a0dc4380ceae75c29450Johann        fprintf(f, "      {");
14537bc9febe8749e98a3812a0dc4380ceae75c29450Johann
14547bc9febe8749e98a3812a0dc4380ceae75c29450Johann        for (l = 0; l < ENTROPY_NODES; ++l) {
14557bc9febe8749e98a3812a0dc4380ceae75c29450Johann          Sum =
14567bc9febe8749e98a3812a0dc4380ceae75c29450Johann              tree_update_hist[i][j][k][l][0] + tree_update_hist[i][j][k][l][1];
14577bc9febe8749e98a3812a0dc4380ceae75c29450Johann
14587bc9febe8749e98a3812a0dc4380ceae75c29450Johann          if (Sum > 0) {
14597bc9febe8749e98a3812a0dc4380ceae75c29450Johann            if (((tree_update_hist[i][j][k][l][0] * 255) / Sum) > 0)
14607bc9febe8749e98a3812a0dc4380ceae75c29450Johann              fprintf(f, "%3ld, ",
14617bc9febe8749e98a3812a0dc4380ceae75c29450Johann                      (tree_update_hist[i][j][k][l][0] * 255) / Sum);
14627bc9febe8749e98a3812a0dc4380ceae75c29450Johann            else
14637bc9febe8749e98a3812a0dc4380ceae75c29450Johann              fprintf(f, "%3ld, ", 1);
14647bc9febe8749e98a3812a0dc4380ceae75c29450Johann          } else
14657bc9febe8749e98a3812a0dc4380ceae75c29450Johann            fprintf(f, "%3ld, ", 128);
146690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
146790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
14687bc9febe8749e98a3812a0dc4380ceae75c29450Johann        fprintf(f, "},\n");
14697bc9febe8749e98a3812a0dc4380ceae75c29450Johann      }
14707bc9febe8749e98a3812a0dc4380ceae75c29450Johann
14717bc9febe8749e98a3812a0dc4380ceae75c29450Johann      fprintf(f, "    },\n");
147290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
147390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
14747bc9febe8749e98a3812a0dc4380ceae75c29450Johann    fprintf(f, "  },\n");
14757bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
14767bc9febe8749e98a3812a0dc4380ceae75c29450Johann
14777bc9febe8749e98a3812a0dc4380ceae75c29450Johann  fprintf(f, "};\n");
14787bc9febe8749e98a3812a0dc4380ceae75c29450Johann  fclose(f);
147990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
148090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
1481