vp9_tokenize.c 28.3 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5 6
 *  that can be found in the LICENSE file in the root of the source
 *  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.
John Koleszar's avatar
John Koleszar committed
9 10 11 12 13 14 15
 */


#include <math.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
16 17
#include "vp9/encoder/vp9_onyx_int.h"
#include "vp9/encoder/vp9_tokenize.h"
John Koleszar's avatar
John Koleszar committed
18 19
#include "vpx_mem/vpx_mem.h"

20 21 22
#include "vp9/common/vp9_pred_common.h"
#include "vp9/common/vp9_seg_common.h"
#include "vp9/common/vp9_entropy.h"
23

John Koleszar's avatar
John Koleszar committed
24
/* Global event counters used for accumulating statistics across several
25
   compressions, then generating vp9_context.c = initial stats. */
John Koleszar's avatar
John Koleszar committed
26 27

#ifdef ENTROPY_STATS
28
INT64 context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];
29 30
INT64 hybrid_context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];

31
INT64 context_counters_8x8[BLOCK_TYPES_8X8] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];
32 33
INT64 hybrid_context_counters_8x8[BLOCK_TYPES_8X8] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];

Daniel Kang's avatar
Daniel Kang committed
34
INT64 context_counters_16x16[BLOCK_TYPES_16X16] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];
35 36
INT64 hybrid_context_counters_16x16[BLOCK_TYPES_16X16] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];

Daniel Kang's avatar
Daniel Kang committed
37 38
extern unsigned int tree_update_hist[BLOCK_TYPES][COEF_BANDS]
                    [PREV_COEF_CONTEXTS][ENTROPY_NODES][2];
39 40
extern unsigned int hybrid_tree_update_hist[BLOCK_TYPES][COEF_BANDS]
                    [PREV_COEF_CONTEXTS][ENTROPY_NODES][2];
Daniel Kang's avatar
Daniel Kang committed
41 42
extern unsigned int tree_update_hist_8x8[BLOCK_TYPES_8X8][COEF_BANDS]
                    [PREV_COEF_CONTEXTS][ENTROPY_NODES] [2];
43 44
extern unsigned int hybrid_tree_update_hist_8x8[BLOCK_TYPES_8X8][COEF_BANDS]
                    [PREV_COEF_CONTEXTS][ENTROPY_NODES] [2];
Daniel Kang's avatar
Daniel Kang committed
45 46
extern unsigned int tree_update_hist_16x16[BLOCK_TYPES_16X16][COEF_BANDS]
                    [PREV_COEF_CONTEXTS][ENTROPY_NODES] [2];
47 48
extern unsigned int hybrid_tree_update_hist_16x16[BLOCK_TYPES_16X16][COEF_BANDS]
                    [PREV_COEF_CONTEXTS][ENTROPY_NODES] [2];
49 50
#endif  /* ENTROPY_STATS */

John Koleszar's avatar
John Koleszar committed
51
static TOKENVALUE dct_value_tokens[DCT_MAX_VALUE * 2];
52
const TOKENVALUE *vp9_dct_value_tokens_ptr;
John Koleszar's avatar
John Koleszar committed
53
static int dct_value_cost[DCT_MAX_VALUE * 2];
54
const int *vp9_dct_value_cost_ptr;
55

John Koleszar's avatar
John Koleszar committed
56
static void fill_value_tokens() {
John Koleszar's avatar
John Koleszar committed
57

John Koleszar's avatar
John Koleszar committed
58
  TOKENVALUE *const t = dct_value_tokens + DCT_MAX_VALUE;
59
  vp9_extra_bit_struct *const e = vp9_extra_bits;
John Koleszar's avatar
John Koleszar committed
60

John Koleszar's avatar
John Koleszar committed
61 62
  int i = -DCT_MAX_VALUE;
  int sign = 1;
John Koleszar's avatar
John Koleszar committed
63

John Koleszar's avatar
John Koleszar committed
64 65 66
  do {
    if (!i)
      sign = 0;
John Koleszar's avatar
John Koleszar committed
67

John Koleszar's avatar
John Koleszar committed
68 69 70
    {
      const int a = sign ? -i : i;
      int eb = sign;
John Koleszar's avatar
John Koleszar committed
71

John Koleszar's avatar
John Koleszar committed
72 73
      if (a > 4) {
        int j = 4;
John Koleszar's avatar
John Koleszar committed
74

John Koleszar's avatar
John Koleszar committed
75
        while (++j < 11  &&  e[j].base_val <= a) {}
John Koleszar's avatar
John Koleszar committed
76

John Koleszar's avatar
John Koleszar committed
77 78 79 80
        t[i].Token = --j;
        eb |= (a - e[j].base_val) << 1;
      } else
        t[i].Token = a;
John Koleszar's avatar
John Koleszar committed
81

John Koleszar's avatar
John Koleszar committed
82 83
      t[i].Extra = eb;
    }
John Koleszar's avatar
John Koleszar committed
84

John Koleszar's avatar
John Koleszar committed
85 86 87
    // initialize the cost for extra bits for all possible coefficient value.
    {
      int cost = 0;
88
      vp9_extra_bit_struct *p = vp9_extra_bits + t[i].Token;
John Koleszar's avatar
John Koleszar committed
89

John Koleszar's avatar
John Koleszar committed
90 91 92
      if (p->base_val) {
        const int extra = t[i].Extra;
        const int Length = p->Len;
John Koleszar's avatar
John Koleszar committed
93

John Koleszar's avatar
John Koleszar committed
94
        if (Length)
95
          cost += treed_cost(p->tree, p->prob, extra >> 1, Length);
John Koleszar's avatar
John Koleszar committed
96

97
        cost += vp9_cost_bit(vp9_prob_half, extra & 1); /* sign */
John Koleszar's avatar
John Koleszar committed
98 99
        dct_value_cost[i + DCT_MAX_VALUE] = cost;
      }
John Koleszar's avatar
John Koleszar committed
100 101 102

    }

John Koleszar's avatar
John Koleszar committed
103 104
  } while (++i < DCT_MAX_VALUE);

105 106
  vp9_dct_value_tokens_ptr = dct_value_tokens + DCT_MAX_VALUE;
  vp9_dct_value_cost_ptr   = dct_value_cost + DCT_MAX_VALUE;
John Koleszar's avatar
John Koleszar committed
107 108
}

