vp9_detokenize.c 9.02 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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
18
#include "vp9/decoder/vp9_dboolhuff.h"
19
20
#include "vp9/decoder/vp9_detokenize.h"
#include "vp9/decoder/vp9_onyxd_int.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
21
#include "vp9/decoder/vp9_treereader.h"
22

John Koleszar's avatar
John Koleszar committed
23
24
25
26
27
28
29
30
31
32
33
34
#define EOB_CONTEXT_NODE            0
#define ZERO_CONTEXT_NODE           1
#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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#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

60
static const vp9_prob cat6_prob[15] = {
61
62
  254, 254, 254, 252, 249, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0
};
John Koleszar's avatar
John Koleszar committed
63

64
65
DECLARE_ALIGNED(16, extern const uint8_t,
                vp9_pt_energy_class[MAX_ENTROPY_TOKENS]);
66
67
68
69
70
71
#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]++;     \
72
    token_cache[scan[c]] = vp9_pt_energy_class[token]; \
73
  } while (0)
74

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

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

90
static int decode_coefs(VP9_COMMON *cm, const MACROBLOCKD *xd,
91
                        vp9_reader *r, int block_idx,
92
                        PLANE_TYPE type, int seg_eob, int16_t *qcoeff_ptr,
93
                        TX_SIZE tx_size, const int16_t *dq,
94
                        ENTROPY_CONTEXT *A, ENTROPY_CONTEXT *L) {
95
96
  FRAME_CONTEXT *const fc = &cm->fc;
  FRAME_COUNTS *const counts = &cm->counts;
97
  ENTROPY_CONTEXT above_ec, left_ec;
98
  const int ref = is_inter_block(&xd->mode_info_context->mbmi);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
99
100
  int band, pt, c = 0;
  vp9_prob (*coef_probs)[PREV_COEF_CONTEXTS][UNCONSTRAINED_NODES] =
101
      fc->coef_probs[tx_size][type][ref];
102
  vp9_prob coef_probs_full[COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES];
Dmitry Kovalev's avatar
Dmitry Kovalev committed
103
  uint8_t load_map[COEF_BANDS][PREV_COEF_CONTEXTS] = { { 0 } };
104
  vp9_prob *prob;
105
  vp9_coeff_count_model *coef_counts = counts->coef[tx_size];
106
  const int16_t *scan, *nb;
107
  uint8_t token_cache[1024];
Dmitry Kovalev's avatar
Dmitry Kovalev committed
108
  const uint8_t *band_translate;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
109

110
  switch (tx_size) {
Daniel Kang's avatar
Daniel Kang committed
111
    default:
Dmitry Kovalev's avatar
Dmitry Kovalev committed
112
    case TX_4X4:
113
      scan = get_scan_4x4(get_tx_type_4x4(type, xd, block_idx));
114
115
      above_ec = A[0] != 0;
      left_ec = L[0] != 0;
Paul Wilkins's avatar
Paul Wilkins committed
116
      band_translate = vp9_coefband_trans_4x4;
Daniel Kang's avatar
Daniel Kang committed
117
      break;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
118
    case TX_8X8:
119
      scan = get_scan_8x8(get_tx_type_8x8(type, xd));
120
121
      above_ec = !!*(uint16_t *)A;
      left_ec  = !!*(uint16_t *)L;
Paul Wilkins's avatar
Paul Wilkins committed
122
      band_translate = vp9_coefband_trans_8x8plus;
Daniel Kang's avatar
Daniel Kang committed
123
      break;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
124
    case TX_16X16:
125
      scan = get_scan_16x16(get_tx_type_16x16(type, xd));
126
127
      above_ec = !!*(uint32_t *)A;
      left_ec  = !!*(uint32_t *)L;
Paul Wilkins's avatar
Paul Wilkins committed
128
      band_translate = vp9_coefband_trans_8x8plus;
Daniel Kang's avatar
Daniel Kang committed
129
      break;
130
    case TX_32X32:
Paul Wilkins's avatar
Paul Wilkins committed
131
      scan = vp9_default_scan_32x32;
132
133
      above_ec = !!*(uint64_t *)A;
      left_ec  = !!*(uint64_t *)L;
Paul Wilkins's avatar
Paul Wilkins committed
134
      band_translate = vp9_coefband_trans_8x8plus;
135
      break;
Daniel Kang's avatar
Daniel Kang committed
136
  }
John Koleszar's avatar
John Koleszar committed
137

138
  pt = combine_entropy_contexts(above_ec, left_ec);
139
  nb = vp9_get_coef_neighbors_handle(scan);
140

John Koleszar's avatar
John Koleszar committed
141
142
143
  while (1) {
    int val;
    const uint8_t *cat6 = cat6_prob;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
144
145
    if (c >= seg_eob)
      break;
146
    if (c)
147
      pt = get_coef_context(nb, token_cache, c);
Paul Wilkins's avatar
Paul Wilkins committed
148
    band = get_coef_band(band_translate, c);
149
    prob = coef_probs[band][pt];
150
    counts->eob_branch[tx_size][type][ref][band][pt]++;
151
152
    if (!vp9_read(r, prob[EOB_CONTEXT_NODE]))
      break;
153

Daniel Kang's avatar
Daniel Kang committed
154
SKIP_START:
Dmitry Kovalev's avatar
Dmitry Kovalev committed
155
156
    if (c >= seg_eob)
      break;
157
    if (c)
158
      pt = get_coef_context(nb, token_cache, c);
Paul Wilkins's avatar
Paul Wilkins committed
159
    band = get_coef_band(band_translate, c);
160
    prob = coef_probs[band][pt];
Paul Wilkins's avatar
Paul Wilkins committed
161

162
    if (!vp9_read(r, prob[ZERO_CONTEXT_NODE])) {
163
      INCREMENT_COUNT(ZERO_TOKEN);
John Koleszar's avatar
John Koleszar committed
164
165
      ++c;
      goto SKIP_START;
166
167
    }

John Koleszar's avatar
John Koleszar committed
168
    // ONE_CONTEXT_NODE_0_
169
    if (!vp9_read(r, prob[ONE_CONTEXT_NODE])) {
170
      WRITE_COEF_CONTINUE(1, ONE_TOKEN);
John Koleszar's avatar
John Koleszar committed
171
    }
172
173
    // Load full probabilities if not already loaded
    if (!load_map[band][pt]) {
174
      vp9_model_to_full_probs(coef_probs[band][pt],
175
176
177
178
                              coef_probs_full[band][pt]);
      load_map[band][pt] = 1;
    }
    prob = coef_probs_full[band][pt];
John Koleszar's avatar
John Koleszar committed
179
    // LOW_VAL_CONTEXT_NODE_0_
180
181
    if (!vp9_read(r, prob[LOW_VAL_CONTEXT_NODE])) {
      if (!vp9_read(r, prob[TWO_CONTEXT_NODE])) {
182
        WRITE_COEF_CONTINUE(2, TWO_TOKEN);
John Koleszar's avatar
John Koleszar committed
183
      }
184
      if (!vp9_read(r, prob[THREE_CONTEXT_NODE])) {
185
        WRITE_COEF_CONTINUE(3, THREE_TOKEN);
John Koleszar's avatar
John Koleszar committed
186
      }
187
      WRITE_COEF_CONTINUE(4, FOUR_TOKEN);
John Koleszar's avatar
John Koleszar committed
188
189
    }
    // HIGH_LOW_CONTEXT_NODE_0_
190
191
    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
192
193
        val = CAT1_MIN_VAL;
        ADJUST_COEF(CAT1_PROB0, 0);
194
        WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY1);
John Koleszar's avatar
John Koleszar committed
195
196
197
198
      }
      val = CAT2_MIN_VAL;
      ADJUST_COEF(CAT2_PROB1, 1);
      ADJUST_COEF(CAT2_PROB0, 0);
