bitstream.c 177 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
19
#include "aom_dsp/aom_dsp_common.h"
#include "aom_mem/aom_mem.h"
20
21
#include "aom_ports/mem_ops.h"
#include "aom_ports/system_state.h"
22
#if CONFIG_BITSTREAM_DEBUG
23
#include "aom_util/debug_util.h"
24
#endif  // CONFIG_BITSTREAM_DEBUG
Jingning Han's avatar
Jingning Han committed
25

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

Alex Converse's avatar
Alex Converse committed
45
#if CONFIG_ANS
Alex Converse's avatar
Alex Converse committed
46
#include "aom_dsp/buf_ans.h"
Alex Converse's avatar
Alex Converse committed
47
#endif  // CONFIG_ANS
48
49
50
51
52
53
54
#include "av1/encoder/bitstream.h"
#include "av1/encoder/cost.h"
#include "av1/encoder/encodemv.h"
#include "av1/encoder/mcomp.h"
#include "av1/encoder/segmentation.h"
#include "av1/encoder/subexp.h"
#include "av1/encoder/tokenize.h"
55
56
57
#if CONFIG_PVQ
#include "av1/encoder/pvq_encoder.h"
#endif
Jingning Han's avatar
Jingning Han committed
58

59
60
static struct av1_token intra_mode_encodings[INTRA_MODES];
static struct av1_token switchable_interp_encodings[SWITCHABLE_FILTERS];
61
#if CONFIG_EXT_PARTITION_TYPES
Yaowu Xu's avatar
Yaowu Xu committed
62
static const struct av1_token ext_partition_encodings[EXT_PARTITION_TYPES] = {
63
64
65
  { 0, 1 },  { 4, 3 },  { 12, 4 }, { 7, 3 },
  { 10, 4 }, { 11, 4 }, { 26, 5 }, { 27, 5 }
};
66
#endif
67
static struct av1_token partition_encodings[PARTITION_TYPES];
68
#if !CONFIG_REF_MV
69
static struct av1_token inter_mode_encodings[INTER_MODES];
70
#endif
71
#if CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
72
static const struct av1_token
73
74
75
76
    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 }
    };
77
#endif  // CONFIG_EXT_INTER
78
#if CONFIG_PALETTE
79
static struct av1_token palette_size_encodings[PALETTE_MAX_SIZE - 1];
80
81
static struct av1_token palette_color_index_encodings[PALETTE_MAX_SIZE - 1]
                                                     [PALETTE_MAX_SIZE];
82
#endif  // CONFIG_PALETTE
83
#if !CONFIG_EC_MULTISYMBOL
Jingning Han's avatar
Jingning Han committed
84
static const struct av1_token tx_size_encodings[MAX_TX_DEPTH][TX_SIZES] = {
85
86
87
  { { 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
88
89
90
#if CONFIG_TX64X64
  { { 0, 1 }, { 2, 2 }, { 6, 3 }, { 14, 4 }, { 15, 4 } },  // Max tx_size 64X64
#endif                                                     // CONFIG_TX64X64
91
};
92
#endif
93

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

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

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

162
163
164
#if CONFIG_PALETTE
  av1_tokens_from_tree(palette_size_encodings, av1_palette_size_tree);
  for (s = 0; s < PALETTE_MAX_SIZE - 1; ++s) {
165
166
    av1_tokens_from_tree(palette_color_index_encodings[s],
                         av1_palette_color_index_tree[s]);
167
168
169
  }
#endif  // CONFIG_PALETTE

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

191
#if CONFIG_EC_MULTISYMBOL
192
  /* This hack is necessary when CONFIG_DUAL_FILTER is enabled because the five
193
194
195
196
      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,
                        SWITCHABLE_FILTERS, av1_switchable_interp_tree);
197
198
199
/* 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. */
David Barker's avatar
David Barker committed
200
#if !CONFIG_EXT_TX
201
202
  av1_indices_from_tree(av1_ext_tx_ind, av1_ext_tx_inv, TX_TYPES,
                        av1_ext_tx_tree);
David Barker's avatar
David Barker committed
203
#endif
204
205
  av1_indices_from_tree(av1_intra_mode_ind, av1_intra_mode_inv, INTRA_MODES,
                        av1_intra_mode_tree);
206
207
  av1_indices_from_tree(av1_inter_mode_ind, av1_inter_mode_inv, INTER_MODES,
                        av1_inter_mode_tree);
208
#endif
209
210
}

211
#if !CONFIG_EC_MULTISYMBOL
Yaowu Xu's avatar
Yaowu Xu committed
212
213
214
static void write_intra_mode(aom_writer *w, PREDICTION_MODE mode,
                             const aom_prob *probs) {
  av1_write_token(w, av1_intra_mode_tree, probs, &intra_mode_encodings[mode]);
Jingning Han's avatar
Jingning Han committed
215
}
216
#endif
Jingning Han's avatar
Jingning Han committed
217

218
#if CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
219
220
221
222
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]);
223
224
225
}
#endif  // CONFIG_EXT_INTER

