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"
Jingning Han's avatar
Jingning Han committed
21

22
23
24
25
26
#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"
27
#include "vp10/common/reconinter.h"
28
29
#include "vp10/common/seg_common.h"
#include "vp10/common/tile_common.h"
Jingning Han's avatar
Jingning Han committed
30

Alex Converse's avatar
Alex Converse committed
31
#if CONFIG_ANS
32
#include "vp10/encoder/buf_ans.h"
Alex Converse's avatar
Alex Converse committed
33
#endif  // CONFIG_ANS
34
35
36
37
38
39
40
#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
41
42
43
44

static const struct vp10_token intra_mode_encodings[INTRA_MODES] = {
  {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
45
#if CONFIG_EXT_INTERP
46
47
static const struct vp10_token switchable_interp_encodings[SWITCHABLE_FILTERS] =
  {{0, 1}, {4, 3}, {6, 3}, {5, 3}, {7, 3}};
48
#else
Jingning Han's avatar
Jingning Han committed
49
50
static const struct vp10_token switchable_interp_encodings[SWITCHABLE_FILTERS] =
  {{0, 1}, {2, 2}, {3, 2}};
Jingning Han's avatar
Jingning Han committed
51
#endif  // CONFIG_EXT_INTERP
52
53
54
55
#if CONFIG_EXT_PARTITION_TYPES
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}};
#endif
Jingning Han's avatar
Jingning Han committed
56
57
static const struct vp10_token partition_encodings[PARTITION_TYPES] =
  {{0, 1}, {2, 2}, {6, 3}, {7, 3}};
58
#if !CONFIG_REF_MV
Jingning Han's avatar
Jingning Han committed
59
static const struct vp10_token inter_mode_encodings[INTER_MODES] =
Yue Chen's avatar
Yue Chen committed
60
61
62
#if CONFIG_EXT_INTER
  {{2, 2}, {6, 3}, {0, 1}, {14, 4}, {15, 4}};
#else
Jingning Han's avatar
Jingning Han committed
63
  {{2, 2}, {6, 3}, {0, 1}, {7, 3}};
Yue Chen's avatar
Yue Chen committed
64
#endif  // CONFIG_EXT_INTER
65
#endif
66
67
68
#if CONFIG_EXT_INTER
static const struct vp10_token inter_compound_mode_encodings
                               [INTER_COMPOUND_MODES] = {
69
  {2, 2}, {50, 6}, {51, 6}, {24, 5}, {52, 6}, {53, 6},
70
71
72
  {54, 6}, {55, 6}, {0, 1}, {7, 3}
};
#endif  // CONFIG_EXT_INTER
hui su's avatar
hui su committed
73
74
75
76
77
78
79
80
81
82
83
84
85
86
static const struct vp10_token palette_size_encodings[] = {
    {0, 1}, {2, 2}, {6, 3}, {14, 4}, {30, 5}, {62, 6}, {63, 6},
};
static const struct vp10_token
palette_color_encodings[PALETTE_MAX_SIZE - 1][PALETTE_MAX_SIZE] = {
    {{0, 1}, {1, 1}},  // 2 colors
    {{0, 1}, {2, 2}, {3, 2}},  // 3 colors
    {{0, 1}, {2, 2}, {6, 3}, {7, 3}},  // 4 colors
    {{0, 1}, {2, 2}, {6, 3}, {14, 4}, {15, 4}},  // 5 colors
    {{0, 1}, {2, 2}, {6, 3}, {14, 4}, {30, 5}, {31, 5}},  // 6 colors
    {{0, 1}, {2, 2}, {6, 3}, {14, 4}, {30, 5}, {62, 6}, {63, 6}},  // 7 colors
    {{0, 1}, {2, 2}, {6, 3}, {14, 4},
        {30, 5}, {62, 6}, {126, 7}, {127, 7}},  // 8 colors
};
hui su's avatar
hui su committed
87

88
89
90
91
92
93
94
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
};

