vp9_detokenize.c 7.67 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
#define EOB_CONTEXT_NODE            0
#define ZERO_CONTEXT_NODE           1
#define ONE_CONTEXT_NODE            2
Jim Bankoski's avatar
Jim Bankoski committed
26
27
28
29
30
31
32
33
#define LOW_VAL_CONTEXT_NODE        0
#define TWO_CONTEXT_NODE            1
#define THREE_CONTEXT_NODE          2
#define HIGH_LOW_CONTEXT_NODE       3
#define CAT_ONE_CONTEXT_NODE        4
#define CAT_THREEFOUR_CONTEXT_NODE  5
#define CAT_THREE_CONTEXT_NODE      6
#define CAT_FIVE_CONTEXT_NODE       7
John Koleszar's avatar
John Koleszar committed
34

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
66
67
68
69
static const int token_to_counttoken[MAX_ENTROPY_TOKENS] = {
  ZERO_TOKEN, ONE_TOKEN, TWO_TOKEN, TWO_TOKEN,
  TWO_TOKEN, TWO_TOKEN, TWO_TOKEN, TWO_TOKEN,
  TWO_TOKEN, TWO_TOKEN, TWO_TOKEN, DCT_EOB_MODEL_TOKEN
};

70
71
72
#define INCREMENT_COUNT(token)                              \
  do {                                                      \
     if (!cm->frame_parallel_decoding_mode)                 \
73
       ++coef_counts[band][pt][token_to_counttoken[token]]; \
74
75
  } while (0)

76

Dmitry Kovalev's avatar
Dmitry Kovalev committed
77
78
#define WRITE_COEF_CONTINUE(val, token)                  \
  {                                                      \
Jim Bankoski's avatar
Jim Bankoski committed
79
80
    v = (val * dqv) >> dq_shift; \
    dqcoeff_ptr[scan[c]] = (vp9_read_bit(r) ? -v : v); \
Dmitry Kovalev's avatar
Dmitry Kovalev committed
81
    INCREMENT_COUNT(token);                              \
Deb Mukherjee's avatar
Deb Mukherjee committed
82
    token_cache[scan[c]] = vp9_pt_energy_class[token];   \
83
    ++c;                                                 \
Jim Bankoski's avatar
Jim Bankoski committed
84
    dqv = dq[1];                                          \
Dmitry Kovalev's avatar
Dmitry Kovalev committed
85
    continue;                                            \
86
  }
John Koleszar's avatar
John Koleszar committed
87

Jim Bankoski's avatar
Jim Bankoski committed
88

Yaowu Xu's avatar
Yaowu Xu committed
89
90
91
#define ADJUST_COEF(prob, bits_count)                   \
  do {                                                  \
    val += (vp9_read(r, prob) << bits_count);           \
92
  } while (0)
John Koleszar's avatar
John Koleszar committed
93

94
static int decode_coefs(VP9_COMMON *cm, const MACROBLOCKD *xd,
95
                        vp9_reader *r, int block_idx,
96
                        PLANE_TYPE type, int seg_eob, int16_t *dqcoeff_ptr,
Deb Mukherjee's avatar
Deb Mukherjee committed
97
                        TX_SIZE tx_size, const int16_t *dq, int pt,
98
                        uint8_t *token_cache) {
99
  const FRAME_CONTEXT *const fc = &cm->fc;
100
  FRAME_COUNTS *const counts = &cm->counts;
101
  const int ref = is_inter_block(&xd->mi_8x8[0]->mbmi);
102
  int band, c = 0;
103
  const vp9_prob (*coef_probs)[PREV_COEF_CONTEXTS][UNCONSTRAINED_NODES] =
104
      fc->coef_probs[tx_size][type][ref];
105
  const vp9_prob *prob;
106
107
108
109
  unsigned int (*coef_counts)[PREV_COEF_CONTEXTS][UNCONSTRAINED_NODES + 1] =
      counts->coef[tx_size][type][ref];
  unsigned int (*eob_branch_count)[PREV_COEF_CONTEXTS] =
      counts->eob_branch[tx_size][type][ref];
110
  const int16_t *scan, *nb;
111
  const uint8_t *cat6;
112
  const uint8_t *band_translate = get_band_translate(tx_size);
Jim Bankoski's avatar
Jim Bankoski committed
113
114
115
  const int dq_shift = (tx_size == TX_32X32);
  int v;
  int16_t dqv = dq[0];
116

117
118
  get_scan(xd, tx_size, type, block_idx, &scan, &nb);

119
  while (c < seg_eob) {
John Koleszar's avatar
John Koleszar committed
120
    int val;
121
    if (c)
122
      pt = get_coef_context(nb, token_cache, c);
123
    band = *band_translate++;
124
    prob = coef_probs[band][pt];
125
    if (!cm->frame_parallel_decoding_mode)
126
      ++eob_branch_count[band][pt];
127
128
    if (!vp9_read(r, prob[EOB_CONTEXT_NODE]))
      break;
129
    goto DECODE_ZERO;
130

131
  SKIP_START:
Dmitry Kovalev's avatar
Dmitry Kovalev committed
132
133
    if (c >= seg_eob)
      break;
134
    if (c)
135
      pt = get_coef_context(nb, token_cache, c);
136
    band = *band_translate++;
137
    prob = coef_probs[band][pt];
Paul Wilkins's avatar
Paul Wilkins committed
138

139
  DECODE_ZERO:
140
    if (!vp9_read(r, prob[ZERO_CONTEXT_NODE])) {
141
      INCREMENT_COUNT(ZERO_TOKEN);
Deb Mukherjee's avatar
Deb Mukherjee committed
142
      token_cache[scan[c]] = vp9_pt_energy_class[ZERO_TOKEN];
Jim Bankoski's avatar
Jim Bankoski committed
143
      dqv = dq[1];                                          \
John Koleszar's avatar
John Koleszar committed
144
145
      ++c;
      goto SKIP_START;
146
147
    }

John Koleszar's avatar
John Koleszar committed
148
    // ONE_CONTEXT_NODE_0_
149
    if (!vp9_read(r, prob[ONE_CONTEXT_NODE])) {
150
      WRITE_COEF_CONTINUE(1, ONE_TOKEN);
John Koleszar's avatar
John Koleszar committed
151
    }
Jim Bankoski's avatar
Jim Bankoski committed
152
153
154

    prob = vp9_pareto8_full[coef_probs[band][pt][PIVOT_NODE]-1];

John Koleszar's avatar
John Koleszar committed
155
    // LOW_VAL_CONTEXT_NODE_0_
156
157
    if (!vp9_read(r, prob[LOW_VAL_CONTEXT_NODE])) {
      if (!vp9_read(r, prob[TWO_CONTEXT_NODE])) {
158
        WRITE_COEF_CONTINUE(2, TWO_TOKEN);
John Koleszar's avatar
John Koleszar committed
159
      }
160
      if (!vp9_read(r, prob[THREE_CONTEXT_NODE])) {
161
        WRITE_COEF_CONTINUE(3, THREE_TOKEN);
John Koleszar's avatar
John Koleszar committed
162
      }
163
      WRITE_COEF_CONTINUE(4, FOUR_TOKEN);
John Koleszar's avatar
John Koleszar committed
164
165
    }
    // HIGH_LOW_CONTEXT_NODE_0_
166
167
    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
168
169
        val = CAT1_MIN_VAL;
        ADJUST_COEF(CAT1_PROB0, 0);
170
        WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY1);
John Koleszar's avatar
John Koleszar committed
171
172
173
174
      }
      val = CAT2_MIN_VAL;
      ADJUST_COEF(CAT2_PROB1, 1);
      ADJUST_COEF(CAT2_PROB0, 0);