226
227
static void write_inter_mode(aom_writer *w, PREDICTION_MODE mode,
                             FRAME_CONTEXT *ec_ctx,
Yue Chen's avatar
Yue Chen committed
228
229
230
#if CONFIG_REF_MV && CONFIG_EXT_INTER
                             int is_compound,
#endif  // CONFIG_REF_MV && CONFIG_EXT_INTER
231
                             const int16_t mode_ctx) {
232
#if CONFIG_REF_MV
233
  const int16_t newmv_ctx = mode_ctx & NEWMV_CTX_MASK;
234
  const aom_prob newmv_prob = ec_ctx->newmv_prob[newmv_ctx];
Yue Chen's avatar
Yue Chen committed
235
#if CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
236
  aom_write(w, mode != NEWMV && mode != NEWFROMNEARMV, newmv_prob);
Yue Chen's avatar
Yue Chen committed
237
238

  if (!is_compound && (mode == NEWMV || mode == NEWFROMNEARMV))
239
    aom_write(w, mode == NEWFROMNEARMV, ec_ctx->new2mv_prob);
Yue Chen's avatar
Yue Chen committed
240
241
242

  if (mode != NEWMV && mode != NEWFROMNEARMV) {
#else
Yaowu Xu's avatar
Yaowu Xu committed
243
  aom_write(w, mode != NEWMV, newmv_prob);
244
245

  if (mode != NEWMV) {
Yue Chen's avatar
Yue Chen committed
246
#endif  // CONFIG_EXT_INTER
247
    const int16_t zeromv_ctx = (mode_ctx >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
248
    const aom_prob zeromv_prob = ec_ctx->zeromv_prob[zeromv_ctx];
249
250
251
252
253
254

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

Yaowu Xu's avatar
Yaowu Xu committed
255
    aom_write(w, mode != ZEROMV, zeromv_prob);
256
257

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

261
262
263
      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;
264

265
      refmv_prob = ec_ctx->refmv_prob[refmv_ctx];
Yaowu Xu's avatar
Yaowu Xu committed
266
      aom_write(w, mode != NEARESTMV, refmv_prob);
267
268
269
    }
  }
#else
Jingning Han's avatar
Jingning Han committed
270
  assert(is_inter_mode(mode));
271
#if CONFIG_EC_MULTISYMBOL
272
  aom_write_symbol(w, av1_inter_mode_ind[INTER_OFFSET(mode)],
273
                   ec_ctx->inter_mode_cdf[mode_ctx], INTER_MODES);
274
275
#else
  {
276
    const aom_prob *const inter_probs = ec_ctx->inter_mode_probs[mode_ctx];
277
278
279
280
    av1_write_token(w, av1_inter_mode_tree, inter_probs,
                    &inter_mode_encodings[INTER_OFFSET(mode)]);
  }
#endif
281
#endif
Jingning Han's avatar
Jingning Han committed
282
283
}

284
#if CONFIG_REF_MV
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
294
295
  if (mbmi->mode == NEWMV) {
    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
296
297
            av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
        aom_prob drl_prob = cm->fc->drl_prob[drl_ctx];
298

Yaowu Xu's avatar
Yaowu Xu committed
299
        aom_write(w, mbmi->ref_mv_idx != idx, drl_prob);
300
        if (mbmi->ref_mv_idx == idx) return;
301
      }
302
303
304
305
    }
    return;
  }