199
      WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY2);
Daniel Kang's avatar
Daniel Kang committed
200
    }
John Koleszar's avatar
John Koleszar committed
201
    // CAT_THREEFOUR_CONTEXT_NODE_0_
202
203
    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
204
205
206
207
        val = CAT3_MIN_VAL;
        ADJUST_COEF(CAT3_PROB2, 2);
        ADJUST_COEF(CAT3_PROB1, 1);
        ADJUST_COEF(CAT3_PROB0, 0);
208
        WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY3);
John Koleszar's avatar
John Koleszar committed
209
210
211
212
213
214
      }
      val = CAT4_MIN_VAL;
      ADJUST_COEF(CAT4_PROB3, 3);
      ADJUST_COEF(CAT4_PROB2, 2);
      ADJUST_COEF(CAT4_PROB1, 1);
      ADJUST_COEF(CAT4_PROB0, 0);
215
      WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY4);
John Koleszar's avatar
John Koleszar committed
216
217
    }
    // CAT_FIVE_CONTEXT_NODE_0_:
218
    if (!vp9_read(r, prob[CAT_FIVE_CONTEXT_NODE])) {
John Koleszar's avatar
John Koleszar committed
219
220
221
222
223
224
      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);
225
      WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY5);
John Koleszar's avatar
John Koleszar committed
226
227
228
    }
    val = 0;
    while (*cat6) {
229
      val = (val << 1) | vp9_read(r, *cat6++);
John Koleszar's avatar
John Koleszar committed
230
231
    }
    val += CAT6_MIN_VAL;