95
static INLINE void write_uniform(vp10_writer *w, int n, int v) {
hui su's avatar
hui su committed
96
97
98
99
100
  int l = get_unsigned_bits(n);
  int m = (1 << l) - n;
  if (l == 0)
    return;
  if (v < m) {
101
    vp10_write_literal(w, v, l - 1);
hui su's avatar
hui su committed
102
  } else {
103
104
    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
105
106
  }
}
Jingning Han's avatar
Jingning Han committed
107

108
#if CONFIG_EXT_TX
109
110
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];
111
#else
112
static struct vp10_token ext_tx_encodings[TX_TYPES];
113
#endif  // CONFIG_EXT_TX
114
115
116
#if CONFIG_GLOBAL_MOTION
static struct vp10_token global_motion_types_encodings[GLOBAL_MOTION_TYPES];
#endif  // CONFIG_GLOBAL_MOTION
117
118
119
#if CONFIG_EXT_INTRA
static struct vp10_token intra_filter_encodings[INTRA_FILTERS];
#endif  // CONFIG_EXT_INTRA
120
121
122
#if CONFIG_EXT_INTER
static struct vp10_token interintra_mode_encodings[INTERINTRA_MODES];
#endif  // CONFIG_EXT_INTER
123
124
125
#if CONFIG_OBMC || CONFIG_WARPED_MOTION
static struct vp10_token motvar_encodings[MOTION_VARIATIONS];
#endif  // CONFIG_OBMC || CONFIG_WARPED_MOTION
126

127
void vp10_encode_token_init(void) {
128
#if CONFIG_EXT_TX
129
130
131
132
133
134
135
  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]);
  }
136
#else
137
  vp10_tokens_from_tree(ext_tx_encodings, vp10_ext_tx_tree);
138
#endif  // CONFIG_EXT_TX
139
140
141
#if CONFIG_EXT_INTRA
  vp10_tokens_from_tree(intra_filter_encodings, vp10_intra_filter_tree);
#endif  // CONFIG_EXT_INTRA
142
143
144
#if CONFIG_EXT_INTER
  vp10_tokens_from_tree(interintra_mode_encodings, vp10_interintra_mode_tree);
#endif  // CONFIG_EXT_INTER
145
146
147
#if CONFIG_OBMC || CONFIG_WARPED_MOTION
  vp10_tokens_from_tree(motvar_encodings, vp10_motvar_tree);
#endif  // CONFIG_OBMC || CONFIG_WARPED_MOTION
148
149
150
151
#if CONFIG_GLOBAL_MOTION
  vp10_tokens_from_tree(global_motion_types_encodings,
                       vp10_global_motion_types_tree);
#endif  // CONFIG_GLOBAL_MOTION
152
153
}

154
static void write_intra_mode(vp10_writer *w, PREDICTION_MODE mode,
Jingning Han's avatar
Jingning Han committed
155
156
157
158
                             const vpx_prob *probs) {
  vp10_write_token(w, vp10_intra_mode_tree, probs, &intra_mode_encodings[mode]);
}

159
#if CONFIG_EXT_INTER
160
static void write_interintra_mode(vp10_writer *w, INTERINTRA_MODE mode,
161
162
163
164
165
166
                                  const vpx_prob *probs) {
  vp10_write_token(w, vp10_interintra_mode_tree, probs,
                   &interintra_mode_encodings[mode]);
}
#endif  // CONFIG_EXT_INTER