109
static void tokenize_b(VP9_COMP *cpi,
110 111 112 113 114 115 116 117
                       MACROBLOCKD *xd,
                       const BLOCKD * const b,
                       TOKENEXTRA **tp,
                       PLANE_TYPE type,
                       ENTROPY_CONTEXT *a,
                       ENTROPY_CONTEXT *l,
                       TX_SIZE tx_size,
                       int dry_run) {
Daniel Kang's avatar
Daniel Kang committed
118
  int pt; /* near block/prev token context index */
119
  int c = (type == PLANE_TYPE_Y_NO_DC) ? 1 : 0;
Daniel Kang's avatar
Daniel Kang committed
120 121 122
  const int eob = b->eob;     /* one beyond last nonzero coeff */
  TOKENEXTRA *t = *tp;        /* store tokens starting here */
  const short *qcoeff_ptr = b->qcoeff;
123
  int seg_eob;
Daniel Kang's avatar
Daniel Kang committed
124
  int segment_id = xd->mode_info_context->mbmi.segment_id;
125 126
  const int *bands, *scan;
  unsigned int (*counts)[COEF_BANDS][PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS];
127
  vp9_prob (*probs)[COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES];
128 129
  const TX_TYPE tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
                          get_tx_type(xd, b) : DCT_DCT;
Daniel Kang's avatar
Daniel Kang committed
130

131
  VP9_COMBINEENTROPYCONTEXTS(pt, *a, *l);
132 133 134 135
  switch (tx_size) {
    default:
    case TX_4X4:
      seg_eob = 16;
136 137
      bands = vp9_coef_bands;
      scan = vp9_default_zig_zag1d;
138 139 140 141
      if (tx_type != DCT_DCT) {
        counts = cpi->hybrid_coef_counts;
        probs = cpi->common.fc.hybrid_coef_probs;
        if (tx_type == ADST_DCT) {
142
          scan = vp9_row_scan;
143
        } else if (tx_type == DCT_ADST) {
144
          scan = vp9_col_scan;
145 146 147 148 149 150 151 152 153
        }
      } else {
        counts = cpi->coef_counts;
        probs = cpi->common.fc.coef_probs;
      }
      break;
    case TX_8X8:
      if (type == PLANE_TYPE_Y2) {
        seg_eob = 4;
154 155
        bands = vp9_coef_bands;
        scan = vp9_default_zig_zag1d;
156 157
      } else {
        seg_eob = 64;
158 159
        bands = vp9_coef_bands_8x8;
        scan = vp9_default_zig_zag1d_8x8;
160 161 162 163 164 165 166 167 168 169 170
      }
      if (tx_type != DCT_DCT) {
        counts = cpi->hybrid_coef_counts_8x8;
        probs = cpi->common.fc.hybrid_coef_probs_8x8;
      } else {
        counts = cpi->coef_counts_8x8;
        probs = cpi->common.fc.coef_probs_8x8;
      }
      break;
    case TX_16X16:
      seg_eob = 256;
171 172
      bands = vp9_coef_bands_16x16;
      scan = vp9_default_zig_zag1d_16x16;
173 174 175 176 177 178 179 180
      if (tx_type != DCT_DCT) {
        counts = cpi->hybrid_coef_counts_16x16;
        probs = cpi->common.fc.hybrid_coef_probs_16x16;
      } else {
        counts = cpi->coef_counts_16x16;
        probs = cpi->common.fc.coef_probs_16x16;
      }
      break;
John Koleszar's avatar
John Koleszar committed
181 182
  }

183 184
  if (vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB))
    seg_eob = vp9_get_segdata(xd, segment_id, SEG_LVL_EOB);
John Koleszar's avatar
John Koleszar committed
185

