vp9_detokenize.c 7.52 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
21
#include "vp9/decoder/vp9_detokenize.h"
#include "vp9/decoder/vp9_onyxd_int.h"

John Koleszar's avatar
John Koleszar committed
22
23
24
#define EOB_CONTEXT_NODE            0
#define ZERO_CONTEXT_NODE           1
#define ONE_CONTEXT_NODE            2
Jim Bankoski's avatar
Jim Bankoski committed
25
26
27
28
29
30
31
32
#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
33

Scott LaVarnway's avatar
Scott LaVarnway committed
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#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

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

63
64
65
66
67
68
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
};

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

75

Dmitry Kovalev's avatar
Dmitry Kovalev committed
76
77
#define WRITE_COEF_CONTINUE(val, token)                  \
  {                                                      \
Jim Bankoski's avatar
Jim Bankoski committed
78
79
    v = (val * dqv) >> dq_shift; \
    dqcoeff_ptr[scan[c]] = (vp9_read_bit(r) ? -v : v); \
Dmitry Kovalev's avatar
Dmitry Kovalev committed
80
    INCREMENT_COUNT(token);                              \
Deb Mukherjee's avatar
Deb Mukherjee committed
81
    token_cache[scan[c]] = vp9_pt_energy_class[token];   \
82
    ++c;                                                 \
Jim Bankoski's avatar
Jim Bankoski committed
83
    pt = get_coef_context(nb, token_cache, 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 max_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 uint8_t *cat6;
111
  const uint8_t *band_translate = get_band_translate(tx_size);
Jim Bankoski's avatar
Jim Bankoski committed
112
  const int dq_shift = (tx_size == TX_32X32);
113
114
115
  const scan_order *so = get_scan(xd, tx_size, type, block_idx);
  const int16_t *scan = so->scan;
  const int16_t *nb = so->neighbors;
Jim Bankoski's avatar
Jim Bankoski committed
116
117
  int v;
  int16_t dqv = dq[0];
118

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

131
    while (!vp9_read(r, prob[ZERO_CONTEXT_NODE])) {
132
      INCREMENT_COUNT(ZERO_TOKEN);
Jim Bankoski's avatar
Jim Bankoski committed
133
      dqv = dq[1];
John Koleszar's avatar
John Koleszar committed
134
      ++c;
135
136
      if (c >= max_eob)
        return c;  // zero tokens at the end (no eob token)
Jim Bankoski's avatar
Jim Bankoski committed
137
138
139
      pt = get_coef_context(nb, token_cache, c);
      band = *band_translate++;
      prob = coef_probs[band][pt];
140
141
    }

John Koleszar's avatar
John Koleszar committed
142
    // ONE_CONTEXT_NODE_0_
143
    if (!vp9_read(r, prob[ONE_CONTEXT_NODE])) {
144
      WRITE_COEF_CONTINUE(1, ONE_TOKEN);
John Koleszar's avatar
John Koleszar committed
145
    }
Jim Bankoski's avatar
Jim Bankoski committed
146

147
    prob = vp9_pareto8_full[prob[PIVOT_NODE] - 1];
Jim Bankoski's avatar
Jim Bankoski committed
148

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

203
    WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY6);
John Koleszar's avatar
John Koleszar committed
204
  }
Jingning Han's avatar
Jingning Han committed
205

John Koleszar's avatar
John Koleszar committed
206
  return c;
Daniel Kang's avatar
Daniel Kang committed
207
}
John Koleszar's avatar
John Koleszar committed
208

209
210
int vp9_decode_block_tokens(VP9_COMMON *cm, MACROBLOCKD *xd,
                            int plane, int block, BLOCK_SIZE plane_bsize,
211
                            int x, int y, TX_SIZE tx_size, vp9_reader *r,
212
                            uint8_t *token_cache) {
213
214
215
  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);
216
217
218
219
  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,
220
                               pd->dequant, pt, token_cache);
221
  set_contexts(xd, pd, plane_bsize, tx_size, eob > 0, x, y);
222
  pd->eobs[block] = eob;
223
  return eob;
224
225
}

226