bitstream.c 127 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1
2
3
4
5
6
7
8
9
10
11
12
/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

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

15
16
17
18
19
20
21
#include "aom/vpx_encoder.h"
#include "aom_dsp/bitwriter_buffer.h"
#include "aom_dsp/vpx_dsp_common.h"
#include "aom_mem/vpx_mem.h"
#include "aom_ports/mem_ops.h"
#include "aom_ports/system_state.h"
#include "aom_util/debug_util.h"
Jingning Han's avatar
Jingning Han committed
22

23
#if CONFIG_CLPF
24
#include "av1/common/clpf.h"
25
#endif
Yaowu Xu's avatar
Yaowu Xu committed
26
#if CONFIG_DERING
27
#include "av1/common/dering.h"
Yaowu Xu's avatar
Yaowu Xu committed
28
#endif  // CONFIG_DERING
29
30
31
32
33
34
35
36
#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"
#include "av1/common/reconinter.h"
#include "av1/common/seg_common.h"
#include "av1/common/tile_common.h"
Jingning Han's avatar
Jingning Han committed
37

Alex Converse's avatar
Alex Converse committed
38
#if CONFIG_ANS
39
#include "av1/encoder/buf_ans.h"
Alex Converse's avatar
Alex Converse committed
40
#endif  // CONFIG_ANS
41
42
43
44
45
46
47
#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"
Jingning Han's avatar
Jingning Han committed
48
49

static const struct vp10_token intra_mode_encodings[INTRA_MODES] = {
50
51
52
  { 0, 1 },  { 6, 3 },   { 28, 5 },  { 30, 5 }, { 58, 6 },
  { 59, 6 }, { 126, 7 }, { 127, 7 }, { 62, 6 }, { 2, 2 }
};
Jingning Han's avatar
Jingning Han committed
53
#if CONFIG_EXT_INTERP
54
static const struct vp10_token switchable_interp_encodings[SWITCHABLE_FILTERS] =
55
    { { 0, 1 }, { 4, 3 }, { 6, 3 }, { 5, 3 }, { 7, 3 } };
56
#else
Jingning Han's avatar
Jingning Han committed
57
static const struct vp10_token switchable_interp_encodings[SWITCHABLE_FILTERS] =
58
    { { 0, 1 }, { 2, 2 }, { 3, 2 } };
Jingning Han's avatar
Jingning Han committed
59
#endif  // CONFIG_EXT_INTERP
60
#if CONFIG_EXT_PARTITION_TYPES
61
62
63
64
static const struct vp10_token ext_partition_encodings[EXT_PARTITION_TYPES] = {
  { 0, 1 },  { 4, 3 },  { 12, 4 }, { 7, 3 },
  { 10, 4 }, { 11, 4 }, { 26, 5 }, { 27, 5 }
};
65
#endif
66
67
68
static const struct vp10_token partition_encodings[PARTITION_TYPES] = {
  { 0, 1 }, { 2, 2 }, { 6, 3 }, { 7, 3 }
};
69
#if !CONFIG_REF_MV
Jingning Han's avatar
Jingning Han committed
70
static const struct vp10_token inter_mode_encodings[INTER_MODES] =
Yue Chen's avatar
Yue Chen committed
71
#if CONFIG_EXT_INTER
72
    { { 2, 2 }, { 6, 3 }, { 0, 1 }, { 14, 4 }, { 15, 4 } };
Yue Chen's avatar
Yue Chen committed
73
#else
74
    { { 2, 2 }, { 6, 3 }, { 0, 1 }, { 7, 3 } };
Yue Chen's avatar
Yue Chen committed
75
#endif  // CONFIG_EXT_INTER
76
#endif
77
#if CONFIG_EXT_INTER
78
79
80
81
82
static const struct vp10_token
    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 }
    };
83
#endif  // CONFIG_EXT_INTER
hui su's avatar
hui su committed
84
static const struct vp10_token palette_size_encodings[] = {
85
  { 0, 1 }, { 2, 2 }, { 6, 3 }, { 14, 4 }, { 30, 5 }, { 62, 6 }, { 63, 6 },
hui su's avatar
hui su committed
86
};
87
static const struct vp10_token
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
    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
    };

