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 #include <math.h> 12 #include <stdio.h> 13 #include <string.h> 14 #include <assert.h> 15 #include "onyx_int.h" 16 #include "tokenize.h" 17 #include "vpx_mem/vpx_mem.h" 18 19 /* Global event counters used for accumulating statistics across several 20 compressions, then generating context.c = initial stats. */ 21 22 void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t); 23 void vp8_fix_contexts(MACROBLOCKD *x); 24 25 #include "dct_value_tokens.h" 26 #include "dct_value_cost.h" 27 28 const TOKENVALUE *const vp8_dct_value_tokens_ptr = 29 dct_value_tokens + DCT_MAX_VALUE; 30 const short *const vp8_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE; 31 32 #if 0 33 int skip_true_count = 0; 34 int skip_false_count = 0; 35 #endif 36 37 /* function used to generate dct_value_tokens and dct_value_cost tables */ 38 /* 39 static void fill_value_tokens() 40 { 41 42 TOKENVALUE *t = dct_value_tokens + DCT_MAX_VALUE; 43 const vp8_extra_bit_struct *e = vp8_extra_bits; 44 45 int i = -DCT_MAX_VALUE; 46 int sign = 1; 47 48 do 49 { 50 if (!i) 51 sign = 0; 52 53 { 54 const int a = sign ? -i : i; 55 int eb = sign; 56 57 if (a > 4) 58 { 59 int j = 4; 60 61 while (++j < 11 && e[j].base_val <= a) {} 62 63 t[i].Token = --j; 64 eb |= (a - e[j].base_val) << 1; 65 } 66 else 67 t[i].Token = a; 68 69 t[i].Extra = eb; 70 } 71 72 // initialize the cost for extra bits for all possible coefficient 73 value. 74 { 75 int cost = 0; 76 const vp8_extra_bit_struct *p = vp8_extra_bits + t[i].Token; 77 78 if (p->base_val) 79 { 80 const int extra = t[i].Extra; 81 const int Length = p->Len; 82 83 if (Length) 84 cost += vp8_treed_cost(p->tree, p->prob, extra >> 1, 85 Length); 86 87 cost += vp8_cost_bit(vp8_prob_half, extra & 1); // sign 88 dct_value_cost[i + DCT_MAX_VALUE] = cost; 89 } 90 91 } 92 93 } 94 while (++i < DCT_MAX_VALUE); 95 96 vp8_dct_value_tokens_ptr = dct_value_tokens + DCT_MAX_VALUE; 97 vp8_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE; 98 } 99 */ 100 101 static void tokenize2nd_order_b(MACROBLOCK *x, TOKENEXTRA **tp, VP8_COMP *cpi) { 102 MACROBLOCKD *xd = &x->e_mbd; 103 int pt; /* near block/prev token context index */ 104 int c; /* start at DC */ 105 TOKENEXTRA *t = *tp; /* store tokens starting here */ 106 const BLOCKD *b; 107 const short *qcoeff_ptr; 108 ENTROPY_CONTEXT *a; 109 ENTROPY_CONTEXT *l; 110 int band, rc, v, token; 111 int eob; 112 113 b = xd->block + 24; 114 qcoeff_ptr = b->qcoeff; 115 a = (ENTROPY_CONTEXT *)xd->above_context + 8; 116 l = (ENTROPY_CONTEXT *)xd->left_context + 8; 117 eob = xd->eobs[24]; 118 VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); 119 120 if (!eob) { 121 /* c = band for this case */ 122 t->Token = DCT_EOB_TOKEN; 123 t->context_tree = cpi->common.fc.coef_probs[1][0][pt]; 124 t->skip_eob_node = 0; 125 126 ++x->coef_counts[1][0][pt][DCT_EOB_TOKEN]; 127 t++; 128 *tp = t; 129 *a = *l = 0; 130 return; 131 } 132 133 v = qcoeff_ptr[0]; 134 t->Extra = vp8_dct_value_tokens_ptr[v].Extra; 135 token = vp8_dct_value_tokens_ptr[v].Token; 136 t->Token = token; 137 138 t->context_tree = cpi->common.fc.coef_probs[1][0][pt]; 139 t->skip_eob_node = 0; 140 ++x->coef_counts[1][0][pt][token]; 141 pt = vp8_prev_token_class[token]; 142 t++; 143 c = 1; 144 145 for (; c < eob; ++c) { 146 rc = vp8_default_zig_zag1d[c]; 147 band = vp8_coef_bands[c]; 148 v = qcoeff_ptr[rc]; 149 150 t->Extra = vp8_dct_value_tokens_ptr[v].Extra; 151 token = vp8_dct_value_tokens_ptr[v].Token; 152 153 t->Token = token; 154 t->context_tree = cpi->common.fc.coef_probs[1][band][pt]; 155 156 t->skip_eob_node = ((pt == 0)); 157 158 ++x->coef_counts[1][band][pt][token]; 159 160 pt = vp8_prev_token_class[token]; 161 t++; 162 } 163 if (c < 16) { 164 band = vp8_coef_bands[c]; 165 t->Token = DCT_EOB_TOKEN; 166 t->context_tree = cpi->common.fc.coef_probs[1][band][pt]; 167 168 t->skip_eob_node = 0; 169 170 ++x->coef_counts[1][band][pt][DCT_EOB_TOKEN]; 171 172 t++; 173 } 174 175 *tp = t; 176 *a = *l = 1; 177 } 178 179 static void tokenize1st_order_b( 180 MACROBLOCK *x, TOKENEXTRA **tp, 181 int type, /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */ 182 VP8_COMP *cpi) { 183 MACROBLOCKD *xd = &x->e_mbd; 184 unsigned int block; 185 const BLOCKD *b; 186 int pt; /* near block/prev token context index */ 187 int c; 188 int token; 189 TOKENEXTRA *t = *tp; /* store tokens starting here */ 190 const short *qcoeff_ptr; 191 ENTROPY_CONTEXT *a; 192 ENTROPY_CONTEXT *l; 193 int band, rc, v; 194 int tmp1, tmp2; 195 196 b = xd->block; 197 /* Luma */ 198 for (block = 0; block < 16; block++, b++) { 199 const int eob = *b->eob; 200 tmp1 = vp8_block2above[block]; 201 tmp2 = vp8_block2left[block]; 202 qcoeff_ptr = b->qcoeff; 203 a = (ENTROPY_CONTEXT *)xd->above_context + tmp1; 204 l = (ENTROPY_CONTEXT *)xd->left_context + tmp2; 205 206 VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); 207 208 c = type ? 0 : 1; 209 210 if (c >= eob) { 211 /* c = band for this case */ 212 t->Token = DCT_EOB_TOKEN; 213 t->context_tree = cpi->common.fc.coef_probs[type][c][pt]; 214 t->skip_eob_node = 0; 215 216 ++x->coef_counts[type][c][pt][DCT_EOB_TOKEN]; 217 t++; 218 *tp = t; 219 *a = *l = 0; 220 continue; 221 } 222 223 v = qcoeff_ptr[c]; 224 225 t->Extra = vp8_dct_value_tokens_ptr[v].Extra; 226 token = vp8_dct_value_tokens_ptr[v].Token; 227 t->Token = token; 228 229 t->context_tree = cpi->common.fc.coef_probs[type][c][pt]; 230 t->skip_eob_node = 0; 231 ++x->coef_counts[type][c][pt][token]; 232 pt = vp8_prev_token_class[token]; 233 t++; 234 c++; 235 236 assert(eob <= 16); 237 for (; c < eob; ++c) { 238 rc = vp8_default_zig_zag1d[c]; 239 band = vp8_coef_bands[c]; 240 v = qcoeff_ptr[rc]; 241 242 t->Extra = vp8_dct_value_tokens_ptr[v].Extra; 243 token = vp8_dct_value_tokens_ptr[v].Token; 244 245 t->Token = token; 246 t->context_tree = cpi->common.fc.coef_probs[type][band][pt]; 247 248 t->skip_eob_node = (pt == 0); 249 ++x->coef_counts[type][band][pt][token]; 250 251 pt = vp8_prev_token_class[token]; 252 t++; 253 } 254 if (c < 16) { 255 band = vp8_coef_bands[c]; 256 t->Token = DCT_EOB_TOKEN; 257 t->context_tree = cpi->common.fc.coef_probs[type][band][pt]; 258 259 t->skip_eob_node = 0; 260 ++x->coef_counts[type][band][pt][DCT_EOB_TOKEN]; 261 262 t++; 263 } 264 *tp = t; 265 *a = *l = 1; 266 } 267 268 /* Chroma */ 269 for (block = 16; block < 24; block++, b++) { 270 const int eob = *b->eob; 271 tmp1 = vp8_block2above[block]; 272 tmp2 = vp8_block2left[block]; 273 qcoeff_ptr = b->qcoeff; 274 a = (ENTROPY_CONTEXT *)xd->above_context + tmp1; 275 l = (ENTROPY_CONTEXT *)xd->left_context + tmp2; 276 277 VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); 278 279 if (!eob) { 280 /* c = band for this case */ 281 t->Token = DCT_EOB_TOKEN; 282 t->context_tree = cpi->common.fc.coef_probs[2][0][pt]; 283 t->skip_eob_node = 0; 284 285 ++x->coef_counts[2][0][pt][DCT_EOB_TOKEN]; 286 t++; 287 *tp = t; 288 *a = *l = 0; 289 continue; 290 } 291 292 v = qcoeff_ptr[0]; 293 294 t->Extra = vp8_dct_value_tokens_ptr[v].Extra; 295 token = vp8_dct_value_tokens_ptr[v].Token; 296 t->Token = token; 297 298 t->context_tree = cpi->common.fc.coef_probs[2][0][pt]; 299 t->skip_eob_node = 0; 300 ++x->coef_counts[2][0][pt][token]; 301 pt = vp8_prev_token_class[token]; 302 t++; 303 c = 1; 304 305 assert(eob <= 16); 306 for (; c < eob; ++c) { 307 rc = vp8_default_zig_zag1d[c]; 308 band = vp8_coef_bands[c]; 309 v = qcoeff_ptr[rc]; 310 311 t->Extra = vp8_dct_value_tokens_ptr[v].Extra; 312 token = vp8_dct_value_tokens_ptr[v].Token; 313 314 t->Token = token; 315 t->context_tree = cpi->common.fc.coef_probs[2][band][pt]; 316 317 t->skip_eob_node = (pt == 0); 318 319 ++x->coef_counts[2][band][pt][token]; 320 321 pt = vp8_prev_token_class[token]; 322 t++; 323 } 324 if (c < 16) { 325 band = vp8_coef_bands[c]; 326 t->Token = DCT_EOB_TOKEN; 327 t->context_tree = cpi->common.fc.coef_probs[2][band][pt]; 328 329 t->skip_eob_node = 0; 330 331 ++x->coef_counts[2][band][pt][DCT_EOB_TOKEN]; 332 333 t++; 334 } 335 *tp = t; 336 *a = *l = 1; 337 } 338 } 339 340 static int mb_is_skippable(MACROBLOCKD *x, int has_y2_block) { 341 int skip = 1; 342 int i = 0; 343 344 if (has_y2_block) { 345 for (i = 0; i < 16; ++i) skip &= (x->eobs[i] < 2); 346 } 347 348 for (; i < 24 + has_y2_block; ++i) skip &= (!x->eobs[i]); 349 350 return skip; 351 } 352 353 void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t) { 354 MACROBLOCKD *xd = &x->e_mbd; 355 int plane_type; 356 int has_y2_block; 357 358 has_y2_block = (xd->mode_info_context->mbmi.mode != B_PRED && 359 xd->mode_info_context->mbmi.mode != SPLITMV); 360 361 xd->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable(xd, has_y2_block); 362 if (xd->mode_info_context->mbmi.mb_skip_coeff) { 363 if (!cpi->common.mb_no_coeff_skip) { 364 vp8_stuff_mb(cpi, x, t); 365 } else { 366 vp8_fix_contexts(xd); 367 x->skip_true_count++; 368 } 369 370 return; 371 } 372 373 plane_type = 3; 374 if (has_y2_block) { 375 tokenize2nd_order_b(x, t, cpi); 376 plane_type = 0; 377 } 378 379 tokenize1st_order_b(x, t, plane_type, cpi); 380 } 381 382 static void stuff2nd_order_b(TOKENEXTRA **tp, ENTROPY_CONTEXT *a, 383 ENTROPY_CONTEXT *l, VP8_COMP *cpi, MACROBLOCK *x) { 384 int pt; /* near block/prev token context index */ 385 TOKENEXTRA *t = *tp; /* store tokens starting here */ 386 VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); 387 388 t->Token = DCT_EOB_TOKEN; 389 t->context_tree = cpi->common.fc.coef_probs[1][0][pt]; 390 t->skip_eob_node = 0; 391 ++x->coef_counts[1][0][pt][DCT_EOB_TOKEN]; 392 ++t; 393 394 *tp = t; 395 pt = 0; 396 *a = *l = pt; 397 } 398 399 static void stuff1st_order_b(TOKENEXTRA **tp, ENTROPY_CONTEXT *a, 400 ENTROPY_CONTEXT *l, int type, VP8_COMP *cpi, 401 MACROBLOCK *x) { 402 int pt; /* near block/prev token context index */ 403 int band; 404 TOKENEXTRA *t = *tp; /* store tokens starting here */ 405 VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); 406 band = type ? 0 : 1; 407 t->Token = DCT_EOB_TOKEN; 408 t->context_tree = cpi->common.fc.coef_probs[type][band][pt]; 409 t->skip_eob_node = 0; 410 ++x->coef_counts[type][band][pt][DCT_EOB_TOKEN]; 411 ++t; 412 *tp = t; 413 pt = 0; /* 0 <-> all coeff data is zero */ 414 *a = *l = pt; 415 } 416 417 static void stuff1st_order_buv(TOKENEXTRA **tp, ENTROPY_CONTEXT *a, 418 ENTROPY_CONTEXT *l, VP8_COMP *cpi, 419 MACROBLOCK *x) { 420 int pt; /* near block/prev token context index */ 421 TOKENEXTRA *t = *tp; /* store tokens starting here */ 422 VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); 423 424 t->Token = DCT_EOB_TOKEN; 425 t->context_tree = cpi->common.fc.coef_probs[2][0][pt]; 426 t->skip_eob_node = 0; 427 ++x->coef_counts[2][0][pt][DCT_EOB_TOKEN]; 428 ++t; 429 *tp = t; 430 pt = 0; /* 0 <-> all coeff data is zero */ 431 *a = *l = pt; 432 } 433 434 void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t) { 435 MACROBLOCKD *xd = &x->e_mbd; 436 ENTROPY_CONTEXT *A = (ENTROPY_CONTEXT *)xd->above_context; 437 ENTROPY_CONTEXT *L = (ENTROPY_CONTEXT *)xd->left_context; 438 int plane_type; 439 int b; 440 plane_type = 3; 441 if ((xd->mode_info_context->mbmi.mode != B_PRED && 442 xd->mode_info_context->mbmi.mode != SPLITMV)) { 443 stuff2nd_order_b(t, A + vp8_block2above[24], L + vp8_block2left[24], cpi, 444 x); 445 plane_type = 0; 446 } 447 448 for (b = 0; b < 16; ++b) { 449 stuff1st_order_b(t, A + vp8_block2above[b], L + vp8_block2left[b], 450 plane_type, cpi, x); 451 } 452 453 for (b = 16; b < 24; ++b) { 454 stuff1st_order_buv(t, A + vp8_block2above[b], L + vp8_block2left[b], cpi, 455 x); 456 } 457 } 458 void vp8_fix_contexts(MACROBLOCKD *x) { 459 /* Clear entropy contexts for Y2 blocks */ 460 if (x->mode_info_context->mbmi.mode != B_PRED && 461 x->mode_info_context->mbmi.mode != SPLITMV) { 462 memset(x->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)); 463 memset(x->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)); 464 } else { 465 memset(x->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1); 466 memset(x->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1); 467 } 468 } 469