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