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/common/vp9_type_aliases.h" |
| 13 #include "vp9/common/vp9_blockd.h" |
| 14 #include "vp9/decoder/vp9_onyxd_int.h" |
| 15 #include "vpx_mem/vpx_mem.h" |
| 16 #include "vpx_ports/mem.h" |
| 17 #include "vp9/decoder/vp9_detokenize.h" |
| 18 |
| 19 #include "vp9/common/vp9_seg_common.h" |
| 20 |
| 21 #define EOB_CONTEXT_NODE 0 |
| 22 #define ZERO_CONTEXT_NODE 1 |
| 23 #define ONE_CONTEXT_NODE 2 |
| 24 #define LOW_VAL_CONTEXT_NODE 3 |
| 25 #define TWO_CONTEXT_NODE 4 |
| 26 #define THREE_CONTEXT_NODE 5 |
| 27 #define HIGH_LOW_CONTEXT_NODE 6 |
| 28 #define CAT_ONE_CONTEXT_NODE 7 |
| 29 #define CAT_THREEFOUR_CONTEXT_NODE 8 |
| 30 #define CAT_THREE_CONTEXT_NODE 9 |
| 31 #define CAT_FIVE_CONTEXT_NODE 10 |
| 32 |
| 33 #define CAT1_MIN_VAL 5 |
| 34 #define CAT2_MIN_VAL 7 |
| 35 #define CAT3_MIN_VAL 11 |
| 36 #define CAT4_MIN_VAL 19 |
| 37 #define CAT5_MIN_VAL 35 |
| 38 #define CAT6_MIN_VAL 67 |
| 39 #define CAT1_PROB0 159 |
| 40 #define CAT2_PROB0 145 |
| 41 #define CAT2_PROB1 165 |
| 42 |
| 43 #define CAT3_PROB0 140 |
| 44 #define CAT3_PROB1 148 |
| 45 #define CAT3_PROB2 173 |
| 46 |
| 47 #define CAT4_PROB0 135 |
| 48 #define CAT4_PROB1 140 |
| 49 #define CAT4_PROB2 155 |
| 50 #define CAT4_PROB3 176 |
| 51 |
| 52 #define CAT5_PROB0 130 |
| 53 #define CAT5_PROB1 134 |
| 54 #define CAT5_PROB2 141 |
| 55 #define CAT5_PROB3 157 |
| 56 #define CAT5_PROB4 180 |
| 57 |
| 58 static const unsigned char cat6_prob[14] = |
| 59 { 254, 254, 252, 249, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0 }; |
| 60 |
| 61 void vp9_reset_mb_tokens_context(MACROBLOCKD* const xd) { |
| 62 /* Clear entropy contexts */ |
| 63 if ((xd->mode_info_context->mbmi.mode != B_PRED && |
| 64 xd->mode_info_context->mbmi.mode != I8X8_PRED && |
| 65 xd->mode_info_context->mbmi.mode != SPLITMV) |
| 66 || xd->mode_info_context->mbmi.txfm_size == TX_16X16) { |
| 67 vpx_memset(xd->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)); |
| 68 vpx_memset(xd->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)); |
| 69 } else { |
| 70 vpx_memset(xd->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1); |
| 71 vpx_memset(xd->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1); |
| 72 xd->above_context->y2 = 1; |
| 73 xd->left_context->y2 = 1; |
| 74 } |
| 75 } |
| 76 |
| 77 DECLARE_ALIGNED(16, extern const unsigned char, vp9_norm[256]); |
| 78 |
| 79 static int get_signed(BOOL_DECODER *br, int value_to_sign) { |
| 80 const int split = (br->range + 1) >> 1; |
| 81 const VP9_BD_VALUE bigsplit = (VP9_BD_VALUE)split << (VP9_BD_VALUE_SIZE - 8); |
| 82 int v; |
| 83 |
| 84 if (br->count < 0) |
| 85 vp9_bool_decoder_fill(br); |
| 86 |
| 87 if (br->value < bigsplit) { |
| 88 br->range = split; |
| 89 v = value_to_sign; |
| 90 } else { |
| 91 br->range = br->range - split; |
| 92 br->value = br->value - bigsplit; |
| 93 v = -value_to_sign; |
| 94 } |
| 95 br->range += br->range; |
| 96 br->value += br->value; |
| 97 --br->count; |
| 98 |
| 99 return v; |
| 100 } |
| 101 |
| 102 #define INCREMENT_COUNT(token) \ |
| 103 do { \ |
| 104 coef_counts[coef_bands[c]][pt][token]++; \ |
| 105 pt = vp9_prev_token_class[token]; \ |
| 106 } while (0) |
| 107 |
| 108 #define WRITE_COEF_CONTINUE(val, token) \ |
| 109 { \ |
| 110 qcoeff_ptr[scan[c]] = (INT16) get_signed(br, val); \ |
| 111 INCREMENT_COUNT(token); \ |
| 112 c++; \ |
| 113 continue; \ |
| 114 } |
| 115 |
| 116 #define ADJUST_COEF(prob, bits_count) \ |
| 117 do { \ |
| 118 if (vp9_read(br, prob)) \ |
| 119 val += (UINT16)(1 << bits_count);\ |
| 120 } while (0); |
| 121 |
| 122 static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd, |
| 123 BOOL_DECODER* const br, |
| 124 ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l, |
| 125 PLANE_TYPE type, |
| 126 TX_TYPE tx_type, |
| 127 int seg_eob, INT16 *qcoeff_ptr, |
| 128 const int *const scan, TX_SIZE txfm_size, |
| 129 const int *coef_bands) { |
| 130 FRAME_CONTEXT *const fc = &dx->common.fc; |
| 131 int pt, c = (type == PLANE_TYPE_Y_NO_DC); |
| 132 vp9_prob (*coef_probs)[PREV_COEF_CONTEXTS][ENTROPY_NODES], *prob; |
| 133 unsigned int (*coef_counts)[PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS]; |
| 134 |
| 135 switch (txfm_size) { |
| 136 default: |
| 137 case TX_4X4: |
| 138 if (tx_type == DCT_DCT) { |
| 139 coef_probs = fc->coef_probs[type]; |
| 140 coef_counts = fc->coef_counts[type]; |
| 141 } else { |
| 142 coef_probs = fc->hybrid_coef_probs[type]; |
| 143 coef_counts = fc->hybrid_coef_counts[type]; |
| 144 } |
| 145 break; |
| 146 case TX_8X8: |
| 147 if (tx_type == DCT_DCT) { |
| 148 coef_probs = fc->coef_probs_8x8[type]; |
| 149 coef_counts = fc->coef_counts_8x8[type]; |
| 150 } else { |
| 151 coef_probs = fc->hybrid_coef_probs_8x8[type]; |
| 152 coef_counts = fc->hybrid_coef_counts_8x8[type]; |
| 153 } |
| 154 break; |
| 155 case TX_16X16: |
| 156 if (tx_type == DCT_DCT) { |
| 157 coef_probs = fc->coef_probs_16x16[type]; |
| 158 coef_counts = fc->coef_counts_16x16[type]; |
| 159 } else { |
| 160 coef_probs = fc->hybrid_coef_probs_16x16[type]; |
| 161 coef_counts = fc->hybrid_coef_counts_16x16[type]; |
| 162 } |
| 163 break; |
| 164 } |
| 165 |
| 166 VP9_COMBINEENTROPYCONTEXTS(pt, *a, *l); |
| 167 while (1) { |
| 168 int val; |
| 169 const uint8_t *cat6 = cat6_prob; |
| 170 if (c >= seg_eob) break; |
| 171 prob = coef_probs[coef_bands[c]][pt]; |
| 172 if (!vp9_read(br, prob[EOB_CONTEXT_NODE])) |
| 173 break; |
| 174 SKIP_START: |
| 175 if (c >= seg_eob) break; |
| 176 if (!vp9_read(br, prob[ZERO_CONTEXT_NODE])) { |
| 177 INCREMENT_COUNT(ZERO_TOKEN); |
| 178 ++c; |
| 179 prob = coef_probs[coef_bands[c]][pt]; |
| 180 goto SKIP_START; |
| 181 } |
| 182 // ONE_CONTEXT_NODE_0_ |
| 183 if (!vp9_read(br, prob[ONE_CONTEXT_NODE])) { |
| 184 WRITE_COEF_CONTINUE(1, ONE_TOKEN); |
| 185 } |
| 186 // LOW_VAL_CONTEXT_NODE_0_ |
| 187 if (!vp9_read(br, prob[LOW_VAL_CONTEXT_NODE])) { |
| 188 if (!vp9_read(br, prob[TWO_CONTEXT_NODE])) { |
| 189 WRITE_COEF_CONTINUE(2, TWO_TOKEN); |
| 190 } |
| 191 if (!vp9_read(br, prob[THREE_CONTEXT_NODE])) { |
| 192 WRITE_COEF_CONTINUE(3, THREE_TOKEN); |
| 193 } |
| 194 WRITE_COEF_CONTINUE(4, FOUR_TOKEN); |
| 195 } |
| 196 // HIGH_LOW_CONTEXT_NODE_0_ |
| 197 if (!vp9_read(br, prob[HIGH_LOW_CONTEXT_NODE])) { |
| 198 if (!vp9_read(br, prob[CAT_ONE_CONTEXT_NODE])) { |
| 199 val = CAT1_MIN_VAL; |
| 200 ADJUST_COEF(CAT1_PROB0, 0); |
| 201 WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY1); |
| 202 } |
| 203 val = CAT2_MIN_VAL; |
| 204 ADJUST_COEF(CAT2_PROB1, 1); |
| 205 ADJUST_COEF(CAT2_PROB0, 0); |
| 206 WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY2); |
| 207 } |
| 208 // CAT_THREEFOUR_CONTEXT_NODE_0_ |
| 209 if (!vp9_read(br, prob[CAT_THREEFOUR_CONTEXT_NODE])) { |
| 210 if (!vp9_read(br, prob[CAT_THREE_CONTEXT_NODE])) { |
| 211 val = CAT3_MIN_VAL; |
| 212 ADJUST_COEF(CAT3_PROB2, 2); |
| 213 ADJUST_COEF(CAT3_PROB1, 1); |
| 214 ADJUST_COEF(CAT3_PROB0, 0); |
| 215 WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY3); |
| 216 } |
| 217 val = CAT4_MIN_VAL; |
| 218 ADJUST_COEF(CAT4_PROB3, 3); |
| 219 ADJUST_COEF(CAT4_PROB2, 2); |
| 220 ADJUST_COEF(CAT4_PROB1, 1); |
| 221 ADJUST_COEF(CAT4_PROB0, 0); |
| 222 WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY4); |
| 223 } |
| 224 // CAT_FIVE_CONTEXT_NODE_0_: |
| 225 if (!vp9_read(br, prob[CAT_FIVE_CONTEXT_NODE])) { |
| 226 val = CAT5_MIN_VAL; |
| 227 ADJUST_COEF(CAT5_PROB4, 4); |
| 228 ADJUST_COEF(CAT5_PROB3, 3); |
| 229 ADJUST_COEF(CAT5_PROB2, 2); |
| 230 ADJUST_COEF(CAT5_PROB1, 1); |
| 231 ADJUST_COEF(CAT5_PROB0, 0); |
| 232 WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY5); |
| 233 } |
| 234 val = 0; |
| 235 while (*cat6) { |
| 236 val = (val << 1) | vp9_read(br, *cat6++); |
| 237 } |
| 238 val += CAT6_MIN_VAL; |
| 239 WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY6); |
| 240 } |
| 241 |
| 242 if (c < seg_eob) |
| 243 coef_counts[coef_bands[c]][pt][DCT_EOB_TOKEN]++; |
| 244 |
| 245 a[0] = l[0] = (c > !type); |
| 246 |
| 247 return c; |
| 248 } |
| 249 |
| 250 static int get_eob(MACROBLOCKD* const xd, int segment_id, int eob_max) { |
| 251 int active = vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB); |
| 252 int eob = vp9_get_segdata(xd, segment_id, SEG_LVL_EOB); |
| 253 |
| 254 if (!active || eob > eob_max) |
| 255 eob = eob_max; |
| 256 return eob; |
| 257 } |
| 258 |
| 259 |
| 260 static int vp9_decode_mb_tokens_16x16(VP9D_COMP* const pbi, |
| 261 MACROBLOCKD* const xd, |
| 262 BOOL_DECODER* const bc) { |
| 263 ENTROPY_CONTEXT* const A = (ENTROPY_CONTEXT *)xd->above_context; |
| 264 ENTROPY_CONTEXT* const L = (ENTROPY_CONTEXT *)xd->left_context; |
| 265 unsigned short* const eobs = xd->eobs; |
| 266 const int segment_id = xd->mode_info_context->mbmi.segment_id; |
| 267 int c, i, eobtotal = 0, seg_eob; |
| 268 |
| 269 // Luma block |
| 270 eobs[0] = c = decode_coefs(pbi, xd, bc, A, L, PLANE_TYPE_Y_WITH_DC, |
| 271 get_tx_type(xd, &xd->block[0]), |
| 272 get_eob(xd, segment_id, 256), |
| 273 xd->qcoeff, vp9_default_zig_zag1d_16x16, |
| 274 TX_16X16, vp9_coef_bands_16x16); |
| 275 A[1] = A[2] = A[3] = A[0]; |
| 276 L[1] = L[2] = L[3] = L[0]; |
| 277 eobtotal += c; |
| 278 |
| 279 // 8x8 chroma blocks |
| 280 seg_eob = get_eob(xd, segment_id, 64); |
| 281 for (i = 16; i < 24; i += 4) { |
| 282 ENTROPY_CONTEXT* const a = A + vp9_block2above_8x8[i]; |
| 283 ENTROPY_CONTEXT* const l = L + vp9_block2left_8x8[i]; |
| 284 |
| 285 eobs[i] = c = decode_coefs(pbi, xd, bc, a, l, PLANE_TYPE_UV, |
| 286 DCT_DCT, seg_eob, xd->block[i].qcoeff, |
| 287 vp9_default_zig_zag1d_8x8, |
| 288 TX_8X8, vp9_coef_bands_8x8); |
| 289 a[1] = a[0]; |
| 290 l[1] = l[0]; |
| 291 eobtotal += c; |
| 292 } |
| 293 A[8] = 0; |
| 294 L[8] = 0; |
| 295 return eobtotal; |
| 296 } |
| 297 |
| 298 static int vp9_decode_mb_tokens_8x8(VP9D_COMP* const pbi, |
| 299 MACROBLOCKD* const xd, |
| 300 BOOL_DECODER* const bc) { |
| 301 ENTROPY_CONTEXT *const A = (ENTROPY_CONTEXT *)xd->above_context; |
| 302 ENTROPY_CONTEXT *const L = (ENTROPY_CONTEXT *)xd->left_context; |
| 303 unsigned short *const eobs = xd->eobs; |
| 304 PLANE_TYPE type; |
| 305 int c, i, eobtotal = 0, seg_eob; |
| 306 const int segment_id = xd->mode_info_context->mbmi.segment_id; |
| 307 |
| 308 int has_2nd_order = get_2nd_order_usage(xd); |
| 309 // 2nd order DC block |
| 310 if (has_2nd_order) { |
| 311 ENTROPY_CONTEXT *const a = A + vp9_block2above_8x8[24]; |
| 312 ENTROPY_CONTEXT *const l = L + vp9_block2left_8x8[24]; |
| 313 |
| 314 eobs[24] = c = decode_coefs(pbi, xd, bc, a, l, PLANE_TYPE_Y2, |
| 315 DCT_DCT, get_eob(xd, segment_id, 4), |
| 316 xd->block[24].qcoeff, |
| 317 vp9_default_zig_zag1d, TX_8X8, vp9_coef_bands); |
| 318 eobtotal += c - 4; |
| 319 type = PLANE_TYPE_Y_NO_DC; |
| 320 } else { |
| 321 xd->above_context->y2 = 1; |
| 322 xd->left_context->y2 = 1; |
| 323 eobs[24] = 0; |
| 324 type = PLANE_TYPE_Y_WITH_DC; |
| 325 } |
| 326 |
| 327 // luma blocks |
| 328 seg_eob = get_eob(xd, segment_id, 64); |
| 329 for (i = 0; i < 16; i += 4) { |
| 330 ENTROPY_CONTEXT *const a = A + vp9_block2above_8x8[i]; |
| 331 ENTROPY_CONTEXT *const l = L + vp9_block2left_8x8[i]; |
| 332 |
| 333 eobs[i] = c = decode_coefs(pbi, xd, bc, a, l, type, |
| 334 type == PLANE_TYPE_Y_WITH_DC ? |
| 335 get_tx_type(xd, xd->block + i) : DCT_DCT, |
| 336 seg_eob, xd->block[i].qcoeff, |
| 337 vp9_default_zig_zag1d_8x8, |
| 338 TX_8X8, vp9_coef_bands_8x8); |
| 339 a[1] = a[0]; |
| 340 l[1] = l[0]; |
| 341 eobtotal += c; |
| 342 } |
| 343 |
| 344 // chroma blocks |
| 345 if (xd->mode_info_context->mbmi.mode == I8X8_PRED || |
| 346 xd->mode_info_context->mbmi.mode == SPLITMV) { |
| 347 // use 4x4 transform for U, V components in I8X8/splitmv prediction mode |
| 348 seg_eob = get_eob(xd, segment_id, 16); |
| 349 for (i = 16; i < 24; i++) { |
| 350 ENTROPY_CONTEXT *const a = A + vp9_block2above[i]; |
| 351 ENTROPY_CONTEXT *const l = L + vp9_block2left[i]; |
| 352 |
| 353 eobs[i] = c = decode_coefs(pbi, xd, bc, a, l, PLANE_TYPE_UV, |
| 354 DCT_DCT, seg_eob, xd->block[i].qcoeff, |
| 355 vp9_default_zig_zag1d, TX_4X4, vp9_coef_bands); |
| 356 eobtotal += c; |
| 357 } |
| 358 } else { |
| 359 for (i = 16; i < 24; i += 4) { |
| 360 ENTROPY_CONTEXT *const a = A + vp9_block2above_8x8[i]; |
| 361 ENTROPY_CONTEXT *const l = L + vp9_block2left_8x8[i]; |
| 362 |
| 363 eobs[i] = c = decode_coefs(pbi, xd, bc, a, l, PLANE_TYPE_UV, |
| 364 DCT_DCT, seg_eob, xd->block[i].qcoeff, |
| 365 vp9_default_zig_zag1d_8x8, |
| 366 TX_8X8, vp9_coef_bands_8x8); |
| 367 a[1] = a[0]; |
| 368 l[1] = l[0]; |
| 369 eobtotal += c; |
| 370 } |
| 371 } |
| 372 |
| 373 return eobtotal; |
| 374 } |
| 375 |
| 376 int vp9_decode_coefs_4x4(VP9D_COMP *dx, MACROBLOCKD *xd, |
| 377 BOOL_DECODER* const bc, |
| 378 PLANE_TYPE type, int i) { |
| 379 ENTROPY_CONTEXT *const A = (ENTROPY_CONTEXT *)xd->above_context; |
| 380 ENTROPY_CONTEXT *const L = (ENTROPY_CONTEXT *)xd->left_context; |
| 381 ENTROPY_CONTEXT *const a = A + vp9_block2above[i]; |
| 382 ENTROPY_CONTEXT *const l = L + vp9_block2left[i]; |
| 383 INT16 *qcoeff_ptr = &xd->qcoeff[0]; |
| 384 const int *scan = vp9_default_zig_zag1d; |
| 385 unsigned short *const eobs = xd->eobs; |
| 386 int segment_id = xd->mode_info_context->mbmi.segment_id; |
| 387 int c, seg_eob = get_eob(xd, segment_id, 16); |
| 388 TX_TYPE tx_type = DCT_DCT; |
| 389 |
| 390 if (type == PLANE_TYPE_Y_WITH_DC) |
| 391 tx_type = get_tx_type_4x4(xd, &xd->block[i]); |
| 392 switch (tx_type) { |
| 393 case ADST_DCT : |
| 394 scan = vp9_row_scan; |
| 395 break; |
| 396 |
| 397 case DCT_ADST : |
| 398 scan = vp9_col_scan; |
| 399 break; |
| 400 |
| 401 default : |
| 402 scan = vp9_default_zig_zag1d; |
| 403 break; |
| 404 } |
| 405 eobs[i] = c = decode_coefs(dx, xd, bc, a, l, type, |
| 406 tx_type, seg_eob, qcoeff_ptr + i * 16, |
| 407 scan, TX_4X4, vp9_coef_bands); |
| 408 return c; |
| 409 } |
| 410 |
| 411 int vp9_decode_mb_tokens_4x4_uv(VP9D_COMP* const dx, |
| 412 MACROBLOCKD* const xd, |
| 413 BOOL_DECODER* const bc) { |
| 414 int eobtotal = 0, i; |
| 415 |
| 416 for (i = 16; i < 24; i++) |
| 417 eobtotal += vp9_decode_coefs_4x4(dx, xd, bc, PLANE_TYPE_UV, i); |
| 418 |
| 419 return eobtotal; |
| 420 } |
| 421 |
| 422 static int vp9_decode_mb_tokens_4x4(VP9D_COMP* const dx, |
| 423 MACROBLOCKD* const xd, |
| 424 BOOL_DECODER* const bc) { |
| 425 int i, eobtotal = 0; |
| 426 PLANE_TYPE type; |
| 427 |
| 428 int has_2nd_order = get_2nd_order_usage(xd); |
| 429 |
| 430 if (has_2nd_order) { |
| 431 eobtotal += vp9_decode_coefs_4x4(dx, xd, bc, PLANE_TYPE_Y2, 24) - 16; |
| 432 type = PLANE_TYPE_Y_NO_DC; |
| 433 } else { |
| 434 xd->above_context->y2 = 1; |
| 435 xd->left_context->y2 = 1; |
| 436 xd->eobs[24] = 0; |
| 437 type = PLANE_TYPE_Y_WITH_DC; |
| 438 } |
| 439 |
| 440 for (i = 0; i < 16; ++i) { |
| 441 eobtotal += vp9_decode_coefs_4x4(dx, xd, bc, type, i); |
| 442 } |
| 443 |
| 444 return eobtotal + vp9_decode_mb_tokens_4x4_uv(dx, xd, bc); |
| 445 } |
| 446 |
| 447 int vp9_decode_mb_tokens(VP9D_COMP* const dx, |
| 448 MACROBLOCKD* const xd, |
| 449 BOOL_DECODER* const bc) { |
| 450 const TX_SIZE tx_size = xd->mode_info_context->mbmi.txfm_size; |
| 451 int eobtotal; |
| 452 |
| 453 if (tx_size == TX_16X16) { |
| 454 eobtotal = vp9_decode_mb_tokens_16x16(dx, xd, bc); |
| 455 } else if (tx_size == TX_8X8) { |
| 456 eobtotal = vp9_decode_mb_tokens_8x8(dx, xd, bc); |
| 457 } else { |
| 458 assert(tx_size == TX_4X4); |
| 459 eobtotal = vp9_decode_mb_tokens_4x4(dx, xd, bc); |
| 460 } |
| 461 |
| 462 return eobtotal; |
| 463 } |
OLD | NEW |