static const struct vp10_token tx_size_encodings[TX_SIZES - 1][TX_SIZES] = {
  { { 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
120
121
};

122
static INLINE void write_uniform(vp10_writer *w, int n, int v) {
hui su's avatar
hui su committed
123
124
  int l = get_unsigned_bits(n);
  int m = (1 << l) - n;
125
  if (l == 0) return;
hui su's avatar
hui su committed
126
  if (v < m) {
127
    vp10_write_literal(w, v, l - 1);
hui su's avatar
hui su committed
128
  } else {
129
130
    vp10_write_literal(w, m + ((v - m) >> 1), l - 1);
    vp10_write_literal(w, (v - m) & 1, 1);
hui su's avatar
hui su committed
131
132
  }
}
Jingning Han's avatar
Jingning Han committed
133

134
#if CONFIG_EXT_TX
135
136
static struct vp10_token ext_tx_inter_encodings[EXT_TX_SETS_INTER][TX_TYPES];
static struct vp10_token ext_tx_intra_encodings[EXT_TX_SETS_INTRA][TX_TYPES];
137
#else
138
static struct vp10_token ext_tx_encodings[TX_TYPES];
139
#endif  // CONFIG_EXT_TX
140
141
142
#if CONFIG_GLOBAL_MOTION
static struct vp10_token global_motion_types_encodings[GLOBAL_MOTION_TYPES];
#endif  // CONFIG_GLOBAL_MOTION
143
144
145
#if CONFIG_EXT_INTRA
static struct vp10_token intra_filter_encodings[INTRA_FILTERS];
#endif  // CONFIG_EXT_INTRA
146
147
148
#if CONFIG_EXT_INTER
static struct vp10_token interintra_mode_encodings[INTERINTRA_MODES];
#endif  // CONFIG_EXT_INTER
149
150
151
#if CONFIG_OBMC || CONFIG_WARPED_MOTION
static struct vp10_token motvar_encodings[MOTION_VARIATIONS];
#endif  // CONFIG_OBMC || CONFIG_WARPED_MOTION
152

153
void vp10_encode_token_init(void) {
154
#if CONFIG_EXT_TX
155
156
157
158
159
160
161
  int s;
  for (s = 1; s < EXT_TX_SETS_INTER; ++s) {
    vp10_tokens_from_tree(ext_tx_inter_encodings[s], vp10_ext_tx_inter_tree[s]);
  }
  for (s = 1; s < EXT_TX_SETS_INTRA; ++s) {
    vp10_tokens_from_tree(ext_tx_intra_encodings[s], vp10_ext_tx_intra_tree[s]);
  }
162
#else
163
  vp10_tokens_from_tree(ext_tx_encodings, vp10_ext_tx_tree);
164
#endif  // CONFIG_EXT_TX
165
166
167
#if CONFIG_EXT_INTRA
  vp10_tokens_from_tree(intra_filter_encodings, vp10_intra_filter_tree);
#endif  // CONFIG_EXT_INTRA
168
169
170
#if CONFIG_EXT_INTER
  vp10_tokens_from_tree(interintra_mode_encodings, vp10_interintra_mode_tree);
#endif  // CONFIG_EXT_INTER
171
172
173
#if CONFIG_OBMC || CONFIG_WARPED_MOTION
  vp10_tokens_from_tree(motvar_encodings, vp10_motvar_tree);
#endif  // CONFIG_OBMC || CONFIG_WARPED_MOTION
174
175
#if CONFIG_GLOBAL_MOTION
  vp10_tokens_from_tree(global_motion_types_encodings,
176
                        vp10_global_motion_types_tree);
177
#endif  // CONFIG_GLOBAL_MOTION
178
179
}

180
static void write_intra_mode(vp10_writer *w, PREDICTION_MODE mode,
Jingning Han's avatar
Jingning Han committed
181
182
183
184
                             const vpx_prob *probs) {
  vp10_write_token(w, vp10_intra_mode_tree, probs, &intra_mode_encodings[mode]);
}

185
#if CONFIG_EXT_INTER
186
static void write_interintra_mode(vp10_writer *w, INTERINTRA_MODE mode,
187
188
189
190
191
192
                                  const vpx_prob *probs) {
  vp10_write_token(w, vp10_interintra_mode_tree, probs,
                   &interintra_mode_encodings[mode]);
}
#endif  // CONFIG_EXT_INTER

193
194
static void write_inter_mode(VP10_COMMON *cm, vp10_writer *w,
                             PREDICTION_MODE mode,
Yue Chen's avatar
Yue Chen committed
195
196
197
#if CONFIG_REF_MV && CONFIG_EXT_INTER
                             int is_compound,
#endif  // CONFIG_REF_MV && CONFIG_EXT_INTER
198
                             const int16_t mode_ctx) {
199
#if CONFIG_REF_MV
200
  const int16_t newmv_ctx = mode_ctx & NEWMV_CTX_MASK;
201
  const vpx_prob newmv_prob = cm->fc->newmv_prob[newmv_ctx];
Yue Chen's avatar
Yue Chen committed
202
#if CONFIG_EXT_INTER
203
  vp10_write(w, mode != NEWMV && mode != NEWFROMNEARMV, newmv_prob);
Yue Chen's avatar
Yue Chen committed
204
205

  if (!is_compound && (mode == NEWMV || mode == NEWFROMNEARMV))
206
    vp10_write(w, mode == NEWFROMNEARMV, cm->fc->new2mv_prob);
Yue Chen's avatar
Yue Chen committed
207
208
209

  if (mode != NEWMV && mode != NEWFROMNEARMV) {
#else
210
  vp10_write(w, mode != NEWMV, newmv_prob);
211
212

  if (mode != NEWMV) {
Yue Chen's avatar
Yue Chen committed
213
#endif  // CONFIG_EXT_INTER
214
    const int16_t zeromv_ctx = (mode_ctx >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
215
    const vpx_prob zeromv_prob = cm->fc->zeromv_prob[zeromv_ctx];
216
217
218
219
220
221

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

222
    vp10_write(w, mode != ZEROMV, zeromv_prob);
223
224

    if (mode != ZEROMV) {
225
226
227
      int16_t refmv_ctx = (mode_ctx >> REFMV_OFFSET) & REFMV_CTX_MASK;
      vpx_prob refmv_prob;

228
229
230
      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;
231
232

      refmv_prob = cm->fc->refmv_prob[refmv_ctx];
233
      vp10_write(w, mode != NEARESTMV, refmv_prob);
234
235
236
237
    }
  }
#else
  const vpx_prob *const inter_probs = cm->fc->inter_mode_probs[mode_ctx];
Jingning Han's avatar
Jingning Han committed
238
  assert(is_inter_mode(mode));
239
  vp10_write_token(w, vp10_inter_mode_tree, inter_probs,
240
                   &inter_mode_encodings[INTER_OFFSET(mode)]);
241
#endif
Jingning Han's avatar
Jingning Han committed
242
243
}

244
#if CONFIG_REF_MV
245
246
static void write_drl_idx(const VP10_COMMON *cm, const MB_MODE_INFO *mbmi,
                          const MB_MODE_INFO_EXT *mbmi_ext, vp10_writer *w) {
247
  uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
248
249
250

  assert(mbmi->ref_mv_idx < 3);

251
252
253
254
255
256
257
258
  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 =
            vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
        vpx_prob drl_prob = cm->fc->drl_prob[drl_ctx];

259
        vp10_write(w, mbmi->ref_mv_idx != idx, drl_prob);
260
        if (mbmi->ref_mv_idx == idx) return;
261
      }
262
263
264
265
    }
    return;
  }

266
267
268
269
270
271
272
273
274
  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 =
            vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
        vpx_prob drl_prob = cm->fc->drl_prob[drl_ctx];

275
        vp10_write(w, mbmi->ref_mv_idx != (idx - 1), drl_prob);
276
        if (mbmi->ref_mv_idx == (idx - 1)) return;
277
      }
278
    }
