bitstream.c 126 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
 *  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 <stdio.h>
#include <limits.h>

#include "vpx/vpx_encoder.h"
#include "vpx_dsp/bitwriter_buffer.h"
17
#include "vpx_dsp/vpx_dsp_common.h"
Jingning Han's avatar
Jingning Han committed
18
19
#include "vpx_mem/vpx_mem.h"
#include "vpx_ports/mem_ops.h"
20
#include "vpx_ports/system_state.h"
Angie Chiang's avatar
Angie Chiang committed
21
#include "vpx_util/debug_util.h"
Jingning Han's avatar
Jingning Han committed
22

23
24
25
#if CONFIG_CLPF
#include "vp10/common/clpf.h"
#endif
Yaowu Xu's avatar
Yaowu Xu committed
26
27
28
#if CONFIG_DERING
#include "vp10/common/dering.h"
#endif  // CONFIG_DERING
29
30
31
32
33
#include "vp10/common/entropy.h"
#include "vp10/common/entropymode.h"
#include "vp10/common/entropymv.h"
#include "vp10/common/mvref_common.h"
#include "vp10/common/pred_common.h"
34
#include "vp10/common/reconinter.h"
35
36
#include "vp10/common/seg_common.h"
#include "vp10/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 "vp10/encoder/buf_ans.h"
Alex Converse's avatar
Alex Converse committed
40
#endif  // CONFIG_ANS
41
42
43
44
45
46
47
#include "vp10/encoder/cost.h"
#include "vp10/encoder/bitstream.h"
#include "vp10/encoder/encodemv.h"
#include "vp10/encoder/mcomp.h"
#include "vp10/encoder/segmentation.h"
#include "vp10/encoder/subexp.h"
#include "vp10/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) {
Jingning Han's avatar
Jingning Han committed
387
388
389
  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];
390
391
  // For sub8x8 blocks the tx_size symbol does not need to be sent
  if (bsize >= BLOCK_8X8) {
392
393
394
395
    vp10_write_token(
        w, vp10_tx_size_tree[max_tx_size - TX_8X8],
        cm->fc->tx_size_probs[max_tx_size - TX_8X8][get_tx_size_context(xd)],
        &tx_size_encodings[max_tx_size - TX_8X8][tx_size]);
Jingning Han's avatar
Jingning Han committed
396
397
398
  }
}

399
#if CONFIG_REF_MV
400
static void update_inter_mode_probs(VP10_COMMON *cm, vp10_writer *w,
401
402
403
404
405
406
407
408
409
410
411
                                    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]);
412
  for (i = 0; i < DRL_MODE_CONTEXTS; ++i)
413
    vp10_cond_prob_diff_update(w, &cm->fc->drl_prob[i], counts->drl_mode[i]);
Yue Chen's avatar
Yue Chen committed
414
415
416
#if CONFIG_EXT_INTER
  vp10_cond_prob_diff_update(w, &cm->fc->new2mv_prob, counts->new2mv_mode);
#endif  // CONFIG_EXT_INTER
417
418
419
}
#endif

420
#if CONFIG_EXT_INTER
421
static void update_inter_compound_mode_probs(VP10_COMMON *cm, vp10_writer *w) {
422
423
424
425
426
427
  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) {
428
429
430
    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);
431
432
  }
  do_update = savings > savings_thresh;
433
  vp10_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
434
435
  if (do_update) {
    for (i = 0; i < INTER_MODE_CONTEXTS; ++i) {
436
437
438
      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);
439
440
441
442
443
    }
  }
}
#endif  // CONFIG_EXT_INTER

Yaowu Xu's avatar
Yaowu Xu committed
444
static int write_skip(const VP10_COMMON *cm, const MACROBLOCKD *xd,
445
                      int segment_id, const MODE_INFO *mi, vp10_writer *w) {
Jingning Han's avatar
Jingning Han committed
446
447
448
449
  if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
    return 1;
  } else {
    const int skip = mi->mbmi.skip;
450
    vp10_write(w, skip, vp10_get_skip_prob(cm, xd));
Jingning Han's avatar
Jingning Han committed
451
452
453
454
    return skip;
  }
}

