bitstream.c 181 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_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
74
static const struct av1_token
75
    inter_compound_mode_encodings[INTER_COMPOUND_MODES] = {
76
77
      { 2, 2 },  { 12, 4 }, { 52, 6 }, { 53, 6 },
      { 54, 6 }, { 55, 6 }, { 0, 1 },  { 7, 3 }
78
    };
79
#endif  // CONFIG_EXT_INTER
80
#if CONFIG_PALETTE
81
82
83
static struct av1_token palette_size_encodings[PALETTE_SIZES];
static struct av1_token palette_color_index_encodings[PALETTE_SIZES]
                                                     [PALETTE_COLORS];
84
#endif  // CONFIG_PALETTE
85
#if !CONFIG_EC_MULTISYMBOL
Jingning Han's avatar
Jingning Han committed
86
static const struct av1_token tx_size_encodings[MAX_TX_DEPTH][TX_SIZES] = {
87
88
89
  { { 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
90
91
92
#if CONFIG_TX64X64
  { { 0, 1 }, { 2, 2 }, { 6, 3 }, { 14, 4 }, { 15, 4 } },  // Max tx_size 64X64
#endif                                                     // CONFIG_TX64X64
93
};
94
#endif
95

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

110
#if CONFIG_EXT_TX
Yaowu Xu's avatar
Yaowu Xu committed
111
112
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];
113
#else
Yaowu Xu's avatar
Yaowu Xu committed
114
static struct av1_token ext_tx_encodings[TX_TYPES];
115
#endif  // CONFIG_EXT_TX
116
#if CONFIG_GLOBAL_MOTION
117
static struct av1_token global_motion_types_encodings[GLOBAL_TRANS_TYPES];
118
#endif  // CONFIG_GLOBAL_MOTION
119
#if CONFIG_EXT_INTRA
hui su's avatar
hui su committed
120
#if CONFIG_INTRA_INTERP
Yaowu Xu's avatar
Yaowu Xu committed
121
static struct av1_token intra_filter_encodings[INTRA_FILTERS];
hui su's avatar
hui su committed
122
#endif  // CONFIG_INTRA_INTERP
123
#endif  // CONFIG_EXT_INTRA
124
#if CONFIG_EXT_INTER
125
#if CONFIG_INTERINTRA
Yaowu Xu's avatar
Yaowu Xu committed
126
static struct av1_token interintra_mode_encodings[INTERINTRA_MODES];
127
#endif
128
#if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
129
static struct av1_token compound_type_encodings[COMPOUND_TYPES];
130
#endif  // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
131
#endif  // CONFIG_EXT_INTER
Yue Chen's avatar
Yue Chen committed
132
133
134
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
static struct av1_token motion_mode_encodings[MOTION_MODES];
#endif  // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
135
136
137
#if CONFIG_LOOP_RESTORATION
static struct av1_token switchable_restore_encodings[RESTORE_SWITCHABLE_TYPES];
#endif  // CONFIG_LOOP_RESTORATION
138
139
140
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);
141
142
143
144
145
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);
146

Yaowu Xu's avatar
Yaowu Xu committed
147
void av1_encode_token_init(void) {
148
#if CONFIG_EXT_TX || CONFIG_PALETTE
149
  int s;
150
151
#endif  // CONFIG_EXT_TX || CONFIG_PALETTE
#if CONFIG_EXT_TX
152
  for (s = 1; s < EXT_TX_SETS_INTER; ++s) {
Yaowu Xu's avatar
Yaowu Xu committed
153
    av1_tokens_from_tree(ext_tx_inter_encodings[s], av1_ext_tx_inter_tree[s]);
154
155
  }
  for (s = 1; s < EXT_TX_SETS_INTRA; ++s) {
Yaowu Xu's avatar
Yaowu Xu committed
156
    av1_tokens_from_tree(ext_tx_intra_encodings[s], av1_ext_tx_intra_tree[s]);
157
  }
158
#else
Yaowu Xu's avatar
Yaowu Xu committed
159
  av1_tokens_from_tree(ext_tx_encodings, av1_ext_tx_tree);
160
#endif  // CONFIG_EXT_TX
161
162
163
164
  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);

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

173
#if CONFIG_EXT_INTRA && CONFIG_INTRA_INTERP
Yaowu Xu's avatar
Yaowu Xu committed
174
  av1_tokens_from_tree(intra_filter_encodings, av1_intra_filter_tree);
