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

17 18
#include "vp9/decoder/vp9_detokenize.h"

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

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

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

60 61 62
#define INCREMENT_COUNT(token)                              \
  do {                                                      \
     if (!cm->frame_parallel_decoding_mode)                 \
63
       ++coef_counts[band][ctx][token];                     \
64 65
  } while (0)

Dmitry Kovalev's avatar
Dmitry Kovalev committed
66 67
#define WRITE_COEF_CONTINUE(val, token)                  \
  {                                                      \
68 69
    v = (val * dqv) >> dq_shift;                         \
    dqcoeff[scan[c]] = vp9_read_bit(r) ? -v : v;         \
Deb Mukherjee's avatar
Deb Mukherjee committed
70
    token_cache[scan[c]] = vp9_pt_energy_class[token];   \
71
    ++c;                                                 \
72 73
    ctx = get_coef_context(nb, token_cache, c);          \
    dqv = dq[1];                                         \
Dmitry Kovalev's avatar
Dmitry Kovalev committed
74
    continue;                                            \
75
  }
John Koleszar's avatar
John Koleszar committed
76

Yaowu Xu's avatar
Yaowu Xu committed
77 78 79
#define ADJUST_COEF(prob, bits_count)                   \
  do {                                                  \
    val += (vp9_read(r, prob) << bits_count);           \
80
  } while (0)
John Koleszar's avatar
John Koleszar committed
81

82 83 84 85
static int decode_coefs(VP9_COMMON *cm, const MACROBLOCKD *xd, PLANE_TYPE type,
                       int16_t *dqcoeff, TX_SIZE tx_size, const int16_t *dq,
                       int ctx, const int16_t *scan, const int16_t *nb,
                       vp9_reader *r) {
86
  const int max_eob = 16 << (tx_size << 1);
87
  const FRAME_CONTEXT *const fc = &cm->fc;
88
  FRAME_COUNTS *const counts = &cm->counts;
89
  const int ref = is_inter_block(&xd->mi_8x8[0]->mbmi);
90
  int band, c = 0;
91
  const vp9_prob (*coef_probs)[COEFF_CONTEXTS][UNCONSTRAINED_NODES] =
92
      fc->coef_probs[tx_size][type][ref];
93
  const vp9_prob *prob;
94
  unsigned int (*coef_counts)[COEFF_CONTEXTS][UNCONSTRAINED_NODES + 1] =
95
      counts->coef[tx_size][type][ref];
96
  unsigned int (*eob_branch_count)[COEFF_CONTEXTS] =
97
      counts->eob_branch[tx_size][type][ref];
98
  uint8_t token_cache[32 * 32];
99
  const uint8_t *cat6;
100
  const uint8_t *band_translate = get_band_translate(tx_size);
Jim Bankoski's avatar
Jim Bankoski committed
101 102 103
  const int dq_shift = (tx_size == TX_32X32);
  int v;
  int16_t dqv = dq[0];
104

105
  while (c < max_eob) {
John Koleszar's avatar
John Koleszar committed
106
    int val;
107
    band = *band_translate++;
108
    prob = coef_probs[band][ctx];
109
    if (!cm->frame_parallel_decoding_mode)
110
      ++eob_branch_count[band][ctx];
111
    if (!vp9_read(r, prob[EOB_CONTEXT_NODE])) {
112
      INCREMENT_COUNT(EOB_MODEL_TOKEN);
113
      break;
114
    }
Paul Wilkins's avatar
Paul Wilkins committed
115

116
    while (!vp9_read(r, prob[ZERO_CONTEXT_NODE])) {
117
      INCREMENT_COUNT(ZERO_TOKEN);
Jim Bankoski's avatar
Jim Bankoski committed
118
      dqv = dq[1];
119
      token_cache[scan[c]] = 0;
John Koleszar's avatar
John Koleszar committed
120
      ++c;
121 122
      if (c >= max_eob)
        return c;  // zero tokens at the end (no eob token)
123
      ctx = get_coef_context(nb, token_cache, c);
Jim Bankoski's avatar
Jim Bankoski committed
124
      band = *band_translate++;
125
      prob = coef_probs[band][ctx];
126 127
    }

John Koleszar's avatar
John Koleszar committed
128
    // ONE_CONTEXT_NODE_0_
129
    if (!vp9_read(r, prob[ONE_CONTEXT_NODE])) {
130
      INCREMENT_COUNT(ONE_TOKEN);
131
      WRITE_COEF_CONTINUE(1, ONE_TOKEN);
John Koleszar's avatar
John Koleszar committed
132
    }
Jim Bankoski's avatar
Jim Bankoski committed
133

134 135
    INCREMENT_COUNT(TWO_TOKEN);

136
    prob = vp9_pareto8_full[prob[PIVOT_NODE] - 1];
Jim Bankoski's avatar
Jim Bankoski committed
137

138 139
    if (!vp9_read(r, prob[LOW_VAL_CONTEXT_NODE])) {
      if (!vp9_read(r, prob[TWO_CONTEXT_NODE])) {
140
        WRITE_COEF_CONTINUE(2, TWO_TOKEN);
John Koleszar's avatar
John Koleszar committed
141
      }
142
      if (!vp9_read(r, prob[THREE_CONTEXT_NODE])) {
143
        WRITE_COEF_CONTINUE(3, THREE_TOKEN);
John Koleszar's avatar
John Koleszar committed
144
      }
145
      WRITE_COEF_CONTINUE(4, FOUR_TOKEN);
John Koleszar's avatar
John Koleszar committed
146
    }
147

148 149
    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
150 151
        val = CAT1_MIN_VAL;
        ADJUST_COEF(CAT1_PROB0, 0);
152
        WRITE_COEF_CONTINUE(val, CATEGORY1_TOKEN);
John Koleszar's avatar
John Koleszar committed
153 154 155 156
      }
      val = CAT2_MIN_VAL;
      ADJUST_COEF(CAT2_PROB1, 1);
      ADJUST_COEF(CAT2_PROB0, 0);
157
      WRITE_COEF_CONTINUE(val, CATEGORY2_TOKEN);
Daniel Kang's avatar
Daniel Kang committed
158
    }
