bitstream.c 188 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1
/*
Yaowu Xu's avatar
Yaowu Xu committed
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Jingning Han's avatar
Jingning Han committed
3
 *
Yaowu Xu's avatar
Yaowu Xu committed
4
5
6
7
8
9
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Jingning Han's avatar
Jingning Han committed
10
11
12
13
 */

#include <assert.h>
#include <limits.h>
14
#include <stdio.h>
Jingning Han's avatar
Jingning Han committed
15

Yaowu Xu's avatar
Yaowu Xu committed
16
#include "aom/aom_encoder.h"
17
#include "aom_dsp/bitwriter_buffer.h"
Yaowu Xu's avatar
Yaowu Xu committed
18
#include "aom_dsp/aom_dsp_common.h"
19
#include "aom_dsp/binary_codes_writer.h"
Yaowu Xu's avatar
Yaowu Xu committed
20
#include "aom_mem/aom_mem.h"
21
22
#include "aom_ports/mem_ops.h"
#include "aom_ports/system_state.h"
23
#if CONFIG_BITSTREAM_DEBUG
24
#include "aom_util/debug_util.h"
25
#endif  // CONFIG_BITSTREAM_DEBUG
Jingning Han's avatar
Jingning Han committed
26

27
#if CONFIG_CDEF
28
#include "av1/common/cdef.h"
29
#include "av1/common/clpf.h"
30
#endif  // CONFIG_CDEF
31
32
33
34
#include "av1/common/entropy.h"
#include "av1/common/entropymode.h"
#include "av1/common/entropymv.h"
#include "av1/common/mvref_common.h"
35
#include "av1/common/odintrin.h"
36
37
#include "av1/common/pred_common.h"
#include "av1/common/reconinter.h"
hui su's avatar
hui su committed
38
39
40
#if CONFIG_EXT_INTRA
#include "av1/common/reconintra.h"
#endif  // CONFIG_EXT_INTRA
41
42
#include "av1/common/seg_common.h"
#include "av1/common/tile_common.h"
Jingning Han's avatar
Jingning Han committed
43

Alex Converse's avatar
Alex Converse committed
44
#if CONFIG_ANS
Alex Converse's avatar
Alex Converse committed
45
#include "aom_dsp/buf_ans.h"
Alex Converse's avatar
Alex Converse committed
46
#endif  // CONFIG_ANS
Angie Chiang's avatar
Angie Chiang committed
47
48
49
#if CONFIG_LV_MAP
#include "av1/encoder/encodetxb.h"
#endif  // CONFIG_LV_MAP
50
51
52
53
#include "av1/encoder/bitstream.h"
#include "av1/encoder/cost.h"
#include "av1/encoder/encodemv.h"
#include "av1/encoder/mcomp.h"
hui su's avatar
hui su committed
54
55
56
#if CONFIG_PALETTE && CONFIG_PALETTE_DELTA_ENCODING
#include "av1/encoder/palette.h"
#endif  // CONFIG_PALETTE && CONFIG_PALETTE_DELTA_ENCODING
57
58
59
#include "av1/encoder/segmentation.h"
#include "av1/encoder/subexp.h"
#include "av1/encoder/tokenize.h"
60
61
62
#if CONFIG_PVQ
#include "av1/encoder/pvq_encoder.h"
#endif
Jingning Han's avatar
Jingning Han committed
63

64
65
static struct av1_token intra_mode_encodings[INTRA_MODES];
static struct av1_token switchable_interp_encodings[SWITCHABLE_FILTERS];
66
#if CONFIG_EXT_PARTITION_TYPES && !CONFIG_EC_MULTISYMBOL
Yaowu Xu's avatar
Yaowu Xu committed
67
static const struct av1_token ext_partition_encodings[EXT_PARTITION_TYPES] = {
68
69
70
  { 0, 1 },  { 4, 3 },  { 12, 4 }, { 7, 3 },
  { 10, 4 }, { 11, 4 }, { 26, 5 }, { 27, 5 }
};
71
#endif
72
static struct av1_token partition_encodings[PARTITION_TYPES];
73
#if !CONFIG_REF_MV
74
static struct av1_token inter_mode_encodings[INTER_MODES];
75
#endif
76
#if CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
77
static const struct av1_token
78
79
80
81
    inter_compound_mode_encodings[INTER_COMPOUND_MODES] = {
      { 2, 2 },  { 50, 6 }, { 51, 6 }, { 24, 5 }, { 52, 6 },
      { 53, 6 }, { 54, 6 }, { 55, 6 }, { 0, 1 },  { 7, 3 }
    };
82
#endif  // CONFIG_EXT_INTER
83
#if CONFIG_PALETTE
84
85
86
static struct av1_token palette_size_encodings[PALETTE_SIZES];
static struct av1_token palette_color_index_encodings[PALETTE_SIZES]
                                                     [PALETTE_COLORS];
87
#endif  // CONFIG_PALETTE
88
#if !CONFIG_EC_MULTISYMBOL
Jingning Han's avatar
Jingning Han committed
89
static const struct av1_token tx_size_encodings[MAX_TX_DEPTH][TX_SIZES] = {
90
91
92
  { { 0, 1 }, { 1, 1 } },                      // Max tx_size is 8X8
  { { 0, 1 }, { 2, 2 }, { 3, 2 } },            // Max tx_size is 16X16
  { { 0, 1 }, { 2, 2 }, { 6, 3 }, { 7, 3 } },  // Max tx_size is 32X32
93
94
95
#if CONFIG_TX64X64
  { { 0, 1 }, { 2, 2 }, { 6, 3 }, { 14, 4 }, { 15, 4 } },  // Max tx_size 64X64
#endif                                                     // CONFIG_TX64X64
96
};
97
#endif
98