175
#endif  // CONFIG_EXT_INTRA && CONFIG_INTRA_INTERP
176
#if CONFIG_EXT_INTER
177
#if CONFIG_INTERINTRA
Yaowu Xu's avatar
Yaowu Xu committed
178
  av1_tokens_from_tree(interintra_mode_encodings, av1_interintra_mode_tree);
179
#endif  // CONFIG_INTERINTRA
180
#if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
181
  av1_tokens_from_tree(compound_type_encodings, av1_compound_type_tree);
182
#endif  // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
183
#endif  // CONFIG_EXT_INTER
Yue Chen's avatar
Yue Chen committed
184
185
186
#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
187
#if CONFIG_GLOBAL_MOTION
Yaowu Xu's avatar
Yaowu Xu committed
188
189
  av1_tokens_from_tree(global_motion_types_encodings,
                       av1_global_motion_types_tree);
190
#endif  // CONFIG_GLOBAL_MOTION
191
192
193
194
#if CONFIG_LOOP_RESTORATION
  av1_tokens_from_tree(switchable_restore_encodings,
                       av1_switchable_restore_tree);
#endif  // CONFIG_LOOP_RESTORATION
195

196
#if CONFIG_EC_MULTISYMBOL
197
  /* This hack is necessary when CONFIG_DUAL_FILTER is enabled because the five
198
199
200
      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
201
                        av1_switchable_interp_tree);
202
203
204
/* 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. */
205
206
207
#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
208
                          av1_ext_tx_intra_tree[s]);
209
210
  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
211
                          av1_ext_tx_inter_tree[s]);
212
#else
Jingning Han's avatar
Jingning Han committed
213
  av1_indices_from_tree(av1_ext_tx_ind, av1_ext_tx_inv, av1_ext_tx_tree);
David Barker's avatar
David Barker committed
214
#endif
Jingning Han's avatar
Jingning Han committed
215
  av1_indices_from_tree(av1_intra_mode_ind, av1_intra_mode_inv,
216
                        av1_intra_mode_tree);
Jingning Han's avatar
Jingning Han committed
217
  av1_indices_from_tree(av1_inter_mode_ind, av1_inter_mode_inv,
218
                        av1_inter_mode_tree);
219
#endif
220
221
}

Jingning Han's avatar
Jingning Han committed
222
223
224
225
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
226
227
228
#if CONFIG_INTRABC
  assert(!is_intrabc_block(&mi->mbmi));
#endif  // CONFIG_INTRABC
Jingning Han's avatar
Jingning Han committed
229
230
231
232
233
234
235
236
237
238
#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;
239
#endif
Jingning Han's avatar
Jingning Han committed
240
}
Jingning Han's avatar
Jingning Han committed
241

242
#if CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xu's avatar
Yaowu Xu committed
243
244
245
246
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]);
247
}
248
#endif  // CONFIG_EXT_INTER && CONFIG_INTERINTRA
249

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

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

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

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

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

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

273
274
275
      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;
276

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

#undef IS_NEWMV_MODE
Jingning Han's avatar
Jingning Han committed
283
284
}

Yaowu Xu's avatar
Yaowu Xu committed
285
286
287
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);
288
289
290

  assert(mbmi->ref_mv_idx < 3);

291
292
293
#if CONFIG_EXT_INTER
  if (mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV) {
#else
294
  if (mbmi->mode == NEWMV) {
295
#endif
296
297
298
299
    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
300
301
            av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
        aom_prob drl_prob = cm->fc->drl_prob[drl_ctx];
302

Yaowu Xu's avatar
Yaowu Xu committed
303
        aom_write(w, mbmi->ref_mv_idx != idx, drl_prob);
304
        if (mbmi->ref_mv_idx == idx) return;
305
      }
306
307
308
309
    }
    return;
  }