159

160 161
    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
162 163 164 165
        val = CAT3_MIN_VAL;
        ADJUST_COEF(CAT3_PROB2, 2);
        ADJUST_COEF(CAT3_PROB1, 1);
        ADJUST_COEF(CAT3_PROB0, 0);
166
        WRITE_COEF_CONTINUE(val, CATEGORY3_TOKEN);
John Koleszar's avatar
John Koleszar committed
167 168 169 170 171 172
      }
      val = CAT4_MIN_VAL;
      ADJUST_COEF(CAT4_PROB3, 3);
      ADJUST_COEF(CAT4_PROB2, 2);
      ADJUST_COEF(CAT4_PROB1, 1);
      ADJUST_COEF(CAT4_PROB0, 0);
173
      WRITE_COEF_CONTINUE(val, CATEGORY4_TOKEN);
John Koleszar's avatar
John Koleszar committed
174
    }
175

176
    if (!vp9_read(r, prob[CAT_FIVE_CONTEXT_NODE])) {
John Koleszar's avatar
John Koleszar committed
177 178 179 180 181 182
      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);
183
      WRITE_COEF_CONTINUE(val, CATEGORY5_TOKEN);
John Koleszar's avatar
John Koleszar committed
184 185
    }
    val = 0;
186
    cat6 = cat6_prob;
187
    while (*cat6)
188
      val = (val << 1) | vp9_read(r, *cat6++);
John Koleszar's avatar
John Koleszar committed
189
    val += CAT6_MIN_VAL;
190

191
    WRITE_COEF_CONTINUE(val, CATEGORY6_TOKEN);
John Koleszar's avatar
John Koleszar committed
192
  }
Jingning Han's avatar
Jingning Han committed
193

John Koleszar's avatar
John Koleszar committed
194
  return c;
Daniel Kang's avatar
Daniel Kang committed
195
}
John Koleszar's avatar
John Koleszar committed
196

197 198
int vp9_decode_block_tokens(VP9_COMMON *cm, MACROBLOCKD *xd,
                            int plane, int block, BLOCK_SIZE plane_bsize,
199
                            int x, int y, TX_SIZE tx_size, vp9_reader *r) {
200
  struct macroblockd_plane *const pd = &xd->plane[plane];
201 202
  const int ctx = get_entropy_context(tx_size, pd->above_context + x,
                                               pd->left_context + y);
203 204
  const scan_order *so = get_scan(xd, tx_size, pd->plane_type, block);
  const int eob = decode_coefs(cm, xd, pd->plane_type,
205
                               BLOCK_OFFSET(pd->dqcoeff, block), tx_size,
206
                               pd->dequant, ctx, so->scan, so->neighbors, r);
207
  vp9_set_contexts(xd, pd, plane_bsize, tx_size, eob > 0, x, y);
208
  return eob;
209 210
}

211