99
#if CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
Yaowu Xu's avatar
Yaowu Xu committed
100
static INLINE void write_uniform(aom_writer *w, int n, int v) {
101
102
  const int l = get_unsigned_bits(n);
  const int m = (1 << l) - n;
103
  if (l == 0) return;
hui su's avatar
hui su committed
104
  if (v < m) {
Yaowu Xu's avatar
Yaowu Xu committed
105
    aom_write_literal(w, v, l - 1);
hui su's avatar
hui su committed
106
  } else {
Yaowu Xu's avatar
Yaowu Xu committed
107
108
    aom_write_literal(w, m + ((v - m) >> 1), l - 1);
    aom_write_literal(w, (v - m) & 1, 1);
hui su's avatar
hui su committed
109
110
  }
}
111
#endif  // CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
Jingning Han's avatar
Jingning Han committed
112

113
#if CONFIG_EXT_TX
Yaowu Xu's avatar
Yaowu Xu committed
114
115
static struct av1_token ext_tx_inter_encodings[EXT_TX_SETS_INTER][TX_TYPES];
static struct av1_token ext_tx_intra_encodings[EXT_TX_SETS_INTRA][TX_TYPES];
116
#else
Yaowu Xu's avatar
Yaowu Xu committed
117
static struct av1_token ext_tx_encodings[TX_TYPES];
118
#endif  // CONFIG_EXT_TX
119
#if CONFIG_GLOBAL_MOTION
120
static struct av1_token global_motion_types_encodings[GLOBAL_TRANS_TYPES];
121
#endif  // CONFIG_GLOBAL_MOTION
122
#if CONFIG_EXT_INTRA
hui su's avatar
hui su committed
123
#if CONFIG_INTRA_INTERP
Yaowu Xu's avatar
Yaowu Xu committed
124
static struct av1_token intra_filter_encodings[INTRA_FILTERS];
hui su's avatar
hui su committed
125
#endif  // CONFIG_INTRA_INTERP
126
#endif  // CONFIG_EXT_INTRA
127
#if CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
128
static struct av1_token interintra_mode_encodings[INTERINTRA_MODES];
129
static struct av1_token compound_type_encodings[COMPOUND_TYPES];
130
#endif  // CONFIG_EXT_INTER
Yue Chen's avatar
Yue Chen committed
131
132
133
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
static struct av1_token motion_mode_encodings[MOTION_MODES];
#endif  // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
134
135
136
#if CONFIG_LOOP_RESTORATION
static struct av1_token switchable_restore_encodings[RESTORE_SWITCHABLE_TYPES];
#endif  // CONFIG_LOOP_RESTORATION
137
138
139
static void write_uncompressed_header(AV1_COMP *cpi,
                                      struct aom_write_bit_buffer *wb);
static uint32_t write_compressed_header(AV1_COMP *cpi, uint8_t *data);
140
141
142
143
144
static int remux_tiles(const AV1_COMMON *const cm, uint8_t *dst,
                       const uint32_t data_size, const uint32_t max_tile_size,
                       const uint32_t max_tile_col_size,
                       int *const tile_size_bytes,
                       int *const tile_col_size_bytes);
145

Yaowu Xu's avatar
Yaowu Xu committed
146
void av1_encode_token_init(void) {
147
#if CONFIG_EXT_TX || CONFIG_PALETTE
148
  int s;
149
150
#endif  // CONFIG_EXT_TX || CONFIG_PALETTE
#if CONFIG_EXT_TX
151
  for (s = 1; s < EXT_TX_SETS_INTER; ++s) {
Yaowu Xu's avatar
Yaowu Xu committed
152
    av1_tokens_from_tree(ext_tx_inter_encodings[s], av1_ext_tx_inter_tree[s]);
153
154
  }
  for (s = 1; s < EXT_TX_SETS_INTRA; ++s) {
Yaowu Xu's avatar
Yaowu Xu committed
155
    av1_tokens_from_tree(ext_tx_intra_encodings[s], av1_ext_tx_intra_tree[s]);
156
  }
157
#else
Yaowu Xu's avatar
Yaowu Xu committed
158
  av1_tokens_from_tree(ext_tx_encodings, av1_ext_tx_tree);
159
#endif  // CONFIG_EXT_TX
160
161
162
163
164
165
166
  av1_tokens_from_tree(intra_mode_encodings, av1_intra_mode_tree);
  av1_tokens_from_tree(switchable_interp_encodings, av1_switchable_interp_tree);
  av1_tokens_from_tree(partition_encodings, av1_partition_tree);
#if !CONFIG_REF_MV
  av1_tokens_from_tree(inter_mode_encodings, av1_inter_mode_tree);
#endif

167
168
#if CONFIG_PALETTE
  av1_tokens_from_tree(palette_size_encodings, av1_palette_size_tree);
169
  for (s = 0; s < PALETTE_SIZES; ++s) {
170
171
    av1_tokens_from_tree(palette_color_index_encodings[s],
                         av1_palette_color_index_tree[s]);
172
173
174
  }
#endif  // CONFIG_PALETTE

175
#if CONFIG_EXT_INTRA && CONFIG_INTRA_INTERP
Yaowu Xu's avatar
Yaowu Xu committed
176
  av1_tokens_from_tree(intra_filter_encodings, av1_intra_filter_tree);
177
#endif  // CONFIG_EXT_INTRA && CONFIG_INTRA_INTERP
178
#if CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
179
  av1_tokens_from_tree(interintra_mode_encodings, av1_interintra_mode_tree);
180
  av1_tokens_from_tree(compound_type_encodings, av1_compound_type_tree);
181
#endif  // CONFIG_EXT_INTER
Yue Chen's avatar
Yue Chen committed
182
183
184
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
  av1_tokens_from_tree(motion_mode_encodings, av1_motion_mode_tree);
#endif  // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
185
#if CONFIG_GLOBAL_MOTION
Yaowu Xu's avatar
Yaowu Xu committed
186
187
  av1_tokens_from_tree(global_motion_types_encodings,
                       av1_global_motion_types_tree);
188
#endif  // CONFIG_GLOBAL_MOTION
189
190
191
192
#if CONFIG_LOOP_RESTORATION
  av1_tokens_from_tree(switchable_restore_encodings,
                       av1_switchable_restore_tree);
#endif  // CONFIG_LOOP_RESTORATION
193

194
#if CONFIG_EC_MULTISYMBOL
195
  /* This hack is necessary when CONFIG_DUAL_FILTER is enabled because the five
196
197
198
      SWITCHABLE_FILTERS are not consecutive, e.g., 0, 1, 2, 3, 4, when doing
      an in-order traversal of the av1_switchable_interp_tree structure. */
  av1_indices_from_tree(av1_switchable_interp_ind, av1_switchable_interp_inv,
Jingning Han's avatar
Jingning Han committed
199
                        av1_switchable_interp_tree);
200
201
202
/* This hack is necessary because the four TX_TYPES are not consecutive,
    e.g., 0, 1, 2, 3, when doing an in-order traversal of the av1_ext_tx_tree
    structure. */
203
204
205
#if CONFIG_EXT_TX
  for (s = 1; s < EXT_TX_SETS_INTRA; ++s)
    av1_indices_from_tree(av1_ext_tx_intra_ind[s], av1_ext_tx_intra_inv[s],
Jingning Han's avatar
Jingning Han committed
206
                          av1_ext_tx_intra_tree[s]);
207
208
  for (s = 1; s < EXT_TX_SETS_INTER; ++s)
    av1_indices_from_tree(av1_ext_tx_inter_ind[s], av1_ext_tx_inter_inv[s],
Jingning Han's avatar
Jingning Han committed
209
                          av1_ext_tx_inter_tree[s]);
210
#else
Jingning Han's avatar
Jingning Han committed
211
  av1_indices_from_tree(av1_ext_tx_ind, av1_ext_tx_inv, av1_ext_tx_tree);
David Barker's avatar
David Barker committed
212
#endif
Jingning Han's avatar
Jingning Han committed
213
  av1_indices_from_tree(av1_intra_mode_ind, av1_intra_mode_inv,
214
                        av1_intra_mode_tree);
Jingning Han's avatar
Jingning Han committed
215
  av1_indices_from_tree(av1_inter_mode_ind, av1_inter_mode_inv,
216
                        av1_inter_mode_tree);
217
#endif
218
219
}