455
static void update_skip_probs(VP10_COMMON *cm, vp10_writer *w,
Jingning Han's avatar
Jingning Han committed
456
457
458
459
460
461
462
                              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]);
}

463
static void update_switchable_interp_probs(VP10_COMMON *cm, vp10_writer *w,
Jingning Han's avatar
Jingning Han committed
464
465
466
467
468
469
470
471
                                           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);
}

472
#if CONFIG_EXT_TX
473
static void update_ext_tx_probs(VP10_COMMON *cm, vp10_writer *w) {
474
475
  const int savings_thresh = vp10_cost_one(GROUP_DIFF_UPDATE_PROB) -
                             vp10_cost_zero(GROUP_DIFF_UPDATE_PROB);
476
  int i, j;
477
478
479
480
481
  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) {
482
      if (!use_inter_ext_tx_for_txsize[s][i]) continue;
483
484
485
486
487
      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;
488
    vp10_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
489
490
    if (do_update) {
      for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
491
        if (!use_inter_ext_tx_for_txsize[s][i]) continue;
492
493
494
        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);
495
      }
496
497
    }
  }
498

499
500
501
502
  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) {
503
      if (!use_intra_ext_tx_for_txsize[s][i]) continue;
504
      for (j = 0; j < INTRA_MODES; ++j)
505
506
507
508
509
        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;
510
    vp10_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
511
512
    if (do_update) {
      for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
513
        if (!use_intra_ext_tx_for_txsize[s][i]) continue;
514
        for (j = 0; j < INTRA_MODES; ++j)
515
516
517
          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);
518
519
      }
    }
520
  }
521
}
Debargha Mukherjee's avatar
Debargha Mukherjee committed
522

523
#else
Debargha Mukherjee's avatar
Debargha Mukherjee committed
524

525
static void update_ext_tx_probs(VP10_COMMON *cm, vp10_writer *w) {
526
527
528
529
530
531
532
533
534
535
536
537
538
  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;
539
  vp10_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
540
541
542
  if (do_update) {
    for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
      for (j = 0; j < TX_TYPES; ++j)
543
544
        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);
545
546
547
548
    }
  }
  savings = 0;
  for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
549
550
551
    savings +=
        prob_diff_update_savings(vp10_ext_tx_tree, cm->fc->inter_ext_tx_prob[i],
                                 cm->counts.inter_ext_tx[i], TX_TYPES);
552
553
  }
  do_update = savings > savings_thresh;
554
  vp10_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
555
556
  if (do_update) {
    for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
557
558
      prob_diff_update(vp10_ext_tx_tree, cm->fc->inter_ext_tx_prob[i],
                       cm->counts.inter_ext_tx[i], TX_TYPES, w);
559
560
561
    }
  }
}
562
563
#endif  // CONFIG_EXT_TX

564
565
static void pack_palette_tokens(vp10_writer *w, const TOKENEXTRA **tp, int n,
                                int num) {
hui su's avatar
hui su committed
566
  int i;
567
  const TOKENEXTRA *p = *tp;
hui su's avatar
hui su committed
568

569
  for (i = 0; i < num; ++i) {
hui su's avatar
hui su committed
570
571
572
573
574
575
576
577
    vp10_write_token(w, vp10_palette_color_tree[n - 2], p->context_tree,
                     &palette_color_encodings[n - 2][p->token]);
    ++p;
  }

  *tp = p;
}