167
static void write_inter_mode(VP10_COMMON *cm,
168
                             vp10_writer *w, PREDICTION_MODE mode,
Yue Chen's avatar
Yue Chen committed
169
170
171
#if CONFIG_REF_MV && CONFIG_EXT_INTER
                             int is_compound,
#endif  // CONFIG_REF_MV && CONFIG_EXT_INTER
172
                             const int16_t mode_ctx) {
173
#if CONFIG_REF_MV
174
  const int16_t newmv_ctx = mode_ctx & NEWMV_CTX_MASK;
175
  const vpx_prob newmv_prob = cm->fc->newmv_prob[newmv_ctx];
Yue Chen's avatar
Yue Chen committed
176
#if CONFIG_EXT_INTER
177
  vp10_write(w, mode != NEWMV && mode != NEWFROMNEARMV, newmv_prob);
Yue Chen's avatar
Yue Chen committed
178
179

  if (!is_compound && (mode == NEWMV || mode == NEWFROMNEARMV))
180
    vp10_write(w, mode == NEWFROMNEARMV, cm->fc->new2mv_prob);
Yue Chen's avatar
Yue Chen committed
181
182
183

  if (mode != NEWMV && mode != NEWFROMNEARMV) {
#else
184
  vp10_write(w, mode != NEWMV, newmv_prob);
185
186

  if (mode != NEWMV) {
Yue Chen's avatar
Yue Chen committed
187
#endif  // CONFIG_EXT_INTER
188
    const int16_t zeromv_ctx = (mode_ctx >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
189
    const vpx_prob zeromv_prob = cm->fc->zeromv_prob[zeromv_ctx];
190
191
192
193
194
195

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

196
    vp10_write(w, mode != ZEROMV, zeromv_prob);
197
198

    if (mode != ZEROMV) {
199
200
201
202
203
204
205
206
207
208
209
      int16_t refmv_ctx = (mode_ctx >> REFMV_OFFSET) & REFMV_CTX_MASK;
      vpx_prob refmv_prob;

      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;

      refmv_prob = cm->fc->refmv_prob[refmv_ctx];
210
      vp10_write(w, mode != NEARESTMV, refmv_prob);
211
212
213
214
    }
  }
#else
  const vpx_prob *const inter_probs = cm->fc->inter_mode_probs[mode_ctx];
Jingning Han's avatar
Jingning Han committed
215
  assert(is_inter_mode(mode));
216
  vp10_write_token(w, vp10_inter_mode_tree, inter_probs,
Jingning Han's avatar
Jingning Han committed
217
                  &inter_mode_encodings[INTER_OFFSET(mode)]);
218
#endif
Jingning Han's avatar
Jingning Han committed
219
220
}

221
222
223
224
#if CONFIG_REF_MV
static void write_drl_idx(const VP10_COMMON *cm,
                          const MB_MODE_INFO *mbmi,
                          const MB_MODE_INFO_EXT *mbmi_ext,
225
                          vp10_writer *w) {
226
  uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
227
228
229

  assert(mbmi->ref_mv_idx < 3);

230
231
232
233
234
235
236
237
  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];

238
        vp10_write(w, mbmi->ref_mv_idx != idx, drl_prob);
239
240
241
        if (mbmi->ref_mv_idx == idx)
          return;
      }
242
243
244
245
    }
    return;
  }

246
247
248
249
250
251
252
253
254
  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];

255
        vp10_write(w, mbmi->ref_mv_idx != (idx - 1), drl_prob);
256
257
258
        if (mbmi->ref_mv_idx == (idx - 1))
          return;
      }
259
    }
260
    return;
261
262
263
264
  }
}
#endif

265
#if CONFIG_EXT_INTER
266
static void write_inter_compound_mode(VP10_COMMON *cm, vp10_writer *w,
267
268
269
270
271
272
273
274
275
276
277
                                      PREDICTION_MODE mode,
                                      const int16_t mode_ctx) {
  const vpx_prob *const inter_compound_probs =
                        cm->fc->inter_compound_mode_probs[mode_ctx];

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

Jingning Han's avatar
Jingning Han committed
278
279
280
281
282
283
284
285
static void encode_unsigned_max(struct vpx_write_bit_buffer *wb,
                                int data, int max) {
  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*/],
                             const unsigned int counts[/*n - 1*/],
286
                             int n, vp10_writer *w) {
Jingning Han's avatar
Jingning Han committed
287
288
289
290
291
292
293
294
295
296
297
  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]);
}

298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
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) {
    savings += vp10_cond_prob_diff_update_savings(&probs[i],
                                                  branch_ct[i]);
  }
  return savings;
}