306
307
308
309
310
311
  if (mbmi->mode == NEARMV) {
    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
312
313
            av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
        aom_prob drl_prob = cm->fc->drl_prob[drl_ctx];
314

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

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

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

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

Yaowu Xu's avatar
Yaowu Xu committed
342
343
static void prob_diff_update(const aom_tree_index *tree,
                             aom_prob probs[/*n - 1*/],
344
                             const unsigned int counts[/*n - 1*/], int n,
345
                             int probwt, aom_writer *w) {
Jingning Han's avatar
Jingning Han committed
346
347
348
349
350
351
  int i;
  unsigned int branch_ct[32][2];

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

Yaowu Xu's avatar
Yaowu Xu committed
352
  av1_tree_probs_from_distribution(tree, branch_ct, counts);
Jingning Han's avatar
Jingning Han committed
353
  for (i = 0; i < n - 1; ++i)
354
    av1_cond_prob_diff_update(w, &probs[i], branch_ct[i], probwt);
Jingning Han's avatar
Jingning Han committed
355
}
356
#if CONFIG_EXT_INTER || CONFIG_EXT_TX || !CONFIG_EC_ADAPT
Yaowu Xu's avatar
Yaowu Xu committed
357
358
static int prob_diff_update_savings(const aom_tree_index *tree,
                                    aom_prob probs[/*n - 1*/],
359
360
                                    const unsigned int counts[/*n - 1*/], int n,
                                    int probwt) {
361
362
363
364
365
366
  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
367
  av1_tree_probs_from_distribution(tree, branch_ct, counts);
368
  for (i = 0; i < n - 1; ++i) {
369
370
    savings +=
        av1_cond_prob_diff_update_savings(&probs[i], branch_ct[i], probwt);
371
372
373
  }
  return savings;
}
374
#endif  // CONFIG_EXT_INTER || CONFIG_EXT_TX || !CONFIG_EC_ADAPT
375

376
#if CONFIG_VAR_TX
Yaowu Xu's avatar
Yaowu Xu committed
377
static void write_tx_size_vartx(const AV1_COMMON *cm, const MACROBLOCKD *xd,
378
                                const MB_MODE_INFO *mbmi, TX_SIZE tx_size,
379
380
                                int depth, int blk_row, int blk_col,
                                aom_writer *w) {
381
382
  const int tx_row = blk_row >> 1;
  const int tx_col = blk_col >> 1;
383
384
385
  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);

386
  int ctx = txfm_partition_context(xd->above_txfm_context + tx_col,
387
388
                                   xd->left_txfm_context + tx_row,
                                   mbmi->sb_type, tx_size);
389

390
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
391

Jingning Han's avatar
Jingning Han committed
392
  if (depth == MAX_VARTX_DEPTH) {
393
    txfm_partition_update(xd->above_txfm_context + tx_col,
394
                          xd->left_txfm_context + tx_row, tx_size, tx_size);
395
396
397
    return;
  }

398
  if (tx_size == mbmi->inter_tx_size[tx_row][tx_col]) {
Yaowu Xu's avatar
Yaowu Xu committed
399
    aom_write(w, 0, cm->fc->txfm_partition_prob[ctx]);
400
    txfm_partition_update(xd->above_txfm_context + tx_col,
401
                          xd->left_txfm_context + tx_row, tx_size, tx_size);
402
  } else {
403
404
    const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
    const int bsl = tx_size_wide_unit[sub_txs];
405
    int i;
406

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

409
    if (tx_size == TX_8X8) {
410
      txfm_partition_update(xd->above_txfm_context + tx_col,
411
                            xd->left_txfm_context + tx_row, sub_txs, tx_size);
412
      return;
413
    }
414
415
416

    assert(bsl > 0);
    for (i = 0; i < 4; ++i) {
417
418
419
420
      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);
421
422
423
    }
  }
}
424