578
#if CONFIG_SUPERTX
579
static void update_supertx_probs(VP10_COMMON *cm, vp10_writer *w) {
580
581
582
583
584
585
586
587
588
589
590
591
  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;
592
  vp10_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
593
594
595
596
597
598
599
600
601
602
603
  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
604
#if !CONFIG_ANS
605
606
static void pack_mb_tokens(vp10_writer *w, const TOKENEXTRA **tp,
                           const TOKENEXTRA *const stop,
607
                           vpx_bit_depth_t bit_depth, const TX_SIZE tx) {
608
  const TOKENEXTRA *p = *tp;
609
610
#if CONFIG_VAR_TX
  int count = 0;
Debargha Mukherjee's avatar
Debargha Mukherjee committed
611
  const int seg_eob = get_tx2d_size(tx);
612
#endif
Jingning Han's avatar
Jingning Han committed
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628

  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];
629
    (void)bit_depth;
Jingning Han's avatar
Jingning Han committed
630
631
632
#endif  // CONFIG_VP9_HIGHBITDEPTH

    /* skip one or two nodes */
633
    if (p->skip_eob_node)
Jingning Han's avatar
Jingning Han committed
634
      n -= p->skip_eob_node;
635
    else
636
      vp10_write(w, t != EOB_TOKEN, p->context_tree[0]);
637
638

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

641
      if (t != ZERO_TOKEN) {
642
        vp10_write(w, t != ONE_TOKEN, p->context_tree[2]);
643
644
645
646

        if (t != ONE_TOKEN) {
          int len = UNCONSTRAINED_NODES - p->skip_eob_node;
          vp10_write_tree(w, vp10_coef_con_tree,
647
648
                          vp10_pareto8_full[p->context_tree[PIVOT_NODE] - 1], v,
                          n - len, 0);
649
650
        }
      }
Jingning Han's avatar
Jingning Han committed
651
652
653
654
    }

    if (b->base_val) {
      const int e = p->extra, l = b->len;
Debargha Mukherjee's avatar
Debargha Mukherjee committed
655
656
657
      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
658
659
660
661

      if (l) {
        const unsigned char *pb = b->prob;
        int v = e >> 1;
662
        int n = l; /* number of bits in v, assumed nonzero */
Jingning Han's avatar
Jingning Han committed
663
664
665
666
        int i = 0;

        do {
          const int bb = (v >> --n) & 1;
667
668
669
670
          if (skip_bits) {
            skip_bits--;
            assert(!bb);
          } else {
671
            vp10_write(w, bb, pb[i >> 1]);
672
          }
Jingning Han's avatar
Jingning Han committed
673
674
675
676
          i = b->tree[i + bb];
        } while (n);
      }

677
      vp10_write_bit(w, e & 1);
Jingning Han's avatar
Jingning Han committed
678
679
    }
    ++p;
680
681
682

#if CONFIG_VAR_TX
    ++count;
683
    if (t == EOB_TOKEN || count == seg_eob) break;
684
#endif
Jingning Han's avatar
Jingning Han committed
685
686
  }

687
  *tp = p;