Jingning Han's avatar
Jingning Han committed
220
221
222
223
static void write_intra_mode_kf(const AV1_COMMON *cm, FRAME_CONTEXT *frame_ctx,
                                const MODE_INFO *mi, const MODE_INFO *above_mi,
                                const MODE_INFO *left_mi, int block,
                                PREDICTION_MODE mode, aom_writer *w) {
Alex Converse's avatar
Alex Converse committed
224
225
226
#if CONFIG_INTRABC
  assert(!is_intrabc_block(&mi->mbmi));
#endif  // CONFIG_INTRABC
Jingning Han's avatar
Jingning Han committed
227
228
229
230
231
232
233
234
235
236
#if CONFIG_EC_MULTISYMBOL
  aom_write_symbol(w, av1_intra_mode_ind[mode],
                   get_y_mode_cdf(frame_ctx, mi, above_mi, left_mi, block),
                   INTRA_MODES);
  (void)cm;
#else
  av1_write_token(w, av1_intra_mode_tree,
                  get_y_mode_probs(cm, mi, above_mi, left_mi, block),
                  &intra_mode_encodings[mode]);
  (void)frame_ctx;
237
#endif
Jingning Han's avatar
Jingning Han committed
238
}
Jingning Han's avatar
Jingning Han committed
239

240
#if CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
241
242
243
244
static void write_interintra_mode(aom_writer *w, INTERINTRA_MODE mode,
                                  const aom_prob *probs) {
  av1_write_token(w, av1_interintra_mode_tree, probs,
                  &interintra_mode_encodings[mode]);
245
246
247
}
#endif  // CONFIG_EXT_INTER

248
static void write_inter_mode(aom_writer *w, PREDICTION_MODE mode,
249
                             FRAME_CONTEXT *ec_ctx, const int16_t mode_ctx) {
250
#if CONFIG_REF_MV
251
  const int16_t newmv_ctx = mode_ctx & NEWMV_CTX_MASK;
252
  const aom_prob newmv_prob = ec_ctx->newmv_prob[newmv_ctx];
Yue Chen's avatar
Yue Chen committed
253

254
255
#define IS_NEWMV_MODE(mode) ((mode) == NEWMV)
  aom_write(w, !IS_NEWMV_MODE(mode), newmv_prob);
256

257
  if (!IS_NEWMV_MODE(mode)) {
258
    const int16_t zeromv_ctx = (mode_ctx >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
259
    const aom_prob zeromv_prob = ec_ctx->zeromv_prob[zeromv_ctx];
260
261
262
263
264
265

    if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET)) {
      assert(mode == ZEROMV);
      return;
    }

Yaowu Xu's avatar
Yaowu Xu committed
266
    aom_write(w, mode != ZEROMV, zeromv_prob);
267
268

    if (mode != ZEROMV) {
269
      int16_t refmv_ctx = (mode_ctx >> REFMV_OFFSET) & REFMV_CTX_MASK;
Yaowu Xu's avatar
Yaowu Xu committed
270
      aom_prob refmv_prob;
271

272
273
274
      if (mode_ctx & (1 << SKIP_NEARESTMV_OFFSET)) refmv_ctx = 6;
      if (mode_ctx & (1 << SKIP_NEARMV_OFFSET)) refmv_ctx = 7;
      if (mode_ctx & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) refmv_ctx = 8;
275

276
      refmv_prob = ec_ctx->refmv_prob[refmv_ctx];
Yaowu Xu's avatar
Yaowu Xu committed
277
      aom_write(w, mode != NEARESTMV, refmv_prob);
278
279
    }
  }
280
281
282
283

