bitstream.c 76.7 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1
/*
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Jingning Han's avatar
Jingning Han committed
3
 *
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 14 15
 */

#include <assert.h>
#include <stdio.h>
#include <limits.h>

Adrian Grange's avatar
Adrian Grange committed
16
#include "aom/aom_encoder.h"
Yaowu Xu's avatar
Yaowu Xu committed
17
#include "aom_dsp/bitwriter_buffer.h"
Adrian Grange's avatar
Adrian Grange committed
18 19
#include "aom_dsp/aom_dsp_common.h"
#include "aom_mem/aom_mem.h"
Yaowu Xu's avatar
Yaowu Xu committed
20 21
#include "aom_ports/mem_ops.h"
#include "aom_ports/system_state.h"
Jingning Han's avatar
Jingning Han committed
22

Yaowu Xu's avatar
Yaowu Xu committed
23
#if CONFIG_CLPF
Yaowu Xu's avatar
Yaowu Xu committed
24
#include "av1/common/clpf.h"
Yaowu Xu's avatar
Yaowu Xu committed
25
#endif
26
#if CONFIG_DERING
Yaowu Xu's avatar
Yaowu Xu committed
27
#include "av1/common/dering.h"
28
#endif  // CONFIG_DERING
Yaowu Xu's avatar
Yaowu Xu committed
29 30 31 32 33
#include "av1/common/entropy.h"
#include "av1/common/entropymode.h"
#include "av1/common/entropymv.h"
#include "av1/common/mvref_common.h"
#include "av1/common/pred_common.h"
34
#include "av1/common/reconinter.h"
Yaowu Xu's avatar
Yaowu Xu committed
35 36
#include "av1/common/seg_common.h"
#include "av1/common/tile_common.h"
Jingning Han's avatar
Jingning Han committed
37

Yaowu Xu's avatar
Yaowu Xu committed
38 39 40 41 42 43 44
#include "av1/encoder/cost.h"
#include "av1/encoder/bitstream.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"
Jingning Han's avatar
Jingning Han committed
45

46 47 48
static struct av1_token intra_mode_encodings[INTRA_MODES];
static struct av1_token switchable_interp_encodings[SWITCHABLE_FILTERS];
static struct av1_token partition_encodings[PARTITION_TYPES];
49
#if !CONFIG_REF_MV
50
static struct av1_token inter_mode_encodings[INTER_MODES];
51
#endif
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86

#if CONFIG_PALETTE
static const struct av1_token palette_size_encodings[] = {
  { 0, 1 }, { 2, 2 }, { 6, 3 }, { 14, 4 }, { 30, 5 }, { 62, 6 }, { 63, 6 },
};
static const struct av1_token
    palette_color_encodings[PALETTE_MAX_SIZE - 1][PALETTE_MAX_SIZE] = {
      { { 0, 1 }, { 1, 1 } },                                  // 2 colors
      { { 0, 1 }, { 2, 2 }, { 3, 2 } },                        // 3 colors
      { { 0, 1 }, { 2, 2 }, { 6, 3 }, { 7, 3 } },              // 4 colors
      { { 0, 1 }, { 2, 2 }, { 6, 3 }, { 14, 4 }, { 15, 4 } },  // 5 colors
      { { 0, 1 },
        { 2, 2 },
        { 6, 3 },
        { 14, 4 },
        { 30, 5 },
        { 31, 5 } },  // 6 colors
      { { 0, 1 },
        { 2, 2 },
        { 6, 3 },
        { 14, 4 },
        { 30, 5 },
        { 62, 6 },
        { 63, 6 } },  // 7 colors
      { { 0, 1 },
        { 2, 2 },
        { 6, 3 },
        { 14, 4 },
        { 30, 5 },
        { 62, 6 },
        { 126, 7 },
        { 127, 7 } },  // 8 colors
    };
#endif  // CONFIG_PALETTE

87 88 89
#if CONFIG_MOTION_VAR
static struct av1_token motion_mode_encodings[MOTION_MODES];
#endif  // CONFIG_MOTION_VAR
90
static struct av1_token ext_tx_encodings[TX_TYPES];
91

92
void av1_encode_token_init() {
93 94 95 96 97 98
  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
99 100 101
#if CONFIG_MOTION_VAR
  av1_tokens_from_tree(motion_mode_encodings, av1_motion_mode_tree);
#endif  // CONFIG_MOTION_VAR
102
  av1_tokens_from_tree(ext_tx_encodings, av1_ext_tx_tree);
103 104 105 106 107 108
#if CONFIG_DAALA_EC
  /* This hack is necessary when CONFIG_EXT_INTERP is enabled because the five
      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);
109 110 111 112 113
  /* 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. */
  av1_indices_from_tree(av1_ext_tx_ind, av1_ext_tx_inv, TX_TYPES,
                        av1_ext_tx_tree);
114 115
  av1_indices_from_tree(av1_intra_mode_ind, av1_intra_mode_inv, INTRA_MODES,
                        av1_intra_mode_tree);
116 117
  av1_indices_from_tree(av1_inter_mode_ind, av1_inter_mode_inv, INTER_MODES,
                        av1_inter_mode_tree);
118
#endif
119 120
}

121
#if !CONFIG_DAALA_EC
Adrian Grange's avatar
Adrian Grange committed
122 123
static void write_intra_mode(aom_writer *w, PREDICTION_MODE mode,
                             const aom_prob *probs) {
124
  av1_write_token(w, av1_intra_mode_tree, probs, &intra_mode_encodings[mode]);
Jingning Han's avatar
Jingning Han committed
125
}
126
#endif
Jingning Han's avatar
Jingning Han committed
127