Jingning Han's avatar
Jingning Han committed
688
}
Alex Converse's avatar
Alex Converse committed
689
#else
690
691
// This function serializes the tokens in forward order using a buffered ans
// coder.
692
static void pack_mb_tokens(struct BufAnsCoder *ans, const TOKENEXTRA **tp,
693
                           const TOKENEXTRA *const stop,
694
                           vpx_bit_depth_t bit_depth, const TX_SIZE tx) {
695
  const TOKENEXTRA *p = *tp;
696
697
698
699
#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
700

701
  while (p < stop && p->token != EOSB_TOKEN) {
Alex Converse's avatar
Alex Converse committed
702
703
    const int t = p->token;
#if CONFIG_VP9_HIGHBITDEPTH
704
705
706
707
708
709
710
    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
711
712
#else
    const vp10_extra_bit *const b = &vp10_extra_bits[t];
713
    (void)bit_depth;
Alex Converse's avatar
Alex Converse committed
714
715
#endif  // CONFIG_VP9_HIGHBITDEPTH

716
717
718
719
720
    /* 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) {
721
722
723
724
725
726
727
728
729
      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
730
731
732
        int skip_bits = (b->base_val == CAT6_MIN_VAL)
                            ? TX_SIZES - 1 - txsize_sqr_up_map[tx]
                            : 0;
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750

        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);
        }
751

752
        buf_uabs_write(ans, e & 1, 128);
753
754
755
756
757
758
759
760
      }
    }
    ++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
761
  }
762
763

  *tp = p;
Alex Converse's avatar
Alex Converse committed
764
765
}
#endif  // !CONFIG_ANS
Jingning Han's avatar
Jingning Han committed
766

767
#if CONFIG_VAR_TX
768
769
770
771
772
773
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) {
774
775
  const struct macroblockd_plane *const pd = &xd->plane[plane];
  const BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
776
777
  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
778
  TX_SIZE plane_tx_size;
779
780
781
782
783
784
785
786
  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);

787
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
788

Debargha Mukherjee's avatar
Debargha Mukherjee committed
789
790
791
792
  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];

793
794
795
796
797
798
799
800
801
802
803
804
  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);
805
      int step = num_4x4_blocks_txsize_lookup[tx_size - 1];
806

807
      if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
808

809
810
      pack_txb_tokens(w, tp, tok_end, xd, mbmi, plane, plane_bsize, bit_depth,
                      block + i * step, offsetr, offsetc, tx_size - 1);
811
812
813
814
815
    }
  }
}
#endif

816
static void write_segment_id(vp10_writer *w, const struct segmentation *seg,
817
                             const struct segmentation_probs *segp,
Jingning Han's avatar
Jingning Han committed
818
819
                             int segment_id) {
  if (seg->enabled && seg->update_map)
820
    vp10_write_tree(w, vp10_segment_tree, segp->tree_probs, segment_id, 3, 0);
Jingning Han's avatar
Jingning Han committed
821
822
823
}

// This function encodes the reference frame
Yaowu Xu's avatar
Yaowu Xu committed
824
static void write_ref_frames(const VP10_COMMON *cm, const MACROBLOCKD *xd,
825
                             vp10_writer *w) {
Jingning Han's avatar
Jingning Han committed
826
827
828
829
830
831
832
833
834
  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] ==
835
           get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME));
Jingning Han's avatar
Jingning Han committed
836
837
838
839
  } else {
    // does the feature use compound prediction or not
    // (if not specified at the frame/segment level)
    if (cm->reference_mode == REFERENCE_MODE_SELECT) {
840
      vp10_write(w, is_compound, vp10_get_reference_mode_prob(cm, xd));
Jingning Han's avatar
Jingning Han committed
841
    } else {
842
      assert((!is_compound) == (cm->reference_mode == SINGLE_REFERENCE));
Jingning Han's avatar
Jingning Han committed
843
844
845
    }

    if (is_compound) {
846
847
#if CONFIG_EXT_REFS
      const int bit = (mbmi->ref_frame[0] == GOLDEN_FRAME ||
848
849
                       mbmi->ref_frame[0] == LAST3_FRAME);
      const int bit_bwd = mbmi->ref_frame[1] == ALTREF_FRAME;
850
#else  // CONFIG_EXT_REFS
851
852
      const int bit = mbmi->ref_frame[0] == GOLDEN_FRAME;
#endif  // CONFIG_EXT_REFS
853

854
      vp10_write(w, bit, vp10_get_pred_prob_comp_ref_p(cm, xd));
855
856
857
858

#if CONFIG_EXT_REFS
      if (!bit) {
        const int bit1 = mbmi->ref_frame[0] == LAST_FRAME;
859
        vp10_write(w, bit1, vp10_get_pred_prob_comp_ref_p1(cm, xd));
860
861
      } else {
        const int bit2 = mbmi->ref_frame[0] == GOLDEN_FRAME;
862
        vp10_write(w, bit2, vp10_get_pred_prob_comp_ref_p2(cm, xd));
863
      }
864
      vp10_write(w, bit_bwd, vp10_get_pred_prob_comp_bwdref_p(cm, xd));
865
#endif  // CONFIG_EXT_REFS
Jingning Han's avatar
Jingning Han committed
866
    } else {
867
#if CONFIG_EXT_REFS
868
869
      const int bit0 = (mbmi->ref_frame[0] == ALTREF_FRAME ||
                        mbmi->ref_frame[0] == BWDREF_FRAME);
870
      vp10_write(w, bit0, vp10_get_pred_prob_single_ref_p1(cm, xd));
871
872

      if (bit0) {
873
        const int bit1 = mbmi->ref_frame[0] == ALTREF_FRAME;
874
        vp10_write(w, bit1, vp10_get_pred_prob_single_ref_p2(cm, xd));
875
876
      } else {
        const int bit2 = (mbmi->ref_frame[0] == LAST3_FRAME ||
877
                          mbmi->ref_frame[0] == GOLDEN_FRAME);
878
        vp10_write(w, bit2, vp10_get_pred_prob_single_ref_p3(cm, xd));
879
880
881

        if (!bit2) {
          const int bit3 = mbmi->ref_frame[0] != LAST_FRAME;
882
          vp10_write(w, bit3, vp10_get_pred_prob_single_ref_p4(cm, xd));
883
884
        } else {
          const int bit4 = mbmi->ref_frame[0] != LAST3_FRAME;
885
          vp10_write(w, bit4, vp10_get_pred_prob_single_ref_p5(cm, xd));
886
887
        }
      }
888
#else   // CONFIG_EXT_REFS
Jingning Han's avatar
Jingning Han committed
889
      const int bit0 = mbmi->ref_frame[0] != LAST_FRAME;
890
      vp10_write(w, bit0, vp10_get_pred_prob_single_ref_p1(cm, xd));
891

Jingning Han's avatar
Jingning Han committed
892
893
      if (bit0) {
        const int bit1 = mbmi->ref_frame[0] != GOLDEN_FRAME;
894
        vp10_write(w, bit1, vp10_get_pred_prob_single_ref_p2(cm, xd));
Jingning Han's avatar
Jingning Han committed
895
      }
896
#endif  // CONFIG_EXT_REFS
Jingning Han's avatar
Jingning Han committed
897
898
899
900
    }
  }
}

hui su's avatar
hui su committed
901
902
903
#if CONFIG_EXT_INTRA
static void write_ext_intra_mode_info(const VP10_COMMON *const cm,
                                      const MB_MODE_INFO *const mbmi,
904
                                      vp10_writer *w) {
hui su's avatar
hui su committed
905
906
907
#if !ALLOW_FILTER_INTRA_MODES
  return;
#endif
908
  if (mbmi->mode == DC_PRED && mbmi->palette_mode_info.palette_size[0] == 0) {
909
    vp10_write(w, mbmi->ext_intra_mode_info.use_ext_intra_mode[0],
910
               cm->fc->ext_intra_probs[0]);
hui su's avatar
hui su committed
911
912
    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
913
      write_uniform(w, FILTER_INTRA_MODES, mode);
hui su's avatar
hui su committed
914
915
    }
  }
916

917
918
  if (mbmi->uv_mode == DC_PRED &&
      mbmi->palette_mode_info.palette_size[1] == 0) {
919
    vp10_write(w, mbmi->ext_intra_mode_info.use_ext_intra_mode[1],
920
               cm->fc->ext_intra_probs[1]);
hui su's avatar
hui su committed
921
922
    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
923
      write_uniform(w, FILTER_INTRA_MODES, mode);
hui su's avatar
hui su committed
924
925
926
    }
  }
}
927
928
929
930
931
932
933
934

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;

935
  if (bsize < BLOCK_8X8) return;
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952

  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
953
954
#endif  // CONFIG_EXT_INTRA

955
956
static void write_switchable_interp_filter(VP10_COMP *cpi,
                                           const MACROBLOCKD *xd,
957
                                           vp10_writer *w) {
958
959
  VP10_COMMON *const cm = &cpi->common;
  const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
960
961
962
#if CONFIG_DUAL_FILTER
  int dir;
#endif
963
964
  if (cm->interp_filter == SWITCHABLE) {
#if CONFIG_EXT_INTERP
965
966
967
968
969
970
#if CONFIG_DUAL_FILTER
    if (!vp10_is_interp_needed(xd)) {
      assert(mbmi->interp_filter[0] == EIGHTTAP_REGULAR);
      return;
    }
#else
971
    if (!vp10_is_interp_needed(xd)) {
972
973
974
975
#if CONFIG_DUAL_FILTER
      assert(mbmi->interp_filter[0] == EIGHTTAP_REGULAR);
      assert(mbmi->interp_filter[1] == EIGHTTAP_REGULAR);
#else
976
      assert(mbmi->interp_filter == EIGHTTAP_REGULAR);
977
#endif
978
979
      return;
    }
980
981
982
#endif  // CONFIG_DUAL_FILTER
#endif  // CONFIG_EXT_INTERP
#if CONFIG_DUAL_FILTER
983
    for (dir = 0; dir < 2; ++dir) {
984
      if (has_subpel_mv_component(xd->mi[0], xd, dir) ||
985
          (mbmi->ref_frame[1] > INTRA_FRAME &&
986
           has_subpel_mv_component(xd->mi[0], xd, dir + 2))) {
987
        const int ctx = vp10_get_pred_context_switchable_interp(xd, dir);