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

11
12
#include "vpx_mem/vpx_mem.h"
#include "vpx_ports/mem.h"
John Koleszar's avatar
John Koleszar committed
13

14
#include "vp9/common/vp9_blockd.h"
John Koleszar's avatar
John Koleszar committed
15
#include "vp9/common/vp9_common.h"
16
#include "vp9/common/vp9_seg_common.h"
17

18
19
20
#include "vp9/decoder/vp9_detokenize.h"
#include "vp9/decoder/vp9_onyxd_int.h"

21
22
23
24
#if CONFIG_BALANCED_COEFTREE
#define ZERO_CONTEXT_NODE           0
#define EOB_CONTEXT_NODE            1
#else
John Koleszar's avatar
John Koleszar committed
25
26
#define EOB_CONTEXT_NODE            0
#define ZERO_CONTEXT_NODE           1
27
#endif
28

John Koleszar's avatar
John Koleszar committed
29
30
31
32
33
34
35
36
37
38
#define ONE_CONTEXT_NODE            2
#define LOW_VAL_CONTEXT_NODE        3
#define TWO_CONTEXT_NODE            4
#define THREE_CONTEXT_NODE          5
#define HIGH_LOW_CONTEXT_NODE       6
#define CAT_ONE_CONTEXT_NODE        7
#define CAT_THREEFOUR_CONTEXT_NODE  8
#define CAT_THREE_CONTEXT_NODE      9
#define CAT_FIVE_CONTEXT_NODE       10

Scott LaVarnway's avatar
Scott LaVarnway committed
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#define CAT1_MIN_VAL    5
#define CAT2_MIN_VAL    7
#define CAT3_MIN_VAL   11
#define CAT4_MIN_VAL   19
#define CAT5_MIN_VAL   35
#define CAT6_MIN_VAL   67
#define CAT1_PROB0    159
#define CAT2_PROB0    145
#define CAT2_PROB1    165

#define CAT3_PROB0 140
#define CAT3_PROB1 148
#define CAT3_PROB2 173

#define CAT4_PROB0 135
#define CAT4_PROB1 140
#define CAT4_PROB2 155
#define CAT4_PROB3 176

#define CAT5_PROB0 130
#define CAT5_PROB1 134
#define CAT5_PROB2 141
#define CAT5_PROB3 157
#define CAT5_PROB4 180

64
static const vp9_prob cat6_prob[15] = {
65
66
  254, 254, 254, 252, 249, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0
};
John Koleszar's avatar
John Koleszar committed
67

68
69
DECLARE_ALIGNED(16, extern const uint8_t,
                vp9_pt_energy_class[MAX_ENTROPY_TOKENS]);
70
71
72
73
74
75
#define INCREMENT_COUNT(token)               \
  do {                                       \
    coef_counts[type][ref][band][pt]         \
               [token >= TWO_TOKEN ?     \
                (token == DCT_EOB_TOKEN ? DCT_EOB_MODEL_TOKEN : TWO_TOKEN) : \
                token]++;     \
76
    token_cache[scan[c]] = vp9_pt_energy_class[token]; \
77
  } while (0)
78

Dmitry Kovalev's avatar
Dmitry Kovalev committed
79
80
#define WRITE_COEF_CONTINUE(val, token)                  \
  {                                                      \
81
82
    qcoeff_ptr[scan[c]] = vp9_read_and_apply_sign(r, val) * \
                            dq[c > 0] / (1 + (txfm_size == TX_32X32)); \
Dmitry Kovalev's avatar
Dmitry Kovalev committed
83
84
85
    INCREMENT_COUNT(token);                              \
    c++;                                                 \
    continue;                                            \
86
  }
John Koleszar's avatar
John Koleszar committed
87

Daniel Kang's avatar
Daniel Kang committed
88
89
#define ADJUST_COEF(prob, bits_count)  \
  do {                                 \
90
    if (vp9_read(r, prob))             \
Dmitry Kovalev's avatar
Dmitry Kovalev committed
91
      val += 1 << bits_count;          \
John Koleszar's avatar
John Koleszar committed
92
  } while (0);
John Koleszar's avatar
John Koleszar committed
93