175
      WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY2);
Daniel Kang's avatar
Daniel Kang committed
176
    }
John Koleszar's avatar
John Koleszar committed
177
    // CAT_THREEFOUR_CONTEXT_NODE_0_
178
179
    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
180
181
182
183
        val = CAT3_MIN_VAL;
        ADJUST_COEF(CAT3_PROB2, 2);
        ADJUST_COEF(CAT3_PROB1, 1);
        ADJUST_COEF(CAT3_PROB0, 0);
184
        WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY3);
John Koleszar's avatar
John Koleszar committed
185
186
187
188
189
190
      }
      val = CAT4_MIN_VAL;
      ADJUST_COEF(CAT4_PROB3, 3);
      ADJUST_COEF(CAT4_PROB2, 2);
      ADJUST_COEF(CAT4_PROB1, 1);
      ADJUST_COEF(CAT4_PROB0, 0);
191
      WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY4);
John Koleszar's avatar
John Koleszar committed
192
193
    }
    // CAT_FIVE_CONTEXT_NODE_0_:
194
    if (!vp9_read(r, prob[CAT_FIVE_CONTEXT_NODE])) {
John Koleszar's avatar
John Koleszar committed
195
196
197
198
199
200
      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);
201
      WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY5);
John Koleszar's avatar
John Koleszar committed
202
203
    }
    val = 0;
204
    cat6 = cat6_prob;
205
    while (*cat6)
206
      val = (val << 1) | vp9_read(r, *cat6++);
John Koleszar's avatar
John Koleszar committed
207
    val += CAT6_MIN_VAL;
208

209
    WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY6);
John Koleszar's avatar
John Koleszar committed
210
  }
Jingning Han's avatar
Jingning Han committed
211

212
213
  if (c < seg_eob) {
    if (!cm->frame_parallel_decoding_mode)
214
      ++coef_counts[band][pt][DCT_EOB_MODEL_TOKEN];
215
  }
216

John Koleszar's avatar
John Koleszar committed
217
  return c;
Daniel Kang's avatar
Daniel Kang committed
218
}
John Koleszar's avatar
John Koleszar committed
219

220
221
int vp9_decode_block_tokens(VP9_COMMON *cm, MACROBLOCKD *xd,
                            int plane, int block, BLOCK_SIZE plane_bsize,
222
                            int x, int y, TX_SIZE tx_size, vp9_reader *r,
223
                            uint8_t *token_cache) {
224
225
226
  struct macroblockd_plane *const pd = &xd->plane[plane];
  const int seg_eob = get_tx_eob(&cm->seg, xd->mi_8x8[0]->mbmi.segment_id,
                                 tx_size);
227
228
229
230
  const int pt = get_entropy_context(tx_size, pd->above_context + x,
                                              pd->left_context + y);
  const int eob = decode_coefs(cm, xd, r, block, pd->plane_type, seg_eob,
                               BLOCK_OFFSET(pd->dqcoeff, block), tx_size,
231
                               pd->dequant, pt, token_cache);
232
  set_contexts(xd, pd, plane_bsize, tx_size, eob > 0, x, y);
233
  pd->eobs[block] = eob;
234
  return eob;
235
236
}

237