clang-format's avatar
clang-format committed
128 129
static void write_inter_mode(AV1_COMMON *cm, aom_writer *w,
                             PREDICTION_MODE mode, const int16_t mode_ctx) {
130
#if CONFIG_REF_MV
131
  const int16_t newmv_ctx = mode_ctx & NEWMV_CTX_MASK;
132 133 134 135
  const aom_prob newmv_prob = cm->fc->newmv_prob[newmv_ctx];
  aom_write(w, mode != NEWMV, newmv_prob);

  if (mode != NEWMV) {
136
    const int16_t zeromv_ctx = (mode_ctx >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
137
    const aom_prob zeromv_prob = cm->fc->zeromv_prob[zeromv_ctx];
138 139 140 141 142

    if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET)) {
      assert(mode == ZEROMV);
      return;
    }
143 144 145
    aom_write(w, mode != ZEROMV, zeromv_prob);

    if (mode != ZEROMV) {
146 147 148
      int16_t refmv_ctx = (mode_ctx >> REFMV_OFFSET) & REFMV_CTX_MASK;
      aom_prob refmv_prob;

clang-format's avatar
clang-format committed
149 150 151
      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;
152 153

      refmv_prob = cm->fc->refmv_prob[refmv_ctx];
154 155 156 157
      aom_write(w, mode != NEARESTMV, refmv_prob);
    }
  }
#else
Jingning Han's avatar
Jingning Han committed
158
  assert(is_inter_mode(mode));
159 160 161 162 163 164 165 166 167 168
#if CONFIG_DAALA_EC
  aom_write_symbol(w, av1_inter_mode_ind[INTER_OFFSET(mode)],
                   cm->fc->inter_mode_cdf[mode_ctx], INTER_MODES);
#else
  {
    const aom_prob *const inter_probs = cm->fc->inter_mode_probs[mode_ctx];
    av1_write_token(w, av1_inter_mode_tree, inter_probs,
                    &inter_mode_encodings[INTER_OFFSET(mode)]);
  }
#endif
169
#endif
Jingning Han's avatar
Jingning Han committed
170 171
}

172
#if CONFIG_REF_MV
clang-format's avatar
clang-format committed
173 174
static void write_drl_idx(const AV1_COMMON *cm, const MB_MODE_INFO *mbmi,
                          const MB_MODE_INFO_EXT *mbmi_ext, aom_writer *w) {
175
  uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
176 177 178

  assert(mbmi->ref_mv_idx < 3);

179 180 181 182 183 184 185 186 187
  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 =
            av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
        aom_prob drl_prob = cm->fc->drl_prob[drl_ctx];

        aom_write(w, mbmi->ref_mv_idx != idx, drl_prob);
clang-format's avatar
clang-format committed
188
        if (mbmi->ref_mv_idx == idx) return;
189
      }
190 191 192 193
    }
    return;
  }

194 195 196 197 198 199 200 201 202 203
  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 =
            av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
        aom_prob drl_prob = cm->fc->drl_prob[drl_ctx];

        aom_write(w, mbmi->ref_mv_idx != (idx - 1), drl_prob);
clang-format's avatar
clang-format committed
204
        if (mbmi->ref_mv_idx == (idx - 1)) return;
205
      }
206
    }
207
    return;
208 209 210 211
  }
}
#endif

212 213 214 215 216 217 218 219 220 221
#if CONFIG_MOTION_VAR
static void write_motion_mode(const AV1_COMMON *cm, const MB_MODE_INFO *mbmi,
                              aom_writer *w) {
  if (is_motion_variation_allowed(mbmi))
    av1_write_token(w, av1_motion_mode_tree,
                    cm->fc->motion_mode_prob[mbmi->sb_type],
                    &motion_mode_encodings[mbmi->motion_mode]);
}
#endif  // CONFIG_MOTION_VAR

Adrian Grange's avatar
Adrian Grange committed
222
static void encode_unsigned_max(struct aom_write_bit_buffer *wb, int data,
clang-format's avatar
clang-format committed
223
                                int max) {
Adrian Grange's avatar
Adrian Grange committed
224
  aom_wb_write_literal(wb, data, get_unsigned_bits(max));
Jingning Han's avatar
Jingning Han committed
225 226
}

Adrian Grange's avatar
Adrian Grange committed
227 228
static void prob_diff_update(const aom_tree_index *tree,
                             aom_prob probs[/*n - 1*/],
clang-format's avatar
clang-format committed
229
                             const unsigned int counts[/*n - 1*/], int n,
Adrian Grange's avatar
Adrian Grange committed
230
                             aom_writer *w) {
Jingning Han's avatar
Jingning Han committed
231 232 233 234 235 236
  int i;
  unsigned int branch_ct[32][2];

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

237
  av1_tree_probs_from_distribution(tree, branch_ct, counts);
Jingning Han's avatar
Jingning Han committed
238
  for (i = 0; i < n - 1; ++i)
239
    av1_cond_prob_diff_update(w, &probs[i], branch_ct[i]);
Jingning Han's avatar
Jingning Han committed
240 241
}

Adrian Grange's avatar
Adrian Grange committed
242 243
static int prob_diff_update_savings(const aom_tree_index *tree,
                                    aom_prob probs[/*n - 1*/],
244 245 246 247 248 249 250 251
                                    const unsigned int counts[/*n - 1*/],
                                    int n) {
  int i;
  unsigned int branch_ct[32][2];
  int savings = 0;

  // Assuming max number of probabilities <= 32
  assert(n <= 32);
252
  av1_tree_probs_from_distribution(tree, branch_ct, counts);
253
  for (i = 0; i < n - 1; ++i) {
254
    savings += av1_cond_prob_diff_update_savings(&probs[i], branch_ct[i]);
255 256 257 258
  }
  return savings;
}

259
static void write_selected_tx_size(const AV1_COMMON *cm, const MACROBLOCKD *xd,
Adrian Grange's avatar
Adrian Grange committed
260
                                   aom_writer *w) {
Jingning Han's avatar
Jingning Han committed
261 262 263
  TX_SIZE tx_size = xd->mi[0]->mbmi.tx_size;
  BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
  const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
Adrian Grange's avatar
Adrian Grange committed
264
  const aom_prob *const tx_probs =
clang-format's avatar
clang-format committed
265
      get_tx_probs2(max_tx_size, xd, &cm->fc->tx_probs);
Adrian Grange's avatar
Adrian Grange committed
266
  aom_write(w, tx_size != TX_4X4, tx_probs[0]);
Jingning Han's avatar
Jingning Han committed
267
  if (tx_size != TX_4X4 && max_tx_size >= TX_16X16) {
Adrian Grange's avatar
Adrian Grange committed
268
    aom_write(w, tx_size != TX_8X8, tx_probs[1]);
Jingning Han's avatar
Jingning Han committed
269
    if (tx_size != TX_8X8 && max_tx_size >= TX_32X32)
Adrian Grange's avatar
Adrian Grange committed
270
      aom_write(w, tx_size != TX_16X16, tx_probs[2]);
Jingning Han's avatar
Jingning Han committed
271 272 273
  }
}