Yaowu Xu's avatar
Yaowu Xu committed
425
static void update_txfm_partition_probs(AV1_COMMON *cm, aom_writer *w,
426
                                        FRAME_COUNTS *counts, int probwt) {
427
428
  int k;
  for (k = 0; k < TXFM_PARTITION_CONTEXTS; ++k)
Yaowu Xu's avatar
Yaowu Xu committed
429
    av1_cond_prob_diff_update(w, &cm->fc->txfm_partition_prob[k],
430
                              counts->txfm_partition[k], probwt);
431
}
432
433
#endif

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

461
462
463
464
#if CONFIG_EC_MULTISYMBOL
    aom_write_symbol(w, depth, cm->fc->tx_size_cdf[tx_size_cat][tx_size_ctx],
                     tx_size_cat + 2);
#else
Yaowu Xu's avatar
Yaowu Xu committed
465
466
    av1_write_token(w, av1_tx_size_tree[tx_size_cat],
                    cm->fc->tx_size_probs[tx_size_cat][tx_size_ctx],
467
                    &tx_size_encodings[tx_size_cat][depth]);
468
#endif
Jingning Han's avatar
Jingning Han committed
469
470
471
  }
}

472
#if CONFIG_REF_MV
Yaowu Xu's avatar
Yaowu Xu committed
473
static void update_inter_mode_probs(AV1_COMMON *cm, aom_writer *w,
474
475
                                    FRAME_COUNTS *counts) {
  int i;
476
477
478
479
480
#if CONFIG_TILE_GROUPS
  const int probwt = cm->num_tg;
#else
  const int probwt = 1;
#endif
481
  for (i = 0; i < NEWMV_MODE_CONTEXTS; ++i)
482
483
    av1_cond_prob_diff_update(w, &cm->fc->newmv_prob[i], counts->newmv_mode[i],
                              probwt);
484
  for (i = 0; i < ZEROMV_MODE_CONTEXTS; ++i)
Yaowu Xu's avatar
Yaowu Xu committed
485
    av1_cond_prob_diff_update(w, &cm->fc->zeromv_prob[i],
486
                              counts->zeromv_mode[i], probwt);
487
  for (i = 0; i < REFMV_MODE_CONTEXTS; ++i)
488
489
    av1_cond_prob_diff_update(w, &cm->fc->refmv_prob[i], counts->refmv_mode[i],
                              probwt);
490
  for (i = 0; i < DRL_MODE_CONTEXTS; ++i)
491
492
    av1_cond_prob_diff_update(w, &cm->fc->drl_prob[i], counts->drl_mode[i],
                              probwt);
Yue Chen's avatar
Yue Chen committed
493
#if CONFIG_EXT_INTER
494
495
  av1_cond_prob_diff_update(w, &cm->fc->new2mv_prob, counts->new2mv_mode,
                            probwt);
Yue Chen's avatar
Yue Chen committed
496
#endif  // CONFIG_EXT_INTER
497
498
499
}
#endif

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

Yaowu Xu's avatar
Yaowu Xu committed
525
526
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
527
528
529
530
  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
531
    aom_write(w, skip, av1_get_skip_prob(cm, xd));
Jingning Han's avatar
Jingning Han committed
532
533
534
535
    return skip;
  }
}

