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 "quantize.h" 16 #include "vp8/common/entropy.h" 17 18 #define EXACT_QUANT 19 20 #ifdef EXACT_FASTQUANT 21 void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d) 22 { 23 int i, rc, eob; 24 int zbin; 25 int x, y, z, sz; 26 short *coeff_ptr = b->coeff; 27 short *zbin_ptr = b->zbin; 28 short *round_ptr = b->round; 29 short *quant_ptr = b->quant_fast; 30 short *quant_shift_ptr = b->quant_shift; 31 short *qcoeff_ptr = d->qcoeff; 32 short *dqcoeff_ptr = d->dqcoeff; 33 short *dequant_ptr = d->dequant; 34 35 vpx_memset(qcoeff_ptr, 0, 32); 36 vpx_memset(dqcoeff_ptr, 0, 32); 37 38 eob = -1; 39 40 for (i = 0; i < 16; i++) 41 { 42 rc = vp8_default_zig_zag1d[i]; 43 z = coeff_ptr[rc]; 44 zbin = zbin_ptr[rc] ; 45 46 sz = (z >> 31); // sign of z 47 x = (z ^ sz) - sz; // x = abs(z) 48 49 if (x >= zbin) 50 { 51 x += round_ptr[rc]; 52 y = (((x * quant_ptr[rc]) >> 16) + x) 53 >> quant_shift_ptr[rc]; // quantize (x) 54 x = (y ^ sz) - sz; // get the sign back 55 qcoeff_ptr[rc] = x; // write to destination 56 dqcoeff_ptr[rc] = x * dequant_ptr[rc]; // dequantized value 57 58 if (y) 59 { 60 eob = i; // last nonzero coeffs 61 } 62 } 63 } 64 d->eob = eob + 1; 65 } 66 67 #else 68 69 void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d) 70 { 71 int i, rc, eob; 72 int x, y, z, sz; 73 short *coeff_ptr = b->coeff; 74 short *round_ptr = b->round; 75 short *quant_ptr = b->quant_fast; 76 short *qcoeff_ptr = d->qcoeff; 77 short *dqcoeff_ptr = d->dqcoeff; 78 short *dequant_ptr = d->dequant; 79 80 eob = -1; 81 for (i = 0; i < 16; i++) 82 { 83 rc = vp8_default_zig_zag1d[i]; 84 z = coeff_ptr[rc]; 85 86 sz = (z >> 31); // sign of z 87 x = (z ^ sz) - sz; // x = abs(z) 88 89 y = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; // quantize (x) 90 x = (y ^ sz) - sz; // get the sign back 91 qcoeff_ptr[rc] = x; // write to destination 92 dqcoeff_ptr[rc] = x * dequant_ptr[rc]; // dequantized value 93 94 if (y) 95 { 96 eob = i; // last nonzero coeffs 97 } 98 } 99 d->eob = eob + 1; 100 } 101 102 #endif 103 104 #ifdef EXACT_QUANT 105 void vp8_regular_quantize_b(BLOCK *b, BLOCKD *d) 106 { 107 int i, rc, eob; 108 int zbin; 109 int x, y, z, sz; 110 short *zbin_boost_ptr = b->zrun_zbin_boost; 111 short *coeff_ptr = b->coeff; 112 short *zbin_ptr = b->zbin; 113 short *round_ptr = b->round; 114 short *quant_ptr = b->quant; 115 short *quant_shift_ptr = b->quant_shift; 116 short *qcoeff_ptr = d->qcoeff; 117 short *dqcoeff_ptr = d->dqcoeff; 118 short *dequant_ptr = d->dequant; 119 short zbin_oq_value = b->zbin_extra; 120 121 vpx_memset(qcoeff_ptr, 0, 32); 122 vpx_memset(dqcoeff_ptr, 0, 32); 123 124 eob = -1; 125 126 for (i = 0; i < 16; i++) 127 { 128 rc = vp8_default_zig_zag1d[i]; 129 z = coeff_ptr[rc]; 130 131 zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value; 132 133 zbin_boost_ptr ++; 134 sz = (z >> 31); // sign of z 135 x = (z ^ sz) - sz; // x = abs(z) 136 137 if (x >= zbin) 138 { 139 x += round_ptr[rc]; 140 y = (((x * quant_ptr[rc]) >> 16) + x) 141 >> quant_shift_ptr[rc]; // quantize (x) 142 x = (y ^ sz) - sz; // get the sign back 143 qcoeff_ptr[rc] = x; // write to destination 144 dqcoeff_ptr[rc] = x * dequant_ptr[rc]; // dequantized value 145 146 if (y) 147 { 148 eob = i; // last nonzero coeffs 149 zbin_boost_ptr = b->zrun_zbin_boost; // reset zero runlength 150 } 151 } 152 } 153 154 d->eob = eob + 1; 155 } 156 157 /* Perform regular quantization, with unbiased rounding and no zero bin. */ 158 void vp8_strict_quantize_b(BLOCK *b, BLOCKD *d) 159 { 160 int i; 161 int rc; 162 int eob; 163 int x; 164 int y; 165 int z; 166 int sz; 167 short *coeff_ptr; 168 short *quant_ptr; 169 short *quant_shift_ptr; 170 short *qcoeff_ptr; 171 short *dqcoeff_ptr; 172 short *dequant_ptr; 173 174 coeff_ptr = b->coeff; 175 quant_ptr = b->quant; 176 quant_shift_ptr = b->quant_shift; 177 qcoeff_ptr = d->qcoeff; 178 dqcoeff_ptr = d->dqcoeff; 179 dequant_ptr = d->dequant; 180 eob = - 1; 181 vpx_memset(qcoeff_ptr, 0, 32); 182 vpx_memset(dqcoeff_ptr, 0, 32); 183 for (i = 0; i < 16; i++) 184 { 185 int dq; 186 int round; 187 188 /*TODO: These arrays should be stored in zig-zag order.*/ 189 rc = vp8_default_zig_zag1d[i]; 190 z = coeff_ptr[rc]; 191 dq = dequant_ptr[rc]; 192 round = dq >> 1; 193 /* Sign of z. */ 194 sz = -(z < 0); 195 x = (z + sz) ^ sz; 196 x += round; 197 if (x >= dq) 198 { 199 /* Quantize x. */ 200 y = (((x * quant_ptr[rc]) >> 16) + x) >> quant_shift_ptr[rc]; 201 /* Put the sign back. */ 202 x = (y + sz) ^ sz; 203 /* Save the coefficient and its dequantized value. */ 204 qcoeff_ptr[rc] = x; 205 dqcoeff_ptr[rc] = x * dq; 206 /* Remember the last non-zero coefficient. */ 207 if (y) 208 eob = i; 209 } 210 } 211 212 d->eob = eob + 1; 213 } 214 215 #else 216 217 void vp8_regular_quantize_b(BLOCK *b, BLOCKD *d) 218 { 219 int i, rc, eob; 220 int zbin; 221 int x, y, z, sz; 222 short *zbin_boost_ptr = b->zrun_zbin_boost; 223 short *coeff_ptr = b->coeff; 224 short *zbin_ptr = b->zbin; 225 short *round_ptr = b->round; 226 short *quant_ptr = b->quant; 227 short *qcoeff_ptr = d->qcoeff; 228 short *dqcoeff_ptr = d->dqcoeff; 229 short *dequant_ptr = d->dequant; 230 short zbin_oq_value = b->zbin_extra; 231 232 vpx_memset(qcoeff_ptr, 0, 32); 233 vpx_memset(dqcoeff_ptr, 0, 32); 234 235 eob = -1; 236 237 for (i = 0; i < 16; i++) 238 { 239 rc = vp8_default_zig_zag1d[i]; 240 z = coeff_ptr[rc]; 241 242 //if ( i == 0 ) 243 // zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value/2; 244 //else 245 zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value; 246 247 zbin_boost_ptr ++; 248 sz = (z >> 31); // sign of z 249 x = (z ^ sz) - sz; // x = abs(z) 250 251 if (x >= zbin) 252 { 253 y = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; // quantize (x) 254 x = (y ^ sz) - sz; // get the sign back 255 qcoeff_ptr[rc] = x; // write to destination 256 dqcoeff_ptr[rc] = x * dequant_ptr[rc]; // dequantized value 257 258 if (y) 259 { 260 eob = i; // last nonzero coeffs 261 zbin_boost_ptr = &b->zrun_zbin_boost[0]; // reset zero runlength 262 } 263 } 264 } 265 266 d->eob = eob + 1; 267 } 268 269 #endif 270 271 void vp8_quantize_mby(MACROBLOCK *x) 272 { 273 int i; 274 int has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED 275 && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV); 276 277 for (i = 0; i < 16; i++) 278 x->quantize_b(&x->block[i], &x->e_mbd.block[i]); 279 280 if(has_2nd_order) 281 x->quantize_b(&x->block[24], &x->e_mbd.block[24]); 282 } 283 284 void vp8_quantize_mb(MACROBLOCK *x) 285 { 286 int i; 287 int has_2nd_order=(x->e_mbd.mode_info_context->mbmi.mode != B_PRED 288 && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV); 289 290 for (i = 0; i < 24+has_2nd_order; i++) 291 x->quantize_b(&x->block[i], &x->e_mbd.block[i]); 292 } 293 294 295 void vp8_quantize_mbuv(MACROBLOCK *x) 296 { 297 int i; 298 299 for (i = 16; i < 24; i++) 300 x->quantize_b(&x->block[i], &x->e_mbd.block[i]); 301 } 302