274 275 276 277 278
#if CONFIG_REF_MV
static void update_inter_mode_probs(AV1_COMMON *cm, aom_writer *w,
                                    FRAME_COUNTS *counts) {
  int i;
  for (i = 0; i < NEWMV_MODE_CONTEXTS; ++i)
clang-format's avatar
clang-format committed
279
    av1_cond_prob_diff_update(w, &cm->fc->newmv_prob[i], counts->newmv_mode[i]);
280 281 282 283
  for (i = 0; i < ZEROMV_MODE_CONTEXTS; ++i)
    av1_cond_prob_diff_update(w, &cm->fc->zeromv_prob[i],
                              counts->zeromv_mode[i]);
  for (i = 0; i < REFMV_MODE_CONTEXTS; ++i)
clang-format's avatar
clang-format committed
284
    av1_cond_prob_diff_update(w, &cm->fc->refmv_prob[i], counts->refmv_mode[i]);
285
  for (i = 0; i < DRL_MODE_CONTEXTS; ++i)
clang-format's avatar
clang-format committed
286
    av1_cond_prob_diff_update(w, &cm->fc->drl_prob[i], counts->drl_mode[i]);
287 288 289
}
#endif

290
static int write_skip(const AV1_COMMON *cm, const MACROBLOCKD *xd,
Adrian Grange's avatar
Adrian Grange committed
291
                      int segment_id, const MODE_INFO *mi, aom_writer *w) {
Jingning Han's avatar
Jingning Han committed
292 293 294 295
  if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
    return 1;
  } else {
    const int skip = mi->mbmi.skip;
296
    aom_write(w, skip, av1_get_skip_prob(cm, xd));
Jingning Han's avatar
Jingning Han committed
297 298 299 300
    return skip;
  }
}

301
static void update_skip_probs(AV1_COMMON *cm, aom_writer *w,
Jingning Han's avatar
Jingning Han committed
302 303 304 305
                              FRAME_COUNTS *counts) {
  int k;

  for (k = 0; k < SKIP_CONTEXTS; ++k)
306
    av1_cond_prob_diff_update(w, &cm->fc->skip_probs[k], counts->skip[k]);
Jingning Han's avatar
Jingning Han committed
307 308
}

309
static void update_switchable_interp_probs(AV1_COMMON *cm, aom_writer *w,
Jingning Han's avatar
Jingning Han committed
310 311
                                           FRAME_COUNTS *counts) {
  int j;
312
  for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j) {
313
    prob_diff_update(av1_switchable_interp_tree,
Jingning Han's avatar
Jingning Han committed
314 315
                     cm->fc->switchable_interp_prob[j],
                     counts->switchable_interp[j], SWITCHABLE_FILTERS, w);
316 317 318 319 320 321
#if CONFIG_DAALA_EC
    av1_tree_to_cdf(av1_switchable_interp_tree,
                    cm->fc->switchable_interp_prob[j],
                    cm->fc->switchable_interp_cdf[j]);
#endif
  }
Jingning Han's avatar
Jingning Han committed
322 323
}

324 325 326
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);
327 328 329 330 331 332 333
  int i, j;

  int savings = 0;
  int do_update = 0;
  for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
    for (j = 0; j < TX_TYPES; ++j)
      savings += prob_diff_update_savings(
334
          av1_ext_tx_tree, cm->fc->intra_ext_tx_prob[i][j],
335 336 337
          cm->counts.intra_ext_tx[i][j], TX_TYPES);
  }
  do_update = savings > savings_thresh;
Adrian Grange's avatar
Adrian Grange committed
338
  aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
339 340
  if (do_update) {
    for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
341
      for (j = 0; j < TX_TYPES; ++j) {
342
        prob_diff_update(av1_ext_tx_tree, cm->fc->intra_ext_tx_prob[i][j],
clang-format's avatar
clang-format committed
343
                         cm->counts.intra_ext_tx[i][j], TX_TYPES, w);
344 345 346 347 348
#if CONFIG_DAALA_EC
        av1_tree_to_cdf(av1_ext_tx_tree, cm->fc->intra_ext_tx_prob[i][j],
                        cm->fc->intra_ext_tx_cdf[i][j]);
#endif
      }
349 350 351 352
    }
  }
  savings = 0;
  for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
clang-format's avatar
clang-format committed
353
    savings +=
354
        prob_diff_update_savings(av1_ext_tx_tree, cm->fc->inter_ext_tx_prob[i],
clang-format's avatar
clang-format committed
355
                                 cm->counts.inter_ext_tx[i], TX_TYPES);
356 357
  }
  do_update = savings > savings_thresh;
Adrian Grange's avatar
Adrian Grange committed
358
  aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
359 360
  if (do_update) {
    for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
361
      prob_diff_update(av1_ext_tx_tree, cm->fc->inter_ext_tx_prob[i],
clang-format's avatar
clang-format committed
362
                       cm->counts.inter_ext_tx[i], TX_TYPES, w);
363 364 365 366
#if CONFIG_DAALA_EC
      av1_tree_to_cdf(av1_ext_tx_tree, cm->fc->inter_ext_tx_prob[i],
                      cm->fc->inter_ext_tx_cdf[i]);
#endif
367 368 369 370
    }
  }
}

371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386
#if CONFIG_PALETTE
static void pack_palette_tokens(aom_writer *w, TOKENEXTRA **tp, int n,
                                int num) {
  int i;
  TOKENEXTRA *p = *tp;

  for (i = 0; i < num; ++i) {
    av1_write_token(w, av1_palette_color_tree[n - 2], p->context_tree,
                    &palette_color_encodings[n - 2][p->token]);
    ++p;
  }

  *tp = p;
}
#endif  // CONFIG_PALETTE