#undef IS_NEWMV_MODE

#else  // !CONFIG_REF_MV
Jingning Han's avatar
Jingning Han committed
284
  assert(is_inter_mode(mode));
285
#if CONFIG_EC_MULTISYMBOL
286
  aom_write_symbol(w, av1_inter_mode_ind[INTER_OFFSET(mode)],
287
                   ec_ctx->inter_mode_cdf[mode_ctx], INTER_MODES);
288
289
#else
  {
290
    const aom_prob *const inter_probs = ec_ctx->inter_mode_probs[mode_ctx];
291
292
293
294
    av1_write_token(w, av1_inter_mode_tree, inter_probs,
                    &inter_mode_encodings[INTER_OFFSET(mode)]);
  }
#endif
295
#endif
Jingning Han's avatar
Jingning Han committed
296
297
}

298
#if CONFIG_REF_MV
Yaowu Xu's avatar
Yaowu Xu committed
299
300
301
static void write_drl_idx(const AV1_COMMON *cm, const MB_MODE_INFO *mbmi,
                          const MB_MODE_INFO_EXT *mbmi_ext, aom_writer *w) {
  uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
302
303
304

  assert(mbmi->ref_mv_idx < 3);

305
306
307
#if CONFIG_EXT_INTER
  if (mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV) {
#else
308
  if (mbmi->mode == NEWMV) {
309
#endif
310
311
312
313
    int idx;
    for (idx = 0; idx < 2; ++idx) {
      if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
        uint8_t drl_ctx =
Yaowu Xu's avatar
Yaowu Xu committed
314
315
            av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
        aom_prob drl_prob = cm->fc->drl_prob[drl_ctx];
316

Yaowu Xu's avatar
Yaowu Xu committed
317
        aom_write(w, mbmi->ref_mv_idx != idx, drl_prob);
318
        if (mbmi->ref_mv_idx == idx) return;
319
      }
320
321
322
323
    }
    return;
  }

David Barker's avatar
David Barker committed
324
  if (have_nearmv_in_inter_mode(mbmi->mode)) {
325
326
327
328
329
    int idx;
    // TODO(jingning): Temporary solution to compensate the NEARESTMV offset.
    for (idx = 1; idx < 3; ++idx) {
      if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
        uint8_t drl_ctx =
Yaowu Xu's avatar
Yaowu Xu committed
330
331
            av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
        aom_prob drl_prob = cm->fc->drl_prob[drl_ctx];
332

Yaowu Xu's avatar
Yaowu Xu committed
333
        aom_write(w, mbmi->ref_mv_idx != (idx - 1), drl_prob);
334
        if (mbmi->ref_mv_idx == (idx - 1)) return;
335
      }
336
    }
337
    return;
338
339
340
341
  }
}
#endif

342
#if CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
343
static void write_inter_compound_mode(AV1_COMMON *cm, aom_writer *w,
344
345
                                      PREDICTION_MODE mode,
                                      const int16_t mode_ctx) {
Yaowu Xu's avatar
Yaowu Xu committed
346
  const aom_prob *const inter_compound_probs =
347
      cm->fc->inter_compound_mode_probs[mode_ctx];
348
349

  assert(is_inter_compound_mode(mode));
Yaowu Xu's avatar
Yaowu Xu committed
350
351
  av1_write_token(w, av1_inter_compound_mode_tree, inter_compound_probs,
                  &inter_compound_mode_encodings[INTER_COMPOUND_OFFSET(mode)]);
352
353
354
}
#endif  // CONFIG_EXT_INTER

Yaowu Xu's avatar
Yaowu Xu committed
355
static void encode_unsigned_max(struct aom_write_bit_buffer *wb, int data,
356
                                int max) {
Yaowu Xu's avatar
Yaowu Xu committed
357
  aom_wb_write_literal(wb, data, get_unsigned_bits(max));
Jingning Han's avatar
Jingning Han committed
358
359
}

360
361
#if !CONFIG_EC_ADAPT || \
    (CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION || CONFIG_EXT_INTER)
Yaowu Xu's avatar
Yaowu Xu committed
362
363
static void prob_diff_update(const aom_tree_index *tree,
                             aom_prob probs[/*n - 1*/],
364
                             const unsigned int counts[/*n - 1*/], int n,
365
                             int probwt, aom_writer *w) {
Jingning Han's avatar
Jingning Han committed
366
367
368
369
370
371
  int i;
  unsigned int branch_ct[32][2];

  // Assuming max number of probabilities <= 32
  assert(n <= 32);

Yaowu Xu's avatar
Yaowu Xu committed
372
  av1_tree_probs_from_distribution(tree, branch_ct, counts);
Jingning Han's avatar
Jingning Han committed
373
  for (i = 0; i < n - 1; ++i)
374
    av1_cond_prob_diff_update(w, &probs[i], branch_ct[i], probwt);
Jingning Han's avatar
Jingning Han committed
375
}
376
377
#endif

378
#if CONFIG_EXT_INTER || !CONFIG_EC_ADAPT
Yaowu Xu's avatar
Yaowu Xu committed
379
380
static int prob_diff_update_savings(const aom_tree_index *tree,
                                    aom_prob probs[/*n - 1*/],
381
382
                                    const unsigned int counts[/*n - 1*/], int n,
                                    int probwt) {
383
384
385
386
387
388
  int i;
  unsigned int branch_ct[32][2];
  int savings = 0;

  // Assuming max number of probabilities <= 32
  assert(n <= 32);
Yaowu Xu's avatar
Yaowu Xu committed
389
  av1_tree_probs_from_distribution(tree, branch_ct, counts);
390
  for (i = 0; i < n - 1; ++i) {
391
392
    savings +=
        av1_cond_prob_diff_update_savings(&probs[i], branch_ct[i], probwt);
393
394
395
  }
  return savings;
}
396
#endif  // CONFIG_EXT_INTER || !CONFIG_EC_ADAPT
397

