quantize.c revision 7ce0a1d1337c01056ba24006efab21f00e179e04
1/* 2 * Copyright (c) 2015 The WebM project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * 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. 9 */ 10 11#include "vpx_dsp/quantize.h" 12#include "vpx_mem/vpx_mem.h" 13 14void vpx_quantize_dc(const tran_low_t *coeff_ptr, 15 int n_coeffs, int skip_block, 16 const int16_t *round_ptr, const int16_t quant, 17 tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, 18 const int16_t dequant_ptr, uint16_t *eob_ptr) { 19 const int rc = 0; 20 const int coeff = coeff_ptr[rc]; 21 const int coeff_sign = (coeff >> 31); 22 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; 23 int tmp, eob = -1; 24 25 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); 26 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); 27 28 if (!skip_block) { 29 tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX); 30 tmp = (tmp * quant) >> 16; 31 qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign; 32 dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr; 33 if (tmp) 34 eob = 0; 35 } 36 *eob_ptr = eob + 1; 37} 38 39#if CONFIG_VP9_HIGHBITDEPTH 40void vpx_highbd_quantize_dc(const tran_low_t *coeff_ptr, 41 int n_coeffs, int skip_block, 42 const int16_t *round_ptr, const int16_t quant, 43 tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, 44 const int16_t dequant_ptr, uint16_t *eob_ptr) { 45 int eob = -1; 46 47 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); 48 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); 49 50 if (!skip_block) { 51 const int coeff = coeff_ptr[0]; 52 const int coeff_sign = (coeff >> 31); 53 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; 54 const int64_t tmp = abs_coeff + round_ptr[0]; 55 const uint32_t abs_qcoeff = (uint32_t)((tmp * quant) >> 16); 56 qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign); 57 dqcoeff_ptr[0] = qcoeff_ptr[0] * dequant_ptr; 58 if (abs_qcoeff) 59 eob = 0; 60 } 61 *eob_ptr = eob + 1; 62} 63#endif 64 65void vpx_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block, 66 const int16_t *round_ptr, const int16_t quant, 67 tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, 68 const int16_t dequant_ptr, uint16_t *eob_ptr) { 69 const int n_coeffs = 1024; 70 const int rc = 0; 71 const int coeff = coeff_ptr[rc]; 72 const int coeff_sign = (coeff >> 31); 73 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; 74 int tmp, eob = -1; 75 76 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); 77 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); 78 79 if (!skip_block) { 80 tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1), 81 INT16_MIN, INT16_MAX); 82 tmp = (tmp * quant) >> 15; 83 qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign; 84 dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr / 2; 85 if (tmp) 86 eob = 0; 87 } 88 *eob_ptr = eob + 1; 89} 90 91#if CONFIG_VP9_HIGHBITDEPTH 92void vpx_highbd_quantize_dc_32x32(const tran_low_t *coeff_ptr, 93 int skip_block, 94 const int16_t *round_ptr, 95 const int16_t quant, 96 tran_low_t *qcoeff_ptr, 97 tran_low_t *dqcoeff_ptr, 98 const int16_t dequant_ptr, 99 uint16_t *eob_ptr) { 100 const int n_coeffs = 1024; 101 int eob = -1; 102 103 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); 104 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); 105 106 if (!skip_block) { 107 const int coeff = coeff_ptr[0]; 108 const int coeff_sign = (coeff >> 31); 109 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; 110 const int64_t tmp = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[0], 1); 111 const uint32_t abs_qcoeff = (uint32_t)((tmp * quant) >> 15); 112 qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign); 113 dqcoeff_ptr[0] = qcoeff_ptr[0] * dequant_ptr / 2; 114 if (abs_qcoeff) 115 eob = 0; 116 } 117 *eob_ptr = eob + 1; 118} 119#endif 120 121void vpx_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, 122 int skip_block, 123 const int16_t *zbin_ptr, const int16_t *round_ptr, 124 const int16_t *quant_ptr, const int16_t *quant_shift_ptr, 125 tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, 126 const int16_t *dequant_ptr, 127 uint16_t *eob_ptr, 128 const int16_t *scan, const int16_t *iscan) { 129 int i, non_zero_count = (int)n_coeffs, eob = -1; 130 const int zbins[2] = {zbin_ptr[0], zbin_ptr[1]}; 131 const int nzbins[2] = {zbins[0] * -1, zbins[1] * -1}; 132 (void)iscan; 133 134 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); 135 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); 136 137 if (!skip_block) { 138 // Pre-scan pass 139 for (i = (int)n_coeffs - 1; i >= 0; i--) { 140 const int rc = scan[i]; 141 const int coeff = coeff_ptr[rc]; 142 143 if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0]) 144 non_zero_count--; 145 else 146 break; 147 } 148 149 // Quantization pass: All coefficients with index >= zero_flag are 150 // skippable. Note: zero_flag can be zero. 151 for (i = 0; i < non_zero_count; i++) { 152 const int rc = scan[i]; 153 const int coeff = coeff_ptr[rc]; 154 const int coeff_sign = (coeff >> 31); 155 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; 156 157 if (abs_coeff >= zbins[rc != 0]) { 158 int tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX); 159 tmp = ((((tmp * quant_ptr[rc != 0]) >> 16) + tmp) * 160 quant_shift_ptr[rc != 0]) >> 16; // quantization 161 qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign; 162 dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0]; 163 164 if (tmp) 165 eob = i; 166 } 167 } 168 } 169 *eob_ptr = eob + 1; 170} 171 172#if CONFIG_VP9_HIGHBITDEPTH 173void vpx_highbd_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, 174 int skip_block, const int16_t *zbin_ptr, 175 const int16_t *round_ptr, const int16_t *quant_ptr, 176 const int16_t *quant_shift_ptr, 177 tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, 178 const int16_t *dequant_ptr, 179 uint16_t *eob_ptr, const int16_t *scan, 180 const int16_t *iscan) { 181 int i, non_zero_count = (int)n_coeffs, eob = -1; 182 const int zbins[2] = {zbin_ptr[0], zbin_ptr[1]}; 183 const int nzbins[2] = {zbins[0] * -1, zbins[1] * -1}; 184 (void)iscan; 185 186 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); 187 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); 188 189 if (!skip_block) { 190 // Pre-scan pass 191 for (i = (int)n_coeffs - 1; i >= 0; i--) { 192 const int rc = scan[i]; 193 const int coeff = coeff_ptr[rc]; 194 195 if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0]) 196 non_zero_count--; 197 else 198 break; 199 } 200 201 // Quantization pass: All coefficients with index >= zero_flag are 202 // skippable. Note: zero_flag can be zero. 203 for (i = 0; i < non_zero_count; i++) { 204 const int rc = scan[i]; 205 const int coeff = coeff_ptr[rc]; 206 const int coeff_sign = (coeff >> 31); 207 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; 208 209 if (abs_coeff >= zbins[rc != 0]) { 210 const int64_t tmp1 = abs_coeff + round_ptr[rc != 0]; 211 const int64_t tmp2 = ((tmp1 * quant_ptr[rc != 0]) >> 16) + tmp1; 212 const uint32_t abs_qcoeff = 213 (uint32_t)((tmp2 * quant_shift_ptr[rc != 0]) >> 16); 214 qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign); 215 dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0]; 216 if (abs_qcoeff) 217 eob = i; 218 } 219 } 220 } 221 *eob_ptr = eob + 1; 222} 223#endif 224 225void vpx_quantize_b_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, 226 int skip_block, 227 const int16_t *zbin_ptr, const int16_t *round_ptr, 228 const int16_t *quant_ptr, 229 const int16_t *quant_shift_ptr, 230 tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, 231 const int16_t *dequant_ptr, 232 uint16_t *eob_ptr, 233 const int16_t *scan, const int16_t *iscan) { 234 const int zbins[2] = {ROUND_POWER_OF_TWO(zbin_ptr[0], 1), 235 ROUND_POWER_OF_TWO(zbin_ptr[1], 1)}; 236 const int nzbins[2] = {zbins[0] * -1, zbins[1] * -1}; 237 238 int idx = 0; 239 int idx_arr[1024]; 240 int i, eob = -1; 241 (void)iscan; 242 243 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); 244 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); 245 246 if (!skip_block) { 247 // Pre-scan pass 248 for (i = 0; i < n_coeffs; i++) { 249 const int rc = scan[i]; 250 const int coeff = coeff_ptr[rc]; 251 252 // If the coefficient is out of the base ZBIN range, keep it for 253 // quantization. 254 if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0]) 255 idx_arr[idx++] = i; 256 } 257 258 // Quantization pass: only process the coefficients selected in 259 // pre-scan pass. Note: idx can be zero. 260 for (i = 0; i < idx; i++) { 261 const int rc = scan[idx_arr[i]]; 262 const int coeff = coeff_ptr[rc]; 263 const int coeff_sign = (coeff >> 31); 264 int tmp; 265 int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; 266 abs_coeff += ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1); 267 abs_coeff = clamp(abs_coeff, INT16_MIN, INT16_MAX); 268 tmp = ((((abs_coeff * quant_ptr[rc != 0]) >> 16) + abs_coeff) * 269 quant_shift_ptr[rc != 0]) >> 15; 270 271 qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign; 272 dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2; 273 274 if (tmp) 275 eob = idx_arr[i]; 276 } 277 } 278 *eob_ptr = eob + 1; 279} 280 281#if CONFIG_VP9_HIGHBITDEPTH 282void vpx_highbd_quantize_b_32x32_c(const tran_low_t *coeff_ptr, 283 intptr_t n_coeffs, int skip_block, 284 const int16_t *zbin_ptr, 285 const int16_t *round_ptr, 286 const int16_t *quant_ptr, 287 const int16_t *quant_shift_ptr, 288 tran_low_t *qcoeff_ptr, 289 tran_low_t *dqcoeff_ptr, 290 const int16_t *dequant_ptr, 291 uint16_t *eob_ptr, 292 const int16_t *scan, const int16_t *iscan) { 293 const int zbins[2] = {ROUND_POWER_OF_TWO(zbin_ptr[0], 1), 294 ROUND_POWER_OF_TWO(zbin_ptr[1], 1)}; 295 const int nzbins[2] = {zbins[0] * -1, zbins[1] * -1}; 296 297 int idx = 0; 298 int idx_arr[1024]; 299 int i, eob = -1; 300 (void)iscan; 301 302 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); 303 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); 304 305 if (!skip_block) { 306 // Pre-scan pass 307 for (i = 0; i < n_coeffs; i++) { 308 const int rc = scan[i]; 309 const int coeff = coeff_ptr[rc]; 310 311 // If the coefficient is out of the base ZBIN range, keep it for 312 // quantization. 313 if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0]) 314 idx_arr[idx++] = i; 315 } 316 317 // Quantization pass: only process the coefficients selected in 318 // pre-scan pass. Note: idx can be zero. 319 for (i = 0; i < idx; i++) { 320 const int rc = scan[idx_arr[i]]; 321 const int coeff = coeff_ptr[rc]; 322 const int coeff_sign = (coeff >> 31); 323 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; 324 const int64_t tmp1 = abs_coeff 325 + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1); 326 const int64_t tmp2 = ((tmp1 * quant_ptr[rc != 0]) >> 16) + tmp1; 327 const uint32_t abs_qcoeff = 328 (uint32_t)((tmp2 * quant_shift_ptr[rc != 0]) >> 15); 329 qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign); 330 dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2; 331 if (abs_qcoeff) 332 eob = idx_arr[i]; 333 } 334 } 335 *eob_ptr = eob + 1; 336} 337#endif 338