bitstream.c 182 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_DAALA_EC || CONFIG_ANS)
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_DAALA_EC || CONFIG_ANS)
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  // !(CONFIG_DAALA_EC || CONFIG_ANS)
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_DAALA_EC || CONFIG_ANS
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  // CONFIG_DAALA_EC || CONFIG_ANS
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
229
#if CONFIG_DAALA_EC || CONFIG_ANS
Jingning Han's avatar
Jingning Han committed
230 231 232 233 234 235 236 237 238
  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  // CONFIG_DAALA_EC || CONFIG_ANS
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

Jingning Han's avatar
Jingning Han committed
255
  aom_write(w, mode != NEWMV, newmv_prob);
256

Jingning Han's avatar
Jingning Han committed
257
  if (mode != NEWMV) {
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
    }
  }
Jingning Han's avatar
Jingning Han committed
280 281
}

Yaowu Xu's avatar
Yaowu Xu committed
282 283 284
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);
285 286 287

  assert(mbmi->ref_mv_idx < 3);

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

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

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

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

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
}

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

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

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

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

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

390
  int ctx = txfm_partition_context(xd->above_txfm_context + tx_col,
391 392
                                   xd->left_txfm_context + tx_row,
                                   mbmi->sb_type, tx_size);
393

394
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
395

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

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

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

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

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

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

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

465
#if CONFIG_DAALA_EC || CONFIG_ANS
466
    aom_write_symbol(w, depth, ec_ctx->tx_size_cdf[tx_size_cat][tx_size_ctx],
467 468
                     tx_size_cat + 2);
#else
Yaowu Xu's avatar
Yaowu Xu committed
469
    av1_write_token(w, av1_tx_size_tree[tx_size_cat],
470
                    ec_ctx->tx_size_probs[tx_size_cat][tx_size_ctx],
471
                    &tx_size_encodings[tx_size_cat][depth]);
472
#endif  // CONFIG_DAALA_EC || CONFIG_ANS
473 474 475 476 477
#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
478 479 480
  }
}

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

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

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

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

  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

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

580
#if CONFIG_DAALA_EC || CONFIG_ANS
Thomas Davies's avatar
Thomas Davies committed
581 582 583 584
  aom_write_symbol(w, AOMMIN(abs, DELTA_Q_SMALL), ec_ctx->delta_q_cdf,
                   DELTA_Q_PROBS + 1);
#else
  int i = 0;
585 586
  while (i < DELTA_Q_SMALL && i <= abs) {
    int bit = (i < abs);
Thomas Davies's avatar
Thomas Davies committed
587
    aom_write(w, bit, ec_ctx->delta_q_prob[i]);
588 589
    i++;
  }
590
#endif  // CONFIG_DAALA_EC || CONFIG_ANS
591 592 593 594 595 596

  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);
597 598 599 600 601
  }
  if (abs > 0) {
    aom_write_bit(w, sign);
  }
}
602

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

#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

637
#if CONFIG_DAALA_EC || CONFIG_ANS
Fangwen Fu's avatar
Fangwen Fu committed
638 639 640 641 642 643 644 645 646
  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++;
  }
647
#endif  // CONFIG_DAALA_EC || CONFIG_ANS
Fangwen Fu's avatar
Fangwen Fu committed
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

  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
677
#endif  // CONFIG_DELTA_Q
678

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

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

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

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

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

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

801 802
  savings = 0;
  for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
803
    savings +=
Yaowu Xu's avatar
Yaowu Xu committed
804
        prob_diff_update_savings(av1_ext_tx_tree, cm->fc->inter_ext_tx_prob[i],
805
                                 cm->counts.inter_ext_tx[i], 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) {
Yaowu Xu's avatar
Yaowu Xu committed
811
      prob_diff_update(av1_ext_tx_tree, cm->fc->inter_ext_tx_prob[i],
812
                       cm->counts.inter_ext_tx[i], TX_TYPES, probwt, w);