316
317
#if CONFIG_VAR_TX
static void write_tx_size_inter(const VP10_COMMON *cm,
318
                                const MACROBLOCKD *xd,
319
                                const MB_MODE_INFO *mbmi,
320
                                TX_SIZE tx_size, int blk_row, int blk_col,
321
                                vp10_writer *w) {
322
323
  const int tx_row = blk_row >> 1;
  const int tx_col = blk_col >> 1;
324
325
  int max_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
  int max_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
326
327
  int ctx = txfm_partition_context(xd->above_txfm_context + tx_col,
                                   xd->left_txfm_context + tx_row,
328
329
                                   tx_size);

330
331
332
333
334
335
336
337
  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;

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

338
  if (tx_size == mbmi->inter_tx_size[tx_row][tx_col]) {
339
    vp10_write(w, 0, cm->fc->txfm_partition_prob[ctx]);
340
341
    txfm_partition_update(xd->above_txfm_context + tx_col,
                          xd->left_txfm_context + tx_row, tx_size);
342
343
  } else {
    const BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
344
    int bsl = b_width_log2_lookup[bsize];
345
    int i;
346
    vp10_write(w, 1, cm->fc->txfm_partition_prob[ctx]);
347

348
    if (tx_size == TX_8X8) {
349
350
      txfm_partition_update(xd->above_txfm_context + tx_col,
                            xd->left_txfm_context + tx_row, TX_4X4);
351
      return;
352
    }
353
354
355
356

    assert(bsl > 0);
    --bsl;
    for (i = 0; i < 4; ++i) {
357
358
359
      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);
360
361
362
    }
  }
}
363

364
static void update_txfm_partition_probs(VP10_COMMON *cm, vp10_writer *w,
365
366
367
368
369
370
                                        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]);
}
371
372
#endif

Yaowu Xu's avatar
Yaowu Xu committed
373
static void write_selected_tx_size(const VP10_COMMON *cm,
374
                                   const MACROBLOCKD *xd, vp10_writer *w) {
Jingning Han's avatar
Jingning Han committed
375
376
377
  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];
378
379
380
381
382
  if (max_tx_size > TX_4X4) {
    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
383
384
385
  }
}

386
#if CONFIG_REF_MV
387
static void update_inter_mode_probs(VP10_COMMON *cm, vp10_writer *w,
388
389
390
391
392
393
394
395
396
397
398
                                    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]);
399
  for (i = 0; i < DRL_MODE_CONTEXTS; ++i)
400
401
    vp10_cond_prob_diff_update(w, &cm->fc->drl_prob[i],
                               counts->drl_mode[i]);
Yue Chen's avatar
Yue Chen committed
402
403
404
#if CONFIG_EXT_INTER
  vp10_cond_prob_diff_update(w, &cm->fc->new2mv_prob, counts->new2mv_mode);
#endif  // CONFIG_EXT_INTER
405
406
407
}
#endif

408
#if CONFIG_EXT_INTER
409
static void update_inter_compound_mode_probs(VP10_COMMON *cm, vp10_writer *w) {
410
411
412
413
414
415
416
417
418
419
420
421
  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) {
    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);
  }
  do_update = savings > savings_thresh;
422
  vp10_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
423
424
425
426
427
428
429
430
431
432
433
  if (do_update) {
    for (i = 0; i < INTER_MODE_CONTEXTS; ++i) {
      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);
    }
  }
}
#endif  // CONFIG_EXT_INTER

Yaowu Xu's avatar
Yaowu Xu committed
434
static int write_skip(const VP10_COMMON *cm, const MACROBLOCKD *xd,
435
                      int segment_id, const MODE_INFO *mi, vp10_writer *w) {
Jingning Han's avatar
Jingning Han committed
436
437
438
439
  if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
    return 1;
  } else {
    const int skip = mi->mbmi.skip;
440
    vp10_write(w, skip, vp10_get_skip_prob(cm, xd));
Jingning Han's avatar
Jingning Han committed
441
442
443
444
    return skip;
  }
}

445
static void update_skip_probs(VP10_COMMON *cm, vp10_writer *w,
Jingning Han's avatar
Jingning Han committed
446
447
448
449
450
451
452
                              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]);
}

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

462

463
#if CONFIG_EXT_TX
464
static void update_ext_tx_probs(VP10_COMMON *cm, vp10_writer *w) {
465
466
  const int savings_thresh = vp10_cost_one(GROUP_DIFF_UPDATE_PROB) -
                             vp10_cost_zero(GROUP_DIFF_UPDATE_PROB);
467
  int i, j;
468
469
470
471
472
  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) {
473
      if (!use_inter_ext_tx_for_txsize[s][i]) continue;
474
475
476
477
478
      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;
479
    vp10_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
480
481
    if (do_update) {
      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
        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);
      }