David Barker's avatar
David Barker committed
310
  if (have_nearmv_in_inter_mode(mbmi->mode)) {
311
312
313
314
315
    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
316
317
            av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
        aom_prob drl_prob = cm->fc->drl_prob[drl_ctx];
318

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

327
#if CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
328
static void write_inter_compound_mode(AV1_COMMON *cm, aom_writer *w,
329
330
                                      PREDICTION_MODE mode,
                                      const int16_t mode_ctx) {
Yaowu Xu's avatar
Yaowu Xu committed
331
  const aom_prob *const inter_compound_probs =
332
      cm->fc->inter_compound_mode_probs[mode_ctx];
333
334

  assert(is_inter_compound_mode(mode));
Yaowu Xu's avatar
Yaowu Xu committed
335
336
  av1_write_token(w, av1_inter_compound_mode_tree, inter_compound_probs,
                  &inter_compound_mode_encodings[INTER_COMPOUND_OFFSET(mode)]);
337
338
339
}
#endif  // CONFIG_EXT_INTER

Yaowu Xu's avatar
Yaowu Xu committed
340
static void encode_unsigned_max(struct aom_write_bit_buffer *wb, int data,
341
                                int max) {
Yaowu Xu's avatar
Yaowu Xu committed
342
  aom_wb_write_literal(wb, data, get_unsigned_bits(max));
Jingning Han's avatar
Jingning Han committed
343
344
}

345
346
#if !CONFIG_EC_ADAPT || \
    (CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION || CONFIG_EXT_INTER)
Yaowu Xu's avatar
Yaowu Xu committed
347
348
static void prob_diff_update(const aom_tree_index *tree,
                             aom_prob probs[/*n - 1*/],
349
                             const unsigned int counts[/*n - 1*/], int n,
350
                             int probwt, aom_writer *w) {
Jingning Han's avatar
Jingning Han committed
351
352
353
354
355
356
  int i;
  unsigned int branch_ct[32][2];

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

Yaowu Xu's avatar
Yaowu Xu committed
357
  av1_tree_probs_from_distribution(tree, branch_ct, counts);
Jingning Han's avatar
Jingning Han committed
358
  for (i = 0; i < n - 1; ++i)
359
    av1_cond_prob_diff_update(w, &probs[i], branch_ct[i], probwt);
Jingning Han's avatar
Jingning Han committed
360
}
361
362
#endif

363
#if CONFIG_EXT_INTER || !CONFIG_EC_ADAPT
Yaowu Xu's avatar
Yaowu Xu committed
364
365
static int prob_diff_update_savings(const aom_tree_index *tree,
                                    aom_prob probs[/*n - 1*/],
366
367
                                    const unsigned int counts[/*n - 1*/], int n,
                                    int probwt) {
368
369
370
371
372
373
  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
374
  av1_tree_probs_from_distribution(tree, branch_ct, counts);
375
  for (i = 0; i < n - 1; ++i) {
376
377
    savings +=
        av1_cond_prob_diff_update_savings(&probs[i], branch_ct[i], probwt);
378
379
380
  }
  return savings;
}
381
#endif  // CONFIG_EXT_INTER || !CONFIG_EC_ADAPT
382

383
#if CONFIG_VAR_TX
Yaowu Xu's avatar
Yaowu Xu committed
384
static void write_tx_size_vartx(const AV1_COMMON *cm, const MACROBLOCKD *xd,
385
                                const MB_MODE_INFO *mbmi, TX_SIZE tx_size,
386
387
                                int depth, int blk_row, int blk_col,
                                aom_writer *w) {
388
389
  const int tx_row = blk_row >> 1;
  const int tx_col = blk_col >> 1;
390
391
392
  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);

393
  int ctx = txfm_partition_context(xd->above_txfm_context + tx_col,
394
395
                                   xd->left_txfm_context + tx_row,
                                   mbmi->sb_type, tx_size);
396

397
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
398

Jingning Han's avatar
Jingning Han committed
399
  if (depth == MAX_VARTX_DEPTH) {
400
    txfm_partition_update(xd->above_txfm_context + tx_col,
401
                          xd->left_txfm_context + tx_row, tx_size, tx_size);
402
403
404
    return;
  }

405
  if (tx_size == mbmi->inter_tx_size[tx_row][tx_col]) {
Yaowu Xu's avatar
Yaowu Xu committed
406
    aom_write(w, 0, cm->fc->txfm_partition_prob[ctx]);
407
    txfm_partition_update(xd->above_txfm_context + tx_col,
408
                          xd->left_txfm_context + tx_row, tx_size, tx_size);
409
  } else {
410
411
    const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
    const int bsl = tx_size_wide_unit[sub_txs];
412
    int i;
413

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

416
    if (tx_size == TX_8X8) {
417
      txfm_partition_update(xd->above_txfm_context + tx_col,
418
                            xd->left_txfm_context + tx_row, sub_txs, tx_size);
419
      return;
420
    }
421
422
423

    assert(bsl > 0);
    for (i = 0; i < 4; ++i) {
424
425
426
427
      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);
428
429
430
    }
  }
}
431