186
  do {
187
    const int band = bands[c];
188 189 190
    int token;

    if (c < eob) {
191
      const int rc = scan[c];
192
      const int v = qcoeff_ptr[rc];
John Koleszar's avatar
John Koleszar committed
193

194 195
      assert(-DCT_MAX_VALUE <= v  &&  v < DCT_MAX_VALUE);

196 197
      t->Extra = vp9_dct_value_tokens_ptr[v].Extra;
      token    = vp9_dct_value_tokens_ptr[v].Token;
198 199 200
    } else {
      token = DCT_EOB_TOKEN;
    }
John Koleszar's avatar
John Koleszar committed
201 202

    t->Token = token;
203 204 205
    t->context_tree = probs[type][band][pt];
    t->skip_eob_node = (pt == 0) && ((band > 0 && type != PLANE_TYPE_Y_NO_DC) ||
                                     (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 213 214
  } while (c < eob && ++c < seg_eob);

  *tp = t;
215
  *a = *l = (c > !type); /* 0 <-> all coeff data is zero */
John Koleszar's avatar
John Koleszar committed
216 217
}

218
int vp9_mby_is_skippable_4x4(MACROBLOCKD *xd, int has_2nd_order) {
John Koleszar's avatar
John Koleszar committed
219 220
  int skip = 1;
  int i = 0;
221

222
  if (has_2nd_order) {
John Koleszar's avatar
John Koleszar committed
223
    for (i = 0; i < 16; i++)
Paul Wilkins's avatar
Paul Wilkins committed
224 225
      skip &= (xd->block[i].eob < 2);
    skip &= (!xd->block[24].eob);
John Koleszar's avatar
John Koleszar committed
226 227
  } else {
    for (i = 0; i < 16; i++)
Paul Wilkins's avatar
Paul Wilkins committed
228
      skip &= (!xd->block[i].eob);
John Koleszar's avatar
John Koleszar committed
229 230
  }
  return skip;
231
}
232

233
int vp9_mbuv_is_skippable_4x4(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
234 235
  int skip = 1;
  int i;
236

John Koleszar's avatar
John Koleszar committed
237
  for (i = 16; i < 24; i++)
Paul Wilkins's avatar
Paul Wilkins committed
238
    skip &= (!xd->block[i].eob);
John Koleszar's avatar
John Koleszar committed
239
  return skip;
240 241
}

242 243
static int mb_is_skippable_4x4(MACROBLOCKD *xd, int has_2nd_order) {
  return (vp9_mby_is_skippable_4x4(xd, has_2nd_order) &
244
          vp9_mbuv_is_skippable_4x4(xd));
245
}
Yaowu Xu's avatar
Yaowu Xu committed
246

247
int vp9_mby_is_skippable_8x8(MACROBLOCKD *xd, int has_2nd_order) {
John Koleszar's avatar
John Koleszar committed
248 249
  int skip = 1;
  int i = 0;
250

251
  if (has_2nd_order) {
Deb Mukherjee's avatar
Deb Mukherjee committed
252 253 254 255 256 257 258
    for (i = 0; i < 16; i += 4)
      skip &= (xd->block[i].eob < 2);
    skip &= (!xd->block[24].eob);
  } else {
    for (i = 0; i < 16; i += 4)
      skip &= (!xd->block[i].eob);
  }
John Koleszar's avatar
John Koleszar committed
259
  return skip;
260
}
261

262
int vp9_mbuv_is_skippable_8x8(MACROBLOCKD *xd) {
Paul Wilkins's avatar
Paul Wilkins committed
263
  return (!xd->block[16].eob) & (!xd->block[20].eob);
264
}
265

266 267
static int mb_is_skippable_8x8(MACROBLOCKD *xd, int has_2nd_order) {
  return (vp9_mby_is_skippable_8x8(xd, has_2nd_order) &
268
          vp9_mbuv_is_skippable_8x8(xd));
Deb Mukherjee's avatar
Deb Mukherjee committed
269 270
}

271 272
static int mb_is_skippable_8x8_4x4uv(MACROBLOCKD *xd, int has_2nd_order) {
  return (vp9_mby_is_skippable_8x8(xd, has_2nd_order) &
273
          vp9_mbuv_is_skippable_4x4(xd));
274
}
Yaowu Xu's avatar
Yaowu Xu committed
275

276
int vp9_mby_is_skippable_16x16(MACROBLOCKD *xd) {
Daniel Kang's avatar
Daniel Kang committed
277
  int skip = 1;
Paul Wilkins's avatar
Paul Wilkins committed
278
  skip &= !xd->block[0].eob;
Daniel Kang's avatar
Daniel Kang committed
279 280 281
  return skip;
}

282 283
static int mb_is_skippable_16x16(MACROBLOCKD *xd) {
  return (vp9_mby_is_skippable_16x16(xd) & vp9_mbuv_is_skippable_8x8(xd));
Daniel Kang's avatar
Daniel Kang committed
284
}
285

286
void vp9_tokenize_mb(VP9_COMP *cpi,
Paul Wilkins's avatar
Paul Wilkins committed
287
                     MACROBLOCKD *xd,
288 289
                     TOKENEXTRA **t,
                     int dry_run) {
290
  PLANE_TYPE plane_type;
291
  int has_2nd_order;
John Koleszar's avatar
John Koleszar committed
292
  int b;
293
  int tx_size = xd->mode_info_context->mbmi.txfm_size;
Paul Wilkins's avatar
Paul Wilkins committed
294
  int mb_skip_context = vp9_get_pred_context(&cpi->common, xd, PRED_MBSKIP);
295
  TOKENEXTRA *t_backup = *t;
296 297
  ENTROPY_CONTEXT * A = (ENTROPY_CONTEXT *) xd->above_context;
  ENTROPY_CONTEXT * L = (ENTROPY_CONTEXT *) xd->left_context;
Paul Wilkins's avatar
Paul Wilkins committed
298

John Koleszar's avatar
John Koleszar committed
299 300 301 302
  // If the MB is going to be skipped because of a segment level flag
  // exclude this from the skip count stats used to calculate the
  // transmitted skip probability;
  int skip_inc;
Paul Wilkins's avatar
Paul Wilkins committed
303
  int segment_id = xd->mode_info_context->mbmi.segment_id;
304

305 306
  if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB) ||
      (vp9_get_segdata(xd, segment_id, SEG_LVL_EOB) != 0)) {
John Koleszar's avatar
John Koleszar committed
307 308 309
    skip_inc = 1;
  } else
    skip_inc = 0;
