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
335
336
337
static void write_tx_size_inter(const VP10_COMMON *cm, const MACROBLOCKD *xd,
                                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
371
      int offsetr = blk_row + ((i >> 1) << bsl);
      int offsetc = blk_col + ((i & 0x01) << bsl);
      write_tx_size_inter(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;
611
  const int seg_eob = 16 << (tx << 1);
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;
655
      int skip_bits = (b->base_val == CAT6_MIN_VAL) ? TX_SIZES - 1 - tx : 0;
Jingning Han's avatar
Jingning Han committed
656
657
658
659

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

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

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

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

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

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

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

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

748
        buf_uabs_write(ans, e & 1, 128);
749
750
751
752
753
754
755
756
      }
    }
    ++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
757
  }
758
759

  *tp = p;
Alex Converse's avatar
Alex Converse committed
760
761
}
#endif  // !CONFIG_ANS
Jingning Han's avatar
Jingning Han committed
762

763
#if CONFIG_VAR_TX
764
765
766
767
768
769
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) {
770
771
  const struct macroblockd_plane *const pd = &xd->plane[plane];
  const BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
772
773
  const int tx_row = blk_row >> (1 - pd->subsampling_y);
  const int tx_col = blk_col >> (1 - pd->subsampling_x);
774
775
776
777
  const TX_SIZE 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];
778
779
780
781
782
783
784
785
  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);

786
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
787
788
789
790
791
792
793
794
795
796
797
798
799

  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);
800
      int step = num_4x4_blocks_txsize_lookup[tx_size - 1];
801

802
      if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
803

804
805
      pack_txb_tokens(w, tp, tok_end, xd, mbmi, plane, plane_bsize, bit_depth,
                      block + i * step, offsetr, offsetc, tx_size - 1);
806
807
808
809
810
    }
  }
}
#endif

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

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

    if (is_compound) {
841
842
#if CONFIG_EXT_REFS
      const int bit = (mbmi->ref_frame[0] == GOLDEN_FRAME ||
843
844
                       mbmi->ref_frame[0] == LAST3_FRAME);
      const int bit_bwd = mbmi->ref_frame[1] == ALTREF_FRAME;
845
#else  // CONFIG_EXT_REFS
846
847
      const int bit = mbmi->ref_frame[0] == GOLDEN_FRAME;
#endif  // CONFIG_EXT_REFS
848

849
      vp10_write(w, bit, vp10_get_pred_prob_comp_ref_p(cm, xd));
850
851
852
853

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

      if (bit0) {
868
        const int bit1 = mbmi->ref_frame[0] == ALTREF_FRAME;
869
        vp10_write(w, bit1, vp10_get_pred_prob_single_ref_p2(cm, xd));
870
871
      } else {
        const int bit2 = (mbmi->ref_frame[0] == LAST3_FRAME ||
872
                          mbmi->ref_frame[0] == GOLDEN_FRAME);
873
        vp10_write(w, bit2, vp10_get_pred_prob_single_ref_p3(cm, xd));
874
875
876

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

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

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

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

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;

930
  if (bsize < BLOCK_8X8) return;
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947

  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
948
949
#endif  // CONFIG_EXT_INTRA

950
951
static void write_switchable_interp_filter(VP10_COMP *cpi,
                                           const MACROBLOCKD *xd,
952
                                           vp10_writer *w) {
953
954
  VP10_COMMON *const cm = &cpi->common;
  const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
955
956
957
#if CONFIG_DUAL_FILTER
  int dir;
#endif
958
959
  if (cm->interp_filter == SWITCHABLE) {
#if CONFIG_EXT_INTERP
960
961
962
963
964
965
#if CONFIG_DUAL_FILTER
    if (!vp10_is_interp_needed(xd)) {
      assert(mbmi->interp_filter[0] == EIGHTTAP_REGULAR);
      return;
    }
#else
966
    if (!vp10_is_interp_needed(xd)) {
967
968
969
970
#if CONFIG_DUAL_FILTER
      assert(mbmi->interp_filter[0] == EIGHTTAP_REGULAR);
      assert(mbmi->interp_filter[1] == EIGHTTAP_REGULAR);
#else
971
      assert(mbmi->interp_filter == EIGHTTAP_REGULAR);
972
#endif
973
974
      return;
    }
975
976
977
#endif  // CONFIG_DUAL_FILTER
#endif  // CONFIG_EXT_INTERP
#if CONFIG_DUAL_FILTER
978
    for (dir = 0; dir < 2; ++dir) {
979
      if (has_subpel_mv_component(xd->mi[0], xd, dir) ||
980
          (mbmi->ref_frame[1] > INTRA_FRAME &&
981
           has_subpel_mv_component(xd->mi[0], xd, dir + 2))) {
982
        const int ctx = vp10_get_pred_context_switchable_interp(xd, dir);
983
984
985
        vp10_write_token(
            w, vp10_switchable_interp_tree, cm->fc->switchable_interp_prob[ctx],
            &switchable_interp_encodings[mbmi->interp_filter[dir]]);
986
987
988
989
        ++cpi->interp_filter_selected[0][mbmi->interp_filter[dir]];
      }
    }
#else
Geza Lore's avatar
Geza Lore committed
990
991
992
993
994
995
996
    {
      const int ctx = vp10_get_pred_context_switchable_interp(xd);
      vp10_write_token(w, vp10_switchable_interp_tree,
                       cm->fc->switchable_interp_prob[ctx],
                       &switchable_interp_encodings[mbmi->interp_filter]);
      ++cpi->interp_filter_selected[0][mbmi->interp_filter];
    }