Yue Chen's avatar
Yue Chen committed
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
static void write_motion_mode(const AV1_COMMON *cm, const MB_MODE_INFO *mbmi,
                              aom_writer *w) {
  MOTION_MODE last_motion_mode_allowed = motion_mode_allowed(mbmi);

  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

557
#if CONFIG_DELTA_Q
558
559
static void write_delta_qindex(const AV1_COMMON *cm, int delta_qindex,
                               aom_writer *w) {
560
561
  int sign = delta_qindex < 0;
  int abs = sign ? -delta_qindex : delta_qindex;
562
563
564
565
566
567
568
569
570
571
572
573
574
575
  int rem_bits, thr, i = 0;
  int smallval = abs < DELTA_Q_SMALL ? 1 : 0;

  while (i < DELTA_Q_SMALL && i <= abs) {
    int bit = (i < abs);
    aom_write(w, bit, cm->fc->delta_q_prob[i]);
    i++;
  }

  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);
576
577
578
579
580
  }
  if (abs > 0) {
    aom_write_bit(w, sign);
  }
}
581
582
583
584

static void update_delta_q_probs(AV1_COMMON *cm, aom_writer *w,
                                 FRAME_COUNTS *counts) {
  int k;
585
586
587
588
589
#if CONFIG_TILE_GROUPS
  const int probwt = cm->num_tg;
#else
  const int probwt = 1;
#endif
590
  for (k = 0; k < DELTA_Q_CONTEXTS; ++k) {
591
592
    av1_cond_prob_diff_update(w, &cm->fc->delta_q_prob[k], counts->delta_q[k],
                              probwt);
593
594
  }
}
595
596
#endif

Yaowu Xu's avatar
Yaowu Xu committed
597
static void update_skip_probs(AV1_COMMON *cm, aom_writer *w,
Jingning Han's avatar
Jingning Han committed
598
599
                              FRAME_COUNTS *counts) {
  int k;
600
601
602
603
604
605
606
607
608
#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
609
610
}

611
#if !CONFIG_EC_ADAPT
Yaowu Xu's avatar
Yaowu Xu committed
612
static void update_switchable_interp_probs(AV1_COMMON *cm, aom_writer *w,
Jingning Han's avatar
Jingning Han committed
613
614
                                           FRAME_COUNTS *counts) {
  int j;
615
  for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j) {
616
617
618
619
620
621
622
623
#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);
624
  }
Jingning Han's avatar
Jingning Han committed
625
}
626
#endif
Jingning Han's avatar
Jingning Han committed
627

628
#if CONFIG_EXT_TX
Yaowu Xu's avatar
Yaowu Xu committed
629
630
631
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);
632
  int i, j;
633
  int s;
634
635
636
637
638
#if CONFIG_TILE_GROUPS
  const int probwt = cm->num_tg;
#else
  const int probwt = 1;
#endif
639
640
641
642
  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) {
643
      if (!use_inter_ext_tx_for_txsize[s][i]) continue;
644
      savings += prob_diff_update_savings(
Yaowu Xu's avatar
Yaowu Xu committed
645
          av1_ext_tx_inter_tree[s], cm->fc->inter_ext_tx_prob[s][i],
646
          cm->counts.inter_ext_tx[s][i], num_ext_tx_set_inter[s], probwt);
647
648
    }
    do_update = savings > savings_thresh;
Yaowu Xu's avatar
Yaowu Xu committed
649
    aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
650
651
    if (do_update) {
      for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
652
        if (!use_inter_ext_tx_for_txsize[s][i]) continue;
653
        prob_diff_update(
Yaowu Xu's avatar
Yaowu Xu committed
654
            av1_ext_tx_inter_tree[s], cm->fc->inter_ext_tx_prob[s][i],
655
            cm->counts.inter_ext_tx[s][i], num_ext_tx_set_inter[s], probwt, w);
656
      }
657
658
    }
  }
659

660
661
662
663
  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) {
664
      if (!use_intra_ext_tx_for_txsize[s][i]) continue;
665
      for (j = 0; j < INTRA_MODES; ++j)
666
        savings += prob_diff_update_savings(
Yaowu Xu's avatar
Yaowu Xu committed
667
            av1_ext_tx_intra_tree[s], cm->fc->intra_ext_tx_prob[s][i][j],
668
            cm->counts.intra_ext_tx[s][i][j], num_ext_tx_set_intra[s], probwt);
669
670
    }
    do_update = savings > savings_thresh;
Yaowu Xu's avatar
Yaowu Xu committed
671
    aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