232
    WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY6);
John Koleszar's avatar
John Koleszar committed
233
  }
Jingning Han's avatar
Jingning Han committed
234

235
  if (c < seg_eob)
236
    coef_counts[type][ref][band][pt][DCT_EOB_MODEL_TOKEN]++;
237

238

John Koleszar's avatar
John Koleszar committed
239
  return c;
Daniel Kang's avatar
Daniel Kang committed
240
}
John Koleszar's avatar
John Koleszar committed
241

242
243
static int get_eob(struct segmentation *seg, int segment_id, int eob_max) {
  return vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP) ? 0 : eob_max;
244
245
}

John Koleszar's avatar
John Koleszar committed
246
247
struct decode_block_args {
  VP9D_COMP *pbi;
248
  vp9_reader *r;
John Koleszar's avatar
John Koleszar committed
249
250
  int *eobtotal;
};
251

252
static void decode_block(int plane, int block, BLOCK_SIZE plane_bsize,
253
                         TX_SIZE tx_size, void *argv) {
John Koleszar's avatar
John Koleszar committed
254
  const struct decode_block_args* const arg = argv;
255
256

  // find the maximum eob for this transform size, adjusted by segment
257
  MACROBLOCKD *xd = &arg->pbi->mb;
258
  struct segmentation *seg = &arg->pbi->common.seg;
259
260
  struct macroblockd_plane* pd = &xd->plane[plane];
  const int segment_id = xd->mode_info_context->mbmi.segment_id;
261
  const int ss_txfrm_size = tx_size << 1;
262
  const int seg_eob = get_eob(seg, segment_id, 16 << ss_txfrm_size);
263
264
265
266
267
268
269
270
271
272
  int aoff, loff, eob;

  txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &aoff, &loff);

  eob = decode_coefs(&arg->pbi->common, xd, arg->r, block,
                     pd->plane_type, seg_eob, BLOCK_OFFSET(pd->qcoeff, block),
                     tx_size, pd->dequant,
                     pd->above_context + aoff, pd->left_context + loff);

  set_contexts(xd, pd, plane_bsize, tx_size, eob > 0, aoff, loff);
273

274
275
  pd->eobs[block] = eob;
  *arg->eobtotal += eob;
276
277
}

278
int vp9_decode_tokens(VP9D_COMP *pbi, vp9_reader *r, BLOCK_SIZE bsize) {
John Koleszar's avatar
John Koleszar committed
279
  int eobtotal = 0;
280
281
  struct decode_block_args args = {pbi, r, &eobtotal};
  foreach_transformed_block(&pbi->mb, bsize, decode_block, &args);
John Koleszar's avatar
John Koleszar committed
282
  return eobtotal;
283
}