310

311
  has_2nd_order = get_2nd_order_usage(xd);
John Koleszar's avatar
John Koleszar committed
312

313
  switch (tx_size) {
Daniel Kang's avatar
Daniel Kang committed
314
    case TX_16X16:
Daniel Kang's avatar
Daniel Kang committed
315
      xd->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable_16x16(xd);
Daniel Kang's avatar
Daniel Kang committed
316 317
      break;
    case TX_8X8:
318 319
      if (xd->mode_info_context->mbmi.mode == I8X8_PRED ||
          xd->mode_info_context->mbmi.mode == SPLITMV)
320 321
        xd->mode_info_context->mbmi.mb_skip_coeff =
            mb_is_skippable_8x8_4x4uv(xd, 0);
Deb Mukherjee's avatar
Deb Mukherjee committed
322
      else
323 324
        xd->mode_info_context->mbmi.mb_skip_coeff =
            mb_is_skippable_8x8(xd, has_2nd_order);
Daniel Kang's avatar
Daniel Kang committed
325
      break;
Deb Mukherjee's avatar
Deb Mukherjee committed
326

Daniel Kang's avatar
Daniel Kang committed
327
    default:
328 329
      xd->mode_info_context->mbmi.mb_skip_coeff =
          mb_is_skippable_4x4(xd, has_2nd_order);
Daniel Kang's avatar
Daniel Kang committed
330 331
      break;
  }
332

Paul Wilkins's avatar
Paul Wilkins committed
333
  if (xd->mode_info_context->mbmi.mb_skip_coeff) {
334 335
    if (!dry_run)
      cpi->skip_true_count[mb_skip_context] += skip_inc;
John Koleszar's avatar
John Koleszar committed
336
    if (!cpi->common.mb_no_coeff_skip) {
337
      vp9_stuff_mb(cpi, xd, t, dry_run);
John Koleszar's avatar
John Koleszar committed
338
    } else {
339
      vp9_fix_contexts(xd);
John Koleszar's avatar
John Koleszar committed
340
    }
341 342
    if (dry_run)
      *t = t_backup;
John Koleszar's avatar
John Koleszar committed
343 344 345
    return;
  }

346 347
  if (!dry_run)
    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 354 355
                 TX_8X8, dry_run);
    } else {
      tokenize_b(cpi, xd, xd->block + 24, t, PLANE_TYPE_Y2,
356
                 A + vp9_block2above[24], L + vp9_block2left[24],
357 358
                 TX_4X4, dry_run);
    }
John Koleszar's avatar
John Koleszar committed
359

360
    plane_type = PLANE_TYPE_Y_NO_DC;
Yaowu Xu's avatar
Yaowu Xu committed
361 362 363
  } else {
    xd->above_context->y2 = 1;
    xd->left_context->y2 = 1;
364
    plane_type = PLANE_TYPE_Y_WITH_DC;
Yaowu Xu's avatar
Yaowu Xu committed
365
  }
John Koleszar's avatar
John Koleszar committed
366

367
  if (tx_size == TX_16X16) {
368 369
    tokenize_b(cpi, xd, xd->block, t, PLANE_TYPE_Y_WITH_DC,
               A, L, TX_16X16, dry_run);
370 371
    A[1] = A[2] = A[3] = A[0];
    L[1] = L[2] = L[3] = L[0];
372

Daniel Kang's avatar
Daniel Kang committed
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 378
      A[vp9_block2above_8x8[b] + 1] = A[vp9_block2above_8x8[b]];
      L[vp9_block2left_8x8[b] + 1]  = L[vp9_block2left_8x8[b]];
Daniel Kang's avatar
Daniel Kang committed
379
    }
380 381
    A[8] = 0;
    L[8] = 0;
382
  } else if (tx_size == TX_8X8) {
John Koleszar's avatar
John Koleszar committed
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 388
      A[vp9_block2above_8x8[b] + 1] = A[vp9_block2above_8x8[b]];
      L[vp9_block2left_8x8[b] + 1]  = L[vp9_block2left_8x8[b]];
John Koleszar's avatar
John Koleszar committed
389
    }
390 391
    if (xd->mode_info_context->mbmi.mode == I8X8_PRED ||
        xd->mode_info_context->mbmi.mode == SPLITMV) {
392 393
      for (b = 16; b < 24; b++) {
        tokenize_b(cpi, xd, xd->block + b, t, PLANE_TYPE_UV,
394
                   A + vp9_block2above[b], L + vp9_block2left[b],
395 396
                   TX_4X4, dry_run);
      }
397
    } else {
Deb Mukherjee's avatar
Deb Mukherjee committed
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 403
        A[vp9_block2above_8x8[b] + 1] = A[vp9_block2above_8x8[b]];
        L[vp9_block2left_8x8[b] + 1]  = L[vp9_block2left_8x8[b]];
Deb Mukherjee's avatar
Deb Mukherjee committed
404
      }
