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; 27 short *zbin_ptr = b->zbin; 28 short *round_ptr = b->round; 29 short *quant_ptr = b->quant; 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 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; 73 short *coeff_ptr = b->coeff; 74 short *zbin_ptr = b->zbin; 75 short *round_ptr = b->round; 76 short *quant_ptr = b->quant; 77 short *quant_shift_ptr = b->quant_shift; 78 short *qcoeff_ptr = d->qcoeff; 79 short *dqcoeff_ptr = d->dqcoeff; 80 short *dequant_ptr = d->dequant; 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 122 /* Perform regular quantization, with unbiased rounding and no zero bin. */ 123 void vp8_strict_quantize_b(BLOCK *b, BLOCKD *d) 124 { 125 int i; 126 int rc; 127 int eob; 128 int x; 129 int y; 130 int z; 131 int sz; 132 short *coeff_ptr; 133 short *quant_ptr; 134 short *quant_shift_ptr; 135 short *qcoeff_ptr; 136 short *dqcoeff_ptr; 137 short *dequant_ptr; 138 139 coeff_ptr = b->coeff; 140 quant_ptr = b->quant; 141 quant_shift_ptr = b->quant_shift; 142 qcoeff_ptr = d->qcoeff; 143 dqcoeff_ptr = d->dqcoeff; 144 dequant_ptr = d->dequant; 145 eob = - 1; 146 vpx_memset(qcoeff_ptr, 0, 32); 147 vpx_memset(dqcoeff_ptr, 0, 32); 148 for (i = 0; i < 16; i++) 149 { 150 int dq; 151 int round; 152 153 /*TODO: These arrays should be stored in zig-zag order.*/ 154 rc = vp8_default_zig_zag1d[i]; 155 z = coeff_ptr[rc]; 156 dq = dequant_ptr[rc]; 157 round = dq >> 1; 158 /* Sign of z. */ 159 sz = -(z < 0); 160 x = (z + sz) ^ sz; 161 x += round; 162 if (x >= dq) 163 { 164 /* Quantize x. */ 165 y = (((x * quant_ptr[rc]) >> 16) + x) >> quant_shift_ptr[rc]; 166 /* Put the sign back. */ 167 x = (y + sz) ^ sz; 168 /* Save the coefficient and its dequantized value. */ 169 qcoeff_ptr[rc] = x; 170 dqcoeff_ptr[rc] = x * dq; 171 /* Remember the last non-zero coefficient. */ 172 if (y) 173 eob = i; 174 } 175 } 176 177 d->eob = eob + 1; 178 } 179 180 #else 181 void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d) 182 { 183 int i, rc, eob; 184 int zbin; 185 int x, y, z, sz; 186 short *coeff_ptr = b->coeff; 187 short *round_ptr = b->round; 188 short *quant_ptr = b->quant; 189 short *qcoeff_ptr = d->qcoeff; 190 short *dqcoeff_ptr = d->dqcoeff; 191 short *dequant_ptr = d->dequant; 192 193 eob = -1; 194 for (i = 0; i < 16; i++) 195 { 196 rc = vp8_default_zig_zag1d[i]; 197 z = coeff_ptr[rc]; 198 199 sz = (z >> 31); // sign of z 200 x = (z ^ sz) - sz; // x = abs(z) 201 202 y = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; // quantize (x) 203 x = (y ^ sz) - sz; // get the sign back 204 qcoeff_ptr[rc] = x; // write to destination 205 dqcoeff_ptr[rc] = x * dequant_ptr[rc]; // dequantized value 206 207 if (y) 208 { 209 eob = i; // last nonzero coeffs 210 } 211 } 212 d->eob = eob + 1; 213 } 214 215 void vp8_regular_quantize_b(BLOCK *b, BLOCKD *d) 216 { 217 int i, rc, eob; 218 int zbin; 219 int x, y, z, sz; 220 short *zbin_boost_ptr = b->zrun_zbin_boost; 221 short *coeff_ptr = b->coeff; 222 short *zbin_ptr = b->zbin; 223 short *round_ptr = b->round; 224 short *quant_ptr = b->quant; 225 short *qcoeff_ptr = d->qcoeff; 226 short *dqcoeff_ptr = d->dqcoeff; 227 short *dequant_ptr = d->dequant; 228 short zbin_oq_value = b->zbin_extra; 229 230 vpx_memset(qcoeff_ptr, 0, 32); 231 vpx_memset(dqcoeff_ptr, 0, 32); 232 233 eob = -1; 234 235 for (i = 0; i < 16; i++) 236 { 237 rc = vp8_default_zig_zag1d[i]; 238 z = coeff_ptr[rc]; 239 240 //if ( i == 0 ) 241 // zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value/2; 242 //else 243 zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value; 244 245 zbin_boost_ptr ++; 246 sz = (z >> 31); // sign of z 247 x = (z ^ sz) - sz; // x = abs(z) 248 249 if (x >= zbin) 250 { 251 y = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; // quantize (x) 252 x = (y ^ sz) - sz; // get the sign back 253 qcoeff_ptr[rc] = x; // write to destination 254 dqcoeff_ptr[rc] = x * dequant_ptr[rc]; // dequantized value 255 256 if (y) 257 { 258 eob = i; // last nonzero coeffs 259 zbin_boost_ptr = &b->zrun_zbin_boost[0]; // reset zero runlength 260 } 261 } 262 } 263 264 d->eob = eob + 1; 265 } 266 267 #endif 268 269 void vp8_quantize_mby(MACROBLOCK *x) 270 { 271 int i; 272 int has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED 273 && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV); 274 275 for (i = 0; i < 16; i++) 276 x->quantize_b(&x->block[i], &x->e_mbd.block[i]); 277 278 if(has_2nd_order) 279 x->quantize_b(&x->block[24], &x->e_mbd.block[24]); 280 } 281 282 void vp8_quantize_mb(MACROBLOCK *x) 283 { 284 int i; 285 int has_2nd_order=(x->e_mbd.mode_info_context->mbmi.mode != B_PRED 286 && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV); 287 288 for (i = 0; i < 24+has_2nd_order; i++) 289 x->quantize_b(&x->block[i], &x->e_mbd.block[i]); 290 } 291 292 293 void vp8_quantize_mbuv(MACROBLOCK *x) 294 { 295 int i; 296 297 for (i = 16; i < 24; i++) 298 x->quantize_b(&x->block[i], &x->e_mbd.block[i]); 299 } 300