672
673
    if (do_update) {
      for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
674
        if (!use_intra_ext_tx_for_txsize[s][i]) continue;
675
        for (j = 0; j < INTRA_MODES; ++j)
676
677
678
679
          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],
                           num_ext_tx_set_intra[s], probwt, w);
680
681
      }
    }
682
  }
683
}
Debargha Mukherjee's avatar
Debargha Mukherjee committed
684

685
#else
686
#if !CONFIG_EC_ADAPT
Yaowu Xu's avatar
Yaowu Xu committed
687
688
689
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);
690
691
692
693
  int i, j;

  int savings = 0;
  int do_update = 0;
694
695
696
697
698
#if CONFIG_TILE_GROUPS
  const int probwt = cm->num_tg;
#else
  const int probwt = 1;
#endif
699
700
701
  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
702
          av1_ext_tx_tree, cm->fc->intra_ext_tx_prob[i][j],
703
          cm->counts.intra_ext_tx[i][j], TX_TYPES, probwt);
704
705
  }
  do_update = savings > savings_thresh;
Yaowu Xu's avatar
Yaowu Xu committed
706
  aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
707
708
  if (do_update) {
    for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
709
      for (j = 0; j < TX_TYPES; ++j) {
Yaowu Xu's avatar
Yaowu Xu committed
710
        prob_diff_update(av1_ext_tx_tree, cm->fc->intra_ext_tx_prob[i][j],
711
                         cm->counts.intra_ext_tx[i][j], TX_TYPES, probwt, w);
712
      }
713
714
    }
  }
715

716
717
  savings = 0;
  for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
718
    savings +=
Yaowu Xu's avatar
Yaowu Xu committed
719
        prob_diff_update_savings(av1_ext_tx_tree, cm->fc->inter_ext_tx_prob[i],
720
                                 cm->counts.inter_ext_tx[i], TX_TYPES, probwt);
721
722
  }
  do_update = savings > savings_thresh;
Yaowu Xu's avatar
Yaowu Xu committed
723
  aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
724
725
  if (do_update) {
    for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
Yaowu Xu's avatar
Yaowu Xu committed
726
      prob_diff_update(av1_ext_tx_tree, cm->fc->inter_ext_tx_prob[i],
727
                       cm->counts.inter_ext_tx[i], TX_TYPES, probwt, w);
728
729
730
    }
  }
}
731
#endif  // CONFIG_EXT_TX
732
#endif
733
#if CONFIG_PALETTE
Yaowu Xu's avatar
Yaowu Xu committed
734
static void pack_palette_tokens(aom_writer *w, const TOKENEXTRA **tp, int n,
735
                                int num) {
hui su's avatar
hui su committed
736
  int i;
737
  const TOKENEXTRA *p = *tp;
hui su's avatar
hui su committed
738

739
  for (i = 0; i < num; ++i) {
740
741
    av1_write_token(w, av1_palette_color_index_tree[n - 2], p->context_tree,
                    &palette_color_index_encodings[n - 2][p->token]);
hui su's avatar
hui su committed
742
743
744
745
746
    ++p;
  }

  *tp = p;
}
747
#endif  // CONFIG_PALETTE
748
#if !CONFIG_PVQ
749
#if CONFIG_SUPERTX
750
static void update_supertx_probs(AV1_COMMON *cm, int probwt, aom_writer *w) {
Yaowu Xu's avatar
Yaowu Xu committed
751
752
  const int savings_thresh = av1_cost_one(GROUP_DIFF_UPDATE_PROB) -
                             av1_cost_zero(GROUP_DIFF_UPDATE_PROB);
753
754
755
756
  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
757
    for (j = TX_8X8; j < TX_SIZES; ++j) {
758
759
      savings += av1_cond_prob_diff_update_savings(
          &cm->fc->supertx_prob[i][j], cm->counts.supertx[i][j], probwt);
760
761
762
    }
  }
  do_update = savings > savings_thresh;
Yaowu Xu's avatar
Yaowu Xu committed
763
  aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