Adrian Grange's avatar
Adrian Grange committed
387
static void pack_mb_tokens(aom_writer *w, TOKENEXTRA **tp,
clang-format's avatar
clang-format committed
388
                           const TOKENEXTRA *const stop,
Adrian Grange's avatar
Adrian Grange committed
389
                           aom_bit_depth_t bit_depth, const TX_SIZE tx) {
Jingning Han's avatar
Jingning Han committed
390
  TOKENEXTRA *p = *tp;
Alex Converse's avatar
Alex Converse committed
391 392 393 394 395 396 397 398 399
#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
400
#if !CONFIG_MISC_FIXES
clang-format's avatar
clang-format committed
401
  (void)tx;
402
#endif
Jingning Han's avatar
Jingning Han committed
403 404

  while (p < stop && p->token != EOSB_TOKEN) {
405 406
    const uint8_t token = p->token;
    aom_tree_index index = 0;
407
#if !CONFIG_RANS && !CONFIG_DAALA_EC
408 409 410
    const struct av1_token *const coef_encoding = &av1_coef_encodings[token];
    int coef_value = coef_encoding->value;
    int coef_length = coef_encoding->len;
411
#endif  // !CONFIG_RANS
Alex Converse's avatar
Alex Converse committed
412
    const av1_extra_bit *const extra_bits = &extra_bits_table[token];
Jingning Han's avatar
Jingning Han committed
413

414
#if CONFIG_RANS || CONFIG_DAALA_EC
415
    if (!p->skip_eob_node) aom_write(w, token != EOB_TOKEN, p->context_tree[0]);
416

417 418 419
    if (token != EOB_TOKEN) {
      aom_write(w, token != ZERO_TOKEN, p->context_tree[1]);
      if (token != ZERO_TOKEN) {
420 421
        aom_write_symbol(w, token - ONE_TOKEN, *p->token_cdf,
                         CATEGORY6_TOKEN - ONE_TOKEN + 1);
422 423 424
      }
    }
#else
Jingning Han's avatar
Jingning Han committed
425 426
    /* skip one or two nodes */
    if (p->skip_eob_node) {
427 428
      coef_length -= p->skip_eob_node;
      index = 2 * p->skip_eob_node;
Jingning Han's avatar
Jingning Han committed
429 430 431 432 433 434 435 436 437 438
    }

    // TODO(jbb): expanding this can lead to big gains.  It allows
    // much better branch prediction and would enable us to avoid numerous
    // lookups and compares.

    // If we have a token that's in the constrained set, the coefficient tree
    // is split into two treed writes.  The first treed write takes care of the
    // unconstrained nodes.  The second treed write takes care of the
    // constrained nodes.
439 440 441 442 443 444 445 446 447
    if (token >= TWO_TOKEN && token < EOB_TOKEN) {
      const int unconstrained_len = UNCONSTRAINED_NODES - p->skip_eob_node;
      const int unconstrained_bits =
          coef_value >> (coef_length - unconstrained_len);
      // Unconstrained nodes.
      aom_write_tree_bits(w, av1_coef_tree, p->context_tree, unconstrained_bits,
                          unconstrained_len, index);
      coef_value &= (1 << (coef_length - unconstrained_len)) - 1;
      // Constrained nodes.
448
      aom_write_tree(w, av1_coef_con_tree,
449 450
                     av1_pareto8_full[p->context_tree[PIVOT_NODE] - 1],
                     coef_value, coef_length - unconstrained_len, 0);
Jingning Han's avatar
Jingning Han committed
451
    } else {
452 453
      aom_write_tree_bits(w, av1_coef_tree, p->context_tree, coef_value,
                          coef_length, index);
Jingning Han's avatar
Jingning Han committed
454
    }
455
#endif  // CONFIG_RANS
Jingning Han's avatar
Jingning Han committed
456

Alex Converse's avatar
Alex Converse committed
457 458 459 460 461
    if (extra_bits->base_val) {
      const int bit_string = p->extra;
      const int bit_string_length = extra_bits->len;  // Length of extra bits to
                                                      // be written excluding
                                                      // the sign bit.
462
#if CONFIG_MISC_FIXES
463
      int skip_bits =
Alex Converse's avatar
Alex Converse committed
464
          (extra_bits->base_val == CAT6_MIN_VAL) ? TX_SIZES - 1 - tx : 0;
465 466 467
#else
      int skip_bits = 0;
#endif
Jingning Han's avatar
Jingning Han committed
468

Alex Converse's avatar
Alex Converse committed
469 470 471 472
      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
473
        assert(num_bits > 0);
Jingning Han's avatar
Jingning Han committed
474

Alex Converse's avatar
Alex Converse committed
475 476 477
        for (index = 0; index < num_bits; ++index) {
          const int shift = num_bits - index - 1;
          const int bb = (value >> shift) & 1;
478
          if (skip_bits) {
479
            --skip_bits;
480 481
            assert(!bb);
          } else {
Alex Converse's avatar
Alex Converse committed
482
            aom_write(w, bb, pb[index]);
483
          }
Alex Converse's avatar
Alex Converse committed
484
        }
Jingning Han's avatar
Jingning Han committed
485 486
      }

Alex Converse's avatar
Alex Converse committed
487
      aom_write_bit(w, bit_string & 1);
Jingning Han's avatar
Jingning Han committed
488 489 490 491
    }
    ++p;
  }

492
  *tp = p;
Jingning Han's avatar
Jingning Han committed
493 494
}

Adrian Grange's avatar
Adrian Grange committed
495
static void write_segment_id(aom_writer *w, const struct segmentation *seg,
496
                             const struct segmentation_probs *segp,
Jingning Han's avatar
Jingning Han committed
497
                             int segment_id) {
498 499 500 501
  if (seg->enabled && seg->update_map) {
#if CONFIG_DAALA_EC
    aom_write_symbol(w, segment_id, segp->tree_cdf, MAX_SEGMENTS);
#else
502
    aom_write_tree(w, av1_segment_tree, segp->tree_probs, segment_id, 3, 0);
503 504
#endif
  }
Jingning Han's avatar
Jingning Han committed
505 506 507
}