94
static int decode_coefs(FRAME_CONTEXT *fc, const MACROBLOCKD *xd,
95
                        vp9_reader *r, int block_idx,
96
                        PLANE_TYPE type, int seg_eob, int16_t *qcoeff_ptr,
97
98
                        TX_SIZE txfm_size, const int16_t *dq,
                        ENTROPY_CONTEXT *A, ENTROPY_CONTEXT *L) {
99
  ENTROPY_CONTEXT above_ec, left_ec;
100
  int pt, c = 0, pad, default_eob;
Paul Wilkins's avatar
Paul Wilkins committed
101
  int band;
102
103
104
105
106
107
108
109
110
111
112
  vp9_prob (*coef_probs)[PREV_COEF_CONTEXTS][UNCONSTRAINED_NODES];
  vp9_prob coef_probs_full[COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES];
  uint8_t load_map[COEF_BANDS][PREV_COEF_CONTEXTS] = {
    {0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0},
  };

113
  vp9_prob *prob;
114
  vp9_coeff_count_model *coef_counts;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
115
  const int ref = xd->mode_info_context->mbmi.ref_frame[0] != INTRA_FRAME;
116
117
  const int *scan, *nb;
  uint8_t token_cache[1024];
Paul Wilkins's avatar
Paul Wilkins committed
118
  const uint8_t * band_translate;
119
120
121
#if CONFIG_BALANCED_COEFTREE
  int skip_eob_node = 0;
#endif
Daniel Kang's avatar
Daniel Kang committed
122

123
124
  coef_probs  = fc->coef_probs[txfm_size][type][ref];
  coef_counts = fc->coef_counts[txfm_size];
125
  switch (txfm_size) {
Daniel Kang's avatar
Daniel Kang committed
126
    default:
127
    case TX_4X4: {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
128
129
      const TX_TYPE tx_type = type == PLANE_TYPE_Y_WITH_DC ?
                                  get_tx_type_4x4(xd, block_idx) : DCT_DCT;
130
      scan = get_scan_4x4(tx_type);
131
132
      above_ec = A[0] != 0;
      left_ec = L[0] != 0;
133
      default_eob = 16;
Paul Wilkins's avatar
Paul Wilkins committed
134
      band_translate = vp9_coefband_trans_4x4;
Daniel Kang's avatar
Daniel Kang committed
135
      break;
136
    }
137
    case TX_8X8: {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
138
139
      const TX_TYPE tx_type = type == PLANE_TYPE_Y_WITH_DC ?
                                  get_tx_type_8x8(xd) : DCT_DCT;
140
      scan = get_scan_8x8(tx_type);
141
142
      above_ec = (A[0] + A[1]) != 0;
      left_ec = (L[0] + L[1]) != 0;
143
      default_eob = 64;
Paul Wilkins's avatar
Paul Wilkins committed
144
      band_translate = vp9_coefband_trans_8x8plus;
Daniel Kang's avatar
Daniel Kang committed
145
      break;
146
147
    }
    case TX_16X16: {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
148
149
      const TX_TYPE tx_type = type == PLANE_TYPE_Y_WITH_DC ?
                                  get_tx_type_16x16(xd) : DCT_DCT;
150
      scan = get_scan_16x16(tx_type);
151
152
      above_ec = (A[0] + A[1] + A[2] + A[3]) != 0;
      left_ec = (L[0] + L[1] + L[2] + L[3]) != 0;
153
      default_eob = 256;
Paul Wilkins's avatar
Paul Wilkins committed
154
      band_translate = vp9_coefband_trans_8x8plus;
Daniel Kang's avatar
Daniel Kang committed
155
      break;
156
    }
157
    case TX_32X32:
Paul Wilkins's avatar
Paul Wilkins committed
158
      scan = vp9_default_scan_32x32;
159
160
      above_ec = (A[0] + A[1] + A[2] + A[3] + A[4] + A[5] + A[6] + A[7]) != 0;
      left_ec = (L[0] + L[1] + L[2] + L[3] + L[4] + L[5] + L[6] + L[7]) != 0;
161
      default_eob = 1024;
Paul Wilkins's avatar
Paul Wilkins committed
162
      band_translate = vp9_coefband_trans_8x8plus;
163
      break;
Daniel Kang's avatar
Daniel Kang committed
164
  }
John Koleszar's avatar
John Koleszar committed
165

166
  pt = combine_entropy_contexts(above_ec, left_ec);
167
168
  nb = vp9_get_coef_neighbors_handle(scan, &pad);

John Koleszar's avatar
John Koleszar committed
169
170
171
  while (1) {
    int val;
    const uint8_t *cat6 = cat6_prob;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
172
173
    if (c >= seg_eob)
      break;
174
175
176
    if (c)
      pt = vp9_get_coef_context(scan, nb, pad, token_cache,
                                c, default_eob);
Paul Wilkins's avatar
Paul Wilkins committed
177
    band = get_coef_band(band_translate, c);
178
    prob = coef_probs[band][pt];
179
#if !CONFIG_BALANCED_COEFTREE
180
    fc->eob_branch_counts[txfm_size][type][ref][band][pt]++;
181
182
    if (!vp9_read(r, prob[EOB_CONTEXT_NODE]))
      break;
183

Daniel Kang's avatar
Daniel Kang committed
184
SKIP_START:
185
#endif
Dmitry Kovalev's avatar
Dmitry Kovalev committed
186
187
    if (c >= seg_eob)
      break;
188
189
190
    if (c)
      pt = vp9_get_coef_context(scan, nb, pad, token_cache,
                                c, default_eob);
Paul Wilkins's avatar
Paul Wilkins committed
191
    band = get_coef_band(band_translate, c);
192
    prob = coef_probs[band][pt];
Paul Wilkins's avatar
Paul Wilkins committed
193

194
    if (!vp9_read(r, prob[ZERO_CONTEXT_NODE])) {
195
      INCREMENT_COUNT(ZERO_TOKEN);
John Koleszar's avatar
John Koleszar committed
196
      ++c;
197
198
199
200
#if CONFIG_BALANCED_COEFTREE
      skip_eob_node = 1;
      continue;
#else
John Koleszar's avatar
John Koleszar committed
201
      goto SKIP_START;
202
#endif
John Koleszar's avatar
John Koleszar committed
203
    }
204
205
206
207
208
209
210
211
212
#if CONFIG_BALANCED_COEFTREE
    if (!skip_eob_node) {
      fc->eob_branch_counts[txfm_size][type][ref][band][pt]++;
      if (!vp9_read(r, prob[EOB_CONTEXT_NODE]))
        break;
    }
    skip_eob_node = 0;
#endif

John Koleszar's avatar
John Koleszar committed
213
    // ONE_CONTEXT_NODE_0_
214
    if (!vp9_read(r, prob[ONE_CONTEXT_NODE])) {
215
      WRITE_COEF_CONTINUE(1, ONE_TOKEN);
John Koleszar's avatar
John Koleszar committed
216
    }
217
218
    // Load full probabilities if not already loaded
    if (!load_map[band][pt]) {
219
      vp9_model_to_full_probs(coef_probs[band][pt],
220
221
222
223
                              coef_probs_full[band][pt]);
      load_map[band][pt] = 1;
    }
    prob = coef_probs_full[band][pt];
John Koleszar's avatar
John Koleszar committed
224
    // LOW_VAL_CONTEXT_NODE_0_
225
226
    if (!vp9_read(r, prob[LOW_VAL_CONTEXT_NODE])) {
      if (!vp9_read(r, prob[TWO_CONTEXT_NODE])) {
227
        WRITE_COEF_CONTINUE(2, TWO_TOKEN);
John Koleszar's avatar
John Koleszar committed
228
      }
229
      if (!vp9_read(r, prob[THREE_CONTEXT_NODE])) {
230
        WRITE_COEF_CONTINUE(3, THREE_TOKEN);
John Koleszar's avatar
John Koleszar committed
231
      }
232
      WRITE_COEF_CONTINUE(4, FOUR_TOKEN);
John Koleszar's avatar
John Koleszar committed
233
234
    }
    // HIGH_LOW_CONTEXT_NODE_0_
235
236
    if (!vp9_read(r, prob[HIGH_LOW_CONTEXT_NODE])) {
      if (!vp9_read(r, prob[CAT_ONE_CONTEXT_NODE])) {
John Koleszar's avatar
John Koleszar committed
237
238
        val = CAT1_MIN_VAL;
        ADJUST_COEF(CAT1_PROB0, 0);
239
        WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY1);
John Koleszar's avatar
John Koleszar committed
240
241
242
243
      }
      val = CAT2_MIN_VAL;
      ADJUST_COEF(CAT2_PROB1, 1);
      ADJUST_COEF(CAT2_PROB0, 0);
244
      WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY2);
Daniel Kang's avatar
Daniel Kang committed
245
    }
