1ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/*
2ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
4ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  Use of this source code is governed by a BSD-style license
5ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  that can be found in the LICENSE file in the root of the source
6ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  tree. An additional intellectual property rights grant can be found
7ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  in the file PATENTS.  All contributing project authors may
8ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  be found in the AUTHORS file in the root of the source tree.
9ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */
10ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <assert.h>
12ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <stdio.h>
13ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <limits.h>
14ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
15ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vpx/vpx_encoder.h"
16ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vpx_mem/vpx_mem.h"
172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "vpx_ports/mem_ops.h"
18ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "vp9/common/vp9_entropy.h"
20ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_entropymode.h"
21ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_entropymv.h"
22ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_mvref_common.h"
232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "vp9/common/vp9_pred_common.h"
242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "vp9/common/vp9_seg_common.h"
252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "vp9/common/vp9_systemdependent.h"
262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "vp9/common/vp9_tile_common.h"
27ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "vp9/encoder/vp9_cost.h"
29ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_bitstream.h"
302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "vp9/encoder/vp9_encodemv.h"
312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "vp9/encoder/vp9_mcomp.h"
32ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_segmentation.h"
3391037db265ecdd914a26e056cf69207b4f50924ehkuang#include "vp9/encoder/vp9_subexp.h"
342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "vp9/encoder/vp9_tokenize.h"
35ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_write_bit_buffer.h"
36ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic struct vp9_token intra_mode_encodings[INTRA_MODES];
382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic struct vp9_token switchable_interp_encodings[SWITCHABLE_FILTERS];
392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic struct vp9_token partition_encodings[PARTITION_TYPES];
402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic struct vp9_token inter_mode_encodings[INTER_MODES];
41ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid vp9_entropy_mode_init() {
432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  vp9_tokens_from_tree(intra_mode_encodings, vp9_intra_mode_tree);
442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  vp9_tokens_from_tree(switchable_interp_encodings, vp9_switchable_interp_tree);
452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  vp9_tokens_from_tree(partition_encodings, vp9_partition_tree);
462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  vp9_tokens_from_tree(inter_mode_encodings, vp9_inter_mode_tree);
47ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
48ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
49ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic void write_intra_mode(vp9_writer *w, PREDICTION_MODE mode,
502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                             const vp9_prob *probs) {
512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  vp9_write_token(w, vp9_intra_mode_tree, probs, &intra_mode_encodings[mode]);
52ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
54ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic void write_inter_mode(vp9_writer *w, PREDICTION_MODE mode,
552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                             const vp9_prob *probs) {
562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  assert(is_inter_mode(mode));
572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  vp9_write_token(w, vp9_inter_mode_tree, probs,
582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                  &inter_mode_encodings[INTER_OFFSET(mode)]);
59ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
60ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic void encode_unsigned_max(struct vp9_write_bit_buffer *wb,
622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                                int data, int max) {
63ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_wb_write_literal(wb, data, get_unsigned_bits(max));
64ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
65ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic void prob_diff_update(const vp9_tree_index *tree,
672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                             vp9_prob probs[/*n - 1*/],
682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                             const unsigned int counts[/*n - 1*/],
692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                             int n, vp9_writer *w) {
702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  int i;
712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  unsigned int branch_ct[32][2];
72ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  // Assuming max number of probabilities <= 32
742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  assert(n <= 32);
75ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  vp9_tree_probs_from_distribution(tree, branch_ct, counts);
772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  for (i = 0; i < n - 1; ++i)
782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    vp9_cond_prob_diff_update(w, &probs[i], branch_ct[i]);
79ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
80ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
81ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic void write_selected_tx_size(const VP9_COMMON *cm,
82ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                                   const MACROBLOCKD *xd,
831184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                   TX_SIZE tx_size, BLOCK_SIZE bsize,
841184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                   vp9_writer *w) {
859b35249446b07f40ac5fcc3205f2c048616efacchkuang  const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
869b35249446b07f40ac5fcc3205f2c048616efacchkuang  const vp9_prob *const tx_probs = get_tx_probs2(max_tx_size, xd,
87ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                                                 &cm->fc.tx_probs);
8891037db265ecdd914a26e056cf69207b4f50924ehkuang  vp9_write(w, tx_size != TX_4X4, tx_probs[0]);
899b35249446b07f40ac5fcc3205f2c048616efacchkuang  if (tx_size != TX_4X4 && max_tx_size >= TX_16X16) {
9091037db265ecdd914a26e056cf69207b4f50924ehkuang    vp9_write(w, tx_size != TX_8X8, tx_probs[1]);
919b35249446b07f40ac5fcc3205f2c048616efacchkuang    if (tx_size != TX_8X8 && max_tx_size >= TX_32X32)
9291037db265ecdd914a26e056cf69207b4f50924ehkuang      vp9_write(w, tx_size != TX_16X16, tx_probs[2]);
9391037db265ecdd914a26e056cf69207b4f50924ehkuang  }
9491037db265ecdd914a26e056cf69207b4f50924ehkuang}
95ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
96ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic int write_skip(const VP9_COMMON *cm, const MACROBLOCKD *xd,
97ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                      int segment_id, const MODE_INFO *mi, vp9_writer *w) {
98ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
9991037db265ecdd914a26e056cf69207b4f50924ehkuang    return 1;
10091037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
1012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    const int skip = mi->mbmi.skip;
102ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    vp9_write(w, skip, vp9_get_skip_prob(cm, xd));
1032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    return skip;
104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic void update_skip_probs(VP9_COMMON *cm, vp9_writer *w) {
10891037db265ecdd914a26e056cf69207b4f50924ehkuang  int k;
10991037db265ecdd914a26e056cf69207b4f50924ehkuang
1102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  for (k = 0; k < SKIP_CONTEXTS; ++k)
1112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    vp9_cond_prob_diff_update(w, &cm->fc.skip_probs[k], cm->counts.skip[k]);
112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic void update_switchable_interp_probs(VP9_COMMON *cm, vp9_writer *w) {
1152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  int j;
1162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j)
1172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    prob_diff_update(vp9_switchable_interp_tree,
1182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                     cm->fc.switchable_interp_prob[j],
1192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                     cm->counts.switchable_interp[j], SWITCHABLE_FILTERS, w);
120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic void pack_mb_tokens(vp9_writer *w,
123ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                           TOKENEXTRA **tp, const TOKENEXTRA *const stop) {
124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  TOKENEXTRA *p = *tp;
125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  while (p < stop && p->token != EOSB_TOKEN) {
127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int t = p->token;
1289b35249446b07f40ac5fcc3205f2c048616efacchkuang    const struct vp9_token *const a = &vp9_coef_encodings[t];
1299b35249446b07f40ac5fcc3205f2c048616efacchkuang    const vp9_extra_bit *const b = &vp9_extra_bits[t];
130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int i = 0;
131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int v = a->value;
132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int n = a->len;
133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    /* skip one or two nodes */
135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (p->skip_eob_node) {
136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      n -= p->skip_eob_node;
137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      i = 2 * p->skip_eob_node;
138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    // TODO(jbb): expanding this can lead to big gains.  It allows
1412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    // much better branch prediction and would enable us to avoid numerous
1422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    // lookups and compares.
1432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
1442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    // If we have a token that's in the constrained set, the coefficient tree
1452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    // is split into two treed writes.  The first treed write takes care of the
1462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    // unconstrained nodes.  The second treed write takes care of the
1472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    // constrained nodes.
1482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    if (t >= TWO_TOKEN && t < EOB_TOKEN) {
1492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      int len = UNCONSTRAINED_NODES - p->skip_eob_node;
1502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      int bits = v >> (n - len);
1512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      vp9_write_tree(w, vp9_coef_tree, p->context_tree, bits, len, i);
1522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      vp9_write_tree(w, vp9_coef_con_tree,
1532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                     vp9_pareto8_full[p->context_tree[PIVOT_NODE] - 1],
1542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                     v, n - len, 0);
1552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    } else {
1562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      vp9_write_tree(w, vp9_coef_tree, p->context_tree, v, n, i);
1572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    }
158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (b->base_val) {
160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      const int e = p->extra, l = b->len;
161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (l) {
163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        const unsigned char *pb = b->prob;
164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        int v = e >> 1;
165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        int n = l;              /* number of bits in v, assumed nonzero */
166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        int i = 0;
167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        do {
169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          const int bb = (v >> --n) & 1;
1709b35249446b07f40ac5fcc3205f2c048616efacchkuang          vp9_write(w, bb, pb[i >> 1]);
171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          i = b->tree[i + bb];
172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        } while (n);
173ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
174ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1759b35249446b07f40ac5fcc3205f2c048616efacchkuang      vp9_write_bit(w, e & 1);
176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ++p;
178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  *tp = p + (p->token == EOSB_TOKEN);
181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
182ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
18391037db265ecdd914a26e056cf69207b4f50924ehkuangstatic void write_segment_id(vp9_writer *w, const struct segmentation *seg,
18491037db265ecdd914a26e056cf69207b4f50924ehkuang                             int segment_id) {
18591037db265ecdd914a26e056cf69207b4f50924ehkuang  if (seg->enabled && seg->update_map)
1862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    vp9_write_tree(w, vp9_segment_tree, seg->tree_probs, segment_id, 3, 0);
187ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// This function encodes the reference frame
190ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic void write_ref_frames(const VP9_COMMON *cm, const MACROBLOCKD *xd,
191ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                             vp9_writer *w) {
1924fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang  const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  const int is_compound = has_second_ref(mbmi);
1942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  const int segment_id = mbmi->segment_id;
1952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
196ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // If segment level coding of this signal is disabled...
197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // or the segment allows multiple reference frame options
1982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  if (vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) {
1992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    assert(!is_compound);
2002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    assert(mbmi->ref_frame[0] ==
2012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian               vp9_get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME));
2022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  } else {
203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // does the feature use compound prediction or not
204ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // (if not specified at the frame/segment level)
2052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    if (cm->reference_mode == REFERENCE_MODE_SELECT) {
2062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      vp9_write(w, is_compound, vp9_get_reference_mode_prob(cm, xd));
207ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
2082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      assert(!is_compound == (cm->reference_mode == SINGLE_REFERENCE));
209ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
210ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    if (is_compound) {
2122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      vp9_write(w, mbmi->ref_frame[0] == GOLDEN_FRAME,
2131184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                vp9_get_pred_prob_comp_ref_p(cm, xd));
214ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
2152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      const int bit0 = mbmi->ref_frame[0] != LAST_FRAME;
2162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      vp9_write(w, bit0, vp9_get_pred_prob_single_ref_p1(cm, xd));
2172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      if (bit0) {
2182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        const int bit1 = mbmi->ref_frame[0] != GOLDEN_FRAME;
2192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        vp9_write(w, bit1, vp9_get_pred_prob_single_ref_p2(cm, xd));
2202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      }
221ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
222ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
223ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
224ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
2262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                                vp9_writer *w) {
2271184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  VP9_COMMON *const cm = &cpi->common;
2281184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const nmv_context *nmvc = &cm->fc.nmvc;
2292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  const MACROBLOCK *const x = &cpi->mb;
2302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  const MACROBLOCKD *const xd = &x->e_mbd;
2312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  const struct segmentation *const seg = &cm->seg;
2322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  const MB_MODE_INFO *const mbmi = &mi->mbmi;
233ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const PREDICTION_MODE mode = mbmi->mode;
2342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  const int segment_id = mbmi->segment_id;
2352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  const BLOCK_SIZE bsize = mbmi->sb_type;
2365ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const int allow_hp = cm->allow_high_precision_mv;
2372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  const int is_inter = is_inter_block(mbmi);
2382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  const int is_compound = has_second_ref(mbmi);
2392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  int skip, ref;
240ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
24191037db265ecdd914a26e056cf69207b4f50924ehkuang  if (seg->update_map) {
24291037db265ecdd914a26e056cf69207b4f50924ehkuang    if (seg->temporal_update) {
2432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      const int pred_flag = mbmi->seg_id_predicted;
2441184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      vp9_prob pred_prob = vp9_get_pred_prob_seg_id(seg, xd);
2452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      vp9_write(w, pred_flag, pred_prob);
24691037db265ecdd914a26e056cf69207b4f50924ehkuang      if (!pred_flag)
2472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        write_segment_id(w, seg, segment_id);
248ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
2492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      write_segment_id(w, seg, segment_id);
250ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
251ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
252ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
253ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  skip = write_skip(cm, xd, segment_id, mi, w);
254ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
25591037db265ecdd914a26e056cf69207b4f50924ehkuang  if (!vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
2562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    vp9_write(w, is_inter, vp9_get_intra_inter_prob(cm, xd));
257ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2581184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (bsize >= BLOCK_8X8 && cm->tx_mode == TX_MODE_SELECT &&
2592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      !(is_inter &&
2602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        (skip || vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP)))) {
261ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    write_selected_tx_size(cm, xd, mbmi->tx_size, bsize, w);
262ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
263ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  if (!is_inter) {
2651184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    if (bsize >= BLOCK_8X8) {
2662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      write_intra_mode(w, mode, cm->fc.y_mode_prob[size_group_lookup[bsize]]);
267ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
268ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      int idx, idy;
2692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
2702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
2712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      for (idy = 0; idy < 2; idy += num_4x4_h) {
2722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        for (idx = 0; idx < 2; idx += num_4x4_w) {
273ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian          const PREDICTION_MODE b_mode = mi->bmi[idy * 2 + idx].as_mode;
2742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          write_intra_mode(w, b_mode, cm->fc.y_mode_prob[0]);
275ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
276f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      }
277ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
2782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    write_intra_mode(w, mbmi->uv_mode, cm->fc.uv_mode_prob[mode]);
279ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else {
2802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    const int mode_ctx = mbmi->mode_context[mbmi->ref_frame[0]];
2812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    const vp9_prob *const inter_probs = cm->fc.inter_mode_probs[mode_ctx];
282ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    write_ref_frames(cm, xd, w);
283ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
284ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // If segment skip is not enabled code the mode.
28591037db265ecdd914a26e056cf69207b4f50924ehkuang    if (!vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP)) {
2861184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      if (bsize >= BLOCK_8X8) {
2872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        write_inter_mode(w, mode, inter_probs);
2882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        ++cm->counts.inter_mode[mode_ctx][INTER_OFFSET(mode)];
289ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
290ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
291ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    if (cm->interp_filter == SWITCHABLE) {
2931184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      const int ctx = vp9_get_pred_context_switchable_interp(xd);
2942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      vp9_write_token(w, vp9_switchable_interp_tree,
2952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                      cm->fc.switchable_interp_prob[ctx],
2962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                      &switchable_interp_encodings[mbmi->interp_filter]);
297ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
2982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      assert(mbmi->interp_filter == cm->interp_filter);
299ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
300ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3011184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    if (bsize < BLOCK_8X8) {
3022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
3032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
304ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      int idx, idy;
3052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      for (idy = 0; idy < 2; idy += num_4x4_h) {
3062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        for (idx = 0; idx < 2; idx += num_4x4_w) {
3075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          const int j = idy * 2 + idx;
308ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian          const PREDICTION_MODE b_mode = mi->bmi[j].as_mode;
3092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          write_inter_mode(w, b_mode, inter_probs);
3102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          ++cm->counts.inter_mode[mode_ctx][INTER_OFFSET(b_mode)];
3112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          if (b_mode == NEWMV) {
3122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian            for (ref = 0; ref < 1 + is_compound; ++ref)
3132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian              vp9_encode_mv(cpi, w, &mi->bmi[j].as_mv[ref].as_mv,
3142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                            &mbmi->ref_mvs[mbmi->ref_frame[ref]][0].as_mv,
3152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                            nmvc, allow_hp);
316ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          }
317ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
318ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
3192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    } else {
3202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      if (mode == NEWMV) {
3212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        for (ref = 0; ref < 1 + is_compound; ++ref)
3222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          vp9_encode_mv(cpi, w, &mbmi->mv[ref].as_mv,
3232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                        &mbmi->ref_mvs[mbmi->ref_frame[ref]][0].as_mv, nmvc,
3242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                        allow_hp);
3252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      }
326ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
327ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
328ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
329ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
330ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic void write_mb_modes_kf(const VP9_COMMON *cm, const MACROBLOCKD *xd,
331ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                              MODE_INFO **mi_8x8, vp9_writer *w) {
3321184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const struct segmentation *const seg = &cm->seg;
3332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  const MODE_INFO *const mi = mi_8x8[0];
3344fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang  const MODE_INFO *const above_mi = mi_8x8[-xd->mi_stride];
3352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  const MODE_INFO *const left_mi = xd->left_available ? mi_8x8[-1] : NULL;
3362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  const MB_MODE_INFO *const mbmi = &mi->mbmi;
3372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  const BLOCK_SIZE bsize = mbmi->sb_type;
338ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3391184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (seg->update_map)
3402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    write_segment_id(w, seg, mbmi->segment_id);
341ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
342ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  write_skip(cm, xd, mbmi->segment_id, mi, w);
343ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  if (bsize >= BLOCK_8X8 && cm->tx_mode == TX_MODE_SELECT)
345ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    write_selected_tx_size(cm, xd, mbmi->tx_size, bsize, w);
346ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  if (bsize >= BLOCK_8X8) {
3482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    write_intra_mode(w, mbmi->mode, get_y_mode_probs(mi, above_mi, left_mi, 0));
349ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else {
3502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
3512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
352ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int idx, idy;
3532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
3542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    for (idy = 0; idy < 2; idy += num_4x4_h) {
3552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      for (idx = 0; idx < 2; idx += num_4x4_w) {
3562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        const int block = idy * 2 + idx;
3572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        write_intra_mode(w, mi->bmi[block].as_mode,
3582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                         get_y_mode_probs(mi, above_mi, left_mi, block));
359ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
360ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
361ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
362ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  write_intra_mode(w, mbmi->uv_mode, vp9_kf_uv_mode_prob[mbmi->mode]);
364ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
365ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic void write_modes_b(VP9_COMP *cpi, const TileInfo *const tile,
367ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                          vp9_writer *w, TOKENEXTRA **tok,
368ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                          const TOKENEXTRA *const tok_end,
3699b35249446b07f40ac5fcc3205f2c048616efacchkuang                          int mi_row, int mi_col) {
370ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const VP9_COMMON *const cm = &cpi->common;
371ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *const xd = &cpi->mb.e_mbd;
3729b35249446b07f40ac5fcc3205f2c048616efacchkuang  MODE_INFO *m;
373ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3744fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang  xd->mi = cm->mi_grid_visible + (mi_row * cm->mi_stride + mi_col);
3754fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang  m = xd->mi[0];
3761184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
3775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  set_mi_row_col(xd, tile,
3781184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                 mi_row, num_8x8_blocks_high_lookup[m->mbmi.sb_type],
3795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                 mi_col, num_8x8_blocks_wide_lookup[m->mbmi.sb_type],
3805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                 cm->mi_rows, cm->mi_cols);
3815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (frame_is_intra_only(cm)) {
382ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    write_mb_modes_kf(cm, xd, xd->mi, w);
383ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else {
3849b35249446b07f40ac5fcc3205f2c048616efacchkuang    pack_inter_mode_mvs(cpi, m, w);
385ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
386ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
387ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  assert(*tok < tok_end);
3889b35249446b07f40ac5fcc3205f2c048616efacchkuang  pack_mb_tokens(w, tok, tok_end);
389ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
390ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
391ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic void write_partition(const VP9_COMMON *const cm,
392ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                            const MACROBLOCKD *const xd,
3934fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang                            int hbs, int mi_row, int mi_col,
3945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                            PARTITION_TYPE p, BLOCK_SIZE bsize, vp9_writer *w) {
3954fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang  const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
3965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const vp9_prob *const probs = get_partition_probs(cm, ctx);
3975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const int has_rows = (mi_row + hbs) < cm->mi_rows;
3985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const int has_cols = (mi_col + hbs) < cm->mi_cols;
3995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
4005ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (has_rows && has_cols) {
4012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    vp9_write_token(w, vp9_partition_tree, probs, &partition_encodings[p]);
4025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  } else if (!has_rows && has_cols) {
4035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    assert(p == PARTITION_SPLIT || p == PARTITION_HORZ);
4045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vp9_write(w, p == PARTITION_SPLIT, probs[1]);
4055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  } else if (has_rows && !has_cols) {
4065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    assert(p == PARTITION_SPLIT || p == PARTITION_VERT);
4075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vp9_write(w, p == PARTITION_SPLIT, probs[2]);
4085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  } else {
4095ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    assert(p == PARTITION_SPLIT);
4105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
4115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
4125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
4134fb68e5dd4e93c7599dc905d861de11ac39c5585hkuangstatic void write_modes_sb(VP9_COMP *cpi,
414ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                           const TileInfo *const tile, vp9_writer *w,
415ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                           TOKENEXTRA **tok, const TOKENEXTRA *const tok_end,
4169b35249446b07f40ac5fcc3205f2c048616efacchkuang                           int mi_row, int mi_col, BLOCK_SIZE bsize) {
417ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const VP9_COMMON *const cm = &cpi->common;
4184fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang  MACROBLOCKD *const xd = &cpi->mb.e_mbd;
4194fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang
4209b35249446b07f40ac5fcc3205f2c048616efacchkuang  const int bsl = b_width_log2(bsize);
4219b35249446b07f40ac5fcc3205f2c048616efacchkuang  const int bs = (1 << bsl) / 4;
4229b35249446b07f40ac5fcc3205f2c048616efacchkuang  PARTITION_TYPE partition;
4231184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  BLOCK_SIZE subsize;
424ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const MODE_INFO *m = cm->mi_grid_visible[mi_row * cm->mi_stride + mi_col];
425ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
426ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
427ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return;
428ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
42991037db265ecdd914a26e056cf69207b4f50924ehkuang  partition = partition_lookup[bsl][m->mbmi.sb_type];
4304fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang  write_partition(cm, xd, bs, mi_row, mi_col, partition, bsize, w);
431ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  subsize = get_subsize(bsize, partition);
4329b35249446b07f40ac5fcc3205f2c048616efacchkuang  if (subsize < BLOCK_8X8) {
4339b35249446b07f40ac5fcc3205f2c048616efacchkuang    write_modes_b(cpi, tile, w, tok, tok_end, mi_row, mi_col);
4349b35249446b07f40ac5fcc3205f2c048616efacchkuang  } else {
4359b35249446b07f40ac5fcc3205f2c048616efacchkuang    switch (partition) {
4369b35249446b07f40ac5fcc3205f2c048616efacchkuang      case PARTITION_NONE:
4379b35249446b07f40ac5fcc3205f2c048616efacchkuang        write_modes_b(cpi, tile, w, tok, tok_end, mi_row, mi_col);
4389b35249446b07f40ac5fcc3205f2c048616efacchkuang        break;
4399b35249446b07f40ac5fcc3205f2c048616efacchkuang      case PARTITION_HORZ:
4409b35249446b07f40ac5fcc3205f2c048616efacchkuang        write_modes_b(cpi, tile, w, tok, tok_end, mi_row, mi_col);
4419b35249446b07f40ac5fcc3205f2c048616efacchkuang        if (mi_row + bs < cm->mi_rows)
4429b35249446b07f40ac5fcc3205f2c048616efacchkuang          write_modes_b(cpi, tile, w, tok, tok_end, mi_row + bs, mi_col);
4439b35249446b07f40ac5fcc3205f2c048616efacchkuang        break;
4449b35249446b07f40ac5fcc3205f2c048616efacchkuang      case PARTITION_VERT:
4459b35249446b07f40ac5fcc3205f2c048616efacchkuang        write_modes_b(cpi, tile, w, tok, tok_end, mi_row, mi_col);
4469b35249446b07f40ac5fcc3205f2c048616efacchkuang        if (mi_col + bs < cm->mi_cols)
4479b35249446b07f40ac5fcc3205f2c048616efacchkuang          write_modes_b(cpi, tile, w, tok, tok_end, mi_row, mi_col + bs);
4489b35249446b07f40ac5fcc3205f2c048616efacchkuang        break;
4499b35249446b07f40ac5fcc3205f2c048616efacchkuang      case PARTITION_SPLIT:
4509b35249446b07f40ac5fcc3205f2c048616efacchkuang        write_modes_sb(cpi, tile, w, tok, tok_end, mi_row, mi_col, subsize);
4519b35249446b07f40ac5fcc3205f2c048616efacchkuang        write_modes_sb(cpi, tile, w, tok, tok_end, mi_row, mi_col + bs,
4529b35249446b07f40ac5fcc3205f2c048616efacchkuang                       subsize);
4539b35249446b07f40ac5fcc3205f2c048616efacchkuang        write_modes_sb(cpi, tile, w, tok, tok_end, mi_row + bs, mi_col,
4549b35249446b07f40ac5fcc3205f2c048616efacchkuang                       subsize);
4559b35249446b07f40ac5fcc3205f2c048616efacchkuang        write_modes_sb(cpi, tile, w, tok, tok_end, mi_row + bs, mi_col + bs,
4569b35249446b07f40ac5fcc3205f2c048616efacchkuang                       subsize);
4579b35249446b07f40ac5fcc3205f2c048616efacchkuang        break;
4589b35249446b07f40ac5fcc3205f2c048616efacchkuang      default:
4599b35249446b07f40ac5fcc3205f2c048616efacchkuang        assert(0);
4609b35249446b07f40ac5fcc3205f2c048616efacchkuang    }
461ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
462ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
463ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // update partition context
4641184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (bsize >= BLOCK_8X8 &&
4655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      (bsize == BLOCK_8X8 || partition != PARTITION_SPLIT))
4664fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang    update_partition_context(xd, mi_row, mi_col, subsize, bsize);
467ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
468ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4694fb68e5dd4e93c7599dc905d861de11ac39c5585hkuangstatic void write_modes(VP9_COMP *cpi,
470ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                        const TileInfo *const tile, vp9_writer *w,
471ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                        TOKENEXTRA **tok, const TOKENEXTRA *const tok_end) {
472ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int mi_row, mi_col;
4731184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
4745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (mi_row = tile->mi_row_start; mi_row < tile->mi_row_end;
4759b35249446b07f40ac5fcc3205f2c048616efacchkuang       mi_row += MI_BLOCK_SIZE) {
4764fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang    vp9_zero(cpi->mb.e_mbd.left_seg_context);
4775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end;
4789b35249446b07f40ac5fcc3205f2c048616efacchkuang         mi_col += MI_BLOCK_SIZE)
4794fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang      write_modes_sb(cpi, tile, w, tok, tok_end, mi_row, mi_col,
4804fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang                     BLOCK_64X64);
481ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
482ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
483ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4844fb68e5dd4e93c7599dc905d861de11ac39c5585hkuangstatic void build_tree_distribution(VP9_COMP *cpi, TX_SIZE tx_size,
485ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                                    vp9_coeff_stats *coef_branch_ct,
486ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                                    vp9_coeff_probs_model *coef_probs) {
487f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  vp9_coeff_count *coef_counts = cpi->coef_counts[tx_size];
4882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  unsigned int (*eob_branch_ct)[REF_TYPES][COEF_BANDS][COEFF_CONTEXTS] =
489f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      cpi->common.counts.eob_branch[tx_size];
4905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int i, j, k, l, m;
491ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  for (i = 0; i < PLANE_TYPES; ++i) {
493ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (j = 0; j < REF_TYPES; ++j) {
494ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (k = 0; k < COEF_BANDS; ++k) {
4952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) {
496ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          vp9_tree_probs_from_distribution(vp9_coef_tree,
497ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                           coef_branch_ct[i][j][k][l],
4989b35249446b07f40ac5fcc3205f2c048616efacchkuang                                           coef_counts[i][j][k][l]);
499ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          coef_branch_ct[i][j][k][l][0][1] = eob_branch_ct[i][j][k][l] -
500ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                             coef_branch_ct[i][j][k][l][0][0];
5015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          for (m = 0; m < UNCONSTRAINED_NODES; ++m)
5025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            coef_probs[i][j][k][l][m] = get_binary_prob(
5035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                            coef_branch_ct[i][j][k][l][m][0],
5045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                            coef_branch_ct[i][j][k][l][m][1]);
505ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
506ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
507ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
508ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
509ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
510ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
511ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void update_coef_probs_common(vp9_writer* const bc, VP9_COMP *cpi,
5124fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang                                     TX_SIZE tx_size,
513ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                                     vp9_coeff_stats *frame_branch_ct,
514ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                                     vp9_coeff_probs_model *new_coef_probs) {
515ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  vp9_coeff_probs_model *old_coef_probs = cpi->common.fc.coef_probs[tx_size];
5165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const vp9_prob upd = DIFF_UPDATE_PROB;
517ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int entropy_nodes_update = UNCONSTRAINED_NODES;
5181184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int i, j, k, l, t;
5191184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  switch (cpi->sf.use_fast_coef_updates) {
5204fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang    case TWO_LOOP: {
521ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      /* dry run to see if there is any update at all needed */
5221184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      int savings = 0;
5231184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      int update[2] = {0, 0};
5242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      for (i = 0; i < PLANE_TYPES; ++i) {
5251184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        for (j = 0; j < REF_TYPES; ++j) {
5261184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          for (k = 0; k < COEF_BANDS; ++k) {
5272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian            for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) {
5281184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              for (t = 0; t < entropy_nodes_update; ++t) {
529ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                vp9_prob newp = new_coef_probs[i][j][k][l][t];
530ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                const vp9_prob oldp = old_coef_probs[i][j][k][l][t];
5311184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                int s;
5321184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                int u = 0;
5331184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                if (t == PIVOT_NODE)
5341184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  s = vp9_prob_diff_update_savings_search_model(
5351184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                      frame_branch_ct[i][j][k][l][0],
536ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                      old_coef_probs[i][j][k][l], &newp, upd);
5371184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                else
5381184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  s = vp9_prob_diff_update_savings_search(
5391184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                      frame_branch_ct[i][j][k][l][t], oldp, &newp, upd);
5401184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                if (s > 0 && newp != oldp)
5411184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  u = 1;
5421184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                if (u)
5431184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  savings += s - (int)(vp9_cost_zero(upd));
5441184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                else
5451184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  savings -= (int)(vp9_cost_zero(upd));
5461184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                update[u]++;
5471184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              }
5481184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            }
5491184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          }
5501184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        }
5511184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      }
552ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
5531184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      // printf("Update %d %d, savings %d\n", update[0], update[1], savings);
5541184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      /* Is coef updated at all */
5551184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      if (update[1] == 0 || savings < 0) {
5561184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        vp9_write_bit(bc, 0);
5571184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        return;
5581184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      }
5591184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      vp9_write_bit(bc, 1);
5602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      for (i = 0; i < PLANE_TYPES; ++i) {
5611184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        for (j = 0; j < REF_TYPES; ++j) {
5621184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          for (k = 0; k < COEF_BANDS; ++k) {
5632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian            for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) {
5641184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              // calc probs and branch cts for this frame only
5651184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              for (t = 0; t < entropy_nodes_update; ++t) {
566ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                vp9_prob newp = new_coef_probs[i][j][k][l][t];
567ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                vp9_prob *oldp = old_coef_probs[i][j][k][l] + t;
5685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                const vp9_prob upd = DIFF_UPDATE_PROB;
5691184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                int s;
5701184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                int u = 0;
5711184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                if (t == PIVOT_NODE)
5721184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  s = vp9_prob_diff_update_savings_search_model(
5731184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                      frame_branch_ct[i][j][k][l][0],
574ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                      old_coef_probs[i][j][k][l], &newp, upd);
5751184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                else
5761184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  s = vp9_prob_diff_update_savings_search(
5771184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                      frame_branch_ct[i][j][k][l][t],
5781184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                      *oldp, &newp, upd);
5791184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                if (s > 0 && newp != *oldp)
5801184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  u = 1;
5811184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                vp9_write(bc, u, upd);
5821184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                if (u) {
5831184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  /* send/use new probability */
5841184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  vp9_write_prob_diff_update(bc, newp, *oldp);
5851184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  *oldp = newp;
5861184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                }
5871184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              }
5881184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            }
589ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          }
590ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
591ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
5921184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      return;
593ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
594ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
5954fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang    case ONE_LOOP:
5964fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang    case ONE_LOOP_REDUCED: {
5971184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      const int prev_coef_contexts_to_update =
5984fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang          cpi->sf.use_fast_coef_updates == ONE_LOOP_REDUCED ?
5994fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang              COEFF_CONTEXTS >> 1 : COEFF_CONTEXTS;
6001184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      const int coef_band_to_update =
6014fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang          cpi->sf.use_fast_coef_updates == ONE_LOOP_REDUCED ?
6024fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang              COEF_BANDS >> 1 : COEF_BANDS;
6031184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      int updates = 0;
6041184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      int noupdates_before_first = 0;
6052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      for (i = 0; i < PLANE_TYPES; ++i) {
6061184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        for (j = 0; j < REF_TYPES; ++j) {
6071184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          for (k = 0; k < COEF_BANDS; ++k) {
6082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian            for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) {
6091184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              // calc probs and branch cts for this frame only
6101184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              for (t = 0; t < entropy_nodes_update; ++t) {
611ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                vp9_prob newp = new_coef_probs[i][j][k][l][t];
612ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                vp9_prob *oldp = old_coef_probs[i][j][k][l] + t;
6131184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                int s;
6141184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                int u = 0;
6151184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                if (l >= prev_coef_contexts_to_update ||
6161184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                    k >= coef_band_to_update) {
6171184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  u = 0;
6181184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                } else {
6191184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  if (t == PIVOT_NODE)
6201184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                    s = vp9_prob_diff_update_savings_search_model(
6211184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                        frame_branch_ct[i][j][k][l][0],
622ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                        old_coef_probs[i][j][k][l], &newp, upd);
6231184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  else
6241184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                    s = vp9_prob_diff_update_savings_search(
6251184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                        frame_branch_ct[i][j][k][l][t],
6261184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                        *oldp, &newp, upd);
6271184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  if (s > 0 && newp != *oldp)
6281184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                    u = 1;
6291184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                }
6301184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                updates += u;
6311184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                if (u == 0 && updates == 0) {
6321184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  noupdates_before_first++;
6331184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  continue;
6341184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                }
6351184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                if (u == 1 && updates == 1) {
6361184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  int v;
6371184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  // first update
6381184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  vp9_write_bit(bc, 1);
6391184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  for (v = 0; v < noupdates_before_first; ++v)
6401184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                    vp9_write(bc, 0, upd);
6411184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                }
6421184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                vp9_write(bc, u, upd);
6431184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                if (u) {
6441184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  /* send/use new probability */
6451184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  vp9_write_prob_diff_update(bc, newp, *oldp);
6461184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  *oldp = newp;
6471184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                }
6481184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              }
649ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            }
650ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          }
651ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
652ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
6531184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      if (updates == 0) {
6541184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        vp9_write_bit(bc, 0);  // no updates
6551184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      }
6561184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      return;
657ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
6581184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
6591184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    default:
6601184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      assert(0);
661ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
662ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
663ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
6642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic void update_coef_probs(VP9_COMP *cpi, vp9_writer* w) {
66591037db265ecdd914a26e056cf69207b4f50924ehkuang  const TX_MODE tx_mode = cpi->common.tx_mode;
6662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  const TX_SIZE max_tx_size = tx_mode_to_biggest_tx_size[tx_mode];
6672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  TX_SIZE tx_size;
6684fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang  vp9_coeff_stats frame_branch_ct[TX_SIZES][PLANE_TYPES];
669ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  vp9_coeff_probs_model frame_coef_probs[TX_SIZES][PLANE_TYPES];
6704fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang
671ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_clear_system_state();
672ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
6732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  for (tx_size = TX_4X4; tx_size <= TX_32X32; ++tx_size)
674ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    build_tree_distribution(cpi, tx_size, frame_branch_ct[tx_size],
675ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                            frame_coef_probs[tx_size]);
676ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
6772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  for (tx_size = TX_4X4; tx_size <= max_tx_size; ++tx_size)
678ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    update_coef_probs_common(w, cpi, tx_size, frame_branch_ct[tx_size],
679ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                             frame_coef_probs[tx_size]);
680ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
681ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
68291037db265ecdd914a26e056cf69207b4f50924ehkuangstatic void encode_loopfilter(struct loopfilter *lf,
683ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                              struct vp9_write_bit_buffer *wb) {
684ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i;
685ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
686ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Encode the loop filter level and type
68791037db265ecdd914a26e056cf69207b4f50924ehkuang  vp9_wb_write_literal(wb, lf->filter_level, 6);
68891037db265ecdd914a26e056cf69207b4f50924ehkuang  vp9_wb_write_literal(wb, lf->sharpness_level, 3);
689ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
690ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Write out loop filter deltas applied at the MB level based on mode or
691ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // ref frame (if they are enabled).
69291037db265ecdd914a26e056cf69207b4f50924ehkuang  vp9_wb_write_bit(wb, lf->mode_ref_delta_enabled);
693ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
69491037db265ecdd914a26e056cf69207b4f50924ehkuang  if (lf->mode_ref_delta_enabled) {
69591037db265ecdd914a26e056cf69207b4f50924ehkuang    vp9_wb_write_bit(wb, lf->mode_ref_delta_update);
69691037db265ecdd914a26e056cf69207b4f50924ehkuang    if (lf->mode_ref_delta_update) {
697ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (i = 0; i < MAX_REF_LF_DELTAS; i++) {
69891037db265ecdd914a26e056cf69207b4f50924ehkuang        const int delta = lf->ref_deltas[i];
6992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        const int changed = delta != lf->last_ref_deltas[i];
7002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        vp9_wb_write_bit(wb, changed);
7012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        if (changed) {
70291037db265ecdd914a26e056cf69207b4f50924ehkuang          lf->last_ref_deltas[i] = delta;
703ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          vp9_wb_write_literal(wb, abs(delta) & 0x3F, 6);
704ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          vp9_wb_write_bit(wb, delta < 0);
705ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
706ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
707ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
708ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (i = 0; i < MAX_MODE_LF_DELTAS; i++) {
70991037db265ecdd914a26e056cf69207b4f50924ehkuang        const int delta = lf->mode_deltas[i];
7102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        const int changed = delta != lf->last_mode_deltas[i];
7112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        vp9_wb_write_bit(wb, changed);
7122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        if (changed) {
71391037db265ecdd914a26e056cf69207b4f50924ehkuang          lf->last_mode_deltas[i] = delta;
714ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          vp9_wb_write_literal(wb, abs(delta) & 0x3F, 6);
715ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          vp9_wb_write_bit(wb, delta < 0);
716ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
717ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
718ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
719ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
720ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
721ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
722ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void write_delta_q(struct vp9_write_bit_buffer *wb, int delta_q) {
723ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (delta_q != 0) {
724ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_wb_write_bit(wb, 1);
725ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_wb_write_literal(wb, abs(delta_q), 4);
726ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_wb_write_bit(wb, delta_q < 0);
727ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else {
728ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_wb_write_bit(wb, 0);
729ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
730ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
731ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
732ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic void encode_quantization(const VP9_COMMON *const cm,
733ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                struct vp9_write_bit_buffer *wb) {
734ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_wb_write_literal(wb, cm->base_qindex, QINDEX_BITS);
735ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  write_delta_q(wb, cm->y_dc_delta_q);
736ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  write_delta_q(wb, cm->uv_dc_delta_q);
737ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  write_delta_q(wb, cm->uv_ac_delta_q);
738ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
739ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
740ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic void encode_segmentation(VP9_COMMON *cm, MACROBLOCKD *xd,
74191037db265ecdd914a26e056cf69207b4f50924ehkuang                                struct vp9_write_bit_buffer *wb) {
742ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i, j;
743ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
744ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const struct segmentation *seg = &cm->seg;
74591037db265ecdd914a26e056cf69207b4f50924ehkuang
74691037db265ecdd914a26e056cf69207b4f50924ehkuang  vp9_wb_write_bit(wb, seg->enabled);
74791037db265ecdd914a26e056cf69207b4f50924ehkuang  if (!seg->enabled)
748ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return;
749ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
750ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Segmentation map
75191037db265ecdd914a26e056cf69207b4f50924ehkuang  vp9_wb_write_bit(wb, seg->update_map);
75291037db265ecdd914a26e056cf69207b4f50924ehkuang  if (seg->update_map) {
753ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Select the coding strategy (temporal or spatial)
754ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    vp9_choose_segmap_coding_method(cm, xd);
755ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Write out probabilities used to decode unpredicted  macro-block segments
75691037db265ecdd914a26e056cf69207b4f50924ehkuang    for (i = 0; i < SEG_TREE_PROBS; i++) {
75791037db265ecdd914a26e056cf69207b4f50924ehkuang      const int prob = seg->tree_probs[i];
758ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      const int update = prob != MAX_PROB;
759ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      vp9_wb_write_bit(wb, update);
760ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (update)
761ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        vp9_wb_write_literal(wb, prob, 8);
762ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
763ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
764ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Write out the chosen coding method.
76591037db265ecdd914a26e056cf69207b4f50924ehkuang    vp9_wb_write_bit(wb, seg->temporal_update);
76691037db265ecdd914a26e056cf69207b4f50924ehkuang    if (seg->temporal_update) {
767ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (i = 0; i < PREDICTION_PROBS; i++) {
76891037db265ecdd914a26e056cf69207b4f50924ehkuang        const int prob = seg->pred_probs[i];
769ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        const int update = prob != MAX_PROB;
770ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        vp9_wb_write_bit(wb, update);
771ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        if (update)
772ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          vp9_wb_write_literal(wb, prob, 8);
773ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
774ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
775ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
776ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
777ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Segmentation data
77891037db265ecdd914a26e056cf69207b4f50924ehkuang  vp9_wb_write_bit(wb, seg->update_data);
77991037db265ecdd914a26e056cf69207b4f50924ehkuang  if (seg->update_data) {
78091037db265ecdd914a26e056cf69207b4f50924ehkuang    vp9_wb_write_bit(wb, seg->abs_delta);
781ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
78291037db265ecdd914a26e056cf69207b4f50924ehkuang    for (i = 0; i < MAX_SEGMENTS; i++) {
783ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (j = 0; j < SEG_LVL_MAX; j++) {
78491037db265ecdd914a26e056cf69207b4f50924ehkuang        const int active = vp9_segfeature_active(seg, i, j);
785ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        vp9_wb_write_bit(wb, active);
786ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        if (active) {
78791037db265ecdd914a26e056cf69207b4f50924ehkuang          const int data = vp9_get_segdata(seg, i, j);
788ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          const int data_max = vp9_seg_feature_data_max(j);
789ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
790ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          if (vp9_is_segfeature_signed(j)) {
7912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian            encode_unsigned_max(wb, abs(data), data_max);
792ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            vp9_wb_write_bit(wb, data < 0);
793ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          } else {
7942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian            encode_unsigned_max(wb, data, data_max);
795ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          }
796ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
797ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
798ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
799ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
800ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
801ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
8022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic void encode_txfm_probs(VP9_COMMON *cm, vp9_writer *w) {
803ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Mode
80491037db265ecdd914a26e056cf69207b4f50924ehkuang  vp9_write_literal(w, MIN(cm->tx_mode, ALLOW_32X32), 2);
80591037db265ecdd914a26e056cf69207b4f50924ehkuang  if (cm->tx_mode >= ALLOW_32X32)
80691037db265ecdd914a26e056cf69207b4f50924ehkuang    vp9_write_bit(w, cm->tx_mode == TX_MODE_SELECT);
807ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
808ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Probabilities
80991037db265ecdd914a26e056cf69207b4f50924ehkuang  if (cm->tx_mode == TX_MODE_SELECT) {
810ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int i, j;
811f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    unsigned int ct_8x8p[TX_SIZES - 3][2];
812f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    unsigned int ct_16x16p[TX_SIZES - 2][2];
813f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    unsigned int ct_32x32p[TX_SIZES - 1][2];
814ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
815ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
816ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (i = 0; i < TX_SIZE_CONTEXTS; i++) {
8175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      tx_counts_to_branch_counts_8x8(cm->counts.tx.p8x8[i], ct_8x8p);
818f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      for (j = 0; j < TX_SIZES - 3; j++)
8195ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vp9_cond_prob_diff_update(w, &cm->fc.tx_probs.p8x8[i][j], ct_8x8p[j]);
820ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
82191037db265ecdd914a26e056cf69207b4f50924ehkuang
822ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (i = 0; i < TX_SIZE_CONTEXTS; i++) {
8235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      tx_counts_to_branch_counts_16x16(cm->counts.tx.p16x16[i], ct_16x16p);
824f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      for (j = 0; j < TX_SIZES - 2; j++)
82591037db265ecdd914a26e056cf69207b4f50924ehkuang        vp9_cond_prob_diff_update(w, &cm->fc.tx_probs.p16x16[i][j],
8265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                  ct_16x16p[j]);
827ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
82891037db265ecdd914a26e056cf69207b4f50924ehkuang
829ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (i = 0; i < TX_SIZE_CONTEXTS; i++) {
83091037db265ecdd914a26e056cf69207b4f50924ehkuang      tx_counts_to_branch_counts_32x32(cm->counts.tx.p32x32[i], ct_32x32p);
831f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      for (j = 0; j < TX_SIZES - 1; j++)
83291037db265ecdd914a26e056cf69207b4f50924ehkuang        vp9_cond_prob_diff_update(w, &cm->fc.tx_probs.p32x32[i][j],
8335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                  ct_32x32p[j]);
834ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
835ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
836ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
837ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
8382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic void write_interp_filter(INTERP_FILTER filter,
8392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                                struct vp9_write_bit_buffer *wb) {
8402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  const int filter_to_literal[] = { 1, 0, 2, 3 };
8411184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
8422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  vp9_wb_write_bit(wb, filter == SWITCHABLE);
8432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  if (filter != SWITCHABLE)
8442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    vp9_wb_write_literal(wb, filter_to_literal[filter], 2);
845ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
846ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
8472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic void fix_interp_filter(VP9_COMMON *cm) {
8482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  if (cm->interp_filter == SWITCHABLE) {
849ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Check to see if only one of the filters is actually used
8501184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    int count[SWITCHABLE_FILTERS];
851ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int i, j, c = 0;
8521184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
853ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      count[i] = 0;
8545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j)
85591037db265ecdd914a26e056cf69207b4f50924ehkuang        count[i] += cm->counts.switchable_interp[j][i];
856ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      c += (count[i] > 0);
857ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
858ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (c == 1) {
859ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // Only one filter is used. So set the filter at frame level
8601184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
861ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        if (count[i]) {
8622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          cm->interp_filter = i;
863ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          break;
864ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
865ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
866ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
867ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
868ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
869ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
870ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic void write_tile_info(const VP9_COMMON *const cm,
871ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                            struct vp9_write_bit_buffer *wb) {
87291037db265ecdd914a26e056cf69207b4f50924ehkuang  int min_log2_tile_cols, max_log2_tile_cols, ones;
87391037db265ecdd914a26e056cf69207b4f50924ehkuang  vp9_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols);
874ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
87591037db265ecdd914a26e056cf69207b4f50924ehkuang  // columns
87691037db265ecdd914a26e056cf69207b4f50924ehkuang  ones = cm->log2_tile_cols - min_log2_tile_cols;
87791037db265ecdd914a26e056cf69207b4f50924ehkuang  while (ones--)
87891037db265ecdd914a26e056cf69207b4f50924ehkuang    vp9_wb_write_bit(wb, 1);
87991037db265ecdd914a26e056cf69207b4f50924ehkuang
88091037db265ecdd914a26e056cf69207b4f50924ehkuang  if (cm->log2_tile_cols < max_log2_tile_cols)
88191037db265ecdd914a26e056cf69207b4f50924ehkuang    vp9_wb_write_bit(wb, 0);
88291037db265ecdd914a26e056cf69207b4f50924ehkuang
88391037db265ecdd914a26e056cf69207b4f50924ehkuang  // rows
884ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_wb_write_bit(wb, cm->log2_tile_rows != 0);
885ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (cm->log2_tile_rows != 0)
886ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_wb_write_bit(wb, cm->log2_tile_rows != 1);
887ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
888ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
889ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int get_refresh_mask(VP9_COMP *cpi) {
890ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (vp9_preserve_existing_gf(cpi)) {
891ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // We have decided to preserve the previously existing golden frame as our
892ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // new ARF frame. However, in the short term we leave it in the GF slot and,
893ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // if we're updating the GF with the current decoded frame, we save it
894ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // instead to the ARF slot.
895ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // Later, in the function vp9_encoder.c:vp9_update_reference_frames() we
896ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // will swap gld_fb_idx and alt_fb_idx to achieve our objective. We do it
897ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // there so that it can be done outside of the recode loop.
898ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // Note: This is highly specific to the use of ARF as a forward reference,
899ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // and this needs to be generalized as other uses are implemented
900ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // (like RTC/temporal scalability).
901ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return (cpi->refresh_last_frame << cpi->lst_fb_idx) |
902ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian           (cpi->refresh_golden_frame << cpi->alt_fb_idx);
903ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  } else {
904ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int arf_idx = cpi->alt_fb_idx;
905ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if ((cpi->oxcf.pass == 2) && cpi->multi_arf_allowed) {
906ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
907ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      arf_idx = gf_group->arf_update_idx[gf_group->index];
908ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
909ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return (cpi->refresh_last_frame << cpi->lst_fb_idx) |
910ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian           (cpi->refresh_golden_frame << cpi->gld_fb_idx) |
911ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian           (cpi->refresh_alt_ref_frame << arf_idx);
912ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
913ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
914ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
91591037db265ecdd914a26e056cf69207b4f50924ehkuangstatic size_t encode_tiles(VP9_COMP *cpi, uint8_t *data_ptr) {
91691037db265ecdd914a26e056cf69207b4f50924ehkuang  VP9_COMMON *const cm = &cpi->common;
91791037db265ecdd914a26e056cf69207b4f50924ehkuang  vp9_writer residual_bc;
91891037db265ecdd914a26e056cf69207b4f50924ehkuang
91991037db265ecdd914a26e056cf69207b4f50924ehkuang  int tile_row, tile_col;
92091037db265ecdd914a26e056cf69207b4f50924ehkuang  TOKENEXTRA *tok[4][1 << 6], *tok_end;
92191037db265ecdd914a26e056cf69207b4f50924ehkuang  size_t total_size = 0;
92291037db265ecdd914a26e056cf69207b4f50924ehkuang  const int tile_cols = 1 << cm->log2_tile_cols;
92391037db265ecdd914a26e056cf69207b4f50924ehkuang  const int tile_rows = 1 << cm->log2_tile_rows;
92491037db265ecdd914a26e056cf69207b4f50924ehkuang
9254fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang  vpx_memset(cm->above_seg_context, 0, sizeof(*cm->above_seg_context) *
92691037db265ecdd914a26e056cf69207b4f50924ehkuang             mi_cols_aligned_to_sb(cm->mi_cols));
92791037db265ecdd914a26e056cf69207b4f50924ehkuang
92891037db265ecdd914a26e056cf69207b4f50924ehkuang  tok[0][0] = cpi->tok;
92991037db265ecdd914a26e056cf69207b4f50924ehkuang  for (tile_row = 0; tile_row < tile_rows; tile_row++) {
93091037db265ecdd914a26e056cf69207b4f50924ehkuang    if (tile_row)
93191037db265ecdd914a26e056cf69207b4f50924ehkuang      tok[tile_row][0] = tok[tile_row - 1][tile_cols - 1] +
93291037db265ecdd914a26e056cf69207b4f50924ehkuang                         cpi->tok_count[tile_row - 1][tile_cols - 1];
93391037db265ecdd914a26e056cf69207b4f50924ehkuang
93491037db265ecdd914a26e056cf69207b4f50924ehkuang    for (tile_col = 1; tile_col < tile_cols; tile_col++)
93591037db265ecdd914a26e056cf69207b4f50924ehkuang      tok[tile_row][tile_col] = tok[tile_row][tile_col - 1] +
93691037db265ecdd914a26e056cf69207b4f50924ehkuang                                cpi->tok_count[tile_row][tile_col - 1];
93791037db265ecdd914a26e056cf69207b4f50924ehkuang  }
93891037db265ecdd914a26e056cf69207b4f50924ehkuang
93991037db265ecdd914a26e056cf69207b4f50924ehkuang  for (tile_row = 0; tile_row < tile_rows; tile_row++) {
94091037db265ecdd914a26e056cf69207b4f50924ehkuang    for (tile_col = 0; tile_col < tile_cols; tile_col++) {
9415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      TileInfo tile;
9425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
9439b35249446b07f40ac5fcc3205f2c048616efacchkuang      vp9_tile_init(&tile, cm, tile_row, tile_col);
94491037db265ecdd914a26e056cf69207b4f50924ehkuang      tok_end = tok[tile_row][tile_col] + cpi->tok_count[tile_row][tile_col];
94591037db265ecdd914a26e056cf69207b4f50924ehkuang
94691037db265ecdd914a26e056cf69207b4f50924ehkuang      if (tile_col < tile_cols - 1 || tile_row < tile_rows - 1)
94791037db265ecdd914a26e056cf69207b4f50924ehkuang        vp9_start_encode(&residual_bc, data_ptr + total_size + 4);
94891037db265ecdd914a26e056cf69207b4f50924ehkuang      else
94991037db265ecdd914a26e056cf69207b4f50924ehkuang        vp9_start_encode(&residual_bc, data_ptr + total_size);
95091037db265ecdd914a26e056cf69207b4f50924ehkuang
9515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      write_modes(cpi, &tile, &residual_bc, &tok[tile_row][tile_col], tok_end);
95291037db265ecdd914a26e056cf69207b4f50924ehkuang      assert(tok[tile_row][tile_col] == tok_end);
95391037db265ecdd914a26e056cf69207b4f50924ehkuang      vp9_stop_encode(&residual_bc);
95491037db265ecdd914a26e056cf69207b4f50924ehkuang      if (tile_col < tile_cols - 1 || tile_row < tile_rows - 1) {
95591037db265ecdd914a26e056cf69207b4f50924ehkuang        // size of this tile
9562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        mem_put_be32(data_ptr + total_size, residual_bc.pos);
95791037db265ecdd914a26e056cf69207b4f50924ehkuang        total_size += 4;
95891037db265ecdd914a26e056cf69207b4f50924ehkuang      }
95991037db265ecdd914a26e056cf69207b4f50924ehkuang
96091037db265ecdd914a26e056cf69207b4f50924ehkuang      total_size += residual_bc.pos;
96191037db265ecdd914a26e056cf69207b4f50924ehkuang    }
96291037db265ecdd914a26e056cf69207b4f50924ehkuang  }
96391037db265ecdd914a26e056cf69207b4f50924ehkuang
96491037db265ecdd914a26e056cf69207b4f50924ehkuang  return total_size;
96591037db265ecdd914a26e056cf69207b4f50924ehkuang}
96691037db265ecdd914a26e056cf69207b4f50924ehkuang
9672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic void write_display_size(const VP9_COMMON *cm,
9682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                               struct vp9_write_bit_buffer *wb) {
969ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int scaling_active = cm->width != cm->display_width ||
970ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                             cm->height != cm->display_height;
971ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_wb_write_bit(wb, scaling_active);
972ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (scaling_active) {
973ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_wb_write_literal(wb, cm->display_width - 1, 16);
974ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_wb_write_literal(wb, cm->display_height - 1, 16);
975ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
976ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
977ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
9782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic void write_frame_size(const VP9_COMMON *cm,
979ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                             struct vp9_write_bit_buffer *wb) {
980ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_wb_write_literal(wb, cm->width - 1, 16);
981ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_wb_write_literal(wb, cm->height - 1, 16);
982ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
9832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  write_display_size(cm, wb);
984ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
985ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
986ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void write_frame_size_with_refs(VP9_COMP *cpi,
987ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       struct vp9_write_bit_buffer *wb) {
988ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  VP9_COMMON *const cm = &cpi->common;
9892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  int found = 0;
990ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
9912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  MV_REFERENCE_FRAME ref_frame;
9922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
9932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, ref_frame);
994ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    found = cm->width == cfg->y_crop_width &&
995ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            cm->height == cfg->y_crop_height;
9961184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
997ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // Set "found" to 0 for temporal svc and for spatial svc key frame
998ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (cpi->use_svc &&
999ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        (cpi->svc.number_spatial_layers == 1 ||
1000ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian         cpi->svc.layer_context[cpi->svc.spatial_layer_id].is_key_frame)) {
10011184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      found = 0;
10021184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    }
1003ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_wb_write_bit(wb, found);
10041184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    if (found) {
1005ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
10061184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    }
1007ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1008ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1009ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!found) {
1010ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_wb_write_literal(wb, cm->width - 1, 16);
1011ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_wb_write_literal(wb, cm->height - 1, 16);
1012ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1013ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
10142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  write_display_size(cm, wb);
1015ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1016ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1017ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void write_sync_code(struct vp9_write_bit_buffer *wb) {
10185ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vp9_wb_write_literal(wb, VP9_SYNC_CODE_0, 8);
10195ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vp9_wb_write_literal(wb, VP9_SYNC_CODE_1, 8);
10205ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vp9_wb_write_literal(wb, VP9_SYNC_CODE_2, 8);
1021ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1022ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
10234fb68e5dd4e93c7599dc905d861de11ac39c5585hkuangstatic void write_profile(BITSTREAM_PROFILE profile,
10244fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang                          struct vp9_write_bit_buffer *wb) {
1025ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  switch (profile) {
1026ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    case PROFILE_0:
1027ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      vp9_wb_write_literal(wb, 0, 2);
1028ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      break;
1029ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    case PROFILE_1:
1030ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      vp9_wb_write_literal(wb, 2, 2);
1031ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      break;
1032ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    case PROFILE_2:
1033ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      vp9_wb_write_literal(wb, 1, 2);
1034ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      break;
1035ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    case PROFILE_3:
1036ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      vp9_wb_write_literal(wb, 6, 3);
1037ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      break;
1038ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    default:
1039ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      assert(0);
1040ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1041ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1042ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1043ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic void write_bitdepth_colorspace_sampling(
1044ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    VP9_COMMON *const cm, struct vp9_write_bit_buffer *wb) {
1045ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (cm->profile >= PROFILE_2) {
1046ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    assert(cm->bit_depth > BITS_8);
1047ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    vp9_wb_write_bit(wb, cm->bit_depth - BITS_10);
1048ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1049ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  vp9_wb_write_literal(wb, cm->color_space, 3);
1050ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (cm->color_space != SRGB) {
1051ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    vp9_wb_write_bit(wb, 0);  // 0: [16, 235] (i.e. xvYCC), 1: [0, 255]
1052ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (cm->profile == PROFILE_1 || cm->profile == PROFILE_3) {
1053ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      assert(cm->subsampling_x != 1 || cm->subsampling_y != 1);
1054ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      vp9_wb_write_bit(wb, cm->subsampling_x);
1055ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      vp9_wb_write_bit(wb, cm->subsampling_y);
1056ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      vp9_wb_write_bit(wb, 0);  // unused
1057ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    } else {
1058ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      assert(cm->subsampling_x == 1 && cm->subsampling_y == 1);
1059ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
1060ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  } else {
1061ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    assert(cm->profile == PROFILE_1 || cm->profile == PROFILE_3);
1062ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    vp9_wb_write_bit(wb, 0);  // unused
1063ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
10644fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang}
10654fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang
1066ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void write_uncompressed_header(VP9_COMP *cpi,
1067ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                      struct vp9_write_bit_buffer *wb) {
1068ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  VP9_COMMON *const cm = &cpi->common;
1069ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
10705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vp9_wb_write_literal(wb, VP9_FRAME_MARKER, 2);
1071ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
10724fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang  write_profile(cm->profile, wb);
1073ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
10744fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang  vp9_wb_write_bit(wb, 0);  // show_existing_frame
1075ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_wb_write_bit(wb, cm->frame_type);
1076ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_wb_write_bit(wb, cm->show_frame);
1077ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_wb_write_bit(wb, cm->error_resilient_mode);
1078ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1079ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (cm->frame_type == KEY_FRAME) {
1080ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    write_sync_code(wb);
1081ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    write_bitdepth_colorspace_sampling(cm, wb);
10822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    write_frame_size(cm, wb);
1083ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else {
1084ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (!cm->show_frame)
1085ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      vp9_wb_write_bit(wb, cm->intra_only);
1086ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1087ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (!cm->error_resilient_mode)
1088ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      vp9_wb_write_literal(wb, cm->reset_frame_context, 2);
1089ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1090ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (cm->intra_only) {
1091ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      write_sync_code(wb);
1092ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1093ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      // Note for profile 0, 420 8bpp is assumed.
1094ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      if (cm->profile > PROFILE_0) {
1095ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        write_bitdepth_colorspace_sampling(cm, wb);
1096ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      }
1097ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
10982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      vp9_wb_write_literal(wb, get_refresh_mask(cpi), REF_FRAMES);
10992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      write_frame_size(cm, wb);
1100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
11012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      MV_REFERENCE_FRAME ref_frame;
11022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      vp9_wb_write_literal(wb, get_refresh_mask(cpi), REF_FRAMES);
11032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
11042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        vp9_wb_write_literal(wb, get_ref_frame_idx(cpi, ref_frame),
11052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                             REF_FRAMES_LOG2);
11062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        vp9_wb_write_bit(wb, cm->ref_frame_sign_bias[ref_frame]);
1107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
1108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1109ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      write_frame_size_with_refs(cpi, wb);
1110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      vp9_wb_write_bit(wb, cm->allow_high_precision_mv);
1112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      fix_interp_filter(cm);
11142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      write_interp_filter(cm->interp_filter, wb);
1115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
1116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!cm->error_resilient_mode) {
1119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_wb_write_bit(wb, cm->refresh_frame_context);
1120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_wb_write_bit(wb, cm->frame_parallel_decoding_mode);
1121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  vp9_wb_write_literal(wb, cm->frame_context_idx, FRAME_CONTEXTS_LOG2);
1124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11251184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  encode_loopfilter(&cm->lf, wb);
1126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  encode_quantization(cm, wb);
1127ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  encode_segmentation(cm, &cpi->mb.e_mbd, wb);
1128ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  write_tile_info(cm, wb);
1130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
113291037db265ecdd914a26e056cf69207b4f50924ehkuangstatic size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
113391037db265ecdd914a26e056cf69207b4f50924ehkuang  VP9_COMMON *const cm = &cpi->common;
1134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *const xd = &cpi->mb.e_mbd;
113591037db265ecdd914a26e056cf69207b4f50924ehkuang  FRAME_CONTEXT *const fc = &cm->fc;
113691037db265ecdd914a26e056cf69207b4f50924ehkuang  vp9_writer header_bc;
1137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
113891037db265ecdd914a26e056cf69207b4f50924ehkuang  vp9_start_encode(&header_bc, data);
1139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
114091037db265ecdd914a26e056cf69207b4f50924ehkuang  if (xd->lossless)
114191037db265ecdd914a26e056cf69207b4f50924ehkuang    cm->tx_mode = ONLY_4X4;
1142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  else
11432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    encode_txfm_probs(cm, &header_bc);
1144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  update_coef_probs(cpi, &header_bc);
11462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  update_skip_probs(cm, &header_bc);
1147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (!frame_is_intra_only(cm)) {
114991037db265ecdd914a26e056cf69207b4f50924ehkuang    int i;
1150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
11522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      prob_diff_update(vp9_inter_mode_tree, cm->fc.inter_mode_probs[i],
11532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                       cm->counts.inter_mode[i], INTER_MODES, &header_bc);
11542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
115591037db265ecdd914a26e056cf69207b4f50924ehkuang    vp9_zero(cm->counts.inter_mode);
1156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    if (cm->interp_filter == SWITCHABLE)
11582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      update_switchable_interp_probs(cm, &header_bc);
1159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (i = 0; i < INTRA_INTER_CONTEXTS; i++)
116191037db265ecdd914a26e056cf69207b4f50924ehkuang      vp9_cond_prob_diff_update(&header_bc, &fc->intra_inter_prob[i],
11622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                                cm->counts.intra_inter[i]);
1163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
116491037db265ecdd914a26e056cf69207b4f50924ehkuang    if (cm->allow_comp_inter_inter) {
11652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      const int use_compound_pred = cm->reference_mode != SINGLE_REFERENCE;
11662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      const int use_hybrid_pred = cm->reference_mode == REFERENCE_MODE_SELECT;
1167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      vp9_write_bit(&header_bc, use_compound_pred);
1169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (use_compound_pred) {
1170ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        vp9_write_bit(&header_bc, use_hybrid_pred);
117191037db265ecdd914a26e056cf69207b4f50924ehkuang        if (use_hybrid_pred)
1172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          for (i = 0; i < COMP_INTER_CONTEXTS; i++)
117391037db265ecdd914a26e056cf69207b4f50924ehkuang            vp9_cond_prob_diff_update(&header_bc, &fc->comp_inter_prob[i],
11742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                                      cm->counts.comp_inter[i]);
1175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
1176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
1177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    if (cm->reference_mode != COMPOUND_REFERENCE) {
1179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (i = 0; i < REF_CONTEXTS; i++) {
118091037db265ecdd914a26e056cf69207b4f50924ehkuang        vp9_cond_prob_diff_update(&header_bc, &fc->single_ref_prob[i][0],
11812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                                  cm->counts.single_ref[i][0]);
118291037db265ecdd914a26e056cf69207b4f50924ehkuang        vp9_cond_prob_diff_update(&header_bc, &fc->single_ref_prob[i][1],
11832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                                  cm->counts.single_ref[i][1]);
1184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
1185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
1186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    if (cm->reference_mode != SINGLE_REFERENCE)
1188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (i = 0; i < REF_CONTEXTS; i++)
118991037db265ecdd914a26e056cf69207b4f50924ehkuang        vp9_cond_prob_diff_update(&header_bc, &fc->comp_ref_prob[i],
11902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                                  cm->counts.comp_ref[i]);
1191ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    for (i = 0; i < BLOCK_SIZE_GROUPS; ++i)
11932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      prob_diff_update(vp9_intra_mode_tree, cm->fc.y_mode_prob[i],
11942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                       cm->counts.y_mode[i], INTRA_MODES, &header_bc);
1195ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    for (i = 0; i < PARTITION_CONTEXTS; ++i)
11972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      prob_diff_update(vp9_partition_tree, fc->partition_prob[i],
11982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                       cm->counts.partition[i], PARTITION_TYPES, &header_bc);
1199ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
12002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    vp9_write_nmv_probs(cm, cm->allow_high_precision_mv, &header_bc);
1201ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1202ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_stop_encode(&header_bc);
120491037db265ecdd914a26e056cf69207b4f50924ehkuang  assert(header_bc.pos <= 0xffff);
1205ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
120691037db265ecdd914a26e056cf69207b4f50924ehkuang  return header_bc.pos;
120791037db265ecdd914a26e056cf69207b4f50924ehkuang}
1208ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
12092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, size_t *size) {
121091037db265ecdd914a26e056cf69207b4f50924ehkuang  uint8_t *data = dest;
12114fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang  size_t first_part_size, uncompressed_hdr_size;
121291037db265ecdd914a26e056cf69207b4f50924ehkuang  struct vp9_write_bit_buffer wb = {data, 0};
121391037db265ecdd914a26e056cf69207b4f50924ehkuang  struct vp9_write_bit_buffer saved_wb;
1214ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
121591037db265ecdd914a26e056cf69207b4f50924ehkuang  write_uncompressed_header(cpi, &wb);
121691037db265ecdd914a26e056cf69207b4f50924ehkuang  saved_wb = wb;
121791037db265ecdd914a26e056cf69207b4f50924ehkuang  vp9_wb_write_literal(&wb, 0, 16);  // don't know in advance first part. size
1218ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1219ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uncompressed_hdr_size = vp9_wb_bytes_written(&wb);
12204fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang  data += uncompressed_hdr_size;
1221ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
12222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  vp9_clear_system_state();
122391037db265ecdd914a26e056cf69207b4f50924ehkuang
122491037db265ecdd914a26e056cf69207b4f50924ehkuang  first_part_size = write_compressed_header(cpi, data);
122591037db265ecdd914a26e056cf69207b4f50924ehkuang  data += first_part_size;
12262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  // TODO(jbb): Figure out what to do if first_part_size > 16 bits.
12272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  vp9_wb_write_literal(&saved_wb, (int)first_part_size, 16);
122891037db265ecdd914a26e056cf69207b4f50924ehkuang
122991037db265ecdd914a26e056cf69207b4f50924ehkuang  data += encode_tiles(cpi, data);
123091037db265ecdd914a26e056cf69207b4f50924ehkuang
123191037db265ecdd914a26e056cf69207b4f50924ehkuang  *size = data - dest;
1232ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1233