764
765
  if (do_update) {
    for (i = 0; i < PARTITION_SUPERTX_CONTEXTS; ++i) {
Jingning Han's avatar
Jingning Han committed
766
      for (j = TX_8X8; j < TX_SIZES; ++j) {
Yaowu Xu's avatar
Yaowu Xu committed
767
        av1_cond_prob_diff_update(w, &cm->fc->supertx_prob[i][j],
768
                                  cm->counts.supertx[i][j], probwt);
769
770
771
772
773
774
      }
    }
  }
}
#endif  // CONFIG_SUPERTX

775
#if CONFIG_NEW_TOKENSET
Yaowu Xu's avatar
Yaowu Xu committed
776
static void pack_mb_tokens(aom_writer *w, const TOKENEXTRA **tp,
777
                           const TOKENEXTRA *const stop,
778
779
                           aom_bit_depth_t bit_depth, const TX_SIZE tx_size,
                           TOKEN_STATS *token_stats) {
780
  const TOKENEXTRA *p = *tp;
781
782
#if CONFIG_VAR_TX
  int count = 0;
783
  const int seg_eob = tx_size_2d[tx_size];
784
#endif
Alex Converse's avatar
Alex Converse committed
785
786
787
788
789
790
791
792
793
#if CONFIG_AOM_HIGHBITDEPTH
  const av1_extra_bit *const extra_bits_table =
      (bit_depth == AOM_BITS_12)
          ? av1_extra_bits_high12
          : (bit_depth == AOM_BITS_10) ? av1_extra_bits_high10 : av1_extra_bits;
#else
  const av1_extra_bit *const extra_bits_table = av1_extra_bits;
  (void)bit_depth;
#endif  // CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
794
795

  while (p < stop && p->token != EOSB_TOKEN) {
796
797
    const int token = p->token;
    aom_tree_index index = 0;
Alex Converse's avatar
Alex Converse committed
798
    const av1_extra_bit *const extra_bits = &extra_bits_table[token];
Jingning Han's avatar
Jingning Han committed
799

800
801
802
803
804
805
    if (token == BLOCK_Z_TOKEN) {
      aom_write_symbol(w, 0, *p->head_cdf, 6);
      p++;
      continue;
    }
    int comb_symb = 2 * AOMMIN(token, TWO_TOKEN) - p->is_eob + 1;
Alex Converse's avatar
Alex Converse committed
806

807
808
809
810
    aom_write_symbol(w, comb_symb, *p->head_cdf, 6);
    if (token > ONE_TOKEN) {
      aom_write_symbol(w, token - TWO_TOKEN, *p->tail_cdf,
                       CATEGORY6_TOKEN + 1 - 2);
Alex Converse's avatar
Alex Converse committed
811
    }
812
813
814
815

    if (extra_bits->base_val) {
      const int bit_string = p->extra;
      const int bit_string_length = extra_bits->len;  // Length of extra bits to
816
817
      // be written excluding
      // the sign bit.
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
      int skip_bits = (extra_bits->base_val == CAT6_MIN_VAL)
                          ? TX_SIZES - 1 - txsize_sqr_up_map[tx_size]
                          : 0;

      if (bit_string_length > 0) {
        const unsigned char *pb = extra_bits->prob;
        const int value = bit_string >> 1;
        const int num_bits = bit_string_length;  // number of bits in value
        assert(num_bits > 0);

        for (index = 0; index < num_bits; ++index) {
          const int shift = num_bits - index - 1;
          const int bb = (value >> shift) & 1;
          if (skip_bits) {
            --skip_bits;
            assert(!bb);
          } else {
            aom_write_record(w, bb, pb[index], token_stats);
          }
        }
      }

      aom_write_bit_record(w, bit_string & 1, token_stats);
    }
    ++p;

#if CONFIG_VAR_TX
    ++count;
    if (token == EOB_TOKEN || count == seg_eob) break;
#endif
  }

  *tp = p;
}
Alex Converse's avatar
Alex Converse committed
852
#else