Yaowu Xu's avatar
Yaowu Xu committed
432
static void update_txfm_partition_probs(AV1_COMMON *cm, aom_writer *w,
433
                                        FRAME_COUNTS *counts, int probwt) {
434
435
  int k;
  for (k = 0; k < TXFM_PARTITION_CONTEXTS; ++k)
Yaowu Xu's avatar
Yaowu Xu committed
436
    av1_cond_prob_diff_update(w, &cm->fc->txfm_partition_prob[k],
437
                              counts->txfm_partition[k], probwt);
438
}
439
440
#endif

Yaowu Xu's avatar
Yaowu Xu committed
441
442
static void write_selected_tx_size(const AV1_COMMON *cm, const MACROBLOCKD *xd,
                                   aom_writer *w) {
443
444
  const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
  const BLOCK_SIZE bsize = mbmi->sb_type;
445
446
447
448
449
450
#if CONFIG_EC_ADAPT
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  (void)cm;
#else
  FRAME_CONTEXT *ec_ctx = cm->fc;
#endif
451
// For sub8x8 blocks the tx_size symbol does not need to be sent
452
#if CONFIG_CB4X4 && (CONFIG_VAR_TX || CONFIG_EXT_TX) && CONFIG_RECT_TX
453
454
  if (bsize > BLOCK_4X4) {
#else
455
  if (bsize >= BLOCK_8X8) {
456
#endif
457
458
459
460
461
462
    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];
463
    const int depth = tx_size_to_depth(coded_tx_size);
464
#if CONFIG_EXT_TX && CONFIG_RECT_TX
465
    assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed(xd, mbmi)));
466
467
#endif  // CONFIG_EXT_TX && CONFIG_RECT_TX

468
#if CONFIG_EC_MULTISYMBOL
469
    aom_write_symbol(w, depth, ec_ctx->tx_size_cdf[tx_size_cat][tx_size_ctx],
470
471
                     tx_size_cat + 2);
#else
Yaowu Xu's avatar
Yaowu Xu committed
472
    av1_write_token(w, av1_tx_size_tree[tx_size_cat],
473
                    ec_ctx->tx_size_probs[tx_size_cat][tx_size_ctx],
474
                    &tx_size_encodings[tx_size_cat][depth]);
475
#endif
476
477
478
479
480
#if CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT
    if (is_quarter_tx_allowed(xd, mbmi, is_inter) && tx_size != coded_tx_size)
      aom_write(w, tx_size == quarter_txsize_lookup[bsize],
                cm->fc->quarter_tx_size_prob);
#endif  // CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT
Jingning Han's avatar
Jingning Han committed
481
482
483
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
484
static void update_inter_mode_probs(AV1_COMMON *cm, aom_writer *w,
485
486
                                    FRAME_COUNTS *counts) {
  int i;
487
488
489
490
491
#if CONFIG_TILE_GROUPS
  const int probwt = cm->num_tg;
#else
  const int probwt = 1;
#endif
492
  for (i = 0; i < NEWMV_MODE_CONTEXTS; ++i)
493
494
    av1_cond_prob_diff_update(w, &cm->fc->newmv_prob[i], counts->newmv_mode[i],
                              probwt);
495
  for (i = 0; i < ZEROMV_MODE_CONTEXTS; ++i)
Yaowu Xu's avatar
Yaowu Xu committed
496
    av1_cond_prob_diff_update(w, &cm->fc->zeromv_prob[i],
497
                              counts->zeromv_mode[i], probwt);
498
  for (i = 0; i < REFMV_MODE_CONTEXTS; ++i)
499
500
    av1_cond_prob_diff_update(w, &cm->fc->refmv_prob[i], counts->refmv_mode[i],
                              probwt);
501
  for (i = 0; i < DRL_MODE_CONTEXTS; ++i)
502
503
    av1_cond_prob_diff_update(w, &cm->fc->drl_prob[i], counts->drl_mode[i],
                              probwt);
504
505
}