279
    return;
280
281
282
283
  }
}
#endif

284
#if CONFIG_EXT_INTER
285
static void write_inter_compound_mode(VP10_COMMON *cm, vp10_writer *w,
286
287
288
                                      PREDICTION_MODE mode,
                                      const int16_t mode_ctx) {
  const vpx_prob *const inter_compound_probs =
289
      cm->fc->inter_compound_mode_probs[mode_ctx];
290
291
292

  assert(is_inter_compound_mode(mode));
  vp10_write_token(w, vp10_inter_compound_mode_tree, inter_compound_probs,
293
                   &inter_compound_mode_encodings[INTER_COMPOUND_OFFSET(mode)]);
294
295
296
}
#endif  // CONFIG_EXT_INTER

297
298
static void encode_unsigned_max(struct vpx_write_bit_buffer *wb, int data,
                                int max) {
Jingning Han's avatar
Jingning Han committed
299
300
301
302
303
  vpx_wb_write_literal(wb, data, get_unsigned_bits(max));
}

static void prob_diff_update(const vpx_tree_index *tree,
                             vpx_prob probs[/*n - 1*/],
304
305
                             const unsigned int counts[/*n - 1*/], int n,
                             vp10_writer *w) {
Jingning Han's avatar
Jingning Han committed
306
307
308
309
310
311
312
313
314
315
316
  int i;
  unsigned int branch_ct[32][2];

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

  vp10_tree_probs_from_distribution(tree, branch_ct, counts);
  for (i = 0; i < n - 1; ++i)
    vp10_cond_prob_diff_update(w, &probs[i], branch_ct[i]);
}

317
318
319
320
321
322
323
324
325
326
327
328
static int prob_diff_update_savings(const vpx_tree_index *tree,
                                    vpx_prob probs[/*n - 1*/],
                                    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);
  vp10_tree_probs_from_distribution(tree, branch_ct, counts);
  for (i = 0; i < n - 1; ++i) {
329
    savings += vp10_cond_prob_diff_update_savings(&probs[i], branch_ct[i]);
330
331
332
333
  }
  return savings;
}

334
#if CONFIG_VAR_TX
Debargha Mukherjee's avatar
Debargha Mukherjee committed
335
static void write_tx_size_vartx(const VP10_COMMON *cm, const MACROBLOCKD *xd,
336
337
                                const MB_MODE_INFO *mbmi, TX_SIZE tx_size,
                                int blk_row, int blk_col, vp10_writer *w) {
338
339
  const int tx_row = blk_row >> 1;
  const int tx_col = blk_col >> 1;
340
341
  int max_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
  int max_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
342
  int ctx = txfm_partition_context(xd->above_txfm_context + tx_col,
343
                                   xd->left_txfm_context + tx_row, tx_size);
344

345
346
  if (xd->mb_to_bottom_edge < 0) max_blocks_high += xd->mb_to_bottom_edge >> 5;
  if (xd->mb_to_right_edge < 0) max_blocks_wide += xd->mb_to_right_edge >> 5;
347

348
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
349

350
  if (tx_size == mbmi->inter_tx_size[tx_row][tx_col]) {
351
    vp10_write(w, 0, cm->fc->txfm_partition_prob[ctx]);
352
353
    txfm_partition_update(xd->above_txfm_context + tx_col,
                          xd->left_txfm_context + tx_row, tx_size);
354
355
  } else {
    const BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
356
    int bsl = b_width_log2_lookup[bsize];
357
    int i;
358
    vp10_write(w, 1, cm->fc->txfm_partition_prob[ctx]);
359

360
    if (tx_size == TX_8X8) {
361
362
      txfm_partition_update(xd->above_txfm_context + tx_col,
                            xd->left_txfm_context + tx_row, TX_4X4);
363
      return;
364
    }
365
366
367
368

    assert(bsl > 0);
    --bsl;
    for (i = 0; i < 4; ++i) {
369
370
      int offsetr = blk_row + ((i >> 1) << bsl);
      int offsetc = blk_col + ((i & 0x01) << bsl);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
371
      write_tx_size_vartx(cm, xd, mbmi, tx_size - 1, offsetr, offsetc, w);
372
373
374
    }
  }
}
375

376
static void update_txfm_partition_probs(VP10_COMMON *cm, vp10_writer *w,
377
378
379
380
381
382
                                        FRAME_COUNTS *counts) {
  int k;
  for (k = 0; k < TXFM_PARTITION_CONTEXTS; ++k)
    vp10_cond_prob_diff_update(w, &cm->fc->txfm_partition_prob[k],
                               counts->txfm_partition[k]);
}
383
384
#endif

