1 /* 2 * Copyright (c) 2010 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 <math.h> 12 #include "vpx_mem/vpx_mem.h" 13 14 #include "onyx_int.h" 15 #include "vp8/encoder/quantize.h" 16 #include "vp8/common/quant_common.h" 17 18 void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d) { 19 int i, rc, eob; 20 int x, y, z, sz; 21 short *coeff_ptr = b->coeff; 22 short *round_ptr = b->round; 23 short *quant_ptr = b->quant_fast; 24 short *qcoeff_ptr = d->qcoeff; 25 short *dqcoeff_ptr = d->dqcoeff; 26 short *dequant_ptr = d->dequant; 27 28 eob = -1; 29 for (i = 0; i < 16; ++i) { 30 rc = vp8_default_zig_zag1d[i]; 31 z = coeff_ptr[rc]; 32 33 sz = (z >> 31); /* sign of z */ 34 x = (z ^ sz) - sz; /* x = abs(z) */ 35 36 y = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; /* quantize (x) */ 37 x = (y ^ sz) - sz; /* get the sign back */ 38 qcoeff_ptr[rc] = x; /* write to destination */ 39 dqcoeff_ptr[rc] = x * dequant_ptr[rc]; /* dequantized value */ 40 41 if (y) { 42 eob = i; /* last nonzero coeffs */ 43 } 44 } 45 *d->eob = (char)(eob + 1); 46 } 47 48 void vp8_regular_quantize_b_c(BLOCK *b, BLOCKD *d) { 49 int i, rc, eob; 50 int zbin; 51 int x, y, z, sz; 52 short *zbin_boost_ptr = b->zrun_zbin_boost; 53 short *coeff_ptr = b->coeff; 54 short *zbin_ptr = b->zbin; 55 short *round_ptr = b->round; 56 short *quant_ptr = b->quant; 57 short *quant_shift_ptr = b->quant_shift; 58 short *qcoeff_ptr = d->qcoeff; 59 short *dqcoeff_ptr = d->dqcoeff; 60 short *dequant_ptr = d->dequant; 61 short zbin_oq_value = b->zbin_extra; 62 63 memset(qcoeff_ptr, 0, 32); 64 memset(dqcoeff_ptr, 0, 32); 65 66 eob = -1; 67 68 for (i = 0; i < 16; ++i) { 69 rc = vp8_default_zig_zag1d[i]; 70 z = coeff_ptr[rc]; 71 72 zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value; 73 74 zbin_boost_ptr++; 75 sz = (z >> 31); /* sign of z */ 76 x = (z ^ sz) - sz; /* x = abs(z) */ 77 78 if (x >= zbin) { 79 x += round_ptr[rc]; 80 y = ((((x * quant_ptr[rc]) >> 16) + x) * quant_shift_ptr[rc]) >> 81 16; /* quantize (x) */ 82 x = (y ^ sz) - sz; /* get the sign back */ 83 qcoeff_ptr[rc] = x; /* write to destination */ 84 dqcoeff_ptr[rc] = x * dequant_ptr[rc]; /* dequantized value */ 85 86 if (y) { 87 eob = i; /* last nonzero coeffs */ 88 zbin_boost_ptr = b->zrun_zbin_boost; /* reset zero runlength */ 89 } 90 } 91 } 92 93 *d->eob = (char)(eob + 1); 94 } 95 96 void vp8_quantize_mby(MACROBLOCK *x) { 97 int i; 98 int has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED && 99 x->e_mbd.mode_info_context->mbmi.mode != SPLITMV); 100 101 for (i = 0; i < 16; ++i) x->quantize_b(&x->block[i], &x->e_mbd.block[i]); 102 103 if (has_2nd_order) x->quantize_b(&x->block[24], &x->e_mbd.block[24]); 104 } 105 106 void vp8_quantize_mb(MACROBLOCK *x) { 107 int i; 108 int has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED && 109 x->e_mbd.mode_info_context->mbmi.mode != SPLITMV); 110 111 for (i = 0; i < 24 + has_2nd_order; ++i) { 112 x->quantize_b(&x->block[i], &x->e_mbd.block[i]); 113 } 114 } 115 116 void vp8_quantize_mbuv(MACROBLOCK *x) { 117 int i; 118 119 for (i = 16; i < 24; ++i) x->quantize_b(&x->block[i], &x->e_mbd.block[i]); 120 } 121 122 static const int qrounding_factors[129] = { 123 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 124 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 125 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 126 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 127 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 128 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 129 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 130 }; 131 132 static const int qzbin_factors[129] = { 133 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 134 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 135 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 80, 80, 80, 80, 80, 80, 80, 80, 80, 136 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 137 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 138 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 139 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80 140 }; 141 142 static const int qrounding_factors_y2[129] = { 143 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 144 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 145 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 146 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 147 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 148 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 149 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 150 }; 151 152 static const int qzbin_factors_y2[129] = { 153 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 154 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 155 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 80, 80, 80, 80, 80, 80, 80, 80, 80, 156 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 157 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 158 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 159 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80 160 }; 161 162 static void invert_quant(int improved_quant, short *quant, short *shift, 163 short d) { 164 if (improved_quant) { 165 unsigned t; 166 int l, m; 167 t = d; 168 for (l = 0; t > 1; ++l) t >>= 1; 169 m = 1 + (1 << (16 + l)) / d; 170 *quant = (short)(m - (1 << 16)); 171 *shift = l; 172 /* use multiplication and constant shift by 16 */ 173 *shift = 1 << (16 - *shift); 174 } else { 175 *quant = (1 << 16) / d; 176 *shift = 0; 177 /* use multiplication and constant shift by 16 */ 178 *shift = 1 << (16 - *shift); 179 } 180 } 181 182 void vp8cx_init_quantizer(VP8_COMP *cpi) { 183 int i; 184 int quant_val; 185 int Q; 186 187 int zbin_boost[16] = { 0, 0, 8, 10, 12, 14, 16, 20, 188 24, 28, 32, 36, 40, 44, 44, 44 }; 189 190 for (Q = 0; Q < QINDEX_RANGE; ++Q) { 191 /* dc values */ 192 quant_val = vp8_dc_quant(Q, cpi->common.y1dc_delta_q); 193 cpi->Y1quant_fast[Q][0] = (1 << 16) / quant_val; 194 invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + 0, 195 cpi->Y1quant_shift[Q] + 0, quant_val); 196 cpi->Y1zbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7; 197 cpi->Y1round[Q][0] = (qrounding_factors[Q] * quant_val) >> 7; 198 cpi->common.Y1dequant[Q][0] = quant_val; 199 cpi->zrun_zbin_boost_y1[Q][0] = (quant_val * zbin_boost[0]) >> 7; 200 201 quant_val = vp8_dc2quant(Q, cpi->common.y2dc_delta_q); 202 cpi->Y2quant_fast[Q][0] = (1 << 16) / quant_val; 203 invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + 0, 204 cpi->Y2quant_shift[Q] + 0, quant_val); 205 cpi->Y2zbin[Q][0] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7; 206 cpi->Y2round[Q][0] = (qrounding_factors_y2[Q] * quant_val) >> 7; 207 cpi->common.Y2dequant[Q][0] = quant_val; 208 cpi->zrun_zbin_boost_y2[Q][0] = (quant_val * zbin_boost[0]) >> 7; 209 210 quant_val = vp8_dc_uv_quant(Q, cpi->common.uvdc_delta_q); 211 cpi->UVquant_fast[Q][0] = (1 << 16) / quant_val; 212 invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + 0, 213 cpi->UVquant_shift[Q] + 0, quant_val); 214 cpi->UVzbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7; 215 cpi->UVround[Q][0] = (qrounding_factors[Q] * quant_val) >> 7; 216 cpi->common.UVdequant[Q][0] = quant_val; 217 cpi->zrun_zbin_boost_uv[Q][0] = (quant_val * zbin_boost[0]) >> 7; 218 219 /* all the ac values = ; */ 220 quant_val = vp8_ac_yquant(Q); 221 cpi->Y1quant_fast[Q][1] = (1 << 16) / quant_val; 222 invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + 1, 223 cpi->Y1quant_shift[Q] + 1, quant_val); 224 cpi->Y1zbin[Q][1] = ((qzbin_factors[Q] * quant_val) + 64) >> 7; 225 cpi->Y1round[Q][1] = (qrounding_factors[Q] * quant_val) >> 7; 226 cpi->common.Y1dequant[Q][1] = quant_val; 227 cpi->zrun_zbin_boost_y1[Q][1] = (quant_val * zbin_boost[1]) >> 7; 228 229 quant_val = vp8_ac2quant(Q, cpi->common.y2ac_delta_q); 230 cpi->Y2quant_fast[Q][1] = (1 << 16) / quant_val; 231 invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + 1, 232 cpi->Y2quant_shift[Q] + 1, quant_val); 233 cpi->Y2zbin[Q][1] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7; 234 cpi->Y2round[Q][1] = (qrounding_factors_y2[Q] * quant_val) >> 7; 235 cpi->common.Y2dequant[Q][1] = quant_val; 236 cpi->zrun_zbin_boost_y2[Q][1] = (quant_val * zbin_boost[1]) >> 7; 237 238 quant_val = vp8_ac_uv_quant(Q, cpi->common.uvac_delta_q); 239 cpi->UVquant_fast[Q][1] = (1 << 16) / quant_val; 240 invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + 1, 241 cpi->UVquant_shift[Q] + 1, quant_val); 242 cpi->UVzbin[Q][1] = ((qzbin_factors[Q] * quant_val) + 64) >> 7; 243 cpi->UVround[Q][1] = (qrounding_factors[Q] * quant_val) >> 7; 244 cpi->common.UVdequant[Q][1] = quant_val; 245 cpi->zrun_zbin_boost_uv[Q][1] = (quant_val * zbin_boost[1]) >> 7; 246 247 for (i = 2; i < 16; ++i) { 248 cpi->Y1quant_fast[Q][i] = cpi->Y1quant_fast[Q][1]; 249 cpi->Y1quant[Q][i] = cpi->Y1quant[Q][1]; 250 cpi->Y1quant_shift[Q][i] = cpi->Y1quant_shift[Q][1]; 251 cpi->Y1zbin[Q][i] = cpi->Y1zbin[Q][1]; 252 cpi->Y1round[Q][i] = cpi->Y1round[Q][1]; 253 cpi->zrun_zbin_boost_y1[Q][i] = 254 (cpi->common.Y1dequant[Q][1] * zbin_boost[i]) >> 7; 255 256 cpi->Y2quant_fast[Q][i] = cpi->Y2quant_fast[Q][1]; 257 cpi->Y2quant[Q][i] = cpi->Y2quant[Q][1]; 258 cpi->Y2quant_shift[Q][i] = cpi->Y2quant_shift[Q][1]; 259 cpi->Y2zbin[Q][i] = cpi->Y2zbin[Q][1]; 260 cpi->Y2round[Q][i] = cpi->Y2round[Q][1]; 261 cpi->zrun_zbin_boost_y2[Q][i] = 262 (cpi->common.Y2dequant[Q][1] * zbin_boost[i]) >> 7; 263 264 cpi->UVquant_fast[Q][i] = cpi->UVquant_fast[Q][1]; 265 cpi->UVquant[Q][i] = cpi->UVquant[Q][1]; 266 cpi->UVquant_shift[Q][i] = cpi->UVquant_shift[Q][1]; 267 cpi->UVzbin[Q][i] = cpi->UVzbin[Q][1]; 268 cpi->UVround[Q][i] = cpi->UVround[Q][1]; 269 cpi->zrun_zbin_boost_uv[Q][i] = 270 (cpi->common.UVdequant[Q][1] * zbin_boost[i]) >> 7; 271 } 272 } 273 } 274 275 #define ZBIN_EXTRA_Y \ 276 ((cpi->common.Y1dequant[QIndex][1] * \ 277 (x->zbin_over_quant + x->zbin_mode_boost + x->act_zbin_adj)) >> \ 278 7) 279 280 #define ZBIN_EXTRA_UV \ 281 ((cpi->common.UVdequant[QIndex][1] * \ 282 (x->zbin_over_quant + x->zbin_mode_boost + x->act_zbin_adj)) >> \ 283 7) 284 285 #define ZBIN_EXTRA_Y2 \ 286 ((cpi->common.Y2dequant[QIndex][1] * \ 287 ((x->zbin_over_quant / 2) + x->zbin_mode_boost + x->act_zbin_adj)) >> \ 288 7) 289 290 void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x, int ok_to_skip) { 291 int i; 292 int QIndex; 293 MACROBLOCKD *xd = &x->e_mbd; 294 int zbin_extra; 295 296 /* Select the baseline MB Q index. */ 297 if (xd->segmentation_enabled) { 298 /* Abs Value */ 299 if (xd->mb_segement_abs_delta == SEGMENT_ABSDATA) { 300 QIndex = xd->segment_feature_data[MB_LVL_ALT_Q] 301 [xd->mode_info_context->mbmi.segment_id]; 302 /* Delta Value */ 303 } else { 304 QIndex = cpi->common.base_qindex + 305 xd->segment_feature_data[MB_LVL_ALT_Q] 306 [xd->mode_info_context->mbmi.segment_id]; 307 /* Clamp to valid range */ 308 QIndex = (QIndex >= 0) ? ((QIndex <= MAXQ) ? QIndex : MAXQ) : 0; 309 } 310 } else { 311 QIndex = cpi->common.base_qindex; 312 } 313 314 /* This initialization should be called at least once. Use ok_to_skip to 315 * decide if it is ok to skip. 316 * Before encoding a frame, this function is always called with ok_to_skip 317 * =0, which means no skiping of calculations. The "last" values are 318 * initialized at that time. 319 */ 320 if (!ok_to_skip || QIndex != x->q_index) { 321 xd->dequant_y1_dc[0] = 1; 322 xd->dequant_y1[0] = cpi->common.Y1dequant[QIndex][0]; 323 xd->dequant_y2[0] = cpi->common.Y2dequant[QIndex][0]; 324 xd->dequant_uv[0] = cpi->common.UVdequant[QIndex][0]; 325 326 for (i = 1; i < 16; ++i) { 327 xd->dequant_y1_dc[i] = xd->dequant_y1[i] = 328 cpi->common.Y1dequant[QIndex][1]; 329 xd->dequant_y2[i] = cpi->common.Y2dequant[QIndex][1]; 330 xd->dequant_uv[i] = cpi->common.UVdequant[QIndex][1]; 331 } 332 #if 1 333 /*TODO: Remove dequant from BLOCKD. This is a temporary solution until 334 * the quantizer code uses a passed in pointer to the dequant constants. 335 * This will also require modifications to the x86 and neon assembly. 336 * */ 337 for (i = 0; i < 16; ++i) x->e_mbd.block[i].dequant = xd->dequant_y1; 338 for (i = 16; i < 24; ++i) x->e_mbd.block[i].dequant = xd->dequant_uv; 339 x->e_mbd.block[24].dequant = xd->dequant_y2; 340 #endif 341 342 /* Y */ 343 zbin_extra = ZBIN_EXTRA_Y; 344 345 for (i = 0; i < 16; ++i) { 346 x->block[i].quant = cpi->Y1quant[QIndex]; 347 x->block[i].quant_fast = cpi->Y1quant_fast[QIndex]; 348 x->block[i].quant_shift = cpi->Y1quant_shift[QIndex]; 349 x->block[i].zbin = cpi->Y1zbin[QIndex]; 350 x->block[i].round = cpi->Y1round[QIndex]; 351 x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_y1[QIndex]; 352 x->block[i].zbin_extra = (short)zbin_extra; 353 } 354 355 /* UV */ 356 zbin_extra = ZBIN_EXTRA_UV; 357 358 for (i = 16; i < 24; ++i) { 359 x->block[i].quant = cpi->UVquant[QIndex]; 360 x->block[i].quant_fast = cpi->UVquant_fast[QIndex]; 361 x->block[i].quant_shift = cpi->UVquant_shift[QIndex]; 362 x->block[i].zbin = cpi->UVzbin[QIndex]; 363 x->block[i].round = cpi->UVround[QIndex]; 364 x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_uv[QIndex]; 365 x->block[i].zbin_extra = (short)zbin_extra; 366 } 367 368 /* Y2 */ 369 zbin_extra = ZBIN_EXTRA_Y2; 370 371 x->block[24].quant_fast = cpi->Y2quant_fast[QIndex]; 372 x->block[24].quant = cpi->Y2quant[QIndex]; 373 x->block[24].quant_shift = cpi->Y2quant_shift[QIndex]; 374 x->block[24].zbin = cpi->Y2zbin[QIndex]; 375 x->block[24].round = cpi->Y2round[QIndex]; 376 x->block[24].zrun_zbin_boost = cpi->zrun_zbin_boost_y2[QIndex]; 377 x->block[24].zbin_extra = (short)zbin_extra; 378 379 /* save this macroblock QIndex for vp8_update_zbin_extra() */ 380 x->q_index = QIndex; 381 382 x->last_zbin_over_quant = x->zbin_over_quant; 383 x->last_zbin_mode_boost = x->zbin_mode_boost; 384 x->last_act_zbin_adj = x->act_zbin_adj; 385 386 } else if (x->last_zbin_over_quant != x->zbin_over_quant || 387 x->last_zbin_mode_boost != x->zbin_mode_boost || 388 x->last_act_zbin_adj != x->act_zbin_adj) { 389 /* Y */ 390 zbin_extra = ZBIN_EXTRA_Y; 391 392 for (i = 0; i < 16; ++i) x->block[i].zbin_extra = (short)zbin_extra; 393 394 /* UV */ 395 zbin_extra = ZBIN_EXTRA_UV; 396 397 for (i = 16; i < 24; ++i) x->block[i].zbin_extra = (short)zbin_extra; 398 399 /* Y2 */ 400 zbin_extra = ZBIN_EXTRA_Y2; 401 x->block[24].zbin_extra = (short)zbin_extra; 402 403 x->last_zbin_over_quant = x->zbin_over_quant; 404 x->last_zbin_mode_boost = x->zbin_mode_boost; 405 x->last_act_zbin_adj = x->act_zbin_adj; 406 } 407 } 408 409 void vp8_update_zbin_extra(VP8_COMP *cpi, MACROBLOCK *x) { 410 int i; 411 int QIndex = x->q_index; 412 int zbin_extra; 413 414 /* Y */ 415 zbin_extra = ZBIN_EXTRA_Y; 416 417 for (i = 0; i < 16; ++i) x->block[i].zbin_extra = (short)zbin_extra; 418 419 /* UV */ 420 zbin_extra = ZBIN_EXTRA_UV; 421 422 for (i = 16; i < 24; ++i) x->block[i].zbin_extra = (short)zbin_extra; 423 424 /* Y2 */ 425 zbin_extra = ZBIN_EXTRA_Y2; 426 x->block[24].zbin_extra = (short)zbin_extra; 427 } 428 #undef ZBIN_EXTRA_Y 429 #undef ZBIN_EXTRA_UV 430 #undef ZBIN_EXTRA_Y2 431 432 void vp8cx_frame_init_quantizer(VP8_COMP *cpi) { 433 /* Clear Zbin mode boost for default case */ 434 cpi->mb.zbin_mode_boost = 0; 435 436 /* MB level quantizer setup */ 437 vp8cx_mb_init_quantizer(cpi, &cpi->mb, 0); 438 } 439 440 void vp8_set_quantizer(struct VP8_COMP *cpi, int Q) { 441 VP8_COMMON *cm = &cpi->common; 442 MACROBLOCKD *mbd = &cpi->mb.e_mbd; 443 int update = 0; 444 int new_delta_q; 445 int new_uv_delta_q; 446 cm->base_qindex = Q; 447 448 /* if any of the delta_q values are changing update flag has to be set */ 449 /* currently only y2dc_delta_q may change */ 450 451 cm->y1dc_delta_q = 0; 452 cm->y2ac_delta_q = 0; 453 454 if (Q < 4) { 455 new_delta_q = 4 - Q; 456 } else { 457 new_delta_q = 0; 458 } 459 460 update |= cm->y2dc_delta_q != new_delta_q; 461 cm->y2dc_delta_q = new_delta_q; 462 463 new_uv_delta_q = 0; 464 // For screen content, lower the q value for UV channel. For now, select 465 // conservative delta; same delta for dc and ac, and decrease it with lower 466 // Q, and set to 0 below some threshold. May want to condition this in 467 // future on the variance/energy in UV channel. 468 if (cpi->oxcf.screen_content_mode && Q > 40) { 469 new_uv_delta_q = -(int)(0.15 * Q); 470 // Check range: magnitude of delta is 4 bits. 471 if (new_uv_delta_q < -15) { 472 new_uv_delta_q = -15; 473 } 474 } 475 update |= cm->uvdc_delta_q != new_uv_delta_q; 476 cm->uvdc_delta_q = new_uv_delta_q; 477 cm->uvac_delta_q = new_uv_delta_q; 478 479 /* Set Segment specific quatizers */ 480 mbd->segment_feature_data[MB_LVL_ALT_Q][0] = 481 cpi->segment_feature_data[MB_LVL_ALT_Q][0]; 482 mbd->segment_feature_data[MB_LVL_ALT_Q][1] = 483 cpi->segment_feature_data[MB_LVL_ALT_Q][1]; 484 mbd->segment_feature_data[MB_LVL_ALT_Q][2] = 485 cpi->segment_feature_data[MB_LVL_ALT_Q][2]; 486 mbd->segment_feature_data[MB_LVL_ALT_Q][3] = 487 cpi->segment_feature_data[MB_LVL_ALT_Q][3]; 488 489 /* quantizer has to be reinitialized for any delta_q changes */ 490 if (update) vp8cx_init_quantizer(cpi); 491 } 492