506
#if CONFIG_EXT_INTER
507
508
static void update_inter_compound_mode_probs(AV1_COMMON *cm, int probwt,
                                             aom_writer *w) {
Yaowu Xu's avatar
Yaowu Xu committed
509
510
  const int savings_thresh = av1_cost_one(GROUP_DIFF_UPDATE_PROB) -
                             av1_cost_zero(GROUP_DIFF_UPDATE_PROB);
511
512
513
514
  int i;
  int savings = 0;
  int do_update = 0;
  for (i = 0; i < INTER_MODE_CONTEXTS; ++i) {
515
    savings += prob_diff_update_savings(
Yaowu Xu's avatar
Yaowu Xu committed
516
        av1_inter_compound_mode_tree, cm->fc->inter_compound_mode_probs[i],
517
        cm->counts.inter_compound_mode[i], INTER_COMPOUND_MODES, probwt);
518
519
  }
  do_update = savings > savings_thresh;
Yaowu Xu's avatar
Yaowu Xu committed
520
  aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
521
522
  if (do_update) {
    for (i = 0; i < INTER_MODE_CONTEXTS; ++i) {
523
      prob_diff_update(
Yaowu Xu's avatar
Yaowu Xu committed
524
          av1_inter_compound_mode_tree, cm->fc->inter_compound_mode_probs[i],
525
          cm->counts.inter_compound_mode[i], INTER_COMPOUND_MODES, probwt, w);
526
527
528
529
530
    }
  }
}
#endif  // CONFIG_EXT_INTER

Yaowu Xu's avatar
Yaowu Xu committed
531
532
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
533
534
535
536
  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
537
    aom_write(w, skip, av1_get_skip_prob(cm, xd));
Jingning Han's avatar
Jingning Han committed
538
539
540
541
    return skip;
  }
}

Yue Chen's avatar
Yue Chen committed
542
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
543
static void write_motion_mode(const AV1_COMMON *cm, const MODE_INFO *mi,
Yue Chen's avatar
Yue Chen committed
544
                              aom_writer *w) {
545
546
547
548
549
550
  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
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567

  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

568
#if CONFIG_DELTA_Q
Thomas Davies's avatar
Thomas Davies committed
569
570
static void write_delta_qindex(const AV1_COMMON *cm, const MACROBLOCKD *xd,
                               int delta_qindex, aom_writer *w) {
571
572
  int sign = delta_qindex < 0;
  int abs = sign ? -delta_qindex : delta_qindex;
Thomas Davies's avatar
Thomas Davies committed
573
  int rem_bits, thr;
574
  int smallval = abs < DELTA_Q_SMALL ? 1 : 0;
Thomas Davies's avatar
Thomas Davies committed
575
576
577
578
579
580
581
#if CONFIG_EC_ADAPT
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  (void)cm;
#else
  FRAME_CONTEXT *ec_ctx = cm->fc;
  (void)xd;
#endif
582

Thomas Davies's avatar
Thomas Davies committed
583
584
585
586
587
#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;
588
589
  while (i < DELTA_Q_SMALL && i <= abs) {
    int bit = (i < abs);
Thomas Davies's avatar
Thomas Davies committed
590
    aom_write(w, bit, ec_ctx->delta_q_prob[i]);
591
592
    i++;
  }
Thomas Davies's avatar
Thomas Davies committed
593
#endif
594
595
596
597
598
599

  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);
600
601
602
603
604
  }
  if (abs > 0) {
    aom_write_bit(w, sign);
  }
}
605

Thomas Davies's avatar
Thomas Davies committed
606
#if !CONFIG_EC_ADAPT
607
608
609
static void update_delta_q_probs(AV1_COMMON *cm, aom_writer *w,
                                 FRAME_COUNTS *counts) {
  int k;
610
611
612
613
614
#if CONFIG_TILE_GROUPS
  const int probwt = cm->num_tg;
#else
  const int probwt = 1;
#endif
Fangwen Fu's avatar
Fangwen Fu committed
615
616
617
#if CONFIG_EXT_DELTA_Q
  if (!cm->delta_q_present_flag) return;
#endif  // CONFIG_EXT_DELTA_Q
618
  for (k = 0; k < DELTA_Q_PROBS; ++k) {
619
620
    av1_cond_prob_diff_update(w, &cm->fc->delta_q_prob[k], counts->delta_q[k],
                              probwt);
621
622
  }
}
Thomas Davies's avatar
Thomas Davies committed
623
#endif  // CONFIG_EC_ADAPT
Fangwen Fu's avatar
Fangwen Fu committed
624
625
626
627
628
629
630
631
632
633
634
635
636
637
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