385
386
static void write_selected_tx_size(const VP10_COMMON *cm, const MACROBLOCKD *xd,
                                   vp10_writer *w) {
387
388
  const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
  const BLOCK_SIZE bsize = mbmi->sb_type;
389
390
  // For sub8x8 blocks the tx_size symbol does not need to be sent
  if (bsize >= BLOCK_8X8) {
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
    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];

#if CONFIG_EXT_TX && CONFIG_RECT_TX
    assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed(mbmi)));
    assert(
        IMPLIES(is_rect_tx(tx_size), tx_size == max_txsize_rect_lookup[bsize]));
#endif  // CONFIG_EXT_TX && CONFIG_RECT_TX

    vp10_write_token(w, vp10_tx_size_tree[tx_size_cat],
                     cm->fc->tx_size_probs[tx_size_cat][tx_size_ctx],
                     &tx_size_encodings[tx_size_cat][coded_tx_size]);
Jingning Han's avatar
Jingning Han committed
407
408
409
  }
}

410
#if CONFIG_REF_MV
411
static void update_inter_mode_probs(VP10_COMMON *cm, vp10_writer *w,
412
413
414
415
416
417
418
419
420
421
422
                                    FRAME_COUNTS *counts) {
  int i;
  for (i = 0; i < NEWMV_MODE_CONTEXTS; ++i)
    vp10_cond_prob_diff_update(w, &cm->fc->newmv_prob[i],
                               counts->newmv_mode[i]);
  for (i = 0; i < ZEROMV_MODE_CONTEXTS; ++i)
    vp10_cond_prob_diff_update(w, &cm->fc->zeromv_prob[i],
                               counts->zeromv_mode[i]);
  for (i = 0; i < REFMV_MODE_CONTEXTS; ++i)
    vp10_cond_prob_diff_update(w, &cm->fc->refmv_prob[i],
                               counts->refmv_mode[i]);
423
  for (i = 0; i < DRL_MODE_CONTEXTS; ++i)
424
    vp10_cond_prob_diff_update(w, &cm->fc->drl_prob[i], counts->drl_mode[i]);
Yue Chen's avatar
Yue Chen committed
425
426
427
#if CONFIG_EXT_INTER
  vp10_cond_prob_diff_update(w, &cm->fc->new2mv_prob, counts->new2mv_mode);
#endif  // CONFIG_EXT_INTER
428
429
430
}
#endif

431
#if CONFIG_EXT_INTER
432
static void update_inter_compound_mode_probs(VP10_COMMON *cm, vp10_writer *w) {
433
434
435
436
437
438
  const int savings_thresh = vp10_cost_one(GROUP_DIFF_UPDATE_PROB) -
                             vp10_cost_zero(GROUP_DIFF_UPDATE_PROB);
  int i;
  int savings = 0;
  int do_update = 0;
  for (i = 0; i < INTER_MODE_CONTEXTS; ++i) {
439
440
441
    savings += prob_diff_update_savings(
        vp10_inter_compound_mode_tree, cm->fc->inter_compound_mode_probs[i],
        cm->counts.inter_compound_mode[i], INTER_COMPOUND_MODES);
442
443
  }
  do_update = savings > savings_thresh;
444
  vp10_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
445
446
  if (do_update) {
    for (i = 0; i < INTER_MODE_CONTEXTS; ++i) {
447
448
449
      prob_diff_update(
          vp10_inter_compound_mode_tree, cm->fc->inter_compound_mode_probs[i],
          cm->counts.inter_compound_mode[i], INTER_COMPOUND_MODES, w);
450
451
452
453
454
    }
  }
}
#endif  // CONFIG_EXT_INTER

Yaowu Xu's avatar
Yaowu Xu committed
455
static int write_skip(const VP10_COMMON *cm, const MACROBLOCKD *xd,
456
                      int segment_id, const MODE_INFO *mi, vp10_writer *w) {
Jingning Han's avatar
Jingning Han committed
457
458
459
460
  if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
    return 1;
  } else {
    const int skip = mi->mbmi.skip;
461
    vp10_write(w, skip, vp10_get_skip_prob(cm, xd));
Jingning Han's avatar
Jingning Han committed
462
463
464
465
    return skip;
  }
}

466
static void update_skip_probs(VP10_COMMON *cm, vp10_writer *w,
Jingning Han's avatar
Jingning Han committed
467
468
469
470
471
472
473
                              FRAME_COUNTS *counts) {
  int k;

  for (k = 0; k < SKIP_CONTEXTS; ++k)
    vp10_cond_prob_diff_update(w, &cm->fc->skip_probs[k], counts->skip[k]);
}

474
static void update_switchable_interp_probs(VP10_COMMON *cm, vp10_writer *w,
Jingning Han's avatar
Jingning Han committed
475
476
477
478
479
480
481
482
                                           FRAME_COUNTS *counts) {
  int j;
  for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j)
    prob_diff_update(vp10_switchable_interp_tree,
                     cm->fc->switchable_interp_prob[j],
                     counts->switchable_interp[j], SWITCHABLE_FILTERS, w);
}

483
#if CONFIG_EXT_TX
484
static void update_ext_tx_probs(VP10_COMMON *cm, vp10_writer *w) {
485
486
  const int savings_thresh = vp10_cost_one(GROUP_DIFF_UPDATE_PROB) -
                             vp10_cost_zero(GROUP_DIFF_UPDATE_PROB);
487
  int i, j;
488
489
490
491
492
  int s;
  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) {
493
      if (!use_inter_ext_tx_for_txsize[s][i]) continue;
494
495
496
497
498
      savings += prob_diff_update_savings(
          vp10_ext_tx_inter_tree[s], cm->fc->inter_ext_tx_prob[s][i],
          cm->counts.inter_ext_tx[s][i], num_ext_tx_set_inter[s]);
    }
    do_update = savings > savings_thresh;
