quantize.c 11.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
/*
 *  Copyright (c) 2015 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

Johann's avatar
Johann committed
11 12
#include <assert.h>

13
#include "./vpx_dsp_rtcd.h"
14 15 16
#include "vpx_dsp/quantize.h"
#include "vpx_mem/vpx_mem.h"

clang-format's avatar
clang-format committed
17
void vpx_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs, int skip_block,
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
                     const int16_t *round_ptr, const int16_t quant,
                     tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
                     const int16_t dequant_ptr, uint16_t *eob_ptr) {
  const int rc = 0;
  const int coeff = coeff_ptr[rc];
  const int coeff_sign = (coeff >> 31);
  const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
  int tmp, eob = -1;

  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));

  if (!skip_block) {
    tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
    tmp = (tmp * quant) >> 16;
clang-format's avatar
clang-format committed
33
    qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
34
    dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr;
clang-format's avatar
clang-format committed
35
    if (tmp) eob = 0;
36 37 38 39 40
  }
  *eob_ptr = eob + 1;
}

#if CONFIG_VP9_HIGHBITDEPTH
clang-format's avatar
clang-format committed
41 42 43 44 45
void vpx_highbd_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs,
                            int skip_block, const int16_t *round_ptr,
                            const int16_t quant, tran_low_t *qcoeff_ptr,
                            tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr,
                            uint16_t *eob_ptr) {
46 47 48 49 50 51 52 53 54 55
  int eob = -1;

  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));

  if (!skip_block) {
    const int coeff = coeff_ptr[0];
    const int coeff_sign = (coeff >> 31);
    const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
    const int64_t tmp = abs_coeff + round_ptr[0];
56
    const int abs_qcoeff = (int)((tmp * quant) >> 16);
57 58
    qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
    dqcoeff_ptr[0] = qcoeff_ptr[0] * dequant_ptr;
clang-format's avatar
clang-format committed
59
    if (abs_qcoeff) eob = 0;
60 61 62 63 64
  }
  *eob_ptr = eob + 1;
}
#endif

65
void vpx_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
                           const int16_t *round_ptr, const int16_t quant,
                           tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
                           const int16_t dequant_ptr, uint16_t *eob_ptr) {
  const int n_coeffs = 1024;
  const int rc = 0;
  const int coeff = coeff_ptr[rc];
  const int coeff_sign = (coeff >> 31);
  const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
  int tmp, eob = -1;

  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));

  if (!skip_block) {
    tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1),
                INT16_MIN, INT16_MAX);
    tmp = (tmp * quant) >> 15;
clang-format's avatar
clang-format committed
83
    qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
84
    dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr / 2;
clang-format's avatar
clang-format committed
85
    if (tmp) eob = 0;
86 87 88 89 90
  }
  *eob_ptr = eob + 1;
}

#if CONFIG_VP9_HIGHBITDEPTH
clang-format's avatar
clang-format committed
91 92
void vpx_highbd_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
                                  const int16_t *round_ptr, const int16_t quant,
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
                                  tran_low_t *qcoeff_ptr,
                                  tran_low_t *dqcoeff_ptr,
                                  const int16_t dequant_ptr,
                                  uint16_t *eob_ptr) {
  const int n_coeffs = 1024;
  int eob = -1;

  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));

  if (!skip_block) {
    const int coeff = coeff_ptr[0];
    const int coeff_sign = (coeff >> 31);
    const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
    const int64_t tmp = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[0], 1);
108
    const int abs_qcoeff = (int)((tmp * quant) >> 15);
109 110
    qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
    dqcoeff_ptr[0] = qcoeff_ptr[0] * dequant_ptr / 2;
clang-format's avatar
clang-format committed
111
    if (abs_qcoeff) eob = 0;
112 113 114 115 116
  }
  *eob_ptr = eob + 1;
}
#endif

117
void vpx_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
clang-format's avatar
clang-format committed
118 119 120 121 122 123
                      int skip_block, const int16_t *zbin_ptr,
                      const int16_t *round_ptr, const int16_t *quant_ptr,
                      const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
                      tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr,
                      uint16_t *eob_ptr, const int16_t *scan,
                      const int16_t *iscan) {
124
  int i, non_zero_count = (int)n_coeffs, eob = -1;
clang-format's avatar
clang-format committed
125 126
  const int zbins[2] = { zbin_ptr[0], zbin_ptr[1] };
  const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
127
  (void)iscan;
Johann's avatar
Johann committed
128 129
  (void)skip_block;
  assert(!skip_block);
130 131 132 133

  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));

Johann's avatar
Johann committed
134 135 136 137 138 139 140 141 142 143
  // Pre-scan pass
  for (i = (int)n_coeffs - 1; i >= 0; i--) {
    const int rc = scan[i];
    const int coeff = coeff_ptr[rc];

    if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0])
      non_zero_count--;
    else
      break;
  }
144

Johann's avatar
Johann committed
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
  // Quantization pass: All coefficients with index >= zero_flag are
  // skippable. Note: zero_flag can be zero.
  for (i = 0; i < non_zero_count; i++) {
    const int rc = scan[i];
    const int coeff = coeff_ptr[rc];
    const int coeff_sign = (coeff >> 31);
    const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;

    if (abs_coeff >= zbins[rc != 0]) {
      int tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
      tmp = ((((tmp * quant_ptr[rc != 0]) >> 16) + tmp) *
             quant_shift_ptr[rc != 0]) >>
            16;  // quantization
      qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
      dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];

      if (tmp) eob = i;
162 163 164 165 166 167
    }
  }
  *eob_ptr = eob + 1;
}

#if CONFIG_VP9_HIGHBITDEPTH
168
void vpx_highbd_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
169 170 171 172
                             int skip_block, const int16_t *zbin_ptr,
                             const int16_t *round_ptr, const int16_t *quant_ptr,
                             const int16_t *quant_shift_ptr,
                             tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
clang-format's avatar
clang-format committed
173 174
                             const int16_t *dequant_ptr, uint16_t *eob_ptr,
                             const int16_t *scan, const int16_t *iscan) {
175
  int i, non_zero_count = (int)n_coeffs, eob = -1;
clang-format's avatar
clang-format committed
176 177
  const int zbins[2] = { zbin_ptr[0], zbin_ptr[1] };
  const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
178
  (void)iscan;
Johann's avatar
Johann committed
179 180
  (void)skip_block;
  assert(!skip_block);
181 182 183 184

  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));

Johann's avatar
Johann committed
185 186 187 188 189 190 191 192 193 194
  // Pre-scan pass
  for (i = (int)n_coeffs - 1; i >= 0; i--) {
    const int rc = scan[i];
    const int coeff = coeff_ptr[rc];

    if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0])
      non_zero_count--;
    else
      break;
  }
195

Johann's avatar
Johann committed
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
  // Quantization pass: All coefficients with index >= zero_flag are
  // skippable. Note: zero_flag can be zero.
  for (i = 0; i < non_zero_count; i++) {
    const int rc = scan[i];
    const int coeff = coeff_ptr[rc];
    const int coeff_sign = (coeff >> 31);
    const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;

    if (abs_coeff >= zbins[rc != 0]) {
      const int64_t tmp1 = abs_coeff + round_ptr[rc != 0];
      const int64_t tmp2 = ((tmp1 * quant_ptr[rc != 0]) >> 16) + tmp1;
      const int abs_qcoeff = (int)((tmp2 * quant_shift_ptr[rc != 0]) >> 16);
      qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
      dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
      if (abs_qcoeff) eob = i;
211 212 213 214 215 216
    }
  }
  *eob_ptr = eob + 1;
}
#endif

217
void vpx_quantize_b_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
clang-format's avatar
clang-format committed
218 219
                            int skip_block, const int16_t *zbin_ptr,
                            const int16_t *round_ptr, const int16_t *quant_ptr,
220 221
                            const int16_t *quant_shift_ptr,
                            tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
clang-format's avatar
clang-format committed
222
                            const int16_t *dequant_ptr, uint16_t *eob_ptr,
223
                            const int16_t *scan, const int16_t *iscan) {
clang-format's avatar
clang-format committed
224 225 226
  const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], 1),
                         ROUND_POWER_OF_TWO(zbin_ptr[1], 1) };
  const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
227 228 229 230 231

  int idx = 0;
  int idx_arr[1024];
  int i, eob = -1;
  (void)iscan;
Johann's avatar
Johann committed
232 233
  (void)skip_block;
  assert(!skip_block);
234 235 236 237

  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));

Johann's avatar
Johann committed
238 239 240 241
  // Pre-scan pass
  for (i = 0; i < n_coeffs; i++) {
    const int rc = scan[i];
    const int coeff = coeff_ptr[rc];
242

Johann's avatar
Johann committed
243 244 245 246
    // If the coefficient is out of the base ZBIN range, keep it for
    // quantization.
    if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0]) idx_arr[idx++] = i;
  }
247

Johann's avatar
Johann committed
248 249 250 251 252 253 254 255 256 257 258 259 260
  // Quantization pass: only process the coefficients selected in
  // pre-scan pass. Note: idx can be zero.
  for (i = 0; i < idx; i++) {
    const int rc = scan[idx_arr[i]];
    const int coeff = coeff_ptr[rc];
    const int coeff_sign = (coeff >> 31);
    int tmp;
    int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
    abs_coeff += ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
    abs_coeff = clamp(abs_coeff, INT16_MIN, INT16_MAX);
    tmp = ((((abs_coeff * quant_ptr[rc != 0]) >> 16) + abs_coeff) *
           quant_shift_ptr[rc != 0]) >>
          15;
261

Johann's avatar
Johann committed
262 263 264 265
    qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
    dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;

    if (tmp) eob = idx_arr[i];
266 267 268 269 270
  }
  *eob_ptr = eob + 1;
}

#if CONFIG_VP9_HIGHBITDEPTH
clang-format's avatar
clang-format committed
271 272 273 274 275 276 277 278 279
void vpx_highbd_quantize_b_32x32_c(
    const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block,
    const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr,
    const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
    tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
    const int16_t *scan, const int16_t *iscan) {
  const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], 1),
                         ROUND_POWER_OF_TWO(zbin_ptr[1], 1) };
  const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
280 281 282 283 284

  int idx = 0;
  int idx_arr[1024];
  int i, eob = -1;
  (void)iscan;
Johann's avatar
Johann committed
285 286
  (void)skip_block;
  assert(!skip_block);
287 288 289 290

  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));

Johann's avatar
Johann committed
291 292 293 294
  // Pre-scan pass
  for (i = 0; i < n_coeffs; i++) {
    const int rc = scan[i];
    const int coeff = coeff_ptr[rc];
295

Johann's avatar
Johann committed
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
    // If the coefficient is out of the base ZBIN range, keep it for
    // quantization.
    if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0]) idx_arr[idx++] = i;
  }

  // Quantization pass: only process the coefficients selected in
  // pre-scan pass. Note: idx can be zero.
  for (i = 0; i < idx; i++) {
    const int rc = scan[idx_arr[i]];
    const int coeff = coeff_ptr[rc];
    const int coeff_sign = (coeff >> 31);
    const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
    const int64_t tmp1 = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
    const int64_t tmp2 = ((tmp1 * quant_ptr[rc != 0]) >> 16) + tmp1;
    const int abs_qcoeff = (int)((tmp2 * quant_shift_ptr[rc != 0]) >> 15);
    qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
    dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
    if (abs_qcoeff) eob = idx_arr[i];
314 315 316 317
  }
  *eob_ptr = eob + 1;
}
#endif