av1_quantize.c (46434B)
1 /* 2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved. 3 * 4 * This source code is subject to the terms of the BSD 2 Clause License and 5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License 6 * was not distributed with this source code in the LICENSE file, you can 7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open 8 * Media Patent License 1.0 was not distributed with this source code in the 9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent. 10 */ 11 12 #include <math.h> 13 14 #include "config/aom_dsp_rtcd.h" 15 16 #include "aom/aomcx.h" 17 #include "aom_dsp/quantize.h" 18 #include "aom_mem/aom_mem.h" 19 #include "aom_ports/bitops.h" 20 #include "aom_ports/mem.h" 21 22 #include "av1/common/idct.h" 23 #include "av1/common/quant_common.h" 24 #include "av1/common/scan.h" 25 #include "av1/common/seg_common.h" 26 27 #include "av1/encoder/av1_quantize.h" 28 #include "av1/encoder/encoder.h" 29 #include "av1/encoder/rd.h" 30 31 void av1_quantize_skip(intptr_t n_coeffs, tran_low_t *qcoeff_ptr, 32 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr) { 33 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); 34 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); 35 *eob_ptr = 0; 36 } 37 38 int av1_quantize_fp_no_qmatrix(const int16_t quant_ptr[2], 39 const int16_t dequant_ptr[2], 40 const int16_t round_ptr[2], int log_scale, 41 const int16_t *scan, int coeff_count, 42 const tran_low_t *coeff_ptr, 43 tran_low_t *qcoeff_ptr, 44 tran_low_t *dqcoeff_ptr) { 45 memset(qcoeff_ptr, 0, coeff_count * sizeof(*qcoeff_ptr)); 46 memset(dqcoeff_ptr, 0, coeff_count * sizeof(*dqcoeff_ptr)); 47 const int rounding[2] = { ROUND_POWER_OF_TWO(round_ptr[0], log_scale), 48 ROUND_POWER_OF_TWO(round_ptr[1], log_scale) }; 49 int eob = 0; 50 for (int i = 0; i < coeff_count; i++) { 51 const int rc = scan[i]; 52 const int32_t thresh = (int32_t)(dequant_ptr[rc != 0]); 53 const int coeff = coeff_ptr[rc]; 54 const int coeff_sign = AOMSIGN(coeff); 55 int64_t abs_coeff = (coeff ^ coeff_sign) - coeff_sign; 56 int tmp32 = 0; 57 if ((abs_coeff << (1 + log_scale)) >= thresh) { 58 abs_coeff = clamp64(abs_coeff + rounding[rc != 0], INT16_MIN, INT16_MAX); 59 tmp32 = (int)((abs_coeff * quant_ptr[rc != 0]) >> (16 - log_scale)); 60 if (tmp32) { 61 qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign; 62 const tran_low_t abs_dqcoeff = 63 (tmp32 * dequant_ptr[rc != 0]) >> log_scale; 64 dqcoeff_ptr[rc] = (abs_dqcoeff ^ coeff_sign) - coeff_sign; 65 } 66 } 67 if (tmp32) eob = i + 1; 68 } 69 return eob; 70 } 71 72 static void quantize_fp_helper_c( 73 const tran_low_t *coeff_ptr, intptr_t n_coeffs, const int16_t *zbin_ptr, 74 const int16_t *round_ptr, const int16_t *quant_ptr, 75 const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, 76 tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, 77 const int16_t *scan, const int16_t *iscan, const qm_val_t *qm_ptr, 78 const qm_val_t *iqm_ptr, int log_scale) { 79 int i, eob = -1; 80 const int rounding[2] = { ROUND_POWER_OF_TWO(round_ptr[0], log_scale), 81 ROUND_POWER_OF_TWO(round_ptr[1], log_scale) }; 82 // TODO(jingning) Decide the need of these arguments after the 83 // quantization process is completed. 84 (void)zbin_ptr; 85 (void)quant_shift_ptr; 86 (void)iscan; 87 88 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); 89 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); 90 91 if (qm_ptr == NULL && iqm_ptr == NULL) { 92 *eob_ptr = av1_quantize_fp_no_qmatrix(quant_ptr, dequant_ptr, round_ptr, 93 log_scale, scan, (int)n_coeffs, 94 coeff_ptr, qcoeff_ptr, dqcoeff_ptr); 95 } else { 96 // Quantization pass: All coefficients with index >= zero_flag are 97 // skippable. Note: zero_flag can be zero. 98 for (i = 0; i < n_coeffs; i++) { 99 const int rc = scan[i]; 100 const int coeff = coeff_ptr[rc]; 101 const qm_val_t wt = qm_ptr ? qm_ptr[rc] : (1 << AOM_QM_BITS); 102 const qm_val_t iwt = iqm_ptr ? iqm_ptr[rc] : (1 << AOM_QM_BITS); 103 const int dequant = 104 (dequant_ptr[rc != 0] * iwt + (1 << (AOM_QM_BITS - 1))) >> 105 AOM_QM_BITS; 106 const int coeff_sign = AOMSIGN(coeff); 107 int64_t abs_coeff = (coeff ^ coeff_sign) - coeff_sign; 108 int tmp32 = 0; 109 if (abs_coeff * wt >= 110 (dequant_ptr[rc != 0] << (AOM_QM_BITS - (1 + log_scale)))) { 111 abs_coeff += rounding[rc != 0]; 112 abs_coeff = clamp64(abs_coeff, INT16_MIN, INT16_MAX); 113 tmp32 = (int)((abs_coeff * wt * quant_ptr[rc != 0]) >> 114 (16 - log_scale + AOM_QM_BITS)); 115 qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign; 116 const tran_low_t abs_dqcoeff = (tmp32 * dequant) >> log_scale; 117 dqcoeff_ptr[rc] = (abs_dqcoeff ^ coeff_sign) - coeff_sign; 118 } 119 120 if (tmp32) eob = i; 121 } 122 *eob_ptr = eob + 1; 123 } 124 } 125 126 #if CONFIG_AV1_HIGHBITDEPTH 127 static void highbd_quantize_fp_helper_c( 128 const tran_low_t *coeff_ptr, intptr_t count, const int16_t *zbin_ptr, 129 const int16_t *round_ptr, const int16_t *quant_ptr, 130 const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, 131 tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, 132 const int16_t *scan, const int16_t *iscan, const qm_val_t *qm_ptr, 133 const qm_val_t *iqm_ptr, int log_scale) { 134 int i; 135 int eob = -1; 136 const int shift = 16 - log_scale; 137 // TODO(jingning) Decide the need of these arguments after the 138 // quantization process is completed. 139 (void)zbin_ptr; 140 (void)quant_shift_ptr; 141 (void)iscan; 142 143 if (qm_ptr || iqm_ptr) { 144 // Quantization pass: All coefficients with index >= zero_flag are 145 // skippable. Note: zero_flag can be zero. 146 for (i = 0; i < count; i++) { 147 const int rc = scan[i]; 148 const int coeff = coeff_ptr[rc]; 149 const qm_val_t wt = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS); 150 const qm_val_t iwt = iqm_ptr != NULL ? iqm_ptr[rc] : (1 << AOM_QM_BITS); 151 const int dequant = 152 (dequant_ptr[rc != 0] * iwt + (1 << (AOM_QM_BITS - 1))) >> 153 AOM_QM_BITS; 154 const int coeff_sign = AOMSIGN(coeff); 155 const int64_t abs_coeff = (coeff ^ coeff_sign) - coeff_sign; 156 int abs_qcoeff = 0; 157 if (abs_coeff * wt >= 158 (dequant_ptr[rc != 0] << (AOM_QM_BITS - (1 + log_scale)))) { 159 const int64_t tmp = 160 abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], log_scale); 161 abs_qcoeff = 162 (int)((tmp * quant_ptr[rc != 0] * wt) >> (shift + AOM_QM_BITS)); 163 qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign); 164 const tran_low_t abs_dqcoeff = (abs_qcoeff * dequant) >> log_scale; 165 dqcoeff_ptr[rc] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign); 166 if (abs_qcoeff) eob = i; 167 } else { 168 qcoeff_ptr[rc] = 0; 169 dqcoeff_ptr[rc] = 0; 170 } 171 } 172 } else { 173 const int log_scaled_round_arr[2] = { 174 ROUND_POWER_OF_TWO(round_ptr[0], log_scale), 175 ROUND_POWER_OF_TWO(round_ptr[1], log_scale), 176 }; 177 for (i = 0; i < count; i++) { 178 const int rc = scan[i]; 179 const int coeff = coeff_ptr[rc]; 180 const int rc01 = (rc != 0); 181 const int coeff_sign = AOMSIGN(coeff); 182 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; 183 const int log_scaled_round = log_scaled_round_arr[rc01]; 184 if ((abs_coeff << (1 + log_scale)) >= dequant_ptr[rc01]) { 185 const int quant = quant_ptr[rc01]; 186 const int dequant = dequant_ptr[rc01]; 187 const int64_t tmp = (int64_t)abs_coeff + log_scaled_round; 188 const int abs_qcoeff = (int)((tmp * quant) >> shift); 189 qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign); 190 const tran_low_t abs_dqcoeff = (abs_qcoeff * dequant) >> log_scale; 191 if (abs_qcoeff) eob = i; 192 dqcoeff_ptr[rc] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign); 193 } else { 194 qcoeff_ptr[rc] = 0; 195 dqcoeff_ptr[rc] = 0; 196 } 197 } 198 } 199 *eob_ptr = eob + 1; 200 } 201 #endif // CONFIG_AV1_HIGHBITDEPTH 202 203 void av1_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, 204 const int16_t *zbin_ptr, const int16_t *round_ptr, 205 const int16_t *quant_ptr, const int16_t *quant_shift_ptr, 206 tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, 207 const int16_t *dequant_ptr, uint16_t *eob_ptr, 208 const int16_t *scan, const int16_t *iscan) { 209 quantize_fp_helper_c(coeff_ptr, n_coeffs, zbin_ptr, round_ptr, quant_ptr, 210 quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr, 211 eob_ptr, scan, iscan, NULL, NULL, 0); 212 } 213 214 void av1_quantize_lp_c(const int16_t *coeff_ptr, intptr_t n_coeffs, 215 const int16_t *round_ptr, const int16_t *quant_ptr, 216 int16_t *qcoeff_ptr, int16_t *dqcoeff_ptr, 217 const int16_t *dequant_ptr, uint16_t *eob_ptr, 218 const int16_t *scan, const int16_t *iscan) { 219 (void)iscan; 220 int eob = -1; 221 222 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); 223 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); 224 225 // Quantization pass: All coefficients with index >= zero_flag are 226 // skippable. Note: zero_flag can be zero. 227 for (int i = 0; i < n_coeffs; i++) { 228 const int rc = scan[i]; 229 const int coeff = coeff_ptr[rc]; 230 const int coeff_sign = AOMSIGN(coeff); 231 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; 232 233 int tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX); 234 tmp = (tmp * quant_ptr[rc != 0]) >> 16; 235 236 qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign; 237 dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0]; 238 239 if (tmp) eob = i; 240 } 241 *eob_ptr = eob + 1; 242 } 243 244 void av1_quantize_fp_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, 245 const int16_t *zbin_ptr, const int16_t *round_ptr, 246 const int16_t *quant_ptr, 247 const int16_t *quant_shift_ptr, 248 tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, 249 const int16_t *dequant_ptr, uint16_t *eob_ptr, 250 const int16_t *scan, const int16_t *iscan) { 251 quantize_fp_helper_c(coeff_ptr, n_coeffs, zbin_ptr, round_ptr, quant_ptr, 252 quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr, 253 eob_ptr, scan, iscan, NULL, NULL, 1); 254 } 255 256 void av1_quantize_fp_64x64_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, 257 const int16_t *zbin_ptr, const int16_t *round_ptr, 258 const int16_t *quant_ptr, 259 const int16_t *quant_shift_ptr, 260 tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, 261 const int16_t *dequant_ptr, uint16_t *eob_ptr, 262 const int16_t *scan, const int16_t *iscan) { 263 quantize_fp_helper_c(coeff_ptr, n_coeffs, zbin_ptr, round_ptr, quant_ptr, 264 quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr, 265 eob_ptr, scan, iscan, NULL, NULL, 2); 266 } 267 268 void av1_quantize_fp_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs, 269 const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr, 270 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr, 271 const SCAN_ORDER *sc, const QUANT_PARAM *qparam) { 272 const qm_val_t *qm_ptr = qparam->qmatrix; 273 const qm_val_t *iqm_ptr = qparam->iqmatrix; 274 if (qm_ptr != NULL && iqm_ptr != NULL) { 275 quantize_fp_helper_c(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX, 276 p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr, 277 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan, 278 sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale); 279 } else { 280 switch (qparam->log_scale) { 281 case 0: 282 av1_quantize_fp(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX, 283 p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr, 284 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan, 285 sc->iscan); 286 break; 287 case 1: 288 av1_quantize_fp_32x32(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX, 289 p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr, 290 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan, 291 sc->iscan); 292 break; 293 case 2: 294 av1_quantize_fp_64x64(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX, 295 p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr, 296 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan, 297 sc->iscan); 298 break; 299 default: assert(0); 300 } 301 } 302 } 303 304 void av1_quantize_b_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs, 305 const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr, 306 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr, 307 const SCAN_ORDER *sc, const QUANT_PARAM *qparam) { 308 const qm_val_t *qm_ptr = qparam->qmatrix; 309 const qm_val_t *iqm_ptr = qparam->iqmatrix; 310 #if !CONFIG_REALTIME_ONLY 311 if (qparam->use_quant_b_adapt) { 312 // TODO(sarahparker) These quantize_b optimizations need SIMD 313 // implementations 314 if (qm_ptr != NULL && iqm_ptr != NULL) { 315 aom_quantize_b_adaptive_helper_c( 316 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX, 317 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr, 318 sc->scan, sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale); 319 } else { 320 switch (qparam->log_scale) { 321 case 0: 322 aom_quantize_b_adaptive(coeff_ptr, n_coeffs, p->zbin_QTX, 323 p->round_QTX, p->quant_QTX, 324 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, 325 p->dequant_QTX, eob_ptr, sc->scan, sc->iscan); 326 break; 327 case 1: 328 aom_quantize_b_32x32_adaptive( 329 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX, 330 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, 331 eob_ptr, sc->scan, sc->iscan); 332 break; 333 case 2: 334 aom_quantize_b_64x64_adaptive( 335 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX, 336 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, 337 eob_ptr, sc->scan, sc->iscan); 338 break; 339 default: assert(0); 340 } 341 } 342 return; 343 } 344 #endif // !CONFIG_REALTIME_ONLY 345 346 if (qm_ptr != NULL && iqm_ptr != NULL) { 347 aom_quantize_b_helper_c(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, 348 p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr, 349 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan, 350 sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale); 351 } else { 352 switch (qparam->log_scale) { 353 case 0: 354 aom_quantize_b(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, 355 p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr, 356 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan, 357 sc->iscan); 358 break; 359 case 1: 360 aom_quantize_b_32x32(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, 361 p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr, 362 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan, 363 sc->iscan); 364 break; 365 case 2: 366 aom_quantize_b_64x64(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, 367 p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr, 368 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan, 369 sc->iscan); 370 break; 371 default: assert(0); 372 } 373 } 374 } 375 376 static void quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs, 377 int skip_block, const int16_t *round_ptr, 378 const int16_t quant, tran_low_t *qcoeff_ptr, 379 tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr, 380 uint16_t *eob_ptr, const qm_val_t *qm_ptr, 381 const qm_val_t *iqm_ptr, const int log_scale) { 382 const int rc = 0; 383 const int coeff = coeff_ptr[rc]; 384 const int coeff_sign = AOMSIGN(coeff); 385 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; 386 int64_t tmp; 387 int eob = -1; 388 int32_t tmp32; 389 int dequant; 390 391 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); 392 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); 393 394 if (!skip_block) { 395 const int wt = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS); 396 const int iwt = iqm_ptr != NULL ? iqm_ptr[rc] : (1 << AOM_QM_BITS); 397 tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], log_scale), 398 INT16_MIN, INT16_MAX); 399 tmp32 = (int32_t)((tmp * wt * quant) >> (16 - log_scale + AOM_QM_BITS)); 400 qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign; 401 dequant = (dequant_ptr * iwt + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS; 402 const tran_low_t abs_dqcoeff = (tmp32 * dequant) >> log_scale; 403 dqcoeff_ptr[rc] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign); 404 if (tmp32) eob = 0; 405 } 406 *eob_ptr = eob + 1; 407 } 408 409 void av1_quantize_dc_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs, 410 const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr, 411 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr, 412 const SCAN_ORDER *sc, const QUANT_PARAM *qparam) { 413 // obsolete skip_block 414 const int skip_block = 0; 415 (void)sc; 416 assert(qparam->log_scale >= 0 && qparam->log_scale < (3)); 417 const qm_val_t *qm_ptr = qparam->qmatrix; 418 const qm_val_t *iqm_ptr = qparam->iqmatrix; 419 quantize_dc(coeff_ptr, (int)n_coeffs, skip_block, p->round_QTX, 420 p->quant_fp_QTX[0], qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX[0], 421 eob_ptr, qm_ptr, iqm_ptr, qparam->log_scale); 422 } 423 424 #if CONFIG_AV1_HIGHBITDEPTH 425 void av1_highbd_quantize_fp_facade(const tran_low_t *coeff_ptr, 426 intptr_t n_coeffs, const MACROBLOCK_PLANE *p, 427 tran_low_t *qcoeff_ptr, 428 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr, 429 const SCAN_ORDER *sc, 430 const QUANT_PARAM *qparam) { 431 const qm_val_t *qm_ptr = qparam->qmatrix; 432 const qm_val_t *iqm_ptr = qparam->iqmatrix; 433 if (qm_ptr != NULL && iqm_ptr != NULL) { 434 highbd_quantize_fp_helper_c( 435 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX, p->quant_fp_QTX, 436 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr, 437 sc->scan, sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale); 438 } else { 439 av1_highbd_quantize_fp(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX, 440 p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr, 441 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan, 442 sc->iscan, qparam->log_scale); 443 } 444 } 445 446 void av1_highbd_quantize_b_facade(const tran_low_t *coeff_ptr, 447 intptr_t n_coeffs, const MACROBLOCK_PLANE *p, 448 tran_low_t *qcoeff_ptr, 449 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr, 450 const SCAN_ORDER *sc, 451 const QUANT_PARAM *qparam) { 452 const qm_val_t *qm_ptr = qparam->qmatrix; 453 const qm_val_t *iqm_ptr = qparam->iqmatrix; 454 #if !CONFIG_REALTIME_ONLY 455 if (qparam->use_quant_b_adapt) { 456 if (qm_ptr != NULL && iqm_ptr != NULL) { 457 aom_highbd_quantize_b_adaptive_helper_c( 458 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX, 459 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr, 460 sc->scan, sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale); 461 } else { 462 switch (qparam->log_scale) { 463 case 0: 464 aom_highbd_quantize_b_adaptive( 465 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX, 466 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, 467 eob_ptr, sc->scan, sc->iscan); 468 break; 469 case 1: 470 aom_highbd_quantize_b_32x32_adaptive( 471 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX, 472 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, 473 eob_ptr, sc->scan, sc->iscan); 474 break; 475 case 2: 476 aom_highbd_quantize_b_64x64_adaptive( 477 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX, 478 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, 479 eob_ptr, sc->scan, sc->iscan); 480 break; 481 default: assert(0); 482 } 483 } 484 return; 485 } 486 #endif // !CONFIG_REALTIME_ONLY 487 488 if (qm_ptr != NULL && iqm_ptr != NULL) { 489 aom_highbd_quantize_b_helper_c( 490 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX, 491 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr, 492 sc->scan, sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale); 493 } else { 494 switch (qparam->log_scale) { 495 case 0: 496 aom_highbd_quantize_b(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, 497 p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr, 498 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan, 499 sc->iscan); 500 break; 501 case 1: 502 aom_highbd_quantize_b_32x32( 503 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX, 504 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, 505 eob_ptr, sc->scan, sc->iscan); 506 break; 507 case 2: 508 aom_highbd_quantize_b_64x64( 509 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX, 510 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, 511 eob_ptr, sc->scan, sc->iscan); 512 break; 513 default: assert(0); 514 } 515 } 516 } 517 518 static inline void highbd_quantize_dc( 519 const tran_low_t *coeff_ptr, int n_coeffs, int skip_block, 520 const int16_t *round_ptr, const int16_t quant, tran_low_t *qcoeff_ptr, 521 tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr, uint16_t *eob_ptr, 522 const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr, const int log_scale) { 523 int eob = -1; 524 525 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); 526 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); 527 528 if (!skip_block) { 529 const qm_val_t wt = qm_ptr != NULL ? qm_ptr[0] : (1 << AOM_QM_BITS); 530 const qm_val_t iwt = iqm_ptr != NULL ? iqm_ptr[0] : (1 << AOM_QM_BITS); 531 const int coeff = coeff_ptr[0]; 532 const int coeff_sign = AOMSIGN(coeff); 533 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; 534 const int64_t tmp = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[0], log_scale); 535 const int64_t tmpw = tmp * wt; 536 const int abs_qcoeff = 537 (int)((tmpw * quant) >> (16 - log_scale + AOM_QM_BITS)); 538 qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign); 539 const int dequant = 540 (dequant_ptr * iwt + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS; 541 542 const tran_low_t abs_dqcoeff = (abs_qcoeff * dequant) >> log_scale; 543 dqcoeff_ptr[0] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign); 544 if (abs_qcoeff) eob = 0; 545 } 546 *eob_ptr = eob + 1; 547 } 548 549 void av1_highbd_quantize_dc_facade(const tran_low_t *coeff_ptr, 550 intptr_t n_coeffs, const MACROBLOCK_PLANE *p, 551 tran_low_t *qcoeff_ptr, 552 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr, 553 const SCAN_ORDER *sc, 554 const QUANT_PARAM *qparam) { 555 // obsolete skip_block 556 const int skip_block = 0; 557 const qm_val_t *qm_ptr = qparam->qmatrix; 558 const qm_val_t *iqm_ptr = qparam->iqmatrix; 559 (void)sc; 560 561 highbd_quantize_dc(coeff_ptr, (int)n_coeffs, skip_block, p->round_QTX, 562 p->quant_fp_QTX[0], qcoeff_ptr, dqcoeff_ptr, 563 p->dequant_QTX[0], eob_ptr, qm_ptr, iqm_ptr, 564 qparam->log_scale); 565 } 566 567 void av1_highbd_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t count, 568 const int16_t *zbin_ptr, const int16_t *round_ptr, 569 const int16_t *quant_ptr, 570 const int16_t *quant_shift_ptr, 571 tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, 572 const int16_t *dequant_ptr, uint16_t *eob_ptr, 573 const int16_t *scan, const int16_t *iscan, 574 int log_scale) { 575 highbd_quantize_fp_helper_c(coeff_ptr, count, zbin_ptr, round_ptr, quant_ptr, 576 quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, 577 dequant_ptr, eob_ptr, scan, iscan, NULL, NULL, 578 log_scale); 579 } 580 #endif // CONFIG_AV1_HIGHBITDEPTH 581 582 static void invert_quant(int16_t *quant, int16_t *shift, int d) { 583 uint32_t t; 584 int l, m; 585 t = d; 586 l = get_msb(t); 587 m = 1 + (1 << (16 + l)) / d; 588 *quant = (int16_t)(m - (1 << 16)); 589 *shift = 1 << (16 - l); 590 } 591 592 static int get_qzbin_factor(int q, aom_bit_depth_t bit_depth) { 593 const int quant = av1_dc_quant_QTX(q, 0, bit_depth); 594 switch (bit_depth) { 595 case AOM_BITS_8: return q == 0 ? 64 : (quant < 148 ? 84 : 80); 596 case AOM_BITS_10: return q == 0 ? 64 : (quant < 592 ? 84 : 80); 597 case AOM_BITS_12: return q == 0 ? 64 : (quant < 2368 ? 84 : 80); 598 default: 599 assert(0 && "bit_depth should be AOM_BITS_8, AOM_BITS_10 or AOM_BITS_12"); 600 return -1; 601 } 602 } 603 604 void av1_build_quantizer(aom_bit_depth_t bit_depth, int y_dc_delta_q, 605 int u_dc_delta_q, int u_ac_delta_q, int v_dc_delta_q, 606 int v_ac_delta_q, QUANTS *const quants, 607 Dequants *const deq, int sharpness) { 608 int i, q, quant_QTX; 609 const int sharpness_adjustment = 16 * (7 - sharpness) / 7; 610 611 for (q = 0; q < QINDEX_RANGE; q++) { 612 const int qzbin_factor = get_qzbin_factor(q, bit_depth); 613 int qrounding_factor = q == 0 ? 64 : 48; 614 615 for (i = 0; i < 2; ++i) { 616 int qrounding_factor_fp = 64; 617 618 if (sharpness != 0 && q != 0) { 619 qrounding_factor = 64 - sharpness_adjustment; 620 qrounding_factor_fp = 64 - sharpness_adjustment; 621 } 622 623 // y quantizer with TX scale 624 quant_QTX = i == 0 ? av1_dc_quant_QTX(q, y_dc_delta_q, bit_depth) 625 : av1_ac_quant_QTX(q, 0, bit_depth); 626 invert_quant(&quants->y_quant[q][i], &quants->y_quant_shift[q][i], 627 quant_QTX); 628 quants->y_quant_fp[q][i] = (1 << 16) / quant_QTX; 629 quants->y_round_fp[q][i] = (qrounding_factor_fp * quant_QTX) >> 7; 630 quants->y_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7); 631 quants->y_round[q][i] = (qrounding_factor * quant_QTX) >> 7; 632 deq->y_dequant_QTX[q][i] = quant_QTX; 633 634 // u quantizer with TX scale 635 quant_QTX = i == 0 ? av1_dc_quant_QTX(q, u_dc_delta_q, bit_depth) 636 : av1_ac_quant_QTX(q, u_ac_delta_q, bit_depth); 637 invert_quant(&quants->u_quant[q][i], &quants->u_quant_shift[q][i], 638 quant_QTX); 639 quants->u_quant_fp[q][i] = (1 << 16) / quant_QTX; 640 quants->u_round_fp[q][i] = (qrounding_factor_fp * quant_QTX) >> 7; 641 quants->u_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7); 642 quants->u_round[q][i] = (qrounding_factor * quant_QTX) >> 7; 643 deq->u_dequant_QTX[q][i] = quant_QTX; 644 645 // v quantizer with TX scale 646 quant_QTX = i == 0 ? av1_dc_quant_QTX(q, v_dc_delta_q, bit_depth) 647 : av1_ac_quant_QTX(q, v_ac_delta_q, bit_depth); 648 invert_quant(&quants->v_quant[q][i], &quants->v_quant_shift[q][i], 649 quant_QTX); 650 quants->v_quant_fp[q][i] = (1 << 16) / quant_QTX; 651 quants->v_round_fp[q][i] = (qrounding_factor_fp * quant_QTX) >> 7; 652 quants->v_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7); 653 quants->v_round[q][i] = (qrounding_factor * quant_QTX) >> 7; 654 deq->v_dequant_QTX[q][i] = quant_QTX; 655 } 656 657 for (i = 2; i < 8; i++) { // 8: SIMD width 658 quants->y_quant[q][i] = quants->y_quant[q][1]; 659 quants->y_quant_fp[q][i] = quants->y_quant_fp[q][1]; 660 quants->y_round_fp[q][i] = quants->y_round_fp[q][1]; 661 quants->y_quant_shift[q][i] = quants->y_quant_shift[q][1]; 662 quants->y_zbin[q][i] = quants->y_zbin[q][1]; 663 quants->y_round[q][i] = quants->y_round[q][1]; 664 deq->y_dequant_QTX[q][i] = deq->y_dequant_QTX[q][1]; 665 666 quants->u_quant[q][i] = quants->u_quant[q][1]; 667 quants->u_quant_fp[q][i] = quants->u_quant_fp[q][1]; 668 quants->u_round_fp[q][i] = quants->u_round_fp[q][1]; 669 quants->u_quant_shift[q][i] = quants->u_quant_shift[q][1]; 670 quants->u_zbin[q][i] = quants->u_zbin[q][1]; 671 quants->u_round[q][i] = quants->u_round[q][1]; 672 deq->u_dequant_QTX[q][i] = deq->u_dequant_QTX[q][1]; 673 674 quants->v_quant[q][i] = quants->v_quant[q][1]; 675 quants->v_quant_fp[q][i] = quants->v_quant_fp[q][1]; 676 quants->v_round_fp[q][i] = quants->v_round_fp[q][1]; 677 quants->v_quant_shift[q][i] = quants->v_quant_shift[q][1]; 678 quants->v_zbin[q][i] = quants->v_zbin[q][1]; 679 quants->v_round[q][i] = quants->v_round[q][1]; 680 deq->v_dequant_QTX[q][i] = deq->v_dequant_QTX[q][1]; 681 } 682 } 683 } 684 685 static inline bool deltaq_params_have_changed( 686 const DeltaQuantParams *prev_deltaq_params, 687 const CommonQuantParams *quant_params) { 688 return (prev_deltaq_params->y_dc_delta_q != quant_params->y_dc_delta_q || 689 prev_deltaq_params->u_dc_delta_q != quant_params->u_dc_delta_q || 690 prev_deltaq_params->v_dc_delta_q != quant_params->v_dc_delta_q || 691 prev_deltaq_params->u_ac_delta_q != quant_params->u_ac_delta_q || 692 prev_deltaq_params->v_ac_delta_q != quant_params->v_ac_delta_q || 693 prev_deltaq_params->sharpness != quant_params->sharpness); 694 } 695 696 void av1_init_quantizer(EncQuantDequantParams *const enc_quant_dequant_params, 697 CommonQuantParams *quant_params, 698 aom_bit_depth_t bit_depth, int sharpness) { 699 DeltaQuantParams *const prev_deltaq_params = 700 &enc_quant_dequant_params->prev_deltaq_params; 701 quant_params->sharpness = sharpness; 702 703 // Re-initialize the quantizer only if any of the dc/ac deltaq parameters 704 // change. 705 if (!deltaq_params_have_changed(prev_deltaq_params, quant_params)) return; 706 QUANTS *const quants = &enc_quant_dequant_params->quants; 707 Dequants *const dequants = &enc_quant_dequant_params->dequants; 708 av1_build_quantizer(bit_depth, quant_params->y_dc_delta_q, 709 quant_params->u_dc_delta_q, quant_params->u_ac_delta_q, 710 quant_params->v_dc_delta_q, quant_params->v_ac_delta_q, 711 quants, dequants, sharpness); 712 713 // Record the state of deltaq parameters. 714 prev_deltaq_params->y_dc_delta_q = quant_params->y_dc_delta_q; 715 prev_deltaq_params->u_dc_delta_q = quant_params->u_dc_delta_q; 716 prev_deltaq_params->v_dc_delta_q = quant_params->v_dc_delta_q; 717 prev_deltaq_params->u_ac_delta_q = quant_params->u_ac_delta_q; 718 prev_deltaq_params->v_ac_delta_q = quant_params->v_ac_delta_q; 719 prev_deltaq_params->sharpness = sharpness; 720 } 721 722 /*!\brief Update quantize parameters in MACROBLOCK 723 * 724 * \param[in] enc_quant_dequant_params This parameter cached the quantize and 725 * dequantize parameters for all q 726 * indices. 727 * \param[in] qindex Quantize index used for the current 728 * superblock. 729 * \param[out] x A superblock data structure for 730 * encoder. 731 */ 732 static void set_q_index(const EncQuantDequantParams *enc_quant_dequant_params, 733 int qindex, MACROBLOCK *x) { 734 const QUANTS *const quants = &enc_quant_dequant_params->quants; 735 const Dequants *const dequants = &enc_quant_dequant_params->dequants; 736 x->qindex = qindex; 737 x->seg_skip_block = 738 0; // TODO(angiebird): Find a proper place to init this variable. 739 740 // Y 741 x->plane[0].quant_QTX = quants->y_quant[qindex]; 742 x->plane[0].quant_fp_QTX = quants->y_quant_fp[qindex]; 743 x->plane[0].round_fp_QTX = quants->y_round_fp[qindex]; 744 x->plane[0].quant_shift_QTX = quants->y_quant_shift[qindex]; 745 x->plane[0].zbin_QTX = quants->y_zbin[qindex]; 746 x->plane[0].round_QTX = quants->y_round[qindex]; 747 x->plane[0].dequant_QTX = dequants->y_dequant_QTX[qindex]; 748 749 // U 750 x->plane[1].quant_QTX = quants->u_quant[qindex]; 751 x->plane[1].quant_fp_QTX = quants->u_quant_fp[qindex]; 752 x->plane[1].round_fp_QTX = quants->u_round_fp[qindex]; 753 x->plane[1].quant_shift_QTX = quants->u_quant_shift[qindex]; 754 x->plane[1].zbin_QTX = quants->u_zbin[qindex]; 755 x->plane[1].round_QTX = quants->u_round[qindex]; 756 x->plane[1].dequant_QTX = dequants->u_dequant_QTX[qindex]; 757 758 // V 759 x->plane[2].quant_QTX = quants->v_quant[qindex]; 760 x->plane[2].quant_fp_QTX = quants->v_quant_fp[qindex]; 761 x->plane[2].round_fp_QTX = quants->v_round_fp[qindex]; 762 x->plane[2].quant_shift_QTX = quants->v_quant_shift[qindex]; 763 x->plane[2].zbin_QTX = quants->v_zbin[qindex]; 764 x->plane[2].round_QTX = quants->v_round[qindex]; 765 x->plane[2].dequant_QTX = dequants->v_dequant_QTX[qindex]; 766 } 767 768 /*!\brief Update quantize matrix in MACROBLOCKD based on segment id 769 * 770 * \param[in] quant_params Quantize parameters used by encoder and decoder 771 * \param[in] segment_id Segment id. 772 * \param[out] xd A superblock data structure used by encoder and 773 * decoder. 774 */ 775 static void set_qmatrix(const CommonQuantParams *quant_params, int segment_id, 776 MACROBLOCKD *xd) { 777 const int use_qmatrix = av1_use_qmatrix(quant_params, xd, segment_id); 778 const int qmlevel_y = 779 use_qmatrix ? quant_params->qmatrix_level_y : NUM_QM_LEVELS - 1; 780 const int qmlevel_u = 781 use_qmatrix ? quant_params->qmatrix_level_u : NUM_QM_LEVELS - 1; 782 const int qmlevel_v = 783 use_qmatrix ? quant_params->qmatrix_level_v : NUM_QM_LEVELS - 1; 784 const int qmlevel_ls[MAX_MB_PLANE] = { qmlevel_y, qmlevel_u, qmlevel_v }; 785 for (int i = 0; i < MAX_MB_PLANE; ++i) { 786 const int qmlevel = qmlevel_ls[i]; 787 memcpy(&xd->plane[i].seg_qmatrix[segment_id], 788 quant_params->gqmatrix[qmlevel][i], 789 sizeof(quant_params->gqmatrix[qmlevel][i])); 790 memcpy(&xd->plane[i].seg_iqmatrix[segment_id], 791 quant_params->giqmatrix[qmlevel][i], 792 sizeof(quant_params->giqmatrix[qmlevel][i])); 793 } 794 } 795 796 void av1_init_plane_quantizers(const AV1_COMP *cpi, MACROBLOCK *x, 797 int segment_id, const int do_update) { 798 const AV1_COMMON *const cm = &cpi->common; 799 const CommonQuantParams *const quant_params = &cm->quant_params; 800 const GF_GROUP *const gf_group = &cpi->ppi->gf_group; 801 const int boost_index = AOMMIN(15, (cpi->ppi->p_rc.gfu_boost / 100)); 802 const int layer_depth = AOMMIN(gf_group->layer_depth[cpi->gf_frame_index], 6); 803 const FRAME_TYPE frame_type = cm->current_frame.frame_type; 804 int qindex_rd; 805 806 const int current_qindex = 807 clamp(cm->delta_q_info.delta_q_present_flag 808 ? quant_params->base_qindex + x->delta_qindex 809 : quant_params->base_qindex, 810 0, QINDEX_RANGE - 1); 811 const int qindex = av1_get_qindex(&cm->seg, segment_id, current_qindex); 812 813 if (cpi->oxcf.sb_qp_sweep) { 814 const int current_rd_qindex = 815 clamp(cm->delta_q_info.delta_q_present_flag 816 ? quant_params->base_qindex + x->rdmult_delta_qindex 817 : quant_params->base_qindex, 818 0, QINDEX_RANGE - 1); 819 qindex_rd = av1_get_qindex(&cm->seg, segment_id, current_rd_qindex); 820 } else { 821 qindex_rd = qindex; 822 } 823 824 const int qindex_rdmult = qindex_rd + quant_params->y_dc_delta_q; 825 const int rdmult = av1_compute_rd_mult( 826 qindex_rdmult, cm->seq_params->bit_depth, 827 cpi->ppi->gf_group.update_type[cpi->gf_frame_index], layer_depth, 828 boost_index, frame_type, cpi->oxcf.q_cfg.use_fixed_qp_offsets, 829 is_stat_consumption_stage(cpi), cpi->oxcf.tune_cfg.tuning); 830 831 const int qindex_change = x->qindex != qindex; 832 if (qindex_change || do_update) { 833 set_q_index(&cpi->enc_quant_dequant_params, qindex, x); 834 } 835 836 MACROBLOCKD *const xd = &x->e_mbd; 837 if ((segment_id != x->prev_segment_id) || 838 av1_use_qmatrix(quant_params, xd, segment_id)) { 839 set_qmatrix(quant_params, segment_id, xd); 840 } 841 842 x->seg_skip_block = segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP); 843 844 av1_set_error_per_bit(&x->errorperbit, rdmult); 845 av1_set_sad_per_bit(cpi, &x->sadperbit, qindex_rd); 846 847 x->prev_segment_id = segment_id; 848 } 849 850 void av1_frame_init_quantizer(AV1_COMP *cpi) { 851 MACROBLOCK *const x = &cpi->td.mb; 852 MACROBLOCKD *const xd = &x->e_mbd; 853 x->prev_segment_id = -1; 854 av1_init_plane_quantizers(cpi, x, xd->mi[0]->segment_id, 1); 855 } 856 857 static int adjust_hdr_cb_deltaq(int base_qindex) { 858 double baseQp = base_qindex / QP_SCALE_FACTOR; 859 const double chromaQp = CHROMA_QP_SCALE * baseQp + CHROMA_QP_OFFSET; 860 const double dcbQP = CHROMA_CB_QP_SCALE * chromaQp * QP_SCALE_FACTOR; 861 int dqpCb = (int)(dcbQP + (dcbQP < 0 ? -0.5 : 0.5)); 862 dqpCb = AOMMIN(0, dqpCb); 863 dqpCb = (int)CLIP(dqpCb, -12 * QP_SCALE_FACTOR, 12 * QP_SCALE_FACTOR); 864 return dqpCb; 865 } 866 867 static int adjust_hdr_cr_deltaq(int base_qindex) { 868 double baseQp = base_qindex / QP_SCALE_FACTOR; 869 const double chromaQp = CHROMA_QP_SCALE * baseQp + CHROMA_QP_OFFSET; 870 const double dcrQP = CHROMA_CR_QP_SCALE * chromaQp * QP_SCALE_FACTOR; 871 int dqpCr = (int)(dcrQP + (dcrQP < 0 ? -0.5 : 0.5)); 872 dqpCr = AOMMIN(0, dqpCr); 873 dqpCr = (int)CLIP(dqpCr, -12 * QP_SCALE_FACTOR, 12 * QP_SCALE_FACTOR); 874 return dqpCr; 875 } 876 877 void av1_set_quantizer(AV1_COMMON *const cm, int min_qmlevel, int max_qmlevel, 878 int q, int enable_chroma_deltaq, int enable_hdr_deltaq, 879 bool is_allintra, aom_tune_metric tuning) { 880 // quantizer has to be reinitialized with av1_init_quantizer() if any 881 // delta_q changes. 882 CommonQuantParams *quant_params = &cm->quant_params; 883 quant_params->base_qindex = AOMMAX(cm->delta_q_info.delta_q_present_flag, q); 884 quant_params->y_dc_delta_q = 0; 885 886 // Disable deltaq in lossless mode. 887 if (enable_chroma_deltaq && q) { 888 if (is_allintra && 889 (tuning == AOM_TUNE_IQ || tuning == AOM_TUNE_SSIMULACRA2)) { 890 int chroma_dc_delta_q = 0; 891 int chroma_ac_delta_q = 0; 892 893 if (cm->seq_params->subsampling_x == 1 && 894 cm->seq_params->subsampling_y == 1) { 895 // 4:2:0 subsampling: Constant chroma delta_q decrease (i.e. improved 896 // chroma quality relative to luma) with gradual ramp-down for very low 897 // qindexes. 898 // Lowering chroma delta_q by 16 was found to improve SSIMULACRA 2 899 // BD-Rate by 1.5-2% on Daala's subset1, as well as reducing chroma 900 // artifacts (smudging, discoloration) during subjective quality 901 // evaluations. 902 // The ramp-down of chroma increase was determined by generating the 903 // convex hull of SSIMULACRA 2 scores (for all boosts from 0-16), and 904 // finding a linear equation that fits the convex hull. 905 chroma_dc_delta_q = -clamp((quant_params->base_qindex / 2) - 14, 0, 16); 906 chroma_ac_delta_q = chroma_dc_delta_q; 907 } else if (cm->seq_params->subsampling_x == 1 && 908 cm->seq_params->subsampling_y == 0) { 909 // 4:2:2 subsampling: Constant chroma AC delta_q increase (i.e. improved 910 // luma quality relative to chroma) with gradual ramp-down for very low 911 // qindexes. 912 // SSIMULACRA 2 appears to have some issues correctly scoring 4:2:2 913 // material. Solely optimizing for maximum scores suggests a chroma AC 914 // delta_q of 12 is the most efficient. However, visual inspection on 915 // difficult-to-encode material resulted in chroma quality degrading too 916 // much relative to luma, and chroma channels ending up being too small 917 // compared to equivalent 4:4:4 or 4:2:0 encodes. 918 // A chroma AC delta_q of 6 was selected because encoded chroma channels 919 // have a much closer size to 4:4:4 and 4:2:0 encodes, and have more 920 // favorable visual quality characteristics. 921 // The ramp-down of chroma decrease was put into place to match 4:2:0 922 // and 4:4:4 behavior. There were no special considerations on 923 // SSIMULACRA 2 scores. 924 chroma_dc_delta_q = 0; 925 chroma_ac_delta_q = clamp((quant_params->base_qindex / 2), 0, 6); 926 } else if (cm->seq_params->subsampling_x == 0 && 927 cm->seq_params->subsampling_y == 0) { 928 // 4:4:4 subsampling: Constant chroma AC delta_q increase (i.e. improved 929 // luma quality relative to chroma) with gradual ramp-down for very low 930 // qindexes. 931 // Raising chroma AC delta_q by 24 was found to improve SSIMULACRA 2 932 // BD-Rate by 2.5-3% on Daala's subset1, as well as providing a more 933 // balanced bit allocation between the (relatively-starved) luma and 934 // chroma channels. 935 // Raising chroma DC delta_q appears to be harmful, both for SSIMULACRA 936 // 2 scores and subjective quality (harshens blocking artifacts). 937 // The ramp-down of chroma decrease was put into place so (lossy) QP 0 938 // encodes still score within 0.1 SSIMULACRA 2 points of the equivalent 939 // with no chroma delta_q (with a small efficiency improvement), while 940 // encodes in the SSIMULACRA 2 <=90 range yield full benefits from this 941 // adjustment. 942 chroma_dc_delta_q = 0; 943 chroma_ac_delta_q = clamp((quant_params->base_qindex / 2), 0, 24); 944 } 945 946 // TODO: bug https://crbug.com/aomedia/375221136 - find chroma_delta_q 947 // values for 4:2:2 subsampling mode. 948 quant_params->u_dc_delta_q = chroma_dc_delta_q; 949 quant_params->u_ac_delta_q = chroma_ac_delta_q; 950 quant_params->v_dc_delta_q = chroma_dc_delta_q; 951 quant_params->v_ac_delta_q = chroma_ac_delta_q; 952 } else { 953 // TODO(aomedia:2717): need to design better delta 954 quant_params->u_dc_delta_q = 2; 955 quant_params->u_ac_delta_q = 2; 956 quant_params->v_dc_delta_q = 2; 957 quant_params->v_ac_delta_q = 2; 958 } 959 } else { 960 quant_params->u_dc_delta_q = 0; 961 quant_params->u_ac_delta_q = 0; 962 quant_params->v_dc_delta_q = 0; 963 quant_params->v_ac_delta_q = 0; 964 } 965 966 // following section 8.3.2 in T-REC-H.Sup15 document 967 // to apply to AV1 qindex in the range of [0, 255] 968 if (enable_hdr_deltaq && q) { 969 int dqpCb = adjust_hdr_cb_deltaq(quant_params->base_qindex); 970 int dqpCr = adjust_hdr_cr_deltaq(quant_params->base_qindex); 971 quant_params->u_dc_delta_q = quant_params->u_ac_delta_q = dqpCb; 972 quant_params->v_dc_delta_q = quant_params->v_ac_delta_q = dqpCr; 973 if (dqpCb != dqpCr) { 974 cm->seq_params->separate_uv_delta_q = 1; 975 } 976 } 977 978 // Select the best luma and chroma QM formulas based on encoding mode and 979 // tuning 980 int (*get_luma_qmlevel)(int, int, int); 981 int (*get_chroma_qmlevel)(int, int, int); 982 983 if (is_allintra) { 984 if (tuning == AOM_TUNE_IQ || tuning == AOM_TUNE_SSIMULACRA2) { 985 if (tuning == AOM_TUNE_SSIMULACRA2) { 986 // Use luma QM formula specifically tailored for tune SSIMULACRA2 987 get_luma_qmlevel = aom_get_qmlevel_luma_ssimulacra2; 988 } else { 989 get_luma_qmlevel = aom_get_qmlevel_allintra; 990 } 991 992 if (cm->seq_params->subsampling_x == 0 && 993 cm->seq_params->subsampling_y == 0) { 994 // 4:4:4 subsampling mode has 4x the number of chroma coefficients 995 // compared to 4:2:0 (2x on each dimension). This means the encoder 996 // should use lower chroma QM levels that more closely match the scaling 997 // of an equivalent 4:2:0 chroma QM. 998 get_chroma_qmlevel = aom_get_qmlevel_444_chroma; 999 } else { 1000 // For all other chroma subsampling modes, use the all intra QM formula 1001 get_chroma_qmlevel = aom_get_qmlevel_allintra; 1002 } 1003 } else { 1004 get_luma_qmlevel = aom_get_qmlevel_allintra; 1005 get_chroma_qmlevel = aom_get_qmlevel_allintra; 1006 } 1007 } else { 1008 get_luma_qmlevel = aom_get_qmlevel; 1009 get_chroma_qmlevel = aom_get_qmlevel; 1010 } 1011 1012 quant_params->qmatrix_level_y = 1013 get_luma_qmlevel(quant_params->base_qindex, min_qmlevel, max_qmlevel); 1014 quant_params->qmatrix_level_u = 1015 get_chroma_qmlevel(quant_params->base_qindex + quant_params->u_ac_delta_q, 1016 min_qmlevel, max_qmlevel); 1017 1018 if (cm->seq_params->separate_uv_delta_q) { 1019 quant_params->qmatrix_level_v = get_chroma_qmlevel( 1020 quant_params->base_qindex + quant_params->v_ac_delta_q, min_qmlevel, 1021 max_qmlevel); 1022 } else { 1023 quant_params->qmatrix_level_v = quant_params->qmatrix_level_u; 1024 } 1025 } 1026 1027 // Table that converts 0-63 Q-range values passed in outside to the Qindex 1028 // range used internally. 1029 static const int quantizer_to_qindex[] = { 1030 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 1031 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 1032 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, 1033 156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204, 1034 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 249, 255, 1035 }; 1036 1037 int av1_quantizer_to_qindex(int quantizer) { 1038 return quantizer_to_qindex[quantizer]; 1039 } 1040 1041 int av1_qindex_to_quantizer(int qindex) { 1042 int quantizer; 1043 1044 for (quantizer = 0; quantizer < 64; ++quantizer) 1045 if (quantizer_to_qindex[quantizer] >= qindex) return quantizer; 1046 1047 return 63; 1048 }