#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
680
#endif  // CONFIG_DELTA_Q
681

Yaowu Xu's avatar
Yaowu Xu committed
682
static void update_skip_probs(AV1_COMMON *cm, aom_writer *w,
Jingning Han's avatar
Jingning Han committed
683
684
                              FRAME_COUNTS *counts) {
  int k;
685
686
687
688
689
690
691
692
693
#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
694
695
}

696
#if !CONFIG_EC_ADAPT
Yaowu Xu's avatar
Yaowu Xu committed
697
static void update_switchable_interp_probs(AV1_COMMON *cm, aom_writer *w,
Jingning Han's avatar
Jingning Han committed
698
699
                                           FRAME_COUNTS *counts) {
  int j;
700
  for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j) {
701
702
703
704
705
706
707
708
#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);
709
  }
Jingning Han's avatar
Jingning Han committed
710
}
711
#endif
Jingning Han's avatar
Jingning Han committed
712

713
#if !CONFIG_EC_ADAPT
714
#if CONFIG_EXT_TX
Yaowu Xu's avatar
Yaowu Xu committed
715
716
717
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);
718
  int i, j;
719
  int s;
720
721
722
723
724
#if CONFIG_TILE_GROUPS
  const int probwt = cm->num_tg;
#else
  const int probwt = 1;
#endif
725
726
727
728
  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) {
729
      if (!use_inter_ext_tx_for_txsize[s][i]) continue;
730
      savings += prob_diff_update_savings(
Yaowu Xu's avatar
Yaowu Xu committed
731
          av1_ext_tx_inter_tree[s], cm->fc->inter_ext_tx_prob[s][i],
732
733
          cm->counts.inter_ext_tx[s][i],
          num_ext_tx_set[ext_tx_set_type_inter[s]], probwt);
734
735
    }
    do_update = savings > savings_thresh;
Yaowu Xu's avatar
Yaowu Xu committed
736
    aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
737
738
    if (do_update) {
      for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
739
        if (!use_inter_ext_tx_for_txsize[s][i]) continue;
740
741
742
743
        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);
744
      }
745
746
    }
  }
747

748
749
750
751
  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) {
752
      if (!use_intra_ext_tx_for_txsize[s][i]) continue;
753
      for (j = 0; j < INTRA_MODES; ++j)
754
        savings += prob_diff_update_savings(
Yaowu Xu's avatar
Yaowu Xu committed
755
            av1_ext_tx_intra_tree[s], cm->fc->intra_ext_tx_prob[s][i][j],
756
757
            cm->counts.intra_ext_tx[s][i][j],
            num_ext_tx_set[ext_tx_set_type_intra[s]], probwt);
758
759
    }
    do_update = savings > savings_thresh;
Yaowu Xu's avatar
Yaowu Xu committed
760
    aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
761
762
    if (do_update) {
      for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
763
        if (!use_intra_ext_tx_for_txsize[s][i]) continue;
764
        for (j = 0; j < INTRA_MODES; ++j)
765
766
767
          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],
768
                           num_ext_tx_set[ext_tx_set_type_intra[s]], probwt, w);
769
770
      }
    }
771
  }
772
}
Debargha Mukherjee's avatar
Debargha Mukherjee committed
773

774
#else
Yaowu Xu's avatar
Yaowu Xu committed
775
776
777
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);
778
779
780
781
  int i, j;

  int savings = 0;
  int do_update = 0;
782
783
784
785
786
#if CONFIG_TILE_GROUPS
  const int probwt = cm->num_tg;
#else
  const int probwt = 1;
#endif
787
788
789
  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
790
          av1_ext_tx_tree, cm->fc->intra_ext_tx_prob[i][j],
791
          cm->counts.intra_ext_tx[i][j], TX_TYPES, probwt);
792
793
  }
  do_update = savings > savings_thresh;
Yaowu Xu's avatar
Yaowu Xu committed
794
  aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
795
796
  if (do_update) {
    for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
797
      for (j = 0; j < TX_TYPES; ++j) {
Yaowu Xu's avatar
Yaowu Xu committed
798
        prob_diff_update(av1_ext_tx_tree, cm->fc->intra_ext_tx_prob[i][j],
799
                         cm->counts.intra_ext_tx[i][j], TX_TYPES, probwt, w);
800
      }
801
802
    }
  }