499
    vp10_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
500
501
    if (do_update) {
      for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
502
        if (!use_inter_ext_tx_for_txsize[s][i]) continue;
503
504
505
        prob_diff_update(
            vp10_ext_tx_inter_tree[s], cm->fc->inter_ext_tx_prob[s][i],
            cm->counts.inter_ext_tx[s][i], num_ext_tx_set_inter[s], w);
506
      }
507
508
    }
  }
509

510
511
512
513
  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) {
514
      if (!use_intra_ext_tx_for_txsize[s][i]) continue;
515
      for (j = 0; j < INTRA_MODES; ++j)
516
517
518
519
520
        savings += prob_diff_update_savings(
            vp10_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]);
    }
    do_update = savings > savings_thresh;
521
    vp10_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
522
523
    if (do_update) {
      for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
524
        if (!use_intra_ext_tx_for_txsize[s][i]) continue;
525
        for (j = 0; j < INTRA_MODES; ++j)
526
527
528
          prob_diff_update(
              vp10_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], w);
529
530
      }
    }
531
  }
532
}
Debargha Mukherjee's avatar
Debargha Mukherjee committed
533

534
#else
Debargha Mukherjee's avatar
Debargha Mukherjee committed
535

536
static void update_ext_tx_probs(VP10_COMMON *cm, vp10_writer *w) {
537
538
539
540
541
542
543
544
545
546
547
548
549
  const int savings_thresh = vp10_cost_one(GROUP_DIFF_UPDATE_PROB) -
                             vp10_cost_zero(GROUP_DIFF_UPDATE_PROB);
  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(
          vp10_ext_tx_tree, cm->fc->intra_ext_tx_prob[i][j],
          cm->counts.intra_ext_tx[i][j], TX_TYPES);
  }
  do_update = savings > savings_thresh;
550
  vp10_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
551
552
553
  if (do_update) {
    for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
      for (j = 0; j < TX_TYPES; ++j)
554
555
        prob_diff_update(vp10_ext_tx_tree, cm->fc->intra_ext_tx_prob[i][j],
                         cm->counts.intra_ext_tx[i][j], TX_TYPES, w);
556
557
558
559
    }
  }
  savings = 0;
  for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
560
561
562
    savings +=
        prob_diff_update_savings(vp10_ext_tx_tree, cm->fc->inter_ext_tx_prob[i],
                                 cm->counts.inter_ext_tx[i], TX_TYPES);
563
564
  }
  do_update = savings > savings_thresh;
565
  vp10_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
566
567
  if (do_update) {
    for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
568
569
      prob_diff_update(vp10_ext_tx_tree, cm->fc->inter_ext_tx_prob[i],
                       cm->counts.inter_ext_tx[i], TX_TYPES, w);
570
571
572
    }
  }
}
573
574
#endif  // CONFIG_EXT_TX

575
576
static void pack_palette_tokens(vp10_writer *w, const TOKENEXTRA **tp, int n,
                                int num) {
hui su's avatar
hui su committed
577
  int i;
578
  const TOKENEXTRA *p = *tp;
hui su's avatar
hui su committed
579

580
  for (i = 0; i < num; ++i) {
hui su's avatar
hui su committed
581
582
583
584
585
586
587
588
    vp10_write_token(w, vp10_palette_color_tree[n - 2], p->context_tree,
                     &palette_color_encodings[n - 2][p->token]);
    ++p;
  }

  *tp = p;
}

589
#if CONFIG_SUPERTX
590
static void update_supertx_probs(VP10_COMMON *cm, vp10_writer *w) {
591
592
593
594
595
596
597
598
599
600
601
602
  const int savings_thresh = vp10_cost_one(GROUP_DIFF_UPDATE_PROB) -
                             vp10_cost_zero(GROUP_DIFF_UPDATE_PROB);
  int i, j;
  int savings = 0;
  int do_update = 0;
  for (i = 0; i < PARTITION_SUPERTX_CONTEXTS; ++i) {
    for (j = 1; j < TX_SIZES; ++j) {
      savings += vp10_cond_prob_diff_update_savings(&cm->fc->supertx_prob[i][j],
                                                    cm->counts.supertx[i][j]);
    }
  }
  do_update = savings > savings_thresh;
603
  vp10_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
604
605
606
607
608
609
610
611
612
613
614
  if (do_update) {
    for (i = 0; i < PARTITION_SUPERTX_CONTEXTS; ++i) {
      for (j = 1; j < TX_SIZES; ++j) {
        vp10_cond_prob_diff_update(w, &cm->fc->supertx_prob[i][j],
                                   cm->counts.supertx[i][j]);
      }
    }
  }
}
#endif  // CONFIG_SUPERTX