488
489
    }
  }
490

491
492
493
494
  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) {
495
      if (!use_intra_ext_tx_for_txsize[s][i]) continue;
496
      for (j = 0; j < INTRA_MODES; ++j)
497
498
499
500
501
        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;
502
    vp10_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
503
504
    if (do_update) {
      for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
505
        if (!use_intra_ext_tx_for_txsize[s][i]) continue;
506
507
508
509
510
511
512
        for (j = 0; j < INTRA_MODES; ++j)
          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);
      }
    }
513
  }
514
}
Debargha Mukherjee's avatar
Debargha Mukherjee committed
515

516
#else
Debargha Mukherjee's avatar
Debargha Mukherjee committed
517

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

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

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

  *tp = p;
}

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

  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];
    (void) bit_depth;
#endif  // CONFIG_VP9_HIGHBITDEPTH

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

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

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

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

    if (b->base_val) {
      const int e = p->extra, l = b->len;
653
654
      int skip_bits =
          (b->base_val == CAT6_MIN_VAL) ? TX_SIZES - 1 - tx : 0;
Jingning Han's avatar
Jingning Han committed
655
656
657
658
659
660
661
662
663

      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;
664
665
666
667
          if (skip_bits) {
            skip_bits--;
            assert(!bb);
          } else {
668
            vp10_write(w, bb, pb[i >> 1]);
669
          }
Jingning Han's avatar
Jingning Han committed
670
671
672
673
          i = b->tree[i + bb];
        } while (n);
      }

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

#if CONFIG_VAR_TX
    ++count;
    if (t == EOB_TOKEN || count == seg_eob)
      break;
#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
691
692
693
694
static void pack_mb_tokens(struct BufAnsCoder *ans,
                           const TOKENEXTRA **tp,
                           const TOKENEXTRA *const stop,
                           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
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
      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);
        }
749

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

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

765
#if CONFIG_VAR_TX
766
static void pack_txb_tokens(vp10_writer *w,
767
768
                           const TOKENEXTRA **tp,
                           const TOKENEXTRA *const tok_end,
769
770
771
772
773
774
775
                           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) {
  const struct macroblockd_plane *const pd = &xd->plane[plane];
  const BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
776
777
778
779
780
  const int tx_row = blk_row >> (1 - pd->subsampling_y);
  const int tx_col = blk_col >> (1 - pd->subsampling_x);
  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];
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
  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);

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

  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);
      int step = 1 << (2 * (tx_size - 1));

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

      pack_txb_tokens(w, tp, tok_end, xd, mbmi, plane,
                      plane_bsize, bit_depth, block + i * step,
                      offsetr, offsetc, tx_size - 1);
    }
  }
}
#endif

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

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

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

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

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

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

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

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

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

919
920
  if (mbmi->uv_mode == DC_PRED &&
      mbmi->palette_mode_info.palette_size[1] == 0) {
921
    vp10_write(w, mbmi->ext_intra_mode_info.use_ext_intra_mode[1],
hui su's avatar
hui su committed
922
923
924
              cm->fc->ext_intra_probs[1]);
    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
925
      write_uniform(w, FILTER_INTRA_MODES, mode);
hui su's avatar
hui su committed
926
927
928
    }
  }
}
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955

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;

  if (bsize < BLOCK_8X8)
    return;

  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
956
957
#endif  // CONFIG_EXT_INTRA

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

