OLD | NEW |
(Empty) | |
| 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 "vp9_rtcd.h" |
| 13 #include "vp9/decoder/vp9_dequantize.h" |
| 14 #include "vpx_mem/vpx_mem.h" |
| 15 #include "vp9/decoder/vp9_onyxd_int.h" |
| 16 |
| 17 static void add_residual(const int16_t *diff, const uint8_t *pred, int pitch, |
| 18 uint8_t *dest, int stride, int width, int height) { |
| 19 int r, c; |
| 20 |
| 21 for (r = 0; r < height; r++) { |
| 22 for (c = 0; c < width; c++) { |
| 23 int a = diff[c] + pred[c]; |
| 24 |
| 25 if (a < 0) |
| 26 a = 0; |
| 27 else if (a > 255) |
| 28 a = 255; |
| 29 |
| 30 dest[c] = (uint8_t) a; |
| 31 } |
| 32 |
| 33 dest += stride; |
| 34 diff += width; |
| 35 pred += pitch; |
| 36 } |
| 37 } |
| 38 |
| 39 static void add_constant_residual(const int16_t diff, const uint8_t *pred, |
| 40 int pitch, uint8_t *dest, int stride, |
| 41 int width, int height) { |
| 42 int r, c; |
| 43 |
| 44 for (r = 0; r < height; r++) { |
| 45 for (c = 0; c < width; c++) { |
| 46 int a = diff + pred[c]; |
| 47 |
| 48 if (a < 0) |
| 49 a = 0; |
| 50 else if (a > 255) |
| 51 a = 255; |
| 52 |
| 53 dest[c] = (uint8_t) a; |
| 54 } |
| 55 |
| 56 dest += stride; |
| 57 pred += pitch; |
| 58 } |
| 59 } |
| 60 |
| 61 void vp9_dequantize_b_c(BLOCKD *d) { |
| 62 |
| 63 int i; |
| 64 int16_t *DQ = d->dqcoeff; |
| 65 const int16_t *Q = d->qcoeff; |
| 66 const int16_t *DQC = d->dequant; |
| 67 |
| 68 for (i = 0; i < 16; i++) { |
| 69 DQ[i] = Q[i] * DQC[i]; |
| 70 } |
| 71 } |
| 72 |
| 73 |
| 74 void vp9_ht_dequant_idct_add_c(TX_TYPE tx_type, int16_t *input, |
| 75 const int16_t *dq, |
| 76 uint8_t *pred, uint8_t *dest, |
| 77 int pitch, int stride) { |
| 78 int16_t output[16]; |
| 79 int16_t *diff_ptr = output; |
| 80 int i; |
| 81 |
| 82 for (i = 0; i < 16; i++) { |
| 83 input[i] = dq[i] * input[i]; |
| 84 } |
| 85 |
| 86 vp9_ihtllm(input, output, 4 << 1, tx_type, 4); |
| 87 |
| 88 vpx_memset(input, 0, 32); |
| 89 |
| 90 add_residual(diff_ptr, pred, pitch, dest, stride, 4, 4); |
| 91 } |
| 92 |
| 93 void vp9_ht_dequant_idct_add_8x8_c(TX_TYPE tx_type, int16_t *input, |
| 94 const int16_t *dq, |
| 95 uint8_t *pred, uint8_t *dest, |
| 96 int pitch, int stride) { |
| 97 int16_t output[64]; |
| 98 int16_t *diff_ptr = output; |
| 99 int i; |
| 100 |
| 101 input[0] = dq[0] * input[0]; |
| 102 for (i = 1; i < 64; i++) { |
| 103 input[i] = dq[1] * input[i]; |
| 104 } |
| 105 |
| 106 vp9_ihtllm(input, output, 16, tx_type, 8); |
| 107 |
| 108 vpx_memset(input, 0, 128); |
| 109 |
| 110 add_residual(diff_ptr, pred, pitch, dest, stride, 8, 8); |
| 111 } |
| 112 |
| 113 void vp9_dequant_idct_add_c(int16_t *input, const int16_t *dq, uint8_t *pred, |
| 114 uint8_t *dest, int pitch, int stride) { |
| 115 int16_t output[16]; |
| 116 int16_t *diff_ptr = output; |
| 117 int i; |
| 118 |
| 119 for (i = 0; i < 16; i++) { |
| 120 input[i] = dq[i] * input[i]; |
| 121 } |
| 122 |
| 123 /* the idct halves ( >> 1) the pitch */ |
| 124 vp9_short_idct4x4llm_c(input, output, 4 << 1); |
| 125 |
| 126 vpx_memset(input, 0, 32); |
| 127 |
| 128 add_residual(diff_ptr, pred, pitch, dest, stride, 4, 4); |
| 129 } |
| 130 |
| 131 void vp9_dequant_dc_idct_add_c(int16_t *input, const int16_t *dq, uint8_t *pred, |
| 132 uint8_t *dest, int pitch, int stride, int Dc) { |
| 133 int i; |
| 134 int16_t output[16]; |
| 135 int16_t *diff_ptr = output; |
| 136 |
| 137 input[0] = (int16_t)Dc; |
| 138 |
| 139 for (i = 1; i < 16; i++) { |
| 140 input[i] = dq[i] * input[i]; |
| 141 } |
| 142 |
| 143 /* the idct halves ( >> 1) the pitch */ |
| 144 vp9_short_idct4x4llm_c(input, output, 4 << 1); |
| 145 |
| 146 vpx_memset(input, 0, 32); |
| 147 |
| 148 add_residual(diff_ptr, pred, pitch, dest, stride, 4, 4); |
| 149 } |
| 150 |
| 151 #if CONFIG_LOSSLESS |
| 152 void vp9_dequant_idct_add_lossless_c(int16_t *input, const int16_t *dq, |
| 153 uint8_t *pred, uint8_t *dest, |
| 154 int pitch, int stride) { |
| 155 int16_t output[16]; |
| 156 int16_t *diff_ptr = output; |
| 157 int i; |
| 158 |
| 159 for (i = 0; i < 16; i++) { |
| 160 input[i] = dq[i] * input[i]; |
| 161 } |
| 162 |
| 163 vp9_short_inv_walsh4x4_x8_c(input, output, 4 << 1); |
| 164 |
| 165 vpx_memset(input, 0, 32); |
| 166 |
| 167 add_residual(diff_ptr, pred, pitch, dest, stride, 4, 4); |
| 168 } |
| 169 |
| 170 void vp9_dequant_dc_idct_add_lossless_c(int16_t *input, const int16_t *dq, |
| 171 uint8_t *pred, |
| 172 uint8_t *dest, |
| 173 int pitch, int stride, int dc) { |
| 174 int i; |
| 175 int16_t output[16]; |
| 176 int16_t *diff_ptr = output; |
| 177 |
| 178 input[0] = (int16_t)dc; |
| 179 |
| 180 for (i = 1; i < 16; i++) { |
| 181 input[i] = dq[i] * input[i]; |
| 182 } |
| 183 |
| 184 vp9_short_inv_walsh4x4_x8_c(input, output, 4 << 1); |
| 185 vpx_memset(input, 0, 32); |
| 186 |
| 187 add_residual(diff_ptr, pred, pitch, dest, stride, 4, 4); |
| 188 } |
| 189 #endif |
| 190 |
| 191 void vp9_dequantize_b_2x2_c(BLOCKD *d) { |
| 192 int i; |
| 193 int16_t *DQ = d->dqcoeff; |
| 194 const int16_t *Q = d->qcoeff; |
| 195 const int16_t *DQC = d->dequant; |
| 196 |
| 197 for (i = 0; i < 16; i++) { |
| 198 DQ[i] = (int16_t)((Q[i] * DQC[i])); |
| 199 } |
| 200 } |
| 201 |
| 202 void vp9_dequant_idct_add_8x8_c(int16_t *input, const int16_t *dq, |
| 203 uint8_t *pred, uint8_t *dest, int pitch, |
| 204 int stride, int dc, uint16_t eobs) { |
| 205 int16_t output[64]; |
| 206 int16_t *diff_ptr = output; |
| 207 int i; |
| 208 |
| 209 /* If dc is 1, then input[0] is the reconstructed value, do not need |
| 210 * dequantization. Also, when dc is 1, dc is counted in eobs, namely eobs >=1. |
| 211 */ |
| 212 if (!dc) |
| 213 input[0] *= dq[0]; |
| 214 |
| 215 /* The calculation can be simplified if there are not many non-zero dct |
| 216 * coefficients. Use eobs to decide what to do. |
| 217 * TODO(yunqingwang): "eobs = 1" case is also handled in vp9_short_idct8x8_c. |
| 218 * Combine that with code here. |
| 219 */ |
| 220 if (eobs == 0) { |
| 221 /* All 0 DCT coefficient */ |
| 222 vp9_copy_mem8x8(pred, pitch, dest, stride); |
| 223 } else if (eobs == 1) { |
| 224 /* DC only DCT coefficient. */ |
| 225 int16_t out; |
| 226 |
| 227 /* Note: the idct1 will need to be modified accordingly whenever |
| 228 * vp9_short_idct8x8_c() is modified. */ |
| 229 out = (input[0] + 1 + (input[0] < 0)) >> 2; |
| 230 out = out << 3; |
| 231 out = (out + 32) >> 7; |
| 232 |
| 233 input[0] = 0; |
| 234 |
| 235 add_constant_residual(out, pred, pitch, dest, stride, 8, 8); |
| 236 } else if (eobs <= 10) { |
| 237 input[1] = input[1] * dq[1]; |
| 238 input[2] = input[2] * dq[1]; |
| 239 input[3] = input[3] * dq[1]; |
| 240 input[8] = input[8] * dq[1]; |
| 241 input[9] = input[9] * dq[1]; |
| 242 input[10] = input[10] * dq[1]; |
| 243 input[16] = input[16] * dq[1]; |
| 244 input[17] = input[17] * dq[1]; |
| 245 input[24] = input[24] * dq[1]; |
| 246 |
| 247 vp9_short_idct10_8x8_c(input, output, 16); |
| 248 |
| 249 input[0] = input[1] = input[2] = input[3] = 0; |
| 250 input[8] = input[9] = input[10] = 0; |
| 251 input[16] = input[17] = 0; |
| 252 input[24] = 0; |
| 253 |
| 254 add_residual(diff_ptr, pred, pitch, dest, stride, 8, 8); |
| 255 } else { |
| 256 // recover quantizer for 4 4x4 blocks |
| 257 for (i = 1; i < 64; i++) { |
| 258 input[i] = input[i] * dq[1]; |
| 259 } |
| 260 // the idct halves ( >> 1) the pitch |
| 261 vp9_short_idct8x8_c(input, output, 16); |
| 262 |
| 263 vpx_memset(input, 0, 128); |
| 264 |
| 265 add_residual(diff_ptr, pred, pitch, dest, stride, 8, 8); |
| 266 |
| 267 } |
| 268 } |
| 269 |
| 270 void vp9_ht_dequant_idct_add_16x16_c(TX_TYPE tx_type, int16_t *input, |
| 271 const int16_t *dq, uint8_t *pred, |
| 272 uint8_t *dest, int pitch, int stride) { |
| 273 int16_t output[256]; |
| 274 int16_t *diff_ptr = output; |
| 275 int i; |
| 276 |
| 277 input[0]= input[0] * dq[0]; |
| 278 |
| 279 // recover quantizer for 4 4x4 blocks |
| 280 for (i = 1; i < 256; i++) |
| 281 input[i] = input[i] * dq[1]; |
| 282 |
| 283 // inverse hybrid transform |
| 284 vp9_ihtllm(input, output, 32, tx_type, 16); |
| 285 |
| 286 // the idct halves ( >> 1) the pitch |
| 287 // vp9_short_idct16x16_c(input, output, 32); |
| 288 |
| 289 vpx_memset(input, 0, 512); |
| 290 |
| 291 add_residual(diff_ptr, pred, pitch, dest, stride, 16, 16); |
| 292 } |
| 293 |
| 294 void vp9_dequant_idct_add_16x16_c(int16_t *input, const int16_t *dq, |
| 295 uint8_t *pred, uint8_t *dest, int pitch, |
| 296 int stride, uint16_t eobs) { |
| 297 int16_t output[256]; |
| 298 int16_t *diff_ptr = output; |
| 299 int i; |
| 300 |
| 301 /* The calculation can be simplified if there are not many non-zero dct |
| 302 * coefficients. Use eobs to separate different cases. */ |
| 303 if (eobs == 0) { |
| 304 /* All 0 DCT coefficient */ |
| 305 vp9_copy_mem16x16(pred, pitch, dest, stride); |
| 306 } else if (eobs == 1) { |
| 307 /* DC only DCT coefficient. */ |
| 308 int16_t out; |
| 309 |
| 310 /* Note: the idct1 will need to be modified accordingly whenever |
| 311 * vp9_short_idct16x16_c() is modified. */ |
| 312 out = (input[0] * dq[0] + 2) >> 2; |
| 313 out = (out + 2) >> 2; |
| 314 out = (out + 4) >> 3; |
| 315 |
| 316 input[0] = 0; |
| 317 |
| 318 add_constant_residual(out, pred, pitch, dest, stride, 16, 16); |
| 319 } else if (eobs <= 10) { |
| 320 input[0]= input[0] * dq[0]; |
| 321 input[1] = input[1] * dq[1]; |
| 322 input[2] = input[2] * dq[1]; |
| 323 input[3] = input[3] * dq[1]; |
| 324 input[16] = input[16] * dq[1]; |
| 325 input[17] = input[17] * dq[1]; |
| 326 input[18] = input[18] * dq[1]; |
| 327 input[32] = input[32] * dq[1]; |
| 328 input[33] = input[33] * dq[1]; |
| 329 input[48] = input[48] * dq[1]; |
| 330 |
| 331 // the idct halves ( >> 1) the pitch |
| 332 vp9_short_idct10_16x16_c(input, output, 32); |
| 333 |
| 334 input[0] = input[1] = input[2] = input[3] = 0; |
| 335 input[16] = input[17] = input[18] = 0; |
| 336 input[32] = input[33] = 0; |
| 337 input[48] = 0; |
| 338 |
| 339 add_residual(diff_ptr, pred, pitch, dest, stride, 16, 16); |
| 340 } else { |
| 341 input[0]= input[0] * dq[0]; |
| 342 |
| 343 // recover quantizer for 4 4x4 blocks |
| 344 for (i = 1; i < 256; i++) |
| 345 input[i] = input[i] * dq[1]; |
| 346 |
| 347 // the idct halves ( >> 1) the pitch |
| 348 vp9_short_idct16x16_c(input, output, 32); |
| 349 |
| 350 vpx_memset(input, 0, 512); |
| 351 |
| 352 add_residual(diff_ptr, pred, pitch, dest, stride, 16, 16); |
| 353 } |
| 354 } |
OLD | NEW |