405
    }
Jingning Han's avatar
Jingning Han committed
406
  } else {
407 408
    for (b = 0; b < 16; b++) {
      tokenize_b(cpi, xd, xd->block + b, t, plane_type,
409
                 A + vp9_block2above[b], L + vp9_block2left[b],
410 411 412 413 414
                 TX_4X4, dry_run);
    }

    for (b = 16; b < 24; b++) {
      tokenize_b(cpi, xd, xd->block + b, t, PLANE_TYPE_UV,
415
                 A + vp9_block2above[b], L + vp9_block2left[b],
416 417
                 TX_4X4, dry_run);
    }
Jingning Han's avatar
Jingning Han committed
418
  }
419 420
  if (dry_run)
    *t = t_backup;
John Koleszar's avatar
John Koleszar committed
421
}
422

John Koleszar's avatar
John Koleszar committed
423 424

#ifdef ENTROPY_STATS
John Koleszar's avatar
John Koleszar committed
425 426 427 428 429
void init_context_counters(void) {
  FILE *f = fopen("context.bin", "rb");
  if (!f) {
    vpx_memset(context_counters, 0, sizeof(context_counters));
    vpx_memset(context_counters_8x8, 0, sizeof(context_counters_8x8));
Daniel Kang's avatar
Daniel Kang committed
430
    vpx_memset(context_counters_16x16, 0, sizeof(context_counters_16x16));
John Koleszar's avatar
John Koleszar committed
431 432 433
  } else {
    fread(context_counters, sizeof(context_counters), 1, f);
    fread(context_counters_8x8, sizeof(context_counters_8x8), 1, f);
Daniel Kang's avatar
Daniel Kang committed
434
    fread(context_counters_16x16, sizeof(context_counters_16x16), 1, f);
John Koleszar's avatar
John Koleszar committed
435 436 437 438 439 440 441
    fclose(f);
  }

  f = fopen("treeupdate.bin", "rb");
  if (!f) {
    vpx_memset(tree_update_hist, 0, sizeof(tree_update_hist));
    vpx_memset(tree_update_hist_8x8, 0, sizeof(tree_update_hist_8x8));
Daniel Kang's avatar
Daniel Kang committed
442
    vpx_memset(tree_update_hist_16x16, 0, sizeof(tree_update_hist_16x16));
John Koleszar's avatar
John Koleszar committed
443 444 445
  } else {
    fread(tree_update_hist, sizeof(tree_update_hist), 1, f);
    fread(tree_update_hist_8x8, sizeof(tree_update_hist_8x8), 1, f);
Daniel Kang's avatar
Daniel Kang committed
446
    fread(tree_update_hist_16x16, sizeof(tree_update_hist_16x16), 1, f);
John Koleszar's avatar
John Koleszar committed
447 448
    fclose(f);
  }
John Koleszar's avatar
John Koleszar committed
449 450
}