Alex Converse's avatar
Alex Converse committed
615
#if !CONFIG_ANS
616
617
static void pack_mb_tokens(vp10_writer *w, const TOKENEXTRA **tp,
                           const TOKENEXTRA *const stop,
618
                           vpx_bit_depth_t bit_depth, const TX_SIZE tx) {
619
  const TOKENEXTRA *p = *tp;
620
621
#if CONFIG_VAR_TX
  int count = 0;
Debargha Mukherjee's avatar
Debargha Mukherjee committed
622
  const int seg_eob = get_tx2d_size(tx);
623
#endif
Jingning Han's avatar
Jingning Han committed
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639

  while (p < stop && p->token != EOSB_TOKEN) {
    const int t = p->token;
    const struct vp10_token *const a = &vp10_coef_encodings[t];
    int v = a->value;
    int n = a->len;
#if CONFIG_VP9_HIGHBITDEPTH
    const vp10_extra_bit *b;
    if (bit_depth == VPX_BITS_12)
      b = &vp10_extra_bits_high12[t];
    else if (bit_depth == VPX_BITS_10)
      b = &vp10_extra_bits_high10[t];
    else
      b = &vp10_extra_bits[t];
#else
    const vp10_extra_bit *const b = &vp10_extra_bits[t];
640
    (void)bit_depth;
Jingning Han's avatar
Jingning Han committed
641
642
643
#endif  // CONFIG_VP9_HIGHBITDEPTH

    /* skip one or two nodes */
644
    if (p->skip_eob_node)
Jingning Han's avatar
Jingning Han committed
645
      n -= p->skip_eob_node;
646
    else
647
      vp10_write(w, t != EOB_TOKEN, p->context_tree[0]);
648
649

    if (t != EOB_TOKEN) {
650
      vp10_write(w, t != ZERO_TOKEN, p->context_tree[1]);
Jingning Han's avatar
Jingning Han committed
651

652
      if (t != ZERO_TOKEN) {
653
        vp10_write(w, t != ONE_TOKEN, p->context_tree[2]);
654
655
656
657

        if (t != ONE_TOKEN) {
          int len = UNCONSTRAINED_NODES - p->skip_eob_node;
          vp10_write_tree(w, vp10_coef_con_tree,
658
659
                          vp10_pareto8_full[p->context_tree[PIVOT_NODE] - 1], v,
                          n - len, 0);
660
661
        }
      }
Jingning Han's avatar
Jingning Han committed
662
663
664
665
    }

    if (b->base_val) {
      const int e = p->extra, l = b->len;
Debargha Mukherjee's avatar
Debargha Mukherjee committed
666
667
668
      int skip_bits = (b->base_val == CAT6_MIN_VAL)
                          ? TX_SIZES - 1 - txsize_sqr_up_map[tx]
                          : 0;
Jingning Han's avatar
Jingning Han committed
669
670
671
672

      if (l) {
        const unsigned char *pb = b->prob;
        int v = e >> 1;
673
        int n = l; /* number of bits in v, assumed nonzero */
Jingning Han's avatar
Jingning Han committed
674
675
676
677
        int i = 0;

        do {
          const int bb = (v >> --n) & 1;
678
679
680
681
          if (skip_bits) {
            skip_bits--;
            assert(!bb);
          } else {
682
            vp10_write(w, bb, pb[i >> 1]);
683
          }
Jingning Han's avatar
Jingning Han committed
684
685
686
687
          i = b->tree[i + bb];
        } while (n);
      }

688
      vp10_write_bit(w, e & 1);
Jingning Han's avatar
Jingning Han committed
689
690
    }
    ++p;
691
692
693

#if CONFIG_VAR_TX
    ++count;
694
    if (t == EOB_TOKEN || count == seg_eob) break;
695
#endif
Jingning Han's avatar
Jingning Han committed
696
697
  }

698
  *tp = p;
Jingning Han's avatar
Jingning Han committed
699
}
Alex Converse's avatar
Alex Converse committed
700
#else
701
702
// This function serializes the tokens in forward order using a buffered ans
// coder.
703
static void pack_mb_tokens(struct BufAnsCoder *ans, const TOKENEXTRA **tp,
704
                           const TOKENEXTRA *const stop,
705
                           vpx_bit_depth_t bit_depth, const TX_SIZE tx) {
706
  const TOKENEXTRA *p = *tp;
707
708
709
710
#if CONFIG_VAR_TX
  int count = 0;
  const int seg_eob = 16 << (tx << 1);
#endif  // CONFIG_VAR_TX
Alex Converse's avatar
Alex Converse committed
711

712
  while (p < stop && p->token != EOSB_TOKEN) {
Alex Converse's avatar
Alex Converse committed
713
714
    const int t = p->token;
#if CONFIG_VP9_HIGHBITDEPTH
715
716
717
718
719
720
721
    const vp10_extra_bit *b;
    if (bit_depth == VPX_BITS_12)
      b = &vp10_extra_bits_high12[t];
    else if (bit_depth == VPX_BITS_10)
      b = &vp10_extra_bits_high10[t];
    else
      b = &vp10_extra_bits[t];
Alex Converse's avatar
Alex Converse committed
722
723
#else
    const vp10_extra_bit *const b = &vp10_extra_bits[t];
724
    (void)bit_depth;
Alex Converse's avatar
Alex Converse committed
725
726
#endif  // CONFIG_VP9_HIGHBITDEPTH

727
728
729
730
731
    /* skip one or two nodes */
    if (!p->skip_eob_node)
      buf_uabs_write(ans, t != EOB_TOKEN, p->context_tree[0]);

    if (t != EOB_TOKEN) {
732
733
734
735
736
737
738
739
740
      struct rans_sym s;
      const rans_dec_lut *token_cdf = p->token_cdf;
      assert(token_cdf);
      s.cum_prob = (*token_cdf)[t - ZERO_TOKEN];
      s.prob = (*token_cdf)[t - ZERO_TOKEN + 1] - s.cum_prob;
      buf_rans_write(ans, &s);

      if (b->base_val) {
        const int e = p->extra, l = b->len;
Debargha Mukherjee's avatar
Debargha Mukherjee committed
741
742
743
        int skip_bits = (b->base_val == CAT6_MIN_VAL)
                            ? TX_SIZES - 1 - txsize_sqr_up_map[tx]
                            : 0;
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761

        if (l) {
          const unsigned char *pb = b->prob;
          int v = e >> 1;
          int n = l; /* number of bits in v, assumed nonzero */
          int i = 0;

          do {
            const int bb = (v >> --n) & 1;
            if (skip_bits) {
              skip_bits--;
              assert(!bb);
            } else {
              buf_uabs_write(ans, bb, pb[i >> 1]);
            }
            i = b->tree[i + bb];
          } while (n);
        }
762

763
        buf_uabs_write(ans, e & 1, 128);
764
765
766
767
768
769
770
771
      }
    }
    ++p;

#if CONFIG_VAR_TX
    ++count;
    if (t == EOB_TOKEN || count == seg_eob) break;
#endif  // CONFIG_VAR_TX
Alex Converse's avatar
Alex Converse committed
772
  }
773
774

  *tp = p;
Alex Converse's avatar
Alex Converse committed
775
776
}
#endif  // !CONFIG_ANS
Jingning Han's avatar
Jingning Han committed
777