398
#if CONFIG_VAR_TX
Yaowu Xu's avatar
Yaowu Xu committed
399
static void write_tx_size_vartx(const AV1_COMMON *cm, const MACROBLOCKD *xd,
400
                                const MB_MODE_INFO *mbmi, TX_SIZE tx_size,
401
402
                                int depth, int blk_row, int blk_col,
                                aom_writer *w) {
403
404
  const int tx_row = blk_row >> 1;
  const int tx_col = blk_col >> 1;
405
406
407
  const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0);
  const int max_blocks_wide = max_block_wide(xd, mbmi->sb_type, 0);

408
  int ctx = txfm_partition_context(xd->above_txfm_context + tx_col,
409
410
                                   xd->left_txfm_context + tx_row,
                                   mbmi->sb_type, tx_size);
411

412
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
413

Jingning Han's avatar
Jingning Han committed
414
  if (depth == MAX_VARTX_DEPTH) {
415
    txfm_partition_update(xd->above_txfm_context + tx_col,
416
                          xd->left_txfm_context + tx_row, tx_size, tx_size);
417
418
419
    return;
  }

420
  if (tx_size == mbmi->inter_tx_size[tx_row][tx_col]) {
Yaowu Xu's avatar
Yaowu Xu committed
421
    aom_write(w, 0, cm->fc->txfm_partition_prob[ctx]);
422
    txfm_partition_update(xd->above_txfm_context + tx_col,
423
                          xd->left_txfm_context + tx_row, tx_size, tx_size);
424
  } else {
425
426
    const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
    const int bsl = tx_size_wide_unit[sub_txs];
427
    int i;
428

Yaowu Xu's avatar
Yaowu Xu committed
429
    aom_write(w, 1, cm->fc->txfm_partition_prob[ctx]);
430

431
    if (tx_size == TX_8X8) {
432
      txfm_partition_update(xd->above_txfm_context + tx_col,
433
                            xd->left_txfm_context + tx_row, sub_txs, tx_size);
434
      return;
435
    }
436
437
438

    assert(bsl > 0);
    for (i = 0; i < 4; ++i) {
439
440
441
442
      int offsetr = blk_row + (i >> 1) * bsl;
      int offsetc = blk_col + (i & 0x01) * bsl;
      write_tx_size_vartx(cm, xd, mbmi, sub_txs, depth + 1, offsetr, offsetc,
                          w);
443
444
445
    }
  }
}
446

Yaowu Xu's avatar
Yaowu Xu committed
447
static void update_txfm_partition_probs(AV1_COMMON *cm, aom_writer *w,
448
                                        FRAME_COUNTS *counts, int probwt) {
449
450
  int k;
  for (k = 0; k < TXFM_PARTITION_CONTEXTS; ++k)
Yaowu Xu's avatar
Yaowu Xu committed
451
    av1_cond_prob_diff_update(w, &cm->fc->txfm_partition_prob[k],
452
                              counts->txfm_partition[k], probwt);
453
}
454
455
#endif

Yaowu Xu's avatar
Yaowu Xu committed
456
457
static void write_selected_tx_size(const AV1_COMMON *cm, const MACROBLOCKD *xd,
                                   aom_writer *w) {
458
459
  const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
  const BLOCK_SIZE bsize = mbmi->sb_type;
460
461
462
463
464
465
#if CONFIG_EC_ADAPT
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  (void)cm;
#else
  FRAME_CONTEXT *ec_ctx = cm->fc;
#endif
466
// For sub8x8 blocks the tx_size symbol does not need to be sent
467
#if CONFIG_CB4X4 && (CONFIG_VAR_TX || CONFIG_EXT_TX) && CONFIG_RECT_TX
468
469
  if (bsize > BLOCK_4X4) {
#else
470
  if (bsize >= BLOCK_8X8) {
471
#endif
472
473
474
475
476
477
    const TX_SIZE tx_size = mbmi->tx_size;
    const int is_inter = is_inter_block(mbmi);
    const int tx_size_ctx = get_tx_size_context(xd);
    const int tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
                                     : intra_tx_size_cat_lookup[bsize];
    const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
478
    const int depth = tx_size_to_depth(coded_tx_size);
479
#if CONFIG_EXT_TX && CONFIG_RECT_TX
480
    assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed(xd, mbmi)));
481
482
483
484
    assert(
        IMPLIES(is_rect_tx(tx_size), tx_size == max_txsize_rect_lookup[bsize]));
#endif  // CONFIG_EXT_TX && CONFIG_RECT_TX

485
#if CONFIG_EC_MULTISYMBOL
486
    aom_write_symbol(w, depth, ec_ctx->tx_size_cdf[tx_size_cat][tx_size_ctx],
487
488
                     tx_size_cat + 2);
#else
Yaowu Xu's avatar
Yaowu Xu committed
489
    av1_write_token(w, av1_tx_size_tree[tx_size_cat],
490
                    ec_ctx->tx_size_probs[tx_size_cat][tx_size_ctx],
491
                    &tx_size_encodings[tx_size_cat][depth]);
492
#endif
Jingning Han's avatar
Jingning Han committed
493
494
495
  }
}

496
#if CONFIG_REF_MV
Yaowu Xu's avatar
Yaowu Xu committed
497
static void update_inter_mode_probs(AV1_COMMON *cm, aom_writer *w,
498
499
                                    FRAME_COUNTS *counts) {
  int i;
500
501
502
503
504
#if CONFIG_TILE_GROUPS
  const int probwt = cm->num_tg;
#else
  const int probwt = 1;
#endif
505
  for (i = 0; i < NEWMV_MODE_CONTEXTS; ++i)
506
507
    av1_cond_prob_diff_update(w, &cm->fc->newmv_prob[i], counts->newmv_mode[i],
                              probwt);
508
  for (i = 0; i < ZEROMV_MODE_CONTEXTS; ++i)
Yaowu Xu's avatar
Yaowu Xu committed
509
    av1_cond_prob_diff_update(w, &cm->fc->zeromv_prob[i],
510
                              counts->zeromv_mode[i], probwt);
511
  for (i = 0; i < REFMV_MODE_CONTEXTS; ++i)
512
513
    av1_cond_prob_diff_update(w, &cm->fc->refmv_prob[i], counts->refmv_mode[i],
                              probwt);
514
  for (i = 0; i < DRL_MODE_CONTEXTS; ++i)
515
516
    av1_cond_prob_diff_update(w, &cm->fc->drl_prob[i], counts->drl_mode[i],
                              probwt);
517
518
519
}
#endif