John Koleszar's avatar
John Koleszar committed
451 452
void print_context_counters() {
  int type, band, pt, t;
453
  FILE *f = fopen("vp9_context.c", "w");
John Koleszar's avatar
John Koleszar committed
454

455
  fprintf(f, "#include \"vp9_entropy.h\"\n");
John Koleszar's avatar
John Koleszar committed
456 457
  fprintf(f, "\n/* *** GENERATED FILE: DO NOT EDIT *** */\n\n");
  fprintf(f, "static const unsigned int\n"
458
          "vp9_default_coef_counts[BLOCK_TYPES]\n"
John Koleszar's avatar
John Koleszar committed
459 460 461
          "                      [COEF_BANDS]\n"
          "                      [PREV_COEF_CONTEXTS]\n"
          "                      [MAX_ENTROPY_TOKENS]={\n");
John Koleszar's avatar
John Koleszar committed
462 463

# define Comma( X) (X? ",":"")
John Koleszar's avatar
John Koleszar committed
464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487
  type = 0;
  do {
    fprintf(f, "%s\n  { /* block Type %d */", Comma(type), type);
    band = 0;
    do {
      fprintf(f, "%s\n    { /* Coeff Band %d */", Comma(band), band);
      pt = 0;
      do {
        fprintf(f, "%s\n      {", Comma(pt));

        t = 0;
        do {
          const INT64 x = context_counters [type] [band] [pt] [t];
          const int y = (int) x;
          assert(x == (INT64) y);  /* no overflow handling yet */
          fprintf(f, "%s %d", Comma(t), y);
        } while (++t < MAX_ENTROPY_TOKENS);
        fprintf(f, "}");
      } while (++pt < PREV_COEF_CONTEXTS);
      fprintf(f, "\n    }");
    } while (++band < COEF_BANDS);
    fprintf(f, "\n  }");
  } while (++type < BLOCK_TYPES);
  fprintf(f, "\n};\n");
488

489
  fprintf(f, "static const unsigned int\nvp9_default_coef_counts_8x8"
John Koleszar's avatar
John Koleszar committed
490 491 492 493 494 495 496 497 498 499 500 501 502 503 504
          "[BLOCK_TYPES_8X8] [COEF_BANDS]"
          "[PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS] = {");
  type = 0;
  do {
    fprintf(f, "%s\n  { /* block Type %d */", Comma(type), type);
    band = 0;
    do {
      fprintf(f, "%s\n    { /* Coeff Band %d */", Comma(band), band);
      pt = 0;
      do {
        fprintf(f, "%s\n      {", Comma(pt));
        t = 0;
        do {
          const INT64 x = context_counters_8x8 [type] [band] [pt] [t];
          const int y = (int) x;
505

John Koleszar's avatar
John Koleszar committed
506 507
          assert(x == (INT64) y);  /* no overflow handling yet */
          fprintf(f, "%s %d", Comma(t), y);
John Koleszar's avatar
John Koleszar committed
508

John Koleszar's avatar
John Koleszar committed
509
        } while (++t < MAX_ENTROPY_TOKENS);
510

John Koleszar's avatar
John Koleszar committed
511 512
        fprintf(f, "}");
      } while (++pt < PREV_COEF_CONTEXTS);
513

John Koleszar's avatar
John Koleszar committed
514
      fprintf(f, "\n    }");
515

John Koleszar's avatar
John Koleszar committed
516
    } while (++band < COEF_BANDS);
517

John Koleszar's avatar
John Koleszar committed
518 519
    fprintf(f, "\n  }");
  } while (++type < BLOCK_TYPES_8X8);
Daniel Kang's avatar
Daniel Kang committed
520
  fprintf(f, "\n};\n");
521

522
  fprintf(f, "static const unsigned int\nvp9_default_coef_counts_16x16"
Daniel Kang's avatar
Daniel Kang committed
523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552
          "[BLOCK_TYPES_16X16] [COEF_BANDS]"
          "[PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS] = {");
  type = 0;
  do {
    fprintf(f, "%s\n  { /* block Type %d */", Comma(type), type);
    band = 0;
    do {
      fprintf(f, "%s\n    { /* Coeff Band %d */", Comma(band), band);
      pt = 0;
      do {
        fprintf(f, "%s\n      {", Comma(pt));
        t = 0;
        do {
          const INT64 x = context_counters_16x16 [type] [band] [pt] [t];
          const int y = (int) x;

          assert(x == (INT64) y);  /* no overflow handling yet */
          fprintf(f, "%s %d", Comma(t), y);

        } while (++t < MAX_ENTROPY_TOKENS);

        fprintf(f, "}");
      } while (++pt < PREV_COEF_CONTEXTS);

      fprintf(f, "\n    }");

    } while (++band < COEF_BANDS);

    fprintf(f, "\n  }");
  } while (++type < BLOCK_TYPES_16X16);
John Koleszar's avatar
John Koleszar committed
553
  fprintf(f, "\n};\n");
554

555
  fprintf(f, "static const vp9_prob\n"
556
          "vp9_default_coef_probs[BLOCK_TYPES] [COEF_BANDS] \n"
John Koleszar's avatar
John Koleszar committed
557 558 559 560 561 562 563 564 565 566 567
          "[PREV_COEF_CONTEXTS] [ENTROPY_NODES] = {");
  type = 0;
  do {
    fprintf(f, "%s\n  { /* block Type %d */", Comma(type), type);
    band = 0;
    do {
      fprintf(f, "%s\n    { /* Coeff Band %d */", Comma(band), band);
      pt = 0;
      do {
        unsigned int branch_ct [ENTROPY_NODES] [2];
        unsigned int coef_counts[MAX_ENTROPY_TOKENS];
568
        vp9_prob coef_probs[ENTROPY_NODES];
John Koleszar's avatar
John Koleszar committed
569 570
        for (t = 0; t < MAX_ENTROPY_TOKENS; ++t)
          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,
John Koleszar's avatar
John Koleszar committed
573 574
          coef_probs, branch_ct, coef_counts, 256, 1);
        fprintf(f, "%s\n      {", Comma(pt));
575

John Koleszar's avatar
John Koleszar committed
576 577 578
        t = 0;
        do {
          fprintf(f, "%s %d", Comma(t), coef_probs[t]);
579

John Koleszar's avatar
John Koleszar committed
580
        } while (++t < ENTROPY_NODES);
581

John Koleszar's avatar
John Koleszar committed
582 583 584 585 586 587 588
        fprintf(f, "}");
      } while (++pt < PREV_COEF_CONTEXTS);
      fprintf(f, "\n    }");
    } while (++band < COEF_BANDS);
    fprintf(f, "\n  }");
  } while (++type < BLOCK_TYPES);
  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"