778
#if CONFIG_VAR_TX
779
780
781
782
783
784
static void pack_txb_tokens(vp10_writer *w, const TOKENEXTRA **tp,
                            const TOKENEXTRA *const tok_end, MACROBLOCKD *xd,
                            MB_MODE_INFO *mbmi, int plane,
                            BLOCK_SIZE plane_bsize, vpx_bit_depth_t bit_depth,
                            int block, int blk_row, int blk_col,
                            TX_SIZE tx_size) {
785
786
  const struct macroblockd_plane *const pd = &xd->plane[plane];
  const BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
787
788
  const int tx_row = blk_row >> (1 - pd->subsampling_y);
  const int tx_col = blk_col >> (1 - pd->subsampling_x);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
789
  TX_SIZE plane_tx_size;
790
791
792
793
794
795
796
797
  int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
  int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];

  if (xd->mb_to_bottom_edge < 0)
    max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
  if (xd->mb_to_right_edge < 0)
    max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);

798
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
799

Debargha Mukherjee's avatar
Debargha Mukherjee committed
800
801
802
803
  plane_tx_size = plane ? get_uv_tx_size_impl(
                              mbmi->inter_tx_size[tx_row][tx_col], bsize, 0, 0)
                        : mbmi->inter_tx_size[tx_row][tx_col];

804
805
806
807
808
809
810
811
812
813
814
815
  if (tx_size == plane_tx_size) {
    pack_mb_tokens(w, tp, tok_end, bit_depth, tx_size);
  } else {
    int bsl = b_width_log2_lookup[bsize];
    int i;

    assert(bsl > 0);
    --bsl;

    for (i = 0; i < 4; ++i) {
      const int offsetr = blk_row + ((i >> 1) << bsl);
      const int offsetc = blk_col + ((i & 0x01) << bsl);
816
      int step = num_4x4_blocks_txsize_lookup[tx_size - 1];
817

818
      if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
819

820
821
      pack_txb_tokens(w, tp, tok_end, xd, mbmi, plane, plane_bsize, bit_depth,
                      block + i * step, offsetr, offsetc, tx_size - 1);
822
823
824
825
826
    }
  }
}
#endif

827
static void write_segment_id(vp10_writer *w, const struct segmentation *seg,
828
                             const struct segmentation_probs *segp,
Jingning Han's avatar
Jingning Han committed
829
830
                             int segment_id) {
  if (seg->enabled && seg->update_map)
831
    vp10_write_tree(w, vp10_segment_tree, segp->tree_probs, segment_id, 3, 0);
Jingning Han's avatar
Jingning Han committed
832
833
834
}

// This function encodes the reference frame
Yaowu Xu's avatar
Yaowu Xu committed
835
static void write_ref_frames(const VP10_COMMON *cm, const MACROBLOCKD *xd,
836
                             vp10_writer *w) {
Jingning Han's avatar
Jingning Han committed
837
838
839
840
841
842
843
844
845
  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] ==
846
           get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME));