520
#if CONFIG_EXT_INTER
521
522
static void update_inter_compound_mode_probs(AV1_COMMON *cm, int probwt,
                                             aom_writer *w) {
Yaowu Xu's avatar
Yaowu Xu committed
523
524
  const int savings_thresh = av1_cost_one(GROUP_DIFF_UPDATE_PROB) -
                             av1_cost_zero(GROUP_DIFF_UPDATE_PROB);
525
526
527
528
  int i;
  int savings = 0;
  int do_update = 0;
  for (i = 0; i < INTER_MODE_CONTEXTS; ++i) {
529
    savings += prob_diff_update_savings(
Yaowu Xu's avatar
Yaowu Xu committed
530
        av1_inter_compound_mode_tree, cm->fc->inter_compound_mode_probs[i],
531
        cm->counts.inter_compound_mode[i], INTER_COMPOUND_MODES, probwt);
532
533
  }
  do_update = savings > savings_thresh;
Yaowu Xu's avatar
Yaowu Xu committed
534
  aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
535
536
  if (do_update) {
    for (i = 0; i < INTER_MODE_CONTEXTS; ++i) {
537
      prob_diff_update(
Yaowu Xu's avatar
Yaowu Xu committed
538
          av1_inter_compound_mode_tree, cm->fc->inter_compound_mode_probs[i],
539
          cm->counts.inter_compound_mode[i], INTER_COMPOUND_MODES, probwt, w);
540
541
542
543
544
    }
  }
}
#endif  // CONFIG_EXT_INTER

Yaowu Xu's avatar
Yaowu Xu committed
545
546
static int write_skip(const AV1_COMMON *cm, const MACROBLOCKD *xd,
                      int segment_id, const MODE_INFO *mi, aom_writer *w) {
Jingning Han's avatar
Jingning Han committed
547
548
549
550
  if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
    return 1;
  } else {
    const int skip = mi->mbmi.skip;
Yaowu Xu's avatar
Yaowu Xu committed
551
    aom_write(w, skip, av1_get_skip_prob(cm, xd));
Jingning Han's avatar
Jingning Han committed
552
553
554
555
    return skip;
  }
}

Yue Chen's avatar
Yue Chen committed
556
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
557
static void write_motion_mode(const AV1_COMMON *cm, const MODE_INFO *mi,
Yue Chen's avatar
Yue Chen committed
558
                              aom_writer *w) {
559
560
561
562
563
564
  const MB_MODE_INFO *mbmi = &mi->mbmi;
  MOTION_MODE last_motion_mode_allowed = motion_mode_allowed(
#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
      0, cm->global_motion,
#endif  // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
      mi);
Yue Chen's avatar
Yue Chen committed
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581

  if (last_motion_mode_allowed == SIMPLE_TRANSLATION) return;
#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
  if (last_motion_mode_allowed == OBMC_CAUSAL) {
    aom_write(w, mbmi->motion_mode == OBMC_CAUSAL,
              cm->fc->obmc_prob[mbmi->sb_type]);
  } else {
#endif  // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
    av1_write_token(w, av1_motion_mode_tree,
                    cm->fc->motion_mode_prob[mbmi->sb_type],
                    &motion_mode_encodings[mbmi->motion_mode]);
#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
  }
#endif  // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
}
#endif  // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION

582
#if CONFIG_DELTA_Q
Thomas Davies's avatar
Thomas Davies committed
583
584
static void write_delta_qindex(const AV1_COMMON *cm, const MACROBLOCKD *xd,
                               int delta_qindex, aom_writer *w) {
585
586
  int sign = delta_qindex < 0;
  int abs = sign ? -delta_qindex : delta_qindex;
Thomas Davies's avatar
Thomas Davies committed
587
  int rem_bits, thr;
588
  int smallval = abs < DELTA_Q_SMALL ? 1 : 0;
Thomas Davies's avatar
Thomas Davies committed
589
590
591
592
593
594
595
#if CONFIG_EC_ADAPT
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  (void)cm;
#else
  FRAME_CONTEXT *ec_ctx = cm->fc;
  (void)xd;
#endif
596

Thomas Davies's avatar
Thomas Davies committed
597
598
599
600
601
#if CONFIG_EC_MULTISYMBOL
  aom_write_symbol(w, AOMMIN(abs, DELTA_Q_SMALL), ec_ctx->delta_q_cdf,
                   DELTA_Q_PROBS + 1);
#else
  int i = 0;
602
603
  while (i < DELTA_Q_SMALL && i <= abs) {
    int bit = (i < abs);
Thomas Davies's avatar
Thomas Davies committed
604
    aom_write(w, bit, ec_ctx->delta_q_prob[i]);
605
606
    i++;
  }
Thomas Davies's avatar
Thomas Davies committed
607
#endif
608
609
610
611
612
613

  if (!smallval) {
    rem_bits = OD_ILOG_NZ(abs - 1) - 1;
    thr = (1 << rem_bits) + 1;
    aom_write_literal(w, rem_bits, 3);
    aom_write_literal(w, abs - thr, rem_bits);
614
615
616
617
618
  }
  if (abs > 0) {
    aom_write_bit(w, sign);
  }
}
619