// This function encodes the reference frame
508
static void write_ref_frames(const AV1_COMMON *cm, const MACROBLOCKD *xd,
Adrian Grange's avatar
Adrian Grange committed
509
                             aom_writer *w) {
Jingning Han's avatar
Jingning Han committed
510 511 512 513 514 515 516 517 518
  const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
  const int is_compound = has_second_ref(mbmi);
  const int segment_id = mbmi->segment_id;

  // If segment level coding of this signal is disabled...
  // or the segment allows multiple reference frame options
  if (segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) {
    assert(!is_compound);
    assert(mbmi->ref_frame[0] ==
clang-format's avatar
clang-format committed
519
           get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME));
Jingning Han's avatar
Jingning Han committed
520 521 522 523
  } else {
    // does the feature use compound prediction or not
    // (if not specified at the frame/segment level)
    if (cm->reference_mode == REFERENCE_MODE_SELECT) {
524
      aom_write(w, is_compound, av1_get_reference_mode_prob(cm, xd));
Jingning Han's avatar
Jingning Han committed
525
    } else {
526
      assert((!is_compound) == (cm->reference_mode == SINGLE_REFERENCE));
Jingning Han's avatar
Jingning Han committed
527 528 529
    }

    if (is_compound) {
530 531 532 533
#if CONFIG_EXT_REFS
      const int bit_fwd = (mbmi->ref_frame[0] == GOLDEN_FRAME ||
                           mbmi->ref_frame[0] == LAST3_FRAME);
      const int bit_bwd = mbmi->ref_frame[1] == ALTREF_FRAME;
534 535

      // Write forward references.
536 537 538 539 540 541 542 543
      aom_write(w, bit_fwd, av1_get_pred_prob_comp_fwdref_p(cm, xd));
      if (!bit_fwd) {
        const int bit1_fwd = mbmi->ref_frame[0] == LAST_FRAME;
        aom_write(w, bit1_fwd, av1_get_pred_prob_comp_fwdref_p1(cm, xd));
      } else {
        const int bit2_fwd = mbmi->ref_frame[0] == GOLDEN_FRAME;
        aom_write(w, bit2_fwd, av1_get_pred_prob_comp_fwdref_p2(cm, xd));
      }
544
      // Write forward references.
545 546
      aom_write(w, bit_bwd, av1_get_pred_prob_comp_bwdref_p(cm, xd));
#else
Adrian Grange's avatar
Adrian Grange committed
547
      aom_write(w, mbmi->ref_frame[0] == GOLDEN_FRAME,
548
                av1_get_pred_prob_comp_ref_p(cm, xd));
549
#endif  // CONFIG_EXT_REFS
Jingning Han's avatar
Jingning Han committed
550
    } else {
551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570
#if CONFIG_EXT_REFS
      const int bit0 = (mbmi->ref_frame[0] == ALTREF_FRAME ||
                        mbmi->ref_frame[0] == BWDREF_FRAME);
      aom_write(w, bit0, av1_get_pred_prob_single_ref_p1(cm, xd));
      if (bit0) {
        const int bit1 = mbmi->ref_frame[0] == ALTREF_FRAME;
        aom_write(w, bit1, av1_get_pred_prob_single_ref_p2(cm, xd));
      } else {
        const int bit2 = (mbmi->ref_frame[0] == LAST3_FRAME ||
                          mbmi->ref_frame[0] == GOLDEN_FRAME);
        aom_write(w, bit2, av1_get_pred_prob_single_ref_p3(cm, xd));
        if (!bit2) {
          const int bit3 = mbmi->ref_frame[0] != LAST_FRAME;
          aom_write(w, bit3, av1_get_pred_prob_single_ref_p4(cm, xd));
        } else {
          const int bit4 = mbmi->ref_frame[0] != LAST3_FRAME;
          aom_write(w, bit4, av1_get_pred_prob_single_ref_p5(cm, xd));
        }
      }
#else
Jingning Han's avatar
Jingning Han committed
571
      const int bit0 = mbmi->ref_frame[0] != LAST_FRAME;
572
      aom_write(w, bit0, av1_get_pred_prob_single_ref_p1(cm, xd));
Jingning Han's avatar
Jingning Han committed
573 574
      if (bit0) {
        const int bit1 = mbmi->ref_frame[0] != GOLDEN_FRAME;
575
        aom_write(w, bit1, av1_get_pred_prob_single_ref_p2(cm, xd));
Jingning Han's avatar
Jingning Han committed
576
      }
577
#endif  // CONFIG_EXT_REFS
Jingning Han's avatar
Jingning Han committed
578 579 580 581
    }
  }
}

582
#if CONFIG_EXT_INTRA || CONFIG_PALETTE
hui su's avatar
hui su committed
583 584 585 586 587 588 589 590 591 592 593 594
static INLINE void write_uniform(aom_writer *w, int n, int v) {
  const int l = get_unsigned_bits(n);
  const int m = (1 << l) - n;

  if (l == 0) return;
  if (v < m) {
    aom_write_literal(w, v, l - 1);
  } else {
    aom_write_literal(w, m + ((v - m) >> 1), l - 1);
    aom_write_literal(w, (v - m) & 1, 1);
  }
}
595
#endif  // CONFIG_EXT_INTRA || CONFIG_PALETTE
hui su's avatar
hui su committed
596

597
#if CONFIG_EXT_INTRA
hui su's avatar
hui su committed
598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615
static void write_intra_angle_info(const MB_MODE_INFO *const mbmi,
                                   aom_writer *w) {
  if (mbmi->sb_type < BLOCK_8X8) return;

  if (is_directional_mode(mbmi->mode)) {
    const TX_SIZE max_tx_size = max_txsize_lookup[mbmi->sb_type];
    const int max_angle_delta = av1_max_angle_delta_y[max_tx_size][mbmi->mode];
    write_uniform(w, 2 * max_angle_delta + 1,
                  max_angle_delta + mbmi->intra_angle_delta[0]);
  }

  if (is_directional_mode(mbmi->uv_mode)) {
    write_uniform(w, 2 * MAX_ANGLE_DELTA_UV + 1,
                  MAX_ANGLE_DELTA_UV + mbmi->intra_angle_delta[1]);
  }
}
#endif  // CONFIG_EXT_INTRA