John Koleszar's avatar
John Koleszar committed
592 593 594 595 596 597 598 599 600 601 602
          "[PREV_COEF_CONTEXTS] [ENTROPY_NODES] = {");
  type = 0;
  do {
    fprintf(f, "%s\n  { /* block Type %d */", Comma(type), type);
    band = 0;
    do {
      fprintf(f, "%s\n    { /* Coeff Band %d */", Comma(band), band);
      pt = 0;
      do {
        unsigned int branch_ct [ENTROPY_NODES] [2];
        unsigned int coef_counts[MAX_ENTROPY_TOKENS];
603
        vp9_prob coef_probs[ENTROPY_NODES];
John Koleszar's avatar
John Koleszar committed
604 605
        for (t = 0; t < MAX_ENTROPY_TOKENS; ++t)
          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,
John Koleszar's avatar
John Koleszar committed
608 609
          coef_probs, branch_ct, coef_counts, 256, 1);
        fprintf(f, "%s\n      {", Comma(pt));
610

Daniel Kang's avatar
Daniel Kang committed
611
        t = 0;
John Koleszar's avatar
John Koleszar committed
612 613 614 615 616 617 618 619 620 621 622
        do {
          fprintf(f, "%s %d", Comma(t), coef_probs[t]);
        } while (++t < ENTROPY_NODES);
        fprintf(f, "}");
      } while (++pt < PREV_COEF_CONTEXTS);
      fprintf(f, "\n    }");
    } while (++band < COEF_BANDS);
    fprintf(f, "\n  }");
  } while (++type < BLOCK_TYPES_8X8);
  fprintf(f, "\n};\n");

623
  fprintf(f, "static const vp9_prob\n"
624
          "vp9_default_coef_probs_16x16[BLOCK_TYPES_16X16] [COEF_BANDS]\n"
Daniel Kang's avatar
Daniel Kang committed
625 626 627 628 629 630 631 632 633 634 635
          "[PREV_COEF_CONTEXTS] [ENTROPY_NODES] = {");
  type = 0;
  do {
    fprintf(f, "%s\n  { /* block Type %d */", Comma(type), type);
    band = 0;
    do {
      fprintf(f, "%s\n    { /* Coeff Band %d */", Comma(band), band);
      pt = 0;
      do {
        unsigned int branch_ct [ENTROPY_NODES] [2];
        unsigned int coef_counts[MAX_ENTROPY_TOKENS];
636
        vp9_prob coef_probs[ENTROPY_NODES];
Daniel Kang's avatar
Daniel Kang committed
637 638
        for (t = 0; t < MAX_ENTROPY_TOKENS; ++t)
          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,
Daniel Kang's avatar
Daniel Kang committed
641 642 643 644 645 646 647 648 649 650 651 652 653 654 655
          coef_probs, branch_ct, coef_counts, 256, 1);
        fprintf(f, "%s\n      {", Comma(pt));

        t = 0;
        do {
          fprintf(f, "%s %d", Comma(t), coef_probs[t]);
        } while (++t < ENTROPY_NODES);
        fprintf(f, "}");
      } while (++pt < PREV_COEF_CONTEXTS);
      fprintf(f, "\n    }");
    } while (++band < COEF_BANDS);
    fprintf(f, "\n  }");
  } while (++type < BLOCK_TYPES_16X16);
  fprintf(f, "\n};\n");

John Koleszar's avatar
John Koleszar committed
656 657 658 659 660
  fclose(f);

  f = fopen("context.bin", "wb");
  fwrite(context_counters, sizeof(context_counters), 1, f);
  fwrite(context_counters_8x8, sizeof(context_counters_8x8), 1, f);
Daniel Kang's avatar
Daniel Kang committed
661
  fwrite(context_counters_16x16, sizeof(context_counters_16x16), 1, f);
John Koleszar's avatar
John Koleszar committed
662
  fclose(f);
John Koleszar's avatar
John Koleszar committed
663 664 665
}
#endif

666
void vp9_tokenize_initialize() {
John Koleszar's avatar
John Koleszar committed
667
  fill_value_tokens();
John Koleszar's avatar
John Koleszar committed
668 669
}

670
static __inline void stuff_b(VP9_COMP *cpi,
671 672 673 674 675 676 677 678 679 680
                             MACROBLOCKD *xd,
                             const BLOCKD * const b,
                             TOKENEXTRA **tp,
                             PLANE_TYPE type,
                             ENTROPY_CONTEXT *a,
                             ENTROPY_CONTEXT *l,
                             TX_SIZE tx_size,
                             int dry_run) {
  const int *bands;
  unsigned int (*counts)[COEF_BANDS][PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS];
681
  vp9_prob (*probs)[COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES];
682 683 684 685
  int pt, band;
  TOKENEXTRA *t = *tp;
  const TX_TYPE tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
                          get_tx_type(xd, b) : DCT_DCT;
686
  VP9_COMBINEENTROPYCONTEXTS(pt, *a, *l);
John Koleszar's avatar
John Koleszar committed
687

688 689 690
  switch (tx_size) {
    default:
    case TX_4X4:
691
      bands = vp9_coef_bands;
692 693 694 695 696 697 698 699 700
      if (tx_type != DCT_DCT) {
        counts = cpi->hybrid_coef_counts;
        probs = cpi->common.fc.hybrid_coef_probs;
      } else {
        counts = cpi->coef_counts;
        probs = cpi->common.fc.coef_probs;
      }
      break;
    case TX_8X8:
701
      bands = vp9_coef_bands_8x8;
702 703 704 705 706 707 708 709 710
      if (tx_type != DCT_DCT) {
        counts = cpi->hybrid_coef_counts_8x8;
        probs = cpi->common.fc.hybrid_coef_probs_8x8;
      } else {
        counts = cpi->coef_counts_8x8;
        probs = cpi->common.fc.coef_probs_8x8;
      }
      break;
    case TX_16X16:
711
      bands = vp9_coef_bands_16x16;
712 713 714 715 716 717 718 719 720 721
      if (tx_type != DCT_DCT) {
        counts = cpi->hybrid_coef_counts_16x16;
        probs = cpi->common.fc.hybrid_coef_probs_16x16;
      } else {
        counts = cpi->coef_counts_16x16;
        probs = cpi->common.fc.coef_probs_16x16;
      }
      break;
  }
  band = bands[(type == PLANE_TYPE_Y_NO_DC) ? 1 : 0];
John Koleszar's avatar
John Koleszar committed
722
  t->Token = DCT_EOB_TOKEN;
723
  t->context_tree = probs[type][band][pt];
John Koleszar's avatar
John Koleszar committed
724 725 726
  t->skip_eob_node = 0;
  ++t;
  *tp = t;
727
  *a = *l = 0;
728
  if (!dry_run) {
729
    ++counts[type][band][pt][DCT_EOB_TOKEN];
730
  }
731 732
}