Thomas Davies's avatar
Thomas Davies committed
620
#if !CONFIG_EC_ADAPT
621
622
623
static void update_delta_q_probs(AV1_COMMON *cm, aom_writer *w,
                                 FRAME_COUNTS *counts) {
  int k;
624
625
626
627
628
#if CONFIG_TILE_GROUPS
  const int probwt = cm->num_tg;
#else
  const int probwt = 1;
#endif
Fangwen Fu's avatar
Fangwen Fu committed
629
630
631
#if CONFIG_EXT_DELTA_Q
  if (!cm->delta_q_present_flag) return;
#endif  // CONFIG_EXT_DELTA_Q
632
  for (k = 0; k < DELTA_Q_PROBS; ++k) {
633
634
    av1_cond_prob_diff_update(w, &cm->fc->delta_q_prob[k], counts->delta_q[k],
                              probwt);
635
636
  }
}
Thomas Davies's avatar
Thomas Davies committed
637
#endif  // CONFIG_EC_ADAPT
Fangwen Fu's avatar
Fangwen Fu committed
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693

#if CONFIG_EXT_DELTA_Q
static void write_delta_lflevel(const AV1_COMMON *cm, const MACROBLOCKD *xd,
                                int delta_lflevel, aom_writer *w) {
  int sign = delta_lflevel < 0;
  int abs = sign ? -delta_lflevel : delta_lflevel;
  int rem_bits, thr;
  int smallval = abs < DELTA_LF_SMALL ? 1 : 0;
#if CONFIG_EC_ADAPT
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  (void)cm;
#else
  FRAME_CONTEXT *ec_ctx = cm->fc;
  (void)xd;
#endif

#if CONFIG_EC_MULTISYMBOL
  aom_write_symbol(w, AOMMIN(abs, DELTA_LF_SMALL), ec_ctx->delta_lf_cdf,
                   DELTA_LF_PROBS + 1);
#else
  int i = 0;
  while (i < DELTA_LF_SMALL && i <= abs) {
    int bit = (i < abs);
    aom_write(w, bit, ec_ctx->delta_lf_prob[i]);
    i++;
  }
#endif  // CONFIG_EC_MULTISYMBOL

  if (!smallval) {
    rem_bits = OD_ILOG_NZ(abs - 1) - 1;
    thr = (1 << rem_bits) + 1;
    aom_write_literal(w, rem_bits, 3);
    aom_write_literal(w, abs - thr, rem_bits);
  }
  if (abs > 0) {
    aom_write_bit(w, sign);
  }
}

#if !CONFIG_EC_ADAPT
static void update_delta_lf_probs(AV1_COMMON *cm, aom_writer *w,
                                  FRAME_COUNTS *counts) {
  int k;
#if CONFIG_TILE_GROUPS
  const int probwt = cm->num_tg;
#else
  const int probwt = 1;
#endif
  if (!cm->delta_lf_present_flag) return;
  for (k = 0; k < DELTA_LF_PROBS; ++k) {
    av1_cond_prob_diff_update(w, &cm->fc->delta_lf_prob[k], counts->delta_lf[k],
                              probwt);
  }
}
#endif  // CONFIG_EC_ADAPT
#endif  // CONFIG_EXT_DELTA_Q
Thomas Davies's avatar
Thomas Davies committed
694
#endif  // CONFIG_DELTA_Q
695

Yaowu Xu's avatar
Yaowu Xu committed
696
static void update_skip_probs(AV1_COMMON *cm, aom_writer *w,
Jingning Han's avatar
Jingning Han committed
697
698
                              FRAME_COUNTS *counts) {
  int k;
699
700
701
702
703
704
705
706
707
#if CONFIG_TILE_GROUPS
  const int probwt = cm->num_tg;
#else
  const int probwt = 1;
#endif
  for (k = 0; k < SKIP_CONTEXTS; ++k) {
    av1_cond_prob_diff_update(w, &cm->fc->skip_probs[k], counts->skip[k],
                              probwt);
  }
Jingning Han's avatar
Jingning Han committed
708
709
}

710
#if !CONFIG_EC_ADAPT
Yaowu Xu's avatar
Yaowu Xu committed
711
static void update_switchable_interp_probs(AV1_COMMON *cm, aom_writer *w,
Jingning Han's avatar
Jingning Han committed
712
713
                                           FRAME_COUNTS *counts) {
  int j;
714
  for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j) {
715
716
717
718
719
720
721
722
#if CONFIG_TILE_GROUPS
    const int probwt = cm->num_tg;
#else
    const int probwt = 1;
#endif
    prob_diff_update(
        av1_switchable_interp_tree, cm->fc->switchable_interp_prob[j],
        counts->switchable_interp[j], SWITCHABLE_FILTERS, probwt, w);
723
  }
Jingning Han's avatar
Jingning Han committed
724
}
725
#endif
Jingning Han's avatar
Jingning Han committed
726

727
#if !CONFIG_EC_ADAPT
728
#if CONFIG_EXT_TX
Yaowu Xu's avatar
Yaowu Xu committed
729
730
731
static void update_ext_tx_probs(AV1_COMMON *cm, aom_writer *w) {
  const int savings_thresh = av1_cost_one(GROUP_DIFF_UPDATE_PROB) -
                             av1_cost_zero(GROUP_DIFF_UPDATE_PROB);
732
  int i, j;
733
  int s;
734
735
736
737
738
#if CONFIG_TILE_GROUPS
  const int probwt = cm->num_tg;
#else
  const int probwt = 1;
#endif
739
740
741
742
  for (s = 1; s < EXT_TX_SETS_INTER; ++s) {
    int savings = 0;
    int do_update = 0;
    for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
743
      if (!use_inter_ext_tx_for_txsize[s][i]) continue;
744
      savings += prob_diff_update_savings(
Yaowu Xu's avatar
Yaowu Xu committed
745
          av1_ext_tx_inter_tree[s], cm->fc->inter_ext_tx_prob[s][i],
746
747
          cm->counts.inter_ext_tx[s][i],
          num_ext_tx_set[ext_tx_set_type_inter[s]], probwt);
748
749
    }
    do_update = savings > savings_thresh;
Yaowu Xu's avatar
Yaowu Xu committed
750
    aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
751
752
    if (do_update) {
      for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
753
        if (!use_inter_ext_tx_for_txsize[s][i]) continue;
754
755
756
757
        prob_diff_update(av1_ext_tx_inter_tree[s],
                         cm->fc->inter_ext_tx_prob[s][i],
                         cm->counts.inter_ext_tx[s][i],
                         num_ext_tx_set[ext_tx_set_type_inter[s]], probwt, w);
758
      }
759
760
    }
  }