616 617 618 619 620 621
static void write_switchable_interp_filter(AV1_COMP *const cpi,
                                           const MACROBLOCKD *const xd,
                                           aom_writer *w) {
  const AV1_COMMON *const cm = &cpi->common;
  const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
  if (cm->interp_filter == SWITCHABLE) {
622
    int ctx;
623
#if CONFIG_EXT_INTERP
624 625 626 627
    if (!is_interp_needed(xd)) {
      assert(mbmi->interp_filter == EIGHTTAP);
      return;
    }
628
#endif
629
    ctx = av1_get_pred_context_switchable_interp(xd);
630
#if CONFIG_DAALA_EC
631 632
    aom_write_symbol(w, av1_switchable_interp_ind[mbmi->interp_filter],
                     cm->fc->switchable_interp_cdf[ctx], SWITCHABLE_FILTERS);
633
#else
634 635 636
    av1_write_token(w, av1_switchable_interp_tree,
                    cm->fc->switchable_interp_prob[ctx],
                    &switchable_interp_encodings[mbmi->interp_filter]);
637
#endif
638
    ++cpi->interp_filter_selected[0][mbmi->interp_filter];
639 640 641
  }
}

642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688
#if CONFIG_PALETTE
static void write_palette_mode_info(const AV1_COMMON *cm, const MACROBLOCKD *xd,
                                    const MODE_INFO *const mi, aom_writer *w) {
  const MB_MODE_INFO *const mbmi = &mi->mbmi;
  const MODE_INFO *const above_mi = xd->above_mi;
  const MODE_INFO *const left_mi = xd->left_mi;
  const BLOCK_SIZE bsize = mbmi->sb_type;
  const PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
  int palette_ctx = 0;
  int n, i;
  if (mbmi->mode == DC_PRED) {
    n = pmi->palette_size[0];
    if (above_mi)
      palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
    if (left_mi)
      palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
    aom_write(w, n > 0,
              av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx]);
    if (n > 0) {
      av1_write_token(w, av1_palette_size_tree,
                      av1_default_palette_y_size_prob[bsize - BLOCK_8X8],
                      &palette_size_encodings[n - 2]);
      for (i = 0; i < n; ++i)
        aom_write_literal(w, pmi->palette_colors[i], cm->bit_depth);
      write_uniform(w, n, pmi->palette_first_color_idx[0]);
    }
  }
  if (mbmi->uv_mode == DC_PRED) {
    n = pmi->palette_size[1];
    aom_write(w, n > 0,
              av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0]);
    if (n > 0) {
      av1_write_token(w, av1_palette_size_tree,
                      av1_default_palette_uv_size_prob[bsize - BLOCK_8X8],
                      &palette_size_encodings[n - 2]);
      for (i = 0; i < n; ++i) {
        aom_write_literal(w, pmi->palette_colors[PALETTE_MAX_SIZE + i],
                          cm->bit_depth);
        aom_write_literal(w, pmi->palette_colors[2 * PALETTE_MAX_SIZE + i],
                          cm->bit_depth);
      }
      write_uniform(w, n, pmi->palette_first_color_idx[1]);
    }
  }
}
#endif  // CONFIG_PALETTE

