vp9_detokenize.c 11.1 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 "vp9/common/vp9_blockd.h"
John Koleszar's avatar
John Koleszar committed
13
#include "vp9/common/vp9_common.h"
14
#include "vp9/decoder/vp9_onyxd_int.h"
John Koleszar's avatar
John Koleszar committed
15 16
#include "vpx_mem/vpx_mem.h"
#include "vpx_ports/mem.h"
17
#include "vp9/decoder/vp9_detokenize.h"
18
#include "vp9/common/vp9_seg_common.h"
19

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

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

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
77 78
#define WRITE_COEF_CONTINUE(val, token)                  \
  {                                                      \
79 80
    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
81 82 83
    INCREMENT_COUNT(token);                              \
    c++;                                                 \
    continue;                                            \
84
  }
John Koleszar's avatar
John Koleszar committed
85

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

92
static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd,
93
                        vp9_reader *r, int block_idx,
94
                        PLANE_TYPE type, int seg_eob, int16_t *qcoeff_ptr,
95 96
                        TX_SIZE txfm_size, const int16_t *dq,
                        ENTROPY_CONTEXT *A, ENTROPY_CONTEXT *L) {
97
  ENTROPY_CONTEXT above_ec, left_ec;
John Koleszar's avatar
John Koleszar committed
98
  FRAME_CONTEXT *const fc = &dx->common.fc;
99
  int pt, c = 0, pad, default_eob;
Paul Wilkins's avatar
Paul Wilkins committed
100
  int band;
101 102 103 104 105 106 107 108 109 110 111
  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},
  };

112
  vp9_prob *prob;
113
  vp9_coeff_count_model *coef_counts;
114
  const int ref = xd->mode_info_context->mbmi.ref_frame != INTRA_FRAME;
115
  TX_TYPE tx_type = DCT_DCT;
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: {
128 129
      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 138
    case TX_8X8: {
      const BLOCK_SIZE_TYPE sb_type = xd->mode_info_context->mbmi.sb_type;
139
      const int sz = 1 + b_width_log2(sb_type);
140
      const int x = block_idx & ((1 << sz) - 1);
141
      const int y = block_idx - x;
142 143
      tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
          get_tx_type_8x8(xd, y + (x >> 1)) : DCT_DCT;
144
      scan = get_scan_8x8(tx_type);
145 146
      above_ec = (A[0] + A[1]) != 0;
      left_ec = (L[0] + L[1]) != 0;
147
      default_eob = 64;
Paul Wilkins's avatar
Paul Wilkins committed
148
      band_translate = vp9_coefband_trans_8x8plus;
Daniel Kang's avatar
Daniel Kang committed
149
      break;
150 151 152
    }
    case TX_16X16: {
      const BLOCK_SIZE_TYPE sb_type = xd->mode_info_context->mbmi.sb_type;
153
      const int sz = 2 + b_width_log2(sb_type);
154
      const int x = block_idx & ((1 << sz) - 1);
155
      const int y = block_idx - x;
156 157
      tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
          get_tx_type_16x16(xd, y + (x >> 2)) : DCT_DCT;
158
      scan = get_scan_16x16(tx_type);
159 160
      above_ec = (A[0] + A[1] + A[2] + A[3]) != 0;
      left_ec = (L[0] + L[1] + L[2] + L[3]) != 0;
161
      default_eob = 256;
Paul Wilkins's avatar
Paul Wilkins committed
162
      band_translate = vp9_coefband_trans_8x8plus;
Daniel Kang's avatar
Daniel Kang committed
163
      break;
164
    }
165
    case TX_32X32:
Paul Wilkins's avatar
Paul Wilkins committed
166
      scan = vp9_default_scan_32x32;
167 168
      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;
169
      default_eob = 1024;
Paul Wilkins's avatar
Paul Wilkins committed
170
      band_translate = vp9_coefband_trans_8x8plus;
171
      break;
Daniel Kang's avatar
Daniel Kang committed
172
  }
John Koleszar's avatar
John Koleszar committed
173

174
  pt = combine_entropy_contexts(above_ec, left_ec);