803

804
805
  savings = 0;
  for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
806
    savings +=
Yaowu Xu's avatar
Yaowu Xu committed
807
        prob_diff_update_savings(av1_ext_tx_tree, cm->fc->inter_ext_tx_prob[i],
808
                                 cm->counts.inter_ext_tx[i], TX_TYPES, probwt);
809
810
  }
  do_update = savings > savings_thresh;
Yaowu Xu's avatar
Yaowu Xu committed
811
  aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
812
813
  if (do_update) {
    for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
Yaowu Xu's avatar
Yaowu Xu committed
814
      prob_diff_update(av1_ext_tx_tree, cm->fc->inter_ext_tx_prob[i],
815
                       cm->counts.inter_ext_tx[i], TX_TYPES, probwt, w);
816
817
818
    }
  }
}
819
#endif  // CONFIG_EXT_TX
820
#endif  // !CONFIG_EC_ADAPT
821
#if CONFIG_PALETTE
Yaowu Xu's avatar
Yaowu Xu committed
822
static void pack_palette_tokens(aom_writer *w, const TOKENEXTRA **tp, int n,
823
                                int num) {
hui su's avatar
hui su committed
824
  int i;
825
  const TOKENEXTRA *p = *tp;
hui su's avatar
hui su committed
826

827
  for (i = 0; i < num; ++i) {
828
829
830
    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
831
832
833
834
835
    ++p;
  }

  *tp = p;
}
836
#endif  // CONFIG_PALETTE
837

838
#if !CONFIG_PVQ
839
#if CONFIG_SUPERTX
840
static void update_supertx_probs(AV1_COMMON *cm, int probwt, aom_writer *w) {
Yaowu Xu's avatar
Yaowu Xu committed
841
842
  const int savings_thresh = av1_cost_one(GROUP_DIFF_UPDATE_PROB) -
                             av1_cost_zero(GROUP_DIFF_UPDATE_PROB);
843
844
845
846
  int i, j;
  int savings = 0;
  int do_update = 0;
  for (i = 0; i < PARTITION_SUPERTX_CONTEXTS; ++i) {
Jingning Han's avatar
Jingning Han committed
847
    for (j = TX_8X8; j < TX_SIZES; ++j) {
848
849
      savings += av1_cond_prob_diff_update_savings(
          &cm->fc->supertx_prob[i][j], cm->counts.supertx[i][j], probwt);
850
851
852
    }
  }
  do_update = savings > savings_thresh;
Yaowu Xu's avatar
Yaowu Xu committed
853
  aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
854
855
  if (do_update) {
    for (i = 0; i < PARTITION_SUPERTX_CONTEXTS; ++i) {
Jingning Han's avatar
Jingning Han committed
856
      for (j = TX_8X8; j < TX_SIZES; ++j) {
Yaowu Xu's avatar
Yaowu Xu committed
857
        av1_cond_prob_diff_update(w, &cm->fc->supertx_prob[i][j],
858
                                  cm->counts.supertx[i][j], probwt);
859
860
861
862
863
864
      }
    }
  }
}
#endif  // CONFIG_SUPERTX

865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
#if CONFIG_NEW_MULTISYMBOL
static INLINE void write_coeff_extra(const aom_cdf_prob *const *cdf, int val,
                                     int n, aom_writer *w) {
  // Code the extra bits from LSB to MSB in groups of 4
  int i = 0;
  int count = 0;
  while (count < n) {
    const int size = AOMMIN(n - count, 4);
    const int mask = (1 << size) - 1;
    aom_write_cdf(w, val & mask, cdf[i++], 1 << size);
    val >>= size;
    count += size;
  }
}
#else
static INLINE void write_coeff_extra(const aom_prob *pb, int value,
                                     int num_bits, int skip_bits, aom_writer *w,
                                     TOKEN_STATS *token_stats) {
  // Code the extra bits from MSB to LSB 1 bit at a time
  int index;
  for (index = skip_bits; index < num_bits; ++index) {
    const int shift = num_bits - index - 1;
    const int bb = (value >> shift) & 1;
    aom_write_record(w, bb, pb[index], token_stats);
  }
}
#endif