689
static void pack_inter_mode_mvs(AV1_COMP *cpi, const MODE_INFO *mi,
Adrian Grange's avatar
Adrian Grange committed
690
                                aom_writer *w) {
691
  AV1_COMMON *const cm = &cpi->common;
692
#if !CONFIG_REF_MV
Jingning Han's avatar
Jingning Han committed
693
  const nmv_context *nmvc = &cm->fc->nmvc;
694
#endif
Jingning Han's avatar
Jingning Han committed
695 696 697
  const MACROBLOCK *const x = &cpi->td.mb;
  const MACROBLOCKD *const xd = &x->e_mbd;
  const struct segmentation *const seg = &cm->seg;
698 699 700 701 702
#if CONFIG_MISC_FIXES
  const struct segmentation_probs *const segp = &cm->fc->seg;
#else
  const struct segmentation_probs *const segp = &cm->segp;
#endif
Jingning Han's avatar
Jingning Han committed
703 704 705 706 707 708 709 710 711 712 713 714 715
  const MB_MODE_INFO *const mbmi = &mi->mbmi;
  const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
  const PREDICTION_MODE mode = mbmi->mode;
  const int segment_id = mbmi->segment_id;
  const BLOCK_SIZE bsize = mbmi->sb_type;
  const int allow_hp = cm->allow_high_precision_mv;
  const int is_inter = is_inter_block(mbmi);
  const int is_compound = has_second_ref(mbmi);
  int skip, ref;

  if (seg->update_map) {
    if (seg->temporal_update) {
      const int pred_flag = mbmi->seg_id_predicted;
716
      aom_prob pred_prob = av1_get_pred_prob_seg_id(segp, xd);
Adrian Grange's avatar
Adrian Grange committed
717
      aom_write(w, pred_flag, pred_prob);
clang-format's avatar
clang-format committed
718
      if (!pred_flag) write_segment_id(w, seg, segp, segment_id);
Jingning Han's avatar
Jingning Han committed
719
    } else {
720
      write_segment_id(w, seg, segp, segment_id);
Jingning Han's avatar
Jingning Han committed
721 722 723 724 725 726
    }
  }

  skip = write_skip(cm, xd, segment_id, mi, w);

  if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
727
    aom_write(w, is_inter, av1_get_intra_inter_prob(cm, xd));
Jingning Han's avatar
Jingning Han committed
728 729

  if (bsize >= BLOCK_8X8 && cm->tx_mode == TX_MODE_SELECT &&
730
      !(is_inter && skip) && !xd->lossless[segment_id]) {
Jingning Han's avatar
Jingning Han committed
731 732 733 734 735
    write_selected_tx_size(cm, xd, w);
  }

  if (!is_inter) {
    if (bsize >= BLOCK_8X8) {
736 737 738 739 740
#if CONFIG_DAALA_EC
      aom_write_symbol(w, av1_intra_mode_ind[mode],
                       cm->fc->y_mode_cdf[size_group_lookup[bsize]],
                       INTRA_MODES);
#else
Jingning Han's avatar
Jingning Han committed
741
      write_intra_mode(w, mode, cm->fc->y_mode_prob[size_group_lookup[bsize]]);
742
#endif
Jingning Han's avatar
Jingning Han committed
743 744 745 746 747 748 749
    } else {
      int idx, idy;
      const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
      const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
      for (idy = 0; idy < 2; idy += num_4x4_h) {
        for (idx = 0; idx < 2; idx += num_4x4_w) {
          const PREDICTION_MODE b_mode = mi->bmi[idy * 2 + idx].as_mode;
750 751 752 753
#if CONFIG_DAALA_EC
          aom_write_symbol(w, av1_intra_mode_ind[b_mode], cm->fc->y_mode_cdf[0],
                           INTRA_MODES);
#else
Jingning Han's avatar
Jingning Han committed
754
          write_intra_mode(w, b_mode, cm->fc->y_mode_prob[0]);
755
#endif
Jingning Han's avatar
Jingning Han committed
756 757 758
        }
      }
    }
759 760 761 762
#if CONFIG_DAALA_EC
    aom_write_symbol(w, av1_intra_mode_ind[mbmi->uv_mode],
                     cm->fc->uv_mode_cdf[mode], INTRA_MODES);
#else
Jingning Han's avatar
Jingning Han committed
763
    write_intra_mode(w, mbmi->uv_mode, cm->fc->uv_mode_prob[mode]);
764
#endif
hui su's avatar
hui su committed
765 766 767
#if CONFIG_EXT_INTRA
    write_intra_angle_info(mbmi, w);
#endif  // CONFIG_EXT_INTRA
768 769 770 771 772

#if CONFIG_PALETTE
    if (bsize >= BLOCK_8X8 && cm->allow_screen_content_tools)
      write_palette_mode_info(cm, xd, mi, w);
#endif  // CONFIG_PALETTE
Jingning Han's avatar
Jingning Han committed
773
  } else {
774
    int16_t mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
Jingning Han's avatar
Jingning Han committed
775 776
    write_ref_frames(cm, xd, w);

777
#if CONFIG_REF_MV
778 779
    mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
                                         mbmi->ref_frame, bsize, -1);
780 781
#endif

Jingning Han's avatar
Jingning Han committed
782 783 784
    // If segment skip is not enabled code the mode.
    if (!segfeature_active(seg, segment_id, SEG_LVL_SKIP)) {
      if (bsize >= BLOCK_8X8) {
785
        write_inter_mode(cm, w, mode, mode_ctx);
786
#if CONFIG_REF_MV
787
        if (mode == NEARMV || mode == NEWMV)
788
          write_drl_idx(cm, mbmi, mbmi_ext, w);
789
#endif
Jingning Han's avatar
Jingning Han committed
790 791 792
      }
    }

793 794 795
#if !CONFIG_EXT_INTERP
    write_switchable_interp_filter(cpi, xd, w);
#endif  // CONFIG_EXT_INTERP
Jingning Han's avatar
Jingning Han committed
796 797 798 799 800 801 802 803 804

    if (bsize < BLOCK_8X8) {
      const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
      const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
      int idx, idy;
      for (idy = 0; idy < 2; idy += num_4x4_h) {
        for (idx = 0; idx < 2; idx += num_4x4_w) {
          const int j = idy * 2 + idx;
          const PREDICTION_MODE b_mode = mi->bmi[j].as_mode;
805 806 807 808
#if CONFIG_REF_MV
          mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
                                               mbmi->ref_frame, bsize, j);
#endif
809
          write_inter_mode(cm, w, b_mode, mode_ctx);
Jingning Han's avatar
Jingning Han committed
810
          if (b_mode == NEWMV) {
811 812
            for (ref = 0; ref < 1 + is_compound; ++ref) {
#if CONFIG_REF_MV
813 814 815 816
              int8_t rf_type = av1_ref_frame_type(mbmi->ref_frame);
              int nmv_ctx = av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type],
                                        mbmi_ext->ref_mv_stack[rf_type], ref,
                                        mbmi->ref_mv_idx);
817 818
              const nmv_context *nmvc = &cm->fc->nmvc[nmv_ctx];
#endif
819
              av1_encode_mv(cpi, w, &mi->bmi[j].as_mv[ref].as_mv,
clang-format's avatar
clang-format committed
820 821
                            &mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0].as_mv,
                            nmvc, allow_hp);
822
            }
Jingning Han's avatar
Jingning Han committed
823 824 825 826 827
          }
        }
      }
    } else {
      if (mode == NEWMV) {
828
        int_mv ref_mv;
829 830
        for (ref = 0; ref < 1 + is_compound; ++ref) {
#if CONFIG_REF_MV
831 832 833 834
          int8_t rf_type = av1_ref_frame_type(mbmi->ref_frame);
          int nmv_ctx = av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type],
                                    mbmi_ext->ref_mv_stack[rf_type], ref,
                                    mbmi->ref_mv_idx);
835
          const nmv_context *nmvc = &cm->fc->nmvc[nmv_ctx];
836
#endif
837
          ref_mv = mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0];
clang-format's avatar
clang-format committed
838 839
          av1_encode_mv(cpi, w, &mbmi->mv[ref].as_mv, &ref_mv.as_mv, nmvc,
                        allow_hp);
840
        }
Jingning Han's avatar
Jingning Han committed
841 842
      }
    }
843 844 845
#if CONFIG_MOTION_VAR
    write_motion_mode(cm, mbmi, w);
#endif  // CONFIG_MOTION_VAR
846 847 848
#if CONFIG_EXT_INTERP
    write_switchable_interp_filter(cpi, xd, w);
#endif  // CONFIG_EXT_INTERP
Jingning Han's avatar
Jingning Han committed
849
  }
850