1009
1010
1011
static void write_palette_mode_info(const VP10_COMMON *cm,
                                    const MACROBLOCKD *xd,
                                    const MODE_INFO *const mi,
1012
                                    vp10_writer *w) {
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
  const MB_MODE_INFO *const mbmi = &mi->mbmi;
  const MODE_INFO *const above_mi = xd->above_mi;
  const MODE_INFO *const left_mi = xd->left_mi;
  const BLOCK_SIZE bsize = mbmi->sb_type;
  const PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
  int palette_ctx = 0;
  int n, i;

  if (mbmi->mode == DC_PRED) {
    n = pmi->palette_size[0];
    if (above_mi)
      palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
    if (left_mi)
      palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
1027
    vp10_write(w, n > 0,
1028
1029
1030
1031
1032
1033
              vp10_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx]);
    if (n > 0) {
      vp10_write_token(w, vp10_palette_size_tree,
                       vp10_default_palette_y_size_prob[bsize - BLOCK_8X8],
                       &palette_size_encodings[n - 2]);
      for (i = 0; i < n; ++i)
1034
        vp10_write_literal(w, pmi->palette_colors[i], cm->bit_depth);
1035
1036
1037
1038
1039
1040
      write_uniform(w, n, pmi->palette_first_color_idx[0]);
    }
  }

  if (mbmi->uv_mode == DC_PRED) {
    n = pmi->palette_size[1];
1041
    vp10_write(w, n > 0,
1042
1043
1044
1045
1046
1047
              vp10_default_palette_uv_mode_prob[pmi->palette_size[0] > 0]);
    if (n > 0) {
      vp10_write_token(w, vp10_palette_size_tree,
                       vp10_default_palette_uv_size_prob[bsize - BLOCK_8X8],
                       &palette_size_encodings[n - 2]);
      for (i = 0; i < n; ++i) {
1048
        vp10_write_literal(w, pmi->palette_colors[PALETTE_MAX_SIZE + i],
1049
                          cm->bit_depth);
1050
        vp10_write_literal(w, pmi->palette_colors[2 * PALETTE_MAX_SIZE + i],
1051
1052
1053
1054
1055
1056
1057
                          cm->bit_depth);
      }
      write_uniform(w, n, pmi->palette_first_color_idx[1]);
    }
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
1058
static void pack_inter_mode_mvs(VP10_COMP *cpi, const MODE_INFO *mi,
1059
1060
1061
#if CONFIG_SUPERTX
                                int supertx_enabled,
#endif
1062
                                vp10_writer *w) {
Yaowu Xu's avatar
Yaowu Xu committed
1063
  VP10_COMMON *const cm = &cpi->common;
1064
#if !CONFIG_REF_MV
Jingning Han's avatar
Jingning Han committed
1065
  const nmv_context *nmvc = &cm->fc->nmvc;
1066
#endif
1067
1068
  const MACROBLOCK *x = &cpi->td.mb;
  const MACROBLOCKD *xd = &x->e_mbd;
Jingning Han's avatar
Jingning Han committed
1069
  const struct segmentation *const seg = &cm->seg;
1070
  const struct segmentation_probs *const segp = &cm->fc->seg;
Jingning Han's avatar
Jingning Han committed
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
  const MB_MODE_INFO *const mbmi = &mi->mbmi;
  const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
  const PREDICTION_MODE mode = mbmi->mode;
  const int segment_id = mbmi->segment_id;
  const BLOCK_SIZE bsize = mbmi->sb_type;
  const int allow_hp = cm->allow_high_precision_mv;
  const int is_inter = is_inter_block(mbmi);
  const int is_compound = has_second_ref(mbmi);
  int skip, ref;

  if (seg->update_map) {
    if (seg->temporal_update) {
      const int pred_flag = mbmi->seg_id_predicted;
1084
      vpx_prob pred_prob = vp10_get_pred_prob_seg_id(segp, xd);
1085
      vp10_write(w, pred_flag, pred_prob);
Jingning Han's avatar
Jingning Han committed
1086
      if (!pred_flag)
1087
        write_segment_id(w, seg, segp, segment_id);
Jingning Han's avatar
Jingning Han committed
1088
    } else {
1089
      write_segment_id(w, seg, segp, segment_id);
Jingning Han's avatar
Jingning Han committed
1090
1091
1092
    }
  }

1093
1094
1095
1096
1097
1098
#if CONFIG_SUPERTX
  if (supertx_enabled)
    skip = mbmi->skip;
  else
    skip = write_skip(cm, xd, segment_id, mi, w);
#else
Jingning Han's avatar
Jingning Han committed
1099
  skip = write_skip(cm, xd, segment_id, mi, w);
1100
#endif  // CONFIG_SUPERTX