761

762
763
764
765
  for (s = 1; s < EXT_TX_SETS_INTRA; ++s) {
    int savings = 0;
    int do_update = 0;
    for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
766
      if (!use_intra_ext_tx_for_txsize[s][i]) continue;
767
      for (j = 0; j < INTRA_MODES; ++j)
768
        savings += prob_diff_update_savings(
Yaowu Xu's avatar
Yaowu Xu committed
769
            av1_ext_tx_intra_tree[s], cm->fc->intra_ext_tx_prob[s][i][j],
770
771
            cm->counts.intra_ext_tx[s][i][j],
            num_ext_tx_set[ext_tx_set_type_intra[s]], probwt);
772
773
    }
    do_update = savings > savings_thresh;
Yaowu Xu's avatar
Yaowu Xu committed
774
    aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
775
776
    if (do_update) {
      for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
777
        if (!use_intra_ext_tx_for_txsize[s][i]) continue;
778
        for (j = 0; j < INTRA_MODES; ++j)
779
780
781
          prob_diff_update(av1_ext_tx_intra_tree[s],
                           cm->fc->intra_ext_tx_prob[s][i][j],
                           cm->counts.intra_ext_tx[s][i][j],
782
                           num_ext_tx_set[ext_tx_set_type_intra[s]], probwt, w);
783
784
      }
    }
785
  }
786
}
Debargha Mukherjee's avatar
Debargha Mukherjee committed
787

788
#else
Yaowu Xu's avatar
Yaowu Xu committed
789
790
791
static void update_ext_tx_probs(AV1_COMMON *cm, aom_writer *w) {
  const int savings_thresh = av1_cost_one(GROUP_DIFF_UPDATE_PROB) -
                             av1_cost_zero(GROUP_DIFF_UPDATE_PROB);
792
793
794
795
  int i, j;

  int savings = 0;
  int do_update = 0;
796
797
798
799
800
#if CONFIG_TILE_GROUPS
  const int probwt = cm->num_tg;
#else
  const int probwt = 1;
#endif
801
802
803
  for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
    for (j = 0; j < TX_TYPES; ++j)
      savings += prob_diff_update_savings(
Yaowu Xu's avatar
Yaowu Xu committed
804
          av1_ext_tx_tree, cm->fc->intra_ext_tx_prob[i][j],
805
          cm->counts.intra_ext_tx[i][j], TX_TYPES, probwt);
806
807
  }
  do_update = savings > savings_thresh;
Yaowu Xu's avatar
Yaowu Xu committed
808
  aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
809
810
  if (do_update) {
    for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
811
      for (j = 0; j < TX_TYPES; ++j) {
Yaowu Xu's avatar
Yaowu Xu committed
812
        prob_diff_update(av1_ext_tx_tree, cm->fc->intra_ext_tx_prob[i][j],
813
                         cm->counts.intra_ext_tx[i][j], TX_TYPES, probwt, w);
814
      }
815
816
    }
  }
817

818
819
  savings = 0;
  for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
820
    savings +=
Yaowu Xu's avatar
Yaowu Xu committed
821
        prob_diff_update_savings(av1_ext_tx_tree, cm->fc->inter_ext_tx_prob[i],
822
                                 cm->counts.inter_ext_tx[i], TX_TYPES, probwt);
823
824
  }
  do_update = savings > savings_thresh;
Yaowu Xu's avatar
Yaowu Xu committed
825
  aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
826
827
  if (do_update) {
    for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
Yaowu Xu's avatar
Yaowu Xu committed
828
      prob_diff_update(av1_ext_tx_tree, cm->fc->inter_ext_tx_prob[i],
829
                       cm->counts.inter_ext_tx[i], TX_TYPES, probwt, w);
830
831
832
    }
  }
}
833
#endif  // CONFIG_EXT_TX
834
#endif  // !CONFIG_EC_ADAPT
835
#if CONFIG_PALETTE
Yaowu Xu's avatar
Yaowu Xu committed
836
static void pack_palette_tokens(aom_writer *w, const TOKENEXTRA **tp, int n,
837
                                int num) {
hui su's avatar
hui su committed
838
  int i;
839
  const TOKENEXTRA *p = *tp;
hui su's avatar
hui su committed
840

841
  for (i = 0; i < num; ++i) {
842
843
844
    av1_write_token(
        w, av1_palette_color_index_tree[n - PALETTE_MIN_SIZE], p->context_tree,
        &palette_color_index_encodings[n - PALETTE_MIN_SIZE][p->token]);
hui su's avatar
hui su committed
845
846
847
848
849
    ++p;
  }

  *tp = p;
}
850
#endif  // CONFIG_PALETTE
851

852
#if !CONFIG_PVQ
853
#if CONFIG_SUPERTX
854
static void update_supertx_probs(AV1_COMMON *cm, int probwt, aom_writer *w) {
Yaowu Xu's avatar
Yaowu Xu committed
855
856
  const int savings_thresh = av1_cost_one(GROUP_DIFF_UPDATE_PROB) -
                             av1_cost_zero(GROUP_DIFF_UPDATE_PROB);
857
858
859
860
  int i, j;
  int savings = 0;
  int do_update = 0;
  for (i = 0; i < PARTITION_SUPERTX_CONTEXTS; ++i) {