clang-format's avatar
clang-format committed
851
  if (mbmi->tx_size < TX_32X32 && cm->base_qindex > 0 && !mbmi->skip &&
852 853
      !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
    if (is_inter) {
854
#if CONFIG_DAALA_EC
855 856
      aom_write_symbol(w, av1_ext_tx_ind[mbmi->tx_type],
                       cm->fc->inter_ext_tx_cdf[mbmi->tx_size], TX_TYPES);
857
#else
858
      av1_write_token(w, av1_ext_tx_tree,
clang-format's avatar
clang-format committed
859 860
                      cm->fc->inter_ext_tx_prob[mbmi->tx_size],
                      &ext_tx_encodings[mbmi->tx_type]);
861
#endif
862
    } else {
863
#if CONFIG_DAALA_EC
864
      aom_write_symbol(
865 866 867 868 869
          w, av1_ext_tx_ind[mbmi->tx_type],
          cm->fc->intra_ext_tx_cdf[mbmi->tx_size]
                                  [intra_mode_to_tx_type_context[mbmi->mode]],
          TX_TYPES);
#else
870 871
      av1_write_token(
          w, av1_ext_tx_tree,
872 873 874
          cm->fc->intra_ext_tx_prob[mbmi->tx_size]
                                   [intra_mode_to_tx_type_context[mbmi->mode]],
          &ext_tx_encodings[mbmi->tx_type]);
875
#endif
876 877
    }
  } else {
clang-format's avatar
clang-format committed
878
    if (!mbmi->skip) assert(mbmi->tx_type == DCT_DCT);
879
  }
Jingning Han's avatar
Jingning Han committed
880 881
}

882
static void write_mb_modes_kf(const AV1_COMMON *cm, const MACROBLOCKD *xd,
Adrian Grange's avatar
Adrian Grange committed
883
                              MODE_INFO **mi_8x8, aom_writer *w) {
Jingning Han's avatar
Jingning Han committed
884
  const struct segmentation *const seg = &cm->seg;
885 886 887 888 889
#if CONFIG_MISC_FIXES
  const struct segmentation_probs *const segp = &cm->fc->seg;
#else
  const struct segmentation_probs *const segp = &cm->segp;
#endif
Jingning Han's avatar
Jingning Han committed
890 891 892 893 894 895
  const MODE_INFO *const mi = mi_8x8[0];
  const MODE_INFO *const above_mi = xd->above_mi;
  const MODE_INFO *const left_mi = xd->left_mi;
  const MB_MODE_INFO *const mbmi = &mi->mbmi;
  const BLOCK_SIZE bsize = mbmi->sb_type;

clang-format's avatar
clang-format committed
896
  if (seg->update_map) write_segment_id(w, seg, segp, mbmi->segment_id);
Jingning Han's avatar
Jingning Han committed
897 898 899

  write_skip(cm, xd, mbmi->segment_id, mi, w);

900 901
  if (bsize >= BLOCK_8X8 && cm->tx_mode == TX_MODE_SELECT &&
      !xd->lossless[mbmi->segment_id])
Jingning Han's avatar
Jingning Han committed
902 903 904
    write_selected_tx_size(cm, xd, w);

  if (bsize >= BLOCK_8X8) {
905 906 907 908
#if CONFIG_DAALA_EC
    aom_write_symbol(w, av1_intra_mode_ind[mbmi->mode],
                     get_y_mode_cdf(cm, mi, above_mi, left_mi, 0), INTRA_MODES);
#else
909 910
    write_intra_mode(w, mbmi->mode,
                     get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
911
#endif
Jingning Han's avatar
Jingning Han committed
912 913 914 915 916 917 918 919
  } else {
    const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
    const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
    int idx, idy;

    for (idy = 0; idy < 2; idy += num_4x4_h) {
      for (idx = 0; idx < 2; idx += num_4x4_w) {
        const int block = idy * 2 + idx;
920 921 922 923 924
#if CONFIG_DAALA_EC
        aom_write_symbol(w, av1_intra_mode_ind[mi->bmi[block].as_mode],
                         get_y_mode_cdf(cm, mi, above_mi, left_mi, block),
                         INTRA_MODES);
#else
Jingning Han's avatar
Jingning Han committed
925
        write_intra_mode(w, mi->bmi[block].as_mode,
926
                         get_y_mode_probs(cm, mi, above_mi, left_mi, block));
927
#endif
Jingning Han's avatar
Jingning Han committed
928 929 930
      }
    }
  }
931 932 933 934
#if CONFIG_DAALA_EC
  aom_write_symbol(w, av1_intra_mode_ind[mbmi->uv_mode],
                   cm->fc->uv_mode_cdf[mbmi->mode], INTRA_MODES);
#else
935
  write_intra_mode(w, mbmi->uv_mode, cm->fc->uv_mode_prob[mbmi->mode]);
936
#endif
hui su's avatar
hui su committed
937 938 939
#if CONFIG_EXT_INTRA
  write_intra_angle_info(mbmi, w);
#endif  // CONFIG_EXT_INTRA
940

941 942 943 944 945
#if CONFIG_PALETTE
  if (bsize >= BLOCK_8X8 && cm->allow_screen_content_tools)
    write_palette_mode_info(cm, xd, mi, w);
#endif  // CONFIG_PALETTE

clang-format's avatar
clang-format committed
946
  if (mbmi->tx_size < TX_32X32 && cm->base_qindex > 0 && !mbmi->skip &&
947
      !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
948 949 950 951 952 953 954
#if CONFIG_DAALA_EC
    aom_write_symbol(
        w, av1_ext_tx_ind[mbmi->tx_type],
        cm->fc->intra_ext_tx_cdf[mbmi->tx_size]
                                [intra_mode_to_tx_type_context[mbmi->mode]],
        TX_TYPES);
#else
955 956
    av1_write_token(
        w, av1_ext_tx_tree,
957 958 959
        cm->fc->intra_ext_tx_prob[mbmi->tx_size]
                                 [intra_mode_to_tx_type_context[mbmi->mode]],
        &ext_tx_encodings[mbmi->tx_type]);
960
#endif
961
  }
Jingning Han's avatar
Jingning Han committed
962 963
}

964
static void write_modes_b(AV1_COMP *cpi, const TileInfo *const tile,
Adrian Grange's avatar
Adrian Grange committed
965
                          aom_writer *w, TOKENEXTRA **tok,
clang-format's avatar
clang-format committed
966 967
                          const TOKENEXTRA *const tok_end, int mi_row,
                          int mi_col) {