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 <math.h> |
| 13 #include <stdio.h> |
| 14 #include <string.h> |
| 15 #include <assert.h> |
| 16 #include "vp9/encoder/vp9_onyx_int.h" |
| 17 #include "vp9/encoder/vp9_tokenize.h" |
| 18 #include "vpx_mem/vpx_mem.h" |
| 19 |
| 20 #include "vp9/common/vp9_pred_common.h" |
| 21 #include "vp9/common/vp9_seg_common.h" |
| 22 #include "vp9/common/vp9_entropy.h" |
| 23 |
| 24 /* Global event counters used for accumulating statistics across several |
| 25 compressions, then generating vp9_context.c = initial stats. */ |
| 26 |
| 27 #ifdef ENTROPY_STATS |
| 28 INT64 context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTRO
PY_TOKENS]; |
| 29 INT64 hybrid_context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MA
X_ENTROPY_TOKENS]; |
| 30 |
| 31 INT64 context_counters_8x8[BLOCK_TYPES_8X8] [COEF_BANDS] [PREV_COEF_CONTEXTS] [M
AX_ENTROPY_TOKENS]; |
| 32 INT64 hybrid_context_counters_8x8[BLOCK_TYPES_8X8] [COEF_BANDS] [PREV_COEF_CONTE
XTS] [MAX_ENTROPY_TOKENS]; |
| 33 |
| 34 INT64 context_counters_16x16[BLOCK_TYPES_16X16] [COEF_BANDS] [PREV_COEF_CONTEXTS
] [MAX_ENTROPY_TOKENS]; |
| 35 INT64 hybrid_context_counters_16x16[BLOCK_TYPES_16X16] [COEF_BANDS] [PREV_COEF_C
ONTEXTS] [MAX_ENTROPY_TOKENS]; |
| 36 |
| 37 extern unsigned int tree_update_hist[BLOCK_TYPES][COEF_BANDS] |
| 38 [PREV_COEF_CONTEXTS][ENTROPY_NODES][2]; |
| 39 extern unsigned int hybrid_tree_update_hist[BLOCK_TYPES][COEF_BANDS] |
| 40 [PREV_COEF_CONTEXTS][ENTROPY_NODES][2]; |
| 41 extern unsigned int tree_update_hist_8x8[BLOCK_TYPES_8X8][COEF_BANDS] |
| 42 [PREV_COEF_CONTEXTS][ENTROPY_NODES] [2]; |
| 43 extern unsigned int hybrid_tree_update_hist_8x8[BLOCK_TYPES_8X8][COEF_BANDS] |
| 44 [PREV_COEF_CONTEXTS][ENTROPY_NODES] [2]; |
| 45 extern unsigned int tree_update_hist_16x16[BLOCK_TYPES_16X16][COEF_BANDS] |
| 46 [PREV_COEF_CONTEXTS][ENTROPY_NODES] [2]; |
| 47 extern unsigned int hybrid_tree_update_hist_16x16[BLOCK_TYPES_16X16][COEF_BANDS] |
| 48 [PREV_COEF_CONTEXTS][ENTROPY_NODES] [2]; |
| 49 #endif /* ENTROPY_STATS */ |
| 50 |
| 51 static TOKENVALUE dct_value_tokens[DCT_MAX_VALUE * 2]; |
| 52 const TOKENVALUE *vp9_dct_value_tokens_ptr; |
| 53 static int dct_value_cost[DCT_MAX_VALUE * 2]; |
| 54 const int *vp9_dct_value_cost_ptr; |
| 55 |
| 56 static void fill_value_tokens() { |
| 57 |
| 58 TOKENVALUE *const t = dct_value_tokens + DCT_MAX_VALUE; |
| 59 vp9_extra_bit_struct *const e = vp9_extra_bits; |
| 60 |
| 61 int i = -DCT_MAX_VALUE; |
| 62 int sign = 1; |
| 63 |
| 64 do { |
| 65 if (!i) |
| 66 sign = 0; |
| 67 |
| 68 { |
| 69 const int a = sign ? -i : i; |
| 70 int eb = sign; |
| 71 |
| 72 if (a > 4) { |
| 73 int j = 4; |
| 74 |
| 75 while (++j < 11 && e[j].base_val <= a) {} |
| 76 |
| 77 t[i].Token = --j; |
| 78 eb |= (a - e[j].base_val) << 1; |
| 79 } else |
| 80 t[i].Token = a; |
| 81 |
| 82 t[i].Extra = eb; |
| 83 } |
| 84 |
| 85 // initialize the cost for extra bits for all possible coefficient value. |
| 86 { |
| 87 int cost = 0; |
| 88 vp9_extra_bit_struct *p = vp9_extra_bits + t[i].Token; |
| 89 |
| 90 if (p->base_val) { |
| 91 const int extra = t[i].Extra; |
| 92 const int Length = p->Len; |
| 93 |
| 94 if (Length) |
| 95 cost += treed_cost(p->tree, p->prob, extra >> 1, Length); |
| 96 |
| 97 cost += vp9_cost_bit(vp9_prob_half, extra & 1); /* sign */ |
| 98 dct_value_cost[i + DCT_MAX_VALUE] = cost; |
| 99 } |
| 100 |
| 101 } |
| 102 |
| 103 } while (++i < DCT_MAX_VALUE); |
| 104 |
| 105 vp9_dct_value_tokens_ptr = dct_value_tokens + DCT_MAX_VALUE; |
| 106 vp9_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE; |
| 107 } |
| 108 |
| 109 static void tokenize_b(VP9_COMP *cpi, |
| 110 MACROBLOCKD *xd, |
| 111 const BLOCKD * const b, |
| 112 TOKENEXTRA **tp, |
| 113 PLANE_TYPE type, |
| 114 ENTROPY_CONTEXT *a, |
| 115 ENTROPY_CONTEXT *l, |
| 116 TX_SIZE tx_size, |
| 117 int dry_run) { |
| 118 int pt; /* near block/prev token context index */ |
| 119 int c = (type == PLANE_TYPE_Y_NO_DC) ? 1 : 0; |
| 120 const int eob = b->eob; /* one beyond last nonzero coeff */ |
| 121 TOKENEXTRA *t = *tp; /* store tokens starting here */ |
| 122 const short *qcoeff_ptr = b->qcoeff; |
| 123 int seg_eob; |
| 124 int segment_id = xd->mode_info_context->mbmi.segment_id; |
| 125 const int *bands, *scan; |
| 126 unsigned int (*counts)[COEF_BANDS][PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS]; |
| 127 vp9_prob (*probs)[COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES]; |
| 128 const TX_TYPE tx_type = (type == PLANE_TYPE_Y_WITH_DC) ? |
| 129 get_tx_type(xd, b) : DCT_DCT; |
| 130 |
| 131 VP9_COMBINEENTROPYCONTEXTS(pt, *a, *l); |
| 132 switch (tx_size) { |
| 133 default: |
| 134 case TX_4X4: |
| 135 seg_eob = 16; |
| 136 bands = vp9_coef_bands; |
| 137 scan = vp9_default_zig_zag1d; |
| 138 if (tx_type != DCT_DCT) { |
| 139 counts = cpi->hybrid_coef_counts; |
| 140 probs = cpi->common.fc.hybrid_coef_probs; |
| 141 if (tx_type == ADST_DCT) { |
| 142 scan = vp9_row_scan; |
| 143 } else if (tx_type == DCT_ADST) { |
| 144 scan = vp9_col_scan; |
| 145 } |
| 146 } else { |
| 147 counts = cpi->coef_counts; |
| 148 probs = cpi->common.fc.coef_probs; |
| 149 } |
| 150 break; |
| 151 case TX_8X8: |
| 152 if (type == PLANE_TYPE_Y2) { |
| 153 seg_eob = 4; |
| 154 bands = vp9_coef_bands; |
| 155 scan = vp9_default_zig_zag1d; |
| 156 } else { |
| 157 seg_eob = 64; |
| 158 bands = vp9_coef_bands_8x8; |
| 159 scan = vp9_default_zig_zag1d_8x8; |
| 160 } |
| 161 if (tx_type != DCT_DCT) { |
| 162 counts = cpi->hybrid_coef_counts_8x8; |
| 163 probs = cpi->common.fc.hybrid_coef_probs_8x8; |
| 164 } else { |
| 165 counts = cpi->coef_counts_8x8; |
| 166 probs = cpi->common.fc.coef_probs_8x8; |
| 167 } |
| 168 break; |
| 169 case TX_16X16: |
| 170 seg_eob = 256; |
| 171 bands = vp9_coef_bands_16x16; |
| 172 scan = vp9_default_zig_zag1d_16x16; |
| 173 if (tx_type != DCT_DCT) { |
| 174 counts = cpi->hybrid_coef_counts_16x16; |
| 175 probs = cpi->common.fc.hybrid_coef_probs_16x16; |
| 176 } else { |
| 177 counts = cpi->coef_counts_16x16; |
| 178 probs = cpi->common.fc.coef_probs_16x16; |
| 179 } |
| 180 break; |
| 181 } |
| 182 |
| 183 if (vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB)) |
| 184 seg_eob = vp9_get_segdata(xd, segment_id, SEG_LVL_EOB); |
| 185 |
| 186 do { |
| 187 const int band = bands[c]; |
| 188 int token; |
| 189 |
| 190 if (c < eob) { |
| 191 const int rc = scan[c]; |
| 192 const int v = qcoeff_ptr[rc]; |
| 193 |
| 194 assert(-DCT_MAX_VALUE <= v && v < DCT_MAX_VALUE); |
| 195 |
| 196 t->Extra = vp9_dct_value_tokens_ptr[v].Extra; |
| 197 token = vp9_dct_value_tokens_ptr[v].Token; |
| 198 } else { |
| 199 token = DCT_EOB_TOKEN; |
| 200 } |
| 201 |
| 202 t->Token = token; |
| 203 t->context_tree = probs[type][band][pt]; |
| 204 t->skip_eob_node = (pt == 0) && ((band > 0 && type != PLANE_TYPE_Y_NO_DC) || |
| 205 (band > 1 && type == PLANE_TYPE_Y_NO_DC)); |
| 206 assert(vp9_coef_encodings[t->Token].Len - t->skip_eob_node > 0); |
| 207 if (!dry_run) { |
| 208 ++counts[type][band][pt][token]; |
| 209 } |
| 210 pt = vp9_prev_token_class[token]; |
| 211 ++t; |
| 212 } while (c < eob && ++c < seg_eob); |
| 213 |
| 214 *tp = t; |
| 215 *a = *l = (c > !type); /* 0 <-> all coeff data is zero */ |
| 216 } |
| 217 |
| 218 int vp9_mby_is_skippable_4x4(MACROBLOCKD *xd, int has_2nd_order) { |
| 219 int skip = 1; |
| 220 int i = 0; |
| 221 |
| 222 if (has_2nd_order) { |
| 223 for (i = 0; i < 16; i++) |
| 224 skip &= (xd->block[i].eob < 2); |
| 225 skip &= (!xd->block[24].eob); |
| 226 } else { |
| 227 for (i = 0; i < 16; i++) |
| 228 skip &= (!xd->block[i].eob); |
| 229 } |
| 230 return skip; |
| 231 } |
| 232 |
| 233 int vp9_mbuv_is_skippable_4x4(MACROBLOCKD *xd) { |
| 234 int skip = 1; |
| 235 int i; |
| 236 |
| 237 for (i = 16; i < 24; i++) |
| 238 skip &= (!xd->block[i].eob); |
| 239 return skip; |
| 240 } |
| 241 |
| 242 static int mb_is_skippable_4x4(MACROBLOCKD *xd, int has_2nd_order) { |
| 243 return (vp9_mby_is_skippable_4x4(xd, has_2nd_order) & |
| 244 vp9_mbuv_is_skippable_4x4(xd)); |
| 245 } |
| 246 |
| 247 int vp9_mby_is_skippable_8x8(MACROBLOCKD *xd, int has_2nd_order) { |
| 248 int skip = 1; |
| 249 int i = 0; |
| 250 |
| 251 if (has_2nd_order) { |
| 252 for (i = 0; i < 16; i += 4) |
| 253 skip &= (xd->block[i].eob < 2); |
| 254 skip &= (!xd->block[24].eob); |
| 255 } else { |
| 256 for (i = 0; i < 16; i += 4) |
| 257 skip &= (!xd->block[i].eob); |
| 258 } |
| 259 return skip; |
| 260 } |
| 261 |
| 262 int vp9_mbuv_is_skippable_8x8(MACROBLOCKD *xd) { |
| 263 return (!xd->block[16].eob) & (!xd->block[20].eob); |
| 264 } |
| 265 |
| 266 static int mb_is_skippable_8x8(MACROBLOCKD *xd, int has_2nd_order) { |
| 267 return (vp9_mby_is_skippable_8x8(xd, has_2nd_order) & |
| 268 vp9_mbuv_is_skippable_8x8(xd)); |
| 269 } |
| 270 |
| 271 static int mb_is_skippable_8x8_4x4uv(MACROBLOCKD *xd, int has_2nd_order) { |
| 272 return (vp9_mby_is_skippable_8x8(xd, has_2nd_order) & |
| 273 vp9_mbuv_is_skippable_4x4(xd)); |
| 274 } |
| 275 |
| 276 int vp9_mby_is_skippable_16x16(MACROBLOCKD *xd) { |
| 277 int skip = 1; |
| 278 skip &= !xd->block[0].eob; |
| 279 return skip; |
| 280 } |
| 281 |
| 282 static int mb_is_skippable_16x16(MACROBLOCKD *xd) { |
| 283 return (vp9_mby_is_skippable_16x16(xd) & vp9_mbuv_is_skippable_8x8(xd)); |
| 284 } |
| 285 |
| 286 void vp9_tokenize_mb(VP9_COMP *cpi, |
| 287 MACROBLOCKD *xd, |
| 288 TOKENEXTRA **t, |
| 289 int dry_run) { |
| 290 PLANE_TYPE plane_type; |
| 291 int has_2nd_order; |
| 292 int b; |
| 293 int tx_size = xd->mode_info_context->mbmi.txfm_size; |
| 294 int mb_skip_context = vp9_get_pred_context(&cpi->common, xd, PRED_MBSKIP); |
| 295 TOKENEXTRA *t_backup = *t; |
| 296 ENTROPY_CONTEXT * A = (ENTROPY_CONTEXT *) xd->above_context; |
| 297 ENTROPY_CONTEXT * L = (ENTROPY_CONTEXT *) xd->left_context; |
| 298 |
| 299 // If the MB is going to be skipped because of a segment level flag |
| 300 // exclude this from the skip count stats used to calculate the |
| 301 // transmitted skip probability; |
| 302 int skip_inc; |
| 303 int segment_id = xd->mode_info_context->mbmi.segment_id; |
| 304 |
| 305 if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB) || |
| 306 (vp9_get_segdata(xd, segment_id, SEG_LVL_EOB) != 0)) { |
| 307 skip_inc = 1; |
| 308 } else |
| 309 skip_inc = 0; |
| 310 |
| 311 has_2nd_order = get_2nd_order_usage(xd); |
| 312 |
| 313 switch (tx_size) { |
| 314 case TX_16X16: |
| 315 xd->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable_16x16(xd); |
| 316 break; |
| 317 case TX_8X8: |
| 318 if (xd->mode_info_context->mbmi.mode == I8X8_PRED || |
| 319 xd->mode_info_context->mbmi.mode == SPLITMV) |
| 320 xd->mode_info_context->mbmi.mb_skip_coeff = |
| 321 mb_is_skippable_8x8_4x4uv(xd, 0); |
| 322 else |
| 323 xd->mode_info_context->mbmi.mb_skip_coeff = |
| 324 mb_is_skippable_8x8(xd, has_2nd_order); |
| 325 break; |
| 326 |
| 327 default: |
| 328 xd->mode_info_context->mbmi.mb_skip_coeff = |
| 329 mb_is_skippable_4x4(xd, has_2nd_order); |
| 330 break; |
| 331 } |
| 332 |
| 333 if (xd->mode_info_context->mbmi.mb_skip_coeff) { |
| 334 if (!dry_run) |
| 335 cpi->skip_true_count[mb_skip_context] += skip_inc; |
| 336 if (!cpi->common.mb_no_coeff_skip) { |
| 337 vp9_stuff_mb(cpi, xd, t, dry_run); |
| 338 } else { |
| 339 vp9_fix_contexts(xd); |
| 340 } |
| 341 if (dry_run) |
| 342 *t = t_backup; |
| 343 return; |
| 344 } |
| 345 |
| 346 if (!dry_run) |
| 347 cpi->skip_false_count[mb_skip_context] += skip_inc; |
| 348 |
| 349 if (has_2nd_order) { |
| 350 if (tx_size == TX_8X8) { |
| 351 tokenize_b(cpi, xd, xd->block + 24, t, PLANE_TYPE_Y2, |
| 352 A + vp9_block2above_8x8[24], L + vp9_block2left_8x8[24], |
| 353 TX_8X8, dry_run); |
| 354 } else { |
| 355 tokenize_b(cpi, xd, xd->block + 24, t, PLANE_TYPE_Y2, |
| 356 A + vp9_block2above[24], L + vp9_block2left[24], |
| 357 TX_4X4, dry_run); |
| 358 } |
| 359 |
| 360 plane_type = PLANE_TYPE_Y_NO_DC; |
| 361 } else { |
| 362 xd->above_context->y2 = 1; |
| 363 xd->left_context->y2 = 1; |
| 364 plane_type = PLANE_TYPE_Y_WITH_DC; |
| 365 } |
| 366 |
| 367 if (tx_size == TX_16X16) { |
| 368 tokenize_b(cpi, xd, xd->block, t, PLANE_TYPE_Y_WITH_DC, |
| 369 A, L, TX_16X16, dry_run); |
| 370 A[1] = A[2] = A[3] = A[0]; |
| 371 L[1] = L[2] = L[3] = L[0]; |
| 372 |
| 373 for (b = 16; b < 24; b += 4) { |
| 374 tokenize_b(cpi, xd, xd->block + b, t, PLANE_TYPE_UV, |
| 375 A + vp9_block2above_8x8[b], L + vp9_block2left_8x8[b], |
| 376 TX_8X8, dry_run); |
| 377 A[vp9_block2above_8x8[b] + 1] = A[vp9_block2above_8x8[b]]; |
| 378 L[vp9_block2left_8x8[b] + 1] = L[vp9_block2left_8x8[b]]; |
| 379 } |
| 380 A[8] = 0; |
| 381 L[8] = 0; |
| 382 } else if (tx_size == TX_8X8) { |
| 383 for (b = 0; b < 16; b += 4) { |
| 384 tokenize_b(cpi, xd, xd->block + b, t, plane_type, |
| 385 A + vp9_block2above_8x8[b], L + vp9_block2left_8x8[b], |
| 386 TX_8X8, dry_run); |
| 387 A[vp9_block2above_8x8[b] + 1] = A[vp9_block2above_8x8[b]]; |
| 388 L[vp9_block2left_8x8[b] + 1] = L[vp9_block2left_8x8[b]]; |
| 389 } |
| 390 if (xd->mode_info_context->mbmi.mode == I8X8_PRED || |
| 391 xd->mode_info_context->mbmi.mode == SPLITMV) { |
| 392 for (b = 16; b < 24; b++) { |
| 393 tokenize_b(cpi, xd, xd->block + b, t, PLANE_TYPE_UV, |
| 394 A + vp9_block2above[b], L + vp9_block2left[b], |
| 395 TX_4X4, dry_run); |
| 396 } |
| 397 } else { |
| 398 for (b = 16; b < 24; b += 4) { |
| 399 tokenize_b(cpi, xd, xd->block + b, t, PLANE_TYPE_UV, |
| 400 A + vp9_block2above_8x8[b], L + vp9_block2left_8x8[b], |
| 401 TX_8X8, dry_run); |
| 402 A[vp9_block2above_8x8[b] + 1] = A[vp9_block2above_8x8[b]]; |
| 403 L[vp9_block2left_8x8[b] + 1] = L[vp9_block2left_8x8[b]]; |
| 404 } |
| 405 } |
| 406 } else { |
| 407 for (b = 0; b < 16; b++) { |
| 408 tokenize_b(cpi, xd, xd->block + b, t, plane_type, |
| 409 A + vp9_block2above[b], L + vp9_block2left[b], |
| 410 TX_4X4, dry_run); |
| 411 } |
| 412 |
| 413 for (b = 16; b < 24; b++) { |
| 414 tokenize_b(cpi, xd, xd->block + b, t, PLANE_TYPE_UV, |
| 415 A + vp9_block2above[b], L + vp9_block2left[b], |
| 416 TX_4X4, dry_run); |
| 417 } |
| 418 } |
| 419 if (dry_run) |
| 420 *t = t_backup; |
| 421 } |
| 422 |
| 423 |
| 424 #ifdef ENTROPY_STATS |
| 425 void init_context_counters(void) { |
| 426 FILE *f = fopen("context.bin", "rb"); |
| 427 if (!f) { |
| 428 vpx_memset(context_counters, 0, sizeof(context_counters)); |
| 429 vpx_memset(context_counters_8x8, 0, sizeof(context_counters_8x8)); |
| 430 vpx_memset(context_counters_16x16, 0, sizeof(context_counters_16x16)); |
| 431 } else { |
| 432 fread(context_counters, sizeof(context_counters), 1, f); |
| 433 fread(context_counters_8x8, sizeof(context_counters_8x8), 1, f); |
| 434 fread(context_counters_16x16, sizeof(context_counters_16x16), 1, f); |
| 435 fclose(f); |
| 436 } |
| 437 |
| 438 f = fopen("treeupdate.bin", "rb"); |
| 439 if (!f) { |
| 440 vpx_memset(tree_update_hist, 0, sizeof(tree_update_hist)); |
| 441 vpx_memset(tree_update_hist_8x8, 0, sizeof(tree_update_hist_8x8)); |
| 442 vpx_memset(tree_update_hist_16x16, 0, sizeof(tree_update_hist_16x16)); |
| 443 } else { |
| 444 fread(tree_update_hist, sizeof(tree_update_hist), 1, f); |
| 445 fread(tree_update_hist_8x8, sizeof(tree_update_hist_8x8), 1, f); |
| 446 fread(tree_update_hist_16x16, sizeof(tree_update_hist_16x16), 1, f); |
| 447 fclose(f); |
| 448 } |
| 449 } |
| 450 |
| 451 void print_context_counters() { |
| 452 int type, band, pt, t; |
| 453 FILE *f = fopen("vp9_context.c", "w"); |
| 454 |
| 455 fprintf(f, "#include \"vp9_entropy.h\"\n"); |
| 456 fprintf(f, "\n/* *** GENERATED FILE: DO NOT EDIT *** */\n\n"); |
| 457 fprintf(f, "static const unsigned int\n" |
| 458 "vp9_default_coef_counts[BLOCK_TYPES]\n" |
| 459 " [COEF_BANDS]\n" |
| 460 " [PREV_COEF_CONTEXTS]\n" |
| 461 " [MAX_ENTROPY_TOKENS]={\n"); |
| 462 |
| 463 # define Comma( X) (X? ",":"") |
| 464 type = 0; |
| 465 do { |
| 466 fprintf(f, "%s\n { /* block Type %d */", Comma(type), type); |
| 467 band = 0; |
| 468 do { |
| 469 fprintf(f, "%s\n { /* Coeff Band %d */", Comma(band), band); |
| 470 pt = 0; |
| 471 do { |
| 472 fprintf(f, "%s\n {", Comma(pt)); |
| 473 |
| 474 t = 0; |
| 475 do { |
| 476 const INT64 x = context_counters [type] [band] [pt] [t]; |
| 477 const int y = (int) x; |
| 478 assert(x == (INT64) y); /* no overflow handling yet */ |
| 479 fprintf(f, "%s %d", Comma(t), y); |
| 480 } while (++t < MAX_ENTROPY_TOKENS); |
| 481 fprintf(f, "}"); |
| 482 } while (++pt < PREV_COEF_CONTEXTS); |
| 483 fprintf(f, "\n }"); |
| 484 } while (++band < COEF_BANDS); |
| 485 fprintf(f, "\n }"); |
| 486 } while (++type < BLOCK_TYPES); |
| 487 fprintf(f, "\n};\n"); |
| 488 |
| 489 fprintf(f, "static const unsigned int\nvp9_default_coef_counts_8x8" |
| 490 "[BLOCK_TYPES_8X8] [COEF_BANDS]" |
| 491 "[PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS] = {"); |
| 492 type = 0; |
| 493 do { |
| 494 fprintf(f, "%s\n { /* block Type %d */", Comma(type), type); |
| 495 band = 0; |
| 496 do { |
| 497 fprintf(f, "%s\n { /* Coeff Band %d */", Comma(band), band); |
| 498 pt = 0; |
| 499 do { |
| 500 fprintf(f, "%s\n {", Comma(pt)); |
| 501 t = 0; |
| 502 do { |
| 503 const INT64 x = context_counters_8x8 [type] [band] [pt] [t]; |
| 504 const int y = (int) x; |
| 505 |
| 506 assert(x == (INT64) y); /* no overflow handling yet */ |
| 507 fprintf(f, "%s %d", Comma(t), y); |
| 508 |
| 509 } while (++t < MAX_ENTROPY_TOKENS); |
| 510 |
| 511 fprintf(f, "}"); |
| 512 } while (++pt < PREV_COEF_CONTEXTS); |
| 513 |
| 514 fprintf(f, "\n }"); |
| 515 |
| 516 } while (++band < COEF_BANDS); |
| 517 |
| 518 fprintf(f, "\n }"); |
| 519 } while (++type < BLOCK_TYPES_8X8); |
| 520 fprintf(f, "\n};\n"); |
| 521 |
| 522 fprintf(f, "static const unsigned int\nvp9_default_coef_counts_16x16" |
| 523 "[BLOCK_TYPES_16X16] [COEF_BANDS]" |
| 524 "[PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS] = {"); |
| 525 type = 0; |
| 526 do { |
| 527 fprintf(f, "%s\n { /* block Type %d */", Comma(type), type); |
| 528 band = 0; |
| 529 do { |
| 530 fprintf(f, "%s\n { /* Coeff Band %d */", Comma(band), band); |
| 531 pt = 0; |
| 532 do { |
| 533 fprintf(f, "%s\n {", Comma(pt)); |
| 534 t = 0; |
| 535 do { |
| 536 const INT64 x = context_counters_16x16 [type] [band] [pt] [t]; |
| 537 const int y = (int) x; |
| 538 |
| 539 assert(x == (INT64) y); /* no overflow handling yet */ |
| 540 fprintf(f, "%s %d", Comma(t), y); |
| 541 |
| 542 } while (++t < MAX_ENTROPY_TOKENS); |
| 543 |
| 544 fprintf(f, "}"); |
| 545 } while (++pt < PREV_COEF_CONTEXTS); |
| 546 |
| 547 fprintf(f, "\n }"); |
| 548 |
| 549 } while (++band < COEF_BANDS); |
| 550 |
| 551 fprintf(f, "\n }"); |
| 552 } while (++type < BLOCK_TYPES_16X16); |
| 553 fprintf(f, "\n};\n"); |
| 554 |
| 555 fprintf(f, "static const vp9_prob\n" |
| 556 "vp9_default_coef_probs[BLOCK_TYPES] [COEF_BANDS] \n" |
| 557 "[PREV_COEF_CONTEXTS] [ENTROPY_NODES] = {"); |
| 558 type = 0; |
| 559 do { |
| 560 fprintf(f, "%s\n { /* block Type %d */", Comma(type), type); |
| 561 band = 0; |
| 562 do { |
| 563 fprintf(f, "%s\n { /* Coeff Band %d */", Comma(band), band); |
| 564 pt = 0; |
| 565 do { |
| 566 unsigned int branch_ct [ENTROPY_NODES] [2]; |
| 567 unsigned int coef_counts[MAX_ENTROPY_TOKENS]; |
| 568 vp9_prob coef_probs[ENTROPY_NODES]; |
| 569 for (t = 0; t < MAX_ENTROPY_TOKENS; ++t) |
| 570 coef_counts[t] = context_counters [type] [band] [pt] [t]; |
| 571 vp9_tree_probs_from_distribution( |
| 572 MAX_ENTROPY_TOKENS, vp9_coef_encodings, vp9_coef_tree, |
| 573 coef_probs, branch_ct, coef_counts, 256, 1); |
| 574 fprintf(f, "%s\n {", Comma(pt)); |
| 575 |
| 576 t = 0; |
| 577 do { |
| 578 fprintf(f, "%s %d", Comma(t), coef_probs[t]); |
| 579 |
| 580 } while (++t < ENTROPY_NODES); |
| 581 |
| 582 fprintf(f, "}"); |
| 583 } while (++pt < PREV_COEF_CONTEXTS); |
| 584 fprintf(f, "\n }"); |
| 585 } while (++band < COEF_BANDS); |
| 586 fprintf(f, "\n }"); |
| 587 } while (++type < BLOCK_TYPES); |
| 588 fprintf(f, "\n};\n"); |
| 589 |
| 590 fprintf(f, "static const vp9_prob\n" |
| 591 "vp9_default_coef_probs_8x8[BLOCK_TYPES_8X8] [COEF_BANDS]\n" |
| 592 "[PREV_COEF_CONTEXTS] [ENTROPY_NODES] = {"); |
| 593 type = 0; |
| 594 do { |
| 595 fprintf(f, "%s\n { /* block Type %d */", Comma(type), type); |
| 596 band = 0; |
| 597 do { |
| 598 fprintf(f, "%s\n { /* Coeff Band %d */", Comma(band), band); |
| 599 pt = 0; |
| 600 do { |
| 601 unsigned int branch_ct [ENTROPY_NODES] [2]; |
| 602 unsigned int coef_counts[MAX_ENTROPY_TOKENS]; |
| 603 vp9_prob coef_probs[ENTROPY_NODES]; |
| 604 for (t = 0; t < MAX_ENTROPY_TOKENS; ++t) |
| 605 coef_counts[t] = context_counters_8x8[type] [band] [pt] [t]; |
| 606 vp9_tree_probs_from_distribution( |
| 607 MAX_ENTROPY_TOKENS, vp9_coef_encodings, vp9_coef_tree, |
| 608 coef_probs, branch_ct, coef_counts, 256, 1); |
| 609 fprintf(f, "%s\n {", Comma(pt)); |
| 610 |
| 611 t = 0; |
| 612 do { |
| 613 fprintf(f, "%s %d", Comma(t), coef_probs[t]); |
| 614 } while (++t < ENTROPY_NODES); |
| 615 fprintf(f, "}"); |
| 616 } while (++pt < PREV_COEF_CONTEXTS); |
| 617 fprintf(f, "\n }"); |
| 618 } while (++band < COEF_BANDS); |
| 619 fprintf(f, "\n }"); |
| 620 } while (++type < BLOCK_TYPES_8X8); |
| 621 fprintf(f, "\n};\n"); |
| 622 |
| 623 fprintf(f, "static const vp9_prob\n" |
| 624 "vp9_default_coef_probs_16x16[BLOCK_TYPES_16X16] [COEF_BANDS]\n" |
| 625 "[PREV_COEF_CONTEXTS] [ENTROPY_NODES] = {"); |
| 626 type = 0; |
| 627 do { |
| 628 fprintf(f, "%s\n { /* block Type %d */", Comma(type), type); |
| 629 band = 0; |
| 630 do { |
| 631 fprintf(f, "%s\n { /* Coeff Band %d */", Comma(band), band); |
| 632 pt = 0; |
| 633 do { |
| 634 unsigned int branch_ct [ENTROPY_NODES] [2]; |
| 635 unsigned int coef_counts[MAX_ENTROPY_TOKENS]; |
| 636 vp9_prob coef_probs[ENTROPY_NODES]; |
| 637 for (t = 0; t < MAX_ENTROPY_TOKENS; ++t) |
| 638 coef_counts[t] = context_counters_16x16[type] [band] [pt] [t]; |
| 639 vp9_tree_probs_from_distribution( |
| 640 MAX_ENTROPY_TOKENS, vp9_coef_encodings, vp9_coef_tree, |
| 641 coef_probs, branch_ct, coef_counts, 256, 1); |
| 642 fprintf(f, "%s\n {", Comma(pt)); |
| 643 |
| 644 t = 0; |
| 645 do { |
| 646 fprintf(f, "%s %d", Comma(t), coef_probs[t]); |
| 647 } while (++t < ENTROPY_NODES); |
| 648 fprintf(f, "}"); |
| 649 } while (++pt < PREV_COEF_CONTEXTS); |
| 650 fprintf(f, "\n }"); |
| 651 } while (++band < COEF_BANDS); |
| 652 fprintf(f, "\n }"); |
| 653 } while (++type < BLOCK_TYPES_16X16); |
| 654 fprintf(f, "\n};\n"); |
| 655 |
| 656 fclose(f); |
| 657 |
| 658 f = fopen("context.bin", "wb"); |
| 659 fwrite(context_counters, sizeof(context_counters), 1, f); |
| 660 fwrite(context_counters_8x8, sizeof(context_counters_8x8), 1, f); |
| 661 fwrite(context_counters_16x16, sizeof(context_counters_16x16), 1, f); |
| 662 fclose(f); |
| 663 } |
| 664 #endif |
| 665 |
| 666 void vp9_tokenize_initialize() { |
| 667 fill_value_tokens(); |
| 668 } |
| 669 |
| 670 static __inline void stuff_b(VP9_COMP *cpi, |
| 671 MACROBLOCKD *xd, |
| 672 const BLOCKD * const b, |
| 673 TOKENEXTRA **tp, |
| 674 PLANE_TYPE type, |
| 675 ENTROPY_CONTEXT *a, |
| 676 ENTROPY_CONTEXT *l, |
| 677 TX_SIZE tx_size, |
| 678 int dry_run) { |
| 679 const int *bands; |
| 680 unsigned int (*counts)[COEF_BANDS][PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS]; |
| 681 vp9_prob (*probs)[COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES]; |
| 682 int pt, band; |
| 683 TOKENEXTRA *t = *tp; |
| 684 const TX_TYPE tx_type = (type == PLANE_TYPE_Y_WITH_DC) ? |
| 685 get_tx_type(xd, b) : DCT_DCT; |
| 686 VP9_COMBINEENTROPYCONTEXTS(pt, *a, *l); |
| 687 |
| 688 switch (tx_size) { |
| 689 default: |
| 690 case TX_4X4: |
| 691 bands = vp9_coef_bands; |
| 692 if (tx_type != DCT_DCT) { |
| 693 counts = cpi->hybrid_coef_counts; |
| 694 probs = cpi->common.fc.hybrid_coef_probs; |
| 695 } else { |
| 696 counts = cpi->coef_counts; |
| 697 probs = cpi->common.fc.coef_probs; |
| 698 } |
| 699 break; |
| 700 case TX_8X8: |
| 701 bands = vp9_coef_bands_8x8; |
| 702 if (tx_type != DCT_DCT) { |
| 703 counts = cpi->hybrid_coef_counts_8x8; |
| 704 probs = cpi->common.fc.hybrid_coef_probs_8x8; |
| 705 } else { |
| 706 counts = cpi->coef_counts_8x8; |
| 707 probs = cpi->common.fc.coef_probs_8x8; |
| 708 } |
| 709 break; |
| 710 case TX_16X16: |
| 711 bands = vp9_coef_bands_16x16; |
| 712 if (tx_type != DCT_DCT) { |
| 713 counts = cpi->hybrid_coef_counts_16x16; |
| 714 probs = cpi->common.fc.hybrid_coef_probs_16x16; |
| 715 } else { |
| 716 counts = cpi->coef_counts_16x16; |
| 717 probs = cpi->common.fc.coef_probs_16x16; |
| 718 } |
| 719 break; |
| 720 } |
| 721 band = bands[(type == PLANE_TYPE_Y_NO_DC) ? 1 : 0]; |
| 722 t->Token = DCT_EOB_TOKEN; |
| 723 t->context_tree = probs[type][band][pt]; |
| 724 t->skip_eob_node = 0; |
| 725 ++t; |
| 726 *tp = t; |
| 727 *a = *l = 0; |
| 728 if (!dry_run) { |
| 729 ++counts[type][band][pt][DCT_EOB_TOKEN]; |
| 730 } |
| 731 } |
| 732 |
| 733 static void stuff_mb_8x8(VP9_COMP *cpi, MACROBLOCKD *xd, |
| 734 TOKENEXTRA **t, int dry_run) { |
| 735 ENTROPY_CONTEXT *A = (ENTROPY_CONTEXT *)xd->above_context; |
| 736 ENTROPY_CONTEXT *L = (ENTROPY_CONTEXT *)xd->left_context; |
| 737 PLANE_TYPE plane_type; |
| 738 int b; |
| 739 int has_2nd_order = get_2nd_order_usage(xd); |
| 740 |
| 741 if (has_2nd_order) { |
| 742 stuff_b(cpi, xd, xd->block + 24, t, PLANE_TYPE_Y2, |
| 743 A + vp9_block2above_8x8[24], L + vp9_block2left_8x8[24], |
| 744 TX_8X8, dry_run); |
| 745 plane_type = PLANE_TYPE_Y_NO_DC; |
| 746 } else { |
| 747 xd->above_context->y2 = 1; |
| 748 xd->left_context->y2 = 1; |
| 749 plane_type = PLANE_TYPE_Y_WITH_DC; |
| 750 } |
| 751 |
| 752 for (b = 0; b < 16; b += 4) { |
| 753 stuff_b(cpi, xd, xd->block + b, t, plane_type, A + vp9_block2above_8x8[b], |
| 754 L + vp9_block2left_8x8[b], TX_8X8, dry_run); |
| 755 A[vp9_block2above_8x8[b] + 1] = A[vp9_block2above_8x8[b]]; |
| 756 L[vp9_block2left_8x8[b] + 1] = L[vp9_block2left_8x8[b]]; |
| 757 } |
| 758 |
| 759 for (b = 16; b < 24; b += 4) { |
| 760 stuff_b(cpi, xd, xd->block + b, t, PLANE_TYPE_UV, |
| 761 A + vp9_block2above_8x8[b], L + vp9_block2left_8x8[b], |
| 762 TX_8X8, dry_run); |
| 763 A[vp9_block2above_8x8[b] + 1] = A[vp9_block2above_8x8[b]]; |
| 764 L[vp9_block2left_8x8[b] + 1] = L[vp9_block2left_8x8[b]]; |
| 765 } |
| 766 } |
| 767 |
| 768 static void stuff_mb_16x16(VP9_COMP *cpi, MACROBLOCKD *xd, |
| 769 TOKENEXTRA **t, int dry_run) { |
| 770 ENTROPY_CONTEXT * A = (ENTROPY_CONTEXT *)xd->above_context; |
| 771 ENTROPY_CONTEXT * L = (ENTROPY_CONTEXT *)xd->left_context; |
| 772 int b; |
| 773 |
| 774 stuff_b(cpi, xd, xd->block, t, PLANE_TYPE_Y_WITH_DC, A, L, TX_16X16, dry_run); |
| 775 A[1] = A[2] = A[3] = A[0]; |
| 776 L[1] = L[2] = L[3] = L[0]; |
| 777 for (b = 16; b < 24; b += 4) { |
| 778 stuff_b(cpi, xd, xd->block + b, t, PLANE_TYPE_UV, A + vp9_block2above[b], |
| 779 L + vp9_block2above_8x8[b], TX_8X8, dry_run); |
| 780 A[vp9_block2above_8x8[b] + 1] = A[vp9_block2above_8x8[b]]; |
| 781 L[vp9_block2left_8x8[b] + 1] = L[vp9_block2left_8x8[b]]; |
| 782 } |
| 783 vpx_memset(&A[8], 0, sizeof(A[8])); |
| 784 vpx_memset(&L[8], 0, sizeof(L[8])); |
| 785 } |
| 786 |
| 787 static void stuff_mb_4x4(VP9_COMP *cpi, MACROBLOCKD *xd, |
| 788 TOKENEXTRA **t, int dry_run) { |
| 789 ENTROPY_CONTEXT *A = (ENTROPY_CONTEXT *)xd->above_context; |
| 790 ENTROPY_CONTEXT *L = (ENTROPY_CONTEXT *)xd->left_context; |
| 791 int b; |
| 792 PLANE_TYPE plane_type; |
| 793 int has_2nd_order = (xd->mode_info_context->mbmi.mode != B_PRED && |
| 794 xd->mode_info_context->mbmi.mode != I8X8_PRED && |
| 795 xd->mode_info_context->mbmi.mode != SPLITMV); |
| 796 if (has_2nd_order && get_tx_type(xd, &xd->block[0]) != DCT_DCT) |
| 797 has_2nd_order = 0; |
| 798 |
| 799 if (has_2nd_order) { |
| 800 stuff_b(cpi, xd, xd->block + 24, t, PLANE_TYPE_Y2, A + vp9_block2above[24], |
| 801 L + vp9_block2left[24], TX_4X4, dry_run); |
| 802 plane_type = PLANE_TYPE_Y_NO_DC; |
| 803 } else { |
| 804 xd->above_context->y2 = 1; |
| 805 xd->left_context->y2 = 1; |
| 806 plane_type = PLANE_TYPE_Y_WITH_DC; |
| 807 } |
| 808 |
| 809 for (b = 0; b < 16; b++) |
| 810 stuff_b(cpi, xd, xd->block + b, t, plane_type, A + vp9_block2above[b], |
| 811 L + vp9_block2left[b], TX_4X4, dry_run); |
| 812 |
| 813 for (b = 16; b < 24; b++) |
| 814 stuff_b(cpi, xd, xd->block + b, t, PLANE_TYPE_UV, A + vp9_block2above[b], |
| 815 L + vp9_block2left[b], TX_4X4, dry_run); |
| 816 } |
| 817 |
| 818 static void stuff_mb_8x8_4x4uv(VP9_COMP *cpi, MACROBLOCKD *xd, |
| 819 TOKENEXTRA **t, int dry_run) { |
| 820 ENTROPY_CONTEXT *A = (ENTROPY_CONTEXT *)xd->above_context; |
| 821 ENTROPY_CONTEXT *L = (ENTROPY_CONTEXT *)xd->left_context; |
| 822 PLANE_TYPE plane_type; |
| 823 int b; |
| 824 |
| 825 int has_2nd_order = get_2nd_order_usage(xd); |
| 826 if (has_2nd_order) { |
| 827 stuff_b(cpi, xd, xd->block + 24, t, PLANE_TYPE_Y2, |
| 828 A + vp9_block2above_8x8[24], L + vp9_block2left_8x8[24], |
| 829 TX_8X8, dry_run); |
| 830 plane_type = PLANE_TYPE_Y_NO_DC; |
| 831 } else { |
| 832 plane_type = PLANE_TYPE_Y_WITH_DC; |
| 833 } |
| 834 |
| 835 for (b = 0; b < 16; b += 4) { |
| 836 stuff_b(cpi, xd, xd->block + b, t, plane_type, |
| 837 A + vp9_block2above_8x8[b], L + vp9_block2left_8x8[b], |
| 838 TX_8X8, dry_run); |
| 839 A[vp9_block2above_8x8[b] + 1] = A[vp9_block2above_8x8[b]]; |
| 840 L[vp9_block2left_8x8[b] + 1] = L[vp9_block2left_8x8[b]]; |
| 841 } |
| 842 |
| 843 for (b = 16; b < 24; b++) |
| 844 stuff_b(cpi, xd, xd->block + b, t, PLANE_TYPE_UV, A + vp9_block2above[b], |
| 845 L + vp9_block2left[b], TX_4X4, dry_run); |
| 846 xd->above_context->y2 = 1; |
| 847 xd->left_context->y2 = 1; |
| 848 } |
| 849 |
| 850 void vp9_stuff_mb(VP9_COMP *cpi, MACROBLOCKD *xd, TOKENEXTRA **t, int dry_run) { |
| 851 TX_SIZE tx_size = xd->mode_info_context->mbmi.txfm_size; |
| 852 TOKENEXTRA * const t_backup = *t; |
| 853 |
| 854 if (tx_size == TX_16X16) { |
| 855 stuff_mb_16x16(cpi, xd, t, dry_run); |
| 856 } else if (tx_size == TX_8X8) { |
| 857 if (xd->mode_info_context->mbmi.mode == I8X8_PRED || |
| 858 xd->mode_info_context->mbmi.mode == SPLITMV) { |
| 859 stuff_mb_8x8_4x4uv(cpi, xd, t, dry_run); |
| 860 } else { |
| 861 stuff_mb_8x8(cpi, xd, t, dry_run); |
| 862 } |
| 863 } else { |
| 864 stuff_mb_4x4(cpi, xd, t, dry_run); |
| 865 } |
| 866 |
| 867 if (dry_run) { |
| 868 *t = t_backup; |
| 869 } |
| 870 } |
| 871 |
| 872 void vp9_fix_contexts(MACROBLOCKD *xd) { |
| 873 /* Clear entropy contexts for blocks */ |
| 874 if ((xd->mode_info_context->mbmi.mode != B_PRED |
| 875 && xd->mode_info_context->mbmi.mode != I8X8_PRED |
| 876 && xd->mode_info_context->mbmi.mode != SPLITMV) |
| 877 || xd->mode_info_context->mbmi.txfm_size == TX_16X16 |
| 878 ) { |
| 879 vpx_memset(xd->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)); |
| 880 vpx_memset(xd->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)); |
| 881 } else { |
| 882 vpx_memset(xd->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1); |
| 883 vpx_memset(xd->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1); |
| 884 xd->above_context->y2 = 1; |
| 885 xd->left_context->y2 = 1; |
| 886 } |
| 887 } |
OLD | NEW |