733 734
static void stuff_mb_8x8(VP9_COMP *cpi, MACROBLOCKD *xd,
                         TOKENEXTRA **t, int dry_run) {
Paul Wilkins's avatar
Paul Wilkins committed
735 736
  ENTROPY_CONTEXT *A = (ENTROPY_CONTEXT *)xd->above_context;
  ENTROPY_CONTEXT *L = (ENTROPY_CONTEXT *)xd->left_context;
737
  PLANE_TYPE plane_type;
John Koleszar's avatar
John Koleszar committed
738
  int b;
739
  int has_2nd_order = get_2nd_order_usage(xd);
John Koleszar's avatar
John Koleszar committed
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 746
    plane_type = PLANE_TYPE_Y_NO_DC;
  } else {
Yaowu Xu's avatar
Yaowu Xu committed
747 748
    xd->above_context->y2 = 1;
    xd->left_context->y2 = 1;
749 750
    plane_type = PLANE_TYPE_Y_WITH_DC;
  }
John Koleszar's avatar
John Koleszar committed
751 752

  for (b = 0; b < 16; b += 4) {
753 754 755 756
    stuff_b(cpi, xd, xd->block + b, t, plane_type, A + vp9_block2above_8x8[b],
            L + vp9_block2left_8x8[b], TX_8X8, dry_run);
    A[vp9_block2above_8x8[b] + 1] = A[vp9_block2above_8x8[b]];
    L[vp9_block2left_8x8[b] + 1]  = L[vp9_block2left_8x8[b]];
John Koleszar's avatar
John Koleszar committed
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 764
    A[vp9_block2above_8x8[b] + 1] = A[vp9_block2above_8x8[b]];
    L[vp9_block2left_8x8[b] + 1]  = L[vp9_block2left_8x8[b]];
John Koleszar's avatar
John Koleszar committed
765
  }
Daniel Kang's avatar
Daniel Kang committed
766 767
}

768 769
static void stuff_mb_16x16(VP9_COMP *cpi, MACROBLOCKD *xd,
                           TOKENEXTRA **t, int dry_run) {
Paul Wilkins's avatar
Paul Wilkins committed
770 771
  ENTROPY_CONTEXT * A = (ENTROPY_CONTEXT *)xd->above_context;
  ENTROPY_CONTEXT * L = (ENTROPY_CONTEXT *)xd->left_context;
772
  int b;
Daniel Kang's avatar
Daniel Kang committed
773

774
  stuff_b(cpi, xd, xd->block, t, PLANE_TYPE_Y_WITH_DC, A, L, TX_16X16, dry_run);
775 776
  A[1] = A[2] = A[3] = A[0];
  L[1] = L[2] = L[3] = L[0];
Daniel Kang's avatar
Daniel Kang committed
777
  for (b = 16; b < 24; b += 4) {
778 779 780 781
    stuff_b(cpi, xd, xd->block + b, t, PLANE_TYPE_UV, A + vp9_block2above[b],
            L + vp9_block2above_8x8[b], TX_8X8, dry_run);
    A[vp9_block2above_8x8[b] + 1] = A[vp9_block2above_8x8[b]];
    L[vp9_block2left_8x8[b] + 1]  = L[vp9_block2left_8x8[b]];
Daniel Kang's avatar
Daniel Kang committed
782 783 784
  }
  vpx_memset(&A[8], 0, sizeof(A[8]));
  vpx_memset(&L[8], 0, sizeof(L[8]));
John Koleszar's avatar
John Koleszar committed
785 786
}

787 788
static void stuff_mb_4x4(VP9_COMP *cpi, MACROBLOCKD *xd,
                         TOKENEXTRA **t, int dry_run) {
Paul Wilkins's avatar
Paul Wilkins committed
789 790
  ENTROPY_CONTEXT *A = (ENTROPY_CONTEXT *)xd->above_context;
  ENTROPY_CONTEXT *L = (ENTROPY_CONTEXT *)xd->left_context;
John Koleszar's avatar
John Koleszar committed
791
  int b;
792
  PLANE_TYPE plane_type;
793 794 795 796 797
  int has_2nd_order = (xd->mode_info_context->mbmi.mode != B_PRED &&
                      xd->mode_info_context->mbmi.mode != I8X8_PRED &&
                      xd->mode_info_context->mbmi.mode != SPLITMV);
  if (has_2nd_order && get_tx_type(xd, &xd->block[0]) != DCT_DCT)
    has_2nd_order = 0;
John Koleszar's avatar
John Koleszar committed
798