Jingning Han's avatar
Jingning Han committed
847
848
849
850
  } else {
    // does the feature use compound prediction or not
    // (if not specified at the frame/segment level)
    if (cm->reference_mode == REFERENCE_MODE_SELECT) {
851
      vp10_write(w, is_compound, vp10_get_reference_mode_prob(cm, xd));
Jingning Han's avatar
Jingning Han committed
852
    } else {
853
      assert((!is_compound) == (cm->reference_mode == SINGLE_REFERENCE));
Jingning Han's avatar
Jingning Han committed
854
855
856
    }

    if (is_compound) {
857
858
#if CONFIG_EXT_REFS
      const int bit = (mbmi->ref_frame[0] == GOLDEN_FRAME ||
859
860
                       mbmi->ref_frame[0] == LAST3_FRAME);
      const int bit_bwd = mbmi->ref_frame[1] == ALTREF_FRAME;
861
#else  // CONFIG_EXT_REFS
862
863
      const int bit = mbmi->ref_frame[0] == GOLDEN_FRAME;
#endif  // CONFIG_EXT_REFS
864

865
      vp10_write(w, bit, vp10_get_pred_prob_comp_ref_p(cm, xd));
866
867
868
869

#if CONFIG_EXT_REFS
      if (!bit) {
        const int bit1 = mbmi->ref_frame[0] == LAST_FRAME;
870
        vp10_write(w, bit1, vp10_get_pred_prob_comp_ref_p1(cm, xd));
871
872
      } else {
        const int bit2 = mbmi->ref_frame[0] == GOLDEN_FRAME;
873
        vp10_write(w, bit2, vp10_get_pred_prob_comp_ref_p2(cm, xd));
874
      }
875
      vp10_write(w, bit_bwd, vp10_get_pred_prob_comp_bwdref_p(cm, xd));
876
#endif  // CONFIG_EXT_REFS
Jingning Han's avatar
Jingning Han committed
877
    } else {
878
#if CONFIG_EXT_REFS
879
880
      const int bit0 = (mbmi->ref_frame[0] == ALTREF_FRAME ||
                        mbmi->ref_frame[0] == BWDREF_FRAME);
881
      vp10_write(w, bit0, vp10_get_pred_prob_single_ref_p1(cm, xd));
882
883

      if (bit0) {
884
        const int bit1 = mbmi->ref_frame[0] == ALTREF_FRAME;
885
        vp10_write(w, bit1, vp10_get_pred_prob_single_ref_p2(cm, xd));
886
887
      } else {
        const int bit2 = (mbmi->ref_frame[0] == LAST3_FRAME ||
888
                          mbmi->ref_frame[0] == GOLDEN_FRAME);
889
        vp10_write(w, bit2, vp10_get_pred_prob_single_ref_p3(cm, xd));
890
891
892

        if (!bit2) {
          const int bit3 = mbmi->ref_frame[0] != LAST_FRAME;
893
          vp10_write(w, bit3, vp10_get_pred_prob_single_ref_p4(cm, xd));
894
895
        } else {
          const int bit4 = mbmi->ref_frame[0] != LAST3_FRAME;
896
          vp10_write(w, bit4, vp10_get_pred_prob_single_ref_p5(cm, xd));
897
898
        }
      }
899
#else   // CONFIG_EXT_REFS
Jingning Han's avatar
Jingning Han committed
900
      const int bit0 = mbmi->ref_frame[0] != LAST_FRAME;
901
      vp10_write(w, bit0, vp10_get_pred_prob_single_ref_p1(cm, xd));
902

Jingning Han's avatar
Jingning Han committed
903
904
      if (bit0) {
        const int bit1 = mbmi->ref_frame[0] != GOLDEN_FRAME;
905
        vp10_write(w, bit1, vp10_get_pred_prob_single_ref_p2(cm, xd));
Jingning Han's avatar
Jingning Han committed
906
      }
907
#endif  // CONFIG_EXT_REFS
Jingning Han's avatar
Jingning Han committed
908
909
910
911
    }
  }
}

hui su's avatar
hui su committed
912
913
914
#if CONFIG_EXT_INTRA
static void write_ext_intra_mode_info(const VP10_COMMON *const cm,
                                      const MB_MODE_INFO *const mbmi,
915
                                      vp10_writer *w) {
hui su's avatar
hui su committed
916
917
918
#if !ALLOW_FILTER_INTRA_MODES
  return;
#endif
919
  if (mbmi->mode == DC_PRED && mbmi->palette_mode_info.palette_size[0] == 0) {
920
    vp10_write(w, mbmi->ext_intra_mode_info.use_ext_intra_mode[0],
921
               cm->fc->ext_intra_probs[0]);
hui su's avatar
hui su committed
922
923
    if (mbmi->ext_intra_mode_info.use_ext_intra_mode[0]) {
      EXT_INTRA_MODE mode = mbmi->ext_intra_mode_info.ext_intra_mode[0];
hui su's avatar
hui su committed
924
      write_uniform(w, FILTER_INTRA_MODES, mode);
hui su's avatar
hui su committed
925
926
    }
  }
927

928
929
  if (mbmi->uv_mode == DC_PRED &&
      mbmi->palette_mode_info.palette_size[1] == 0) {
930
    vp10_write(w, mbmi->ext_intra_mode_info.use_ext_intra_mode[1],
931
               cm->fc->ext_intra_probs[1]);
hui su's avatar
hui su committed
932
933
    if (mbmi->ext_intra_mode_info.use_ext_intra_mode[1]) {
      EXT_INTRA_MODE mode = mbmi->ext_intra_mode_info.ext_intra_mode[1];
hui su's avatar
hui su committed
934
      write_uniform(w, FILTER_INTRA_MODES, mode);
hui su's avatar
hui su committed
935
936
937
    }
  }
}
938
939
940
941
942
943
944
945

static void write_intra_angle_info(const VP10_COMMON *cm, const MACROBLOCKD *xd,
                                   vp10_writer *w) {
  const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
  const BLOCK_SIZE bsize = mbmi->sb_type;
  const int intra_filter_ctx = vp10_get_pred_context_intra_interp(xd);
  int p_angle;

946
  if (bsize < BLOCK_8X8) return;
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963

  if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED) {
    write_uniform(w, 2 * MAX_ANGLE_DELTAS + 1,
                  MAX_ANGLE_DELTAS + mbmi->angle_delta[0]);
    p_angle = mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
    if (vp10_is_intra_filter_switchable(p_angle)) {
      vp10_write_token(w, vp10_intra_filter_tree,
                       cm->fc->intra_filter_probs[intra_filter_ctx],
                       &intra_filter_encodings[mbmi->intra_filter]);
    }
  }

  if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) {
    write_uniform(w, 2 * MAX_ANGLE_DELTAS + 1,
                  MAX_ANGLE_DELTAS + mbmi->angle_delta[1]);
  }
}
hui su's avatar
hui su committed
964
965
#endif  // CONFIG_EXT_INTRA

966
967
static void write_switchable_interp_filter(VP10_COMP *cpi,
                                           const MACROBLOCKD *xd,
968
                                           vp10_writer *w) {
969
970
  VP10_COMMON *const cm = &cpi->common;
  const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
971
972
973
#if CONFIG_DUAL_FILTER
  int dir;
#endif
974
975
  if (cm->interp_filter == SWITCHABLE) {
#if CONFIG_EXT_INTERP
976
977
978
979
980
981
#if CONFIG_DUAL_FILTER
    if (!vp10_is_interp_needed(xd)) {
      assert(