John Koleszar's avatar
John Koleszar committed
246
    // CAT_THREEFOUR_CONTEXT_NODE_0_
247
248
    if (!vp9_read(r, prob[CAT_THREEFOUR_CONTEXT_NODE])) {
      if (!vp9_read(r, prob[CAT_THREE_CONTEXT_NODE])) {
John Koleszar's avatar
John Koleszar committed
249
250
251
252
        val = CAT3_MIN_VAL;
        ADJUST_COEF(CAT3_PROB2, 2);
        ADJUST_COEF(CAT3_PROB1, 1);
        ADJUST_COEF(CAT3_PROB0, 0);
253
        WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY3);
John Koleszar's avatar
John Koleszar committed
254
255
256
257
258
259
      }
      val = CAT4_MIN_VAL;
      ADJUST_COEF(CAT4_PROB3, 3);
      ADJUST_COEF(CAT4_PROB2, 2);
      ADJUST_COEF(CAT4_PROB1, 1);
      ADJUST_COEF(CAT4_PROB0, 0);
260
      WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY4);
John Koleszar's avatar
John Koleszar committed
261
262
    }
    // CAT_FIVE_CONTEXT_NODE_0_:
263
    if (!vp9_read(r, prob[CAT_FIVE_CONTEXT_NODE])) {
John Koleszar's avatar
John Koleszar committed
264
265
266
267
268
269
      val = CAT5_MIN_VAL;
      ADJUST_COEF(CAT5_PROB4, 4);
      ADJUST_COEF(CAT5_PROB3, 3);
      ADJUST_COEF(CAT5_PROB2, 2);
      ADJUST_COEF(CAT5_PROB1, 1);
      ADJUST_COEF(CAT5_PROB0, 0);
270
      WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY5);