175 176
  nb = vp9_get_coef_neighbors_handle(scan, &pad);

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

Daniel Kang's avatar
Daniel Kang committed
192
SKIP_START:
193
#endif
Dmitry Kovalev's avatar
Dmitry Kovalev committed
194 195
    if (c >= seg_eob)
      break;
196 197 198
    if (c)
      pt = vp9_get_coef_context(scan, nb, pad, token_cache,
                                c, default_eob);
Paul Wilkins's avatar
Paul Wilkins committed
199
    band = get_coef_band(band_translate, c);
200
    prob = coef_probs[band][pt];
Paul Wilkins's avatar
Paul Wilkins committed
201

202
    if (!vp9_read(r, prob[ZERO_CONTEXT_NODE])) {
203
      INCREMENT_COUNT(ZERO_TOKEN);
John Koleszar's avatar
John Koleszar committed
204
      ++c;
205 206 207 208
#if CONFIG_BALANCED_COEFTREE
      skip_eob_node = 1;
      continue;
#else
John Koleszar's avatar
John Koleszar committed
209
      goto SKIP_START;
210
#endif
John Koleszar's avatar
John Koleszar committed
211
    }
212 213 214 215 216 217 218 219 220
#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
221
    // ONE_CONTEXT_NODE_0_
222
    if (!vp9_read(r, prob[ONE_CONTEXT_NODE])) {
223
      WRITE_COEF_CONTINUE(1, ONE_TOKEN);
John Koleszar's avatar
John Koleszar committed
224
    }
225 226
    // Load full probabilities if not already loaded
    if (!load_map[band][pt]) {
227
      vp9_model_to_full_probs(coef_probs[band][pt],
228 229 230 231
                              coef_probs_full[band][pt]);
      load_map[band][pt] = 1;
    }
    prob = coef_probs_full[band][pt];
John Koleszar's avatar
John Koleszar committed
232
    // LOW_VAL_CONTEXT_NODE_0_
233 234
    if (!vp9_read(r, prob[LOW_VAL_CONTEXT_NODE])) {
      if (!vp9_read(r, prob[TWO_CONTEXT_NODE])) {
235
        WRITE_COEF_CONTINUE(2, TWO_TOKEN);
John Koleszar's avatar
John Koleszar committed
236
      }
237
      if (!vp9_read(r, prob[THREE_CONTEXT_NODE])) {
238
        WRITE_COEF_CONTINUE(3, THREE_TOKEN);
John Koleszar's avatar
John Koleszar committed
239
      }
240
      WRITE_COEF_CONTINUE(4, FOUR_TOKEN);
John Koleszar's avatar
John Koleszar committed
241 242
    }
    // HIGH_LOW_CONTEXT_NODE_0_
243 244
    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
245 246
        val = CAT1_MIN_VAL;
        ADJUST_COEF(CAT1_PROB0, 0);
247
        WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY1);
John Koleszar's avatar
John Koleszar committed
248 249 250 251
      }
      val = CAT2_MIN_VAL;
      ADJUST_COEF(CAT2_PROB1, 1);
      ADJUST_COEF(CAT2_PROB0, 0);
252
      WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY2);
Daniel Kang's avatar
Daniel Kang committed
253
    }
John Koleszar's avatar
John Koleszar committed
254
    // CAT_THREEFOUR_CONTEXT_NODE_0_
255 256
    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
257 258 259 260
        val = CAT3_MIN_VAL;
        ADJUST_COEF(CAT3_PROB2, 2);
        ADJUST_COEF(CAT3_PROB1, 1);
        ADJUST_COEF(CAT3_PROB0, 0);
261
        WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY3);
John Koleszar's avatar
John Koleszar committed
262 263 264 265 266 267
      }
      val = CAT4_MIN_VAL;
      ADJUST_COEF(CAT4_PROB3, 3);
      ADJUST_COEF(CAT4_PROB2, 2);
      ADJUST_COEF(CAT4_PROB1, 1);
      ADJUST_COEF(CAT4_PROB0, 0);
268
      WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY4);
John Koleszar's avatar
John Koleszar committed
269 270
    }
    // CAT_FIVE_CONTEXT_NODE_0_:
271
    if (!vp9_read(r, prob[CAT_FIVE_CONTEXT_NODE])) {
John Koleszar's avatar
John Koleszar committed
272 273 274 275 276 277
      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);
278
      WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY5);
John Koleszar's avatar
John Koleszar committed
279 280 281
    }
    val = 0;
    while (*cat6) {
282
      val = (val << 1) | vp9_read(r, *cat6++);
John Koleszar's avatar
John Koleszar committed
283 284
    }
    val += CAT6_MIN_VAL;
285
    WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY6);
John Koleszar's avatar
John Koleszar committed
286
  }
Jingning Han's avatar
Jingning Han committed
287

288
  if (c < seg_eob)
289
    coef_counts[type][ref][band][pt][DCT_EOB_MODEL_TOKEN]++;
290

291 292
  for (pt = 0; pt < (1 << txfm_size); pt++) {
    A[pt] = L[pt] = c > 0;
293
  }
294

John Koleszar's avatar
John Koleszar committed
295
  return c;
Daniel Kang's avatar
Daniel Kang committed
296
}
John Koleszar's avatar
John Koleszar committed
297

298
static int get_eob(MACROBLOCKD* const xd, int segment_id, int eob_max) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
299
  return vp9_get_segdata(xd, segment_id, SEG_LVL_SKIP) ? 0 : eob_max;
300 301
}

302

John Koleszar's avatar
John Koleszar committed
303 304 305
struct decode_block_args {
  VP9D_COMP *pbi;
  MACROBLOCKD *xd;
306
  vp9_reader *r;
John Koleszar's avatar
John Koleszar committed
307 308 309
  int *eobtotal;
};
static void decode_block(int plane, int block,
310
                         BLOCK_SIZE_TYPE bsize,
John Koleszar's avatar
John Koleszar committed
311 312 313
                         int ss_txfrm_size,
                         void *argv) {
  const struct decode_block_args* const arg = argv;
John Koleszar's avatar
John Koleszar committed
314
  const int bw = b_width_log2(bsize);
315 316

  // find the maximum eob for this transform size, adjusted by segment
John Koleszar's avatar
John Koleszar committed
317 318 319 320
  const int segment_id = arg->xd->mode_info_context->mbmi.segment_id;
  const TX_SIZE ss_tx_size = ss_txfrm_size / 2;
  const int seg_eob = get_eob(arg->xd, segment_id, 16 << ss_txfrm_size);
  int16_t* const qcoeff_base = arg->xd->plane[plane].qcoeff;
321 322 323 324
  const int off = block >> ss_txfrm_size;
  const int mod = bw - ss_tx_size - arg->xd->plane[plane].subsampling_x;
  const int aoff = (off & ((1 << mod) - 1)) << ss_tx_size;
  const int loff = (off >> mod) << ss_tx_size;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
325

John Koleszar's avatar
John Koleszar committed
326
  const int eob = decode_coefs(arg->pbi, arg->xd, arg->r, block,
John Koleszar's avatar
John Koleszar committed
327 328
                               arg->xd->plane[plane].plane_type, seg_eob,
                               BLOCK_OFFSET(qcoeff_base, block, 16),
329 330 331
                               ss_tx_size, arg->xd->plane[plane].dequant,
                               arg->xd->plane[plane].above_context + aoff,
                               arg->xd->plane[plane].left_context + loff);
332

John Koleszar's avatar
John Koleszar committed
333 334
  arg->xd->plane[plane].eobs[block] = eob;
  arg->eobtotal[0] += eob;
335 336
}

337
int vp9_decode_tokens(VP9D_COMP* const pbi,
338
                         MACROBLOCKD* const xd,
339
                         vp9_reader *r,
340
                         BLOCK_SIZE_TYPE bsize) {
John Koleszar's avatar
John Koleszar committed
341
  int eobtotal = 0;
342
  struct decode_block_args args = {pbi, xd, r, &eobtotal};
343
  foreach_transformed_block(xd, bsize, decode_block, &args);
John Koleszar's avatar
John Koleszar committed
344
  return eobtotal;
345
}