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