John Koleszar's avatar
John Koleszar committed
271
272
273
    }
    val = 0;
    while (*cat6) {
274
      val = (val << 1) | vp9_read(r, *cat6++);
John Koleszar's avatar
John Koleszar committed
275
276
    }
    val += CAT6_MIN_VAL;
277
    WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY6);
John Koleszar's avatar
John Koleszar committed
278
  }
Jingning Han's avatar
Jingning Han committed
279

280
  if (c < seg_eob)
281
    coef_counts[type][ref][band][pt][DCT_EOB_MODEL_TOKEN]++;
282

283

John Koleszar's avatar
John Koleszar committed
284
  return c;
Daniel Kang's avatar
Daniel Kang committed
285
}
John Koleszar's avatar
John Koleszar committed
286

287
static int get_eob(MACROBLOCKD* const xd, int segment_id, int eob_max) {
Paul Wilkins's avatar
Paul Wilkins committed
288
  return vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP) ? 0 : eob_max;
289
290
}

John Koleszar's avatar
John Koleszar committed
291
292
struct decode_block_args {
  VP9D_COMP *pbi;
293
  vp9_reader *r;
John Koleszar's avatar
John Koleszar committed
294
295
  int *eobtotal;
};
296

John Koleszar's avatar
John Koleszar committed
297
static void decode_block(int plane, int block,
298
                         BLOCK_SIZE_TYPE bsize,
John Koleszar's avatar
John Koleszar committed
299
300
301
                         int ss_txfrm_size,
                         void *argv) {
  const struct decode_block_args* const arg = argv;
John Koleszar's avatar
John Koleszar committed
302
  const int bw = b_width_log2(bsize);
303
304

  // find the maximum eob for this transform size, adjusted by segment
305
306
307
  MACROBLOCKD *xd = &arg->pbi->mb;
  struct macroblockd_plane* pd = &xd->plane[plane];
  const int segment_id = xd->mode_info_context->mbmi.segment_id;
John Koleszar's avatar
John Koleszar committed
308
  const TX_SIZE ss_tx_size = ss_txfrm_size / 2;
309
  const int seg_eob = get_eob(xd, segment_id, 16 << ss_txfrm_size);
310
  const int off = block >> ss_txfrm_size;
311
  const int mod = bw - ss_tx_size - pd->subsampling_x;
312
313
  const int aoff = (off & ((1 << mod) - 1)) << ss_tx_size;
  const int loff = (off >> mod) << ss_tx_size;
314
315
316
317
318
319
320

  ENTROPY_CONTEXT *A = pd->above_context + aoff;
  ENTROPY_CONTEXT *L = pd->left_context + loff;
  const int eob = decode_coefs(&arg->pbi->common.fc, xd, arg->r, block,
                               pd->plane_type, seg_eob,
                               BLOCK_OFFSET(pd->qcoeff, block, 16),
                               ss_tx_size, pd->dequant, A, L);
321

322
323
324
  if (xd->mb_to_right_edge < 0 || xd->mb_to_bottom_edge < 0) {
    set_contexts_on_border(xd, bsize, plane, ss_tx_size, eob, aoff, loff, A, L);
  } else {
325
326
    int pt;
    for (pt = 0; pt < (1 << ss_tx_size); pt++)
327
328
      A[pt] = L[pt] = eob > 0;
  }
329
330
  pd->eobs[block] = eob;
  *arg->eobtotal += eob;
331
332
}

333
int vp9_decode_tokens(VP9D_COMP *pbi, vp9_reader *r, BLOCK_SIZE_TYPE bsize) {
John Koleszar's avatar
John Koleszar committed
334
  int eobtotal = 0;
335
336
  struct decode_block_args args = {pbi, r, &eobtotal};
  foreach_transformed_block(&pbi->mb, bsize, decode_block, &args);
John Koleszar's avatar
John Koleszar committed
337
  return eobtotal;
338
}