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