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