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#ifndef VP9_ENCODER_VP9_TOKENIZE_H_
12#define VP9_ENCODER_VP9_TOKENIZE_H_
13
14#include "vp9/common/vp9_entropy.h"
15
16#include "vp9/encoder/vp9_block.h"
17#include "vp9/encoder/vp9_treewriter.h"
18
19#ifdef __cplusplus
20extern "C" {
21#endif
22
23#define EOSB_TOKEN 127  // Not signalled, encoder only
24
25#if CONFIG_VP9_HIGHBITDEPTH
26typedef int32_t EXTRABIT;
27#else
28typedef int16_t EXTRABIT;
29#endif
30
31typedef struct {
32  int16_t token;
33  EXTRABIT extra;
34} TOKENVALUE;
35
36typedef struct {
37  const vpx_prob *context_tree;
38  int16_t token;
39  EXTRABIT extra;
40} TOKENEXTRA;
41
42extern const vpx_tree_index vp9_coef_tree[];
43extern const vpx_tree_index vp9_coef_con_tree[];
44extern const struct vp9_token vp9_coef_encodings[];
45
46int vp9_is_skippable_in_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane);
47int vp9_has_high_freq_in_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane);
48
49struct VP9_COMP;
50struct ThreadData;
51
52void vp9_tokenize_sb(struct VP9_COMP *cpi, struct ThreadData *td,
53                     TOKENEXTRA **t, int dry_run, int seg_skip,
54                     BLOCK_SIZE bsize);
55
56typedef struct {
57  const vpx_prob *prob;
58  int len;
59  int base_val;
60  const int16_t *cost;
61} vp9_extra_bit;
62
63// indexed by token value
64extern const vp9_extra_bit vp9_extra_bits[ENTROPY_TOKENS];
65#if CONFIG_VP9_HIGHBITDEPTH
66extern const vp9_extra_bit vp9_extra_bits_high10[ENTROPY_TOKENS];
67extern const vp9_extra_bit vp9_extra_bits_high12[ENTROPY_TOKENS];
68#endif  // CONFIG_VP9_HIGHBITDEPTH
69
70extern const int16_t *vp9_dct_value_cost_ptr;
71/* TODO: The Token field should be broken out into a separate char array to
72 *  improve cache locality, since it's needed for costing when the rest of the
73 *  fields are not.
74 */
75extern const TOKENVALUE *vp9_dct_value_tokens_ptr;
76extern const TOKENVALUE *vp9_dct_cat_lt_10_value_tokens;
77extern const int *vp9_dct_cat_lt_10_value_cost;
78extern const int16_t vp9_cat6_low_cost[256];
79extern const uint16_t vp9_cat6_high_cost[64];
80extern const uint16_t vp9_cat6_high10_high_cost[256];
81extern const uint16_t vp9_cat6_high12_high_cost[1024];
82
83#if CONFIG_VP9_HIGHBITDEPTH
84static INLINE const uint16_t *vp9_get_high_cost_table(int bit_depth) {
85  return bit_depth == 8 ? vp9_cat6_high_cost
86                        : (bit_depth == 10 ? vp9_cat6_high10_high_cost
87                                           : vp9_cat6_high12_high_cost);
88}
89#else
90static INLINE const uint16_t *vp9_get_high_cost_table(int bit_depth) {
91  (void)bit_depth;
92  return vp9_cat6_high_cost;
93}
94#endif  // CONFIG_VP9_HIGHBITDEPTH
95
96static INLINE void vp9_get_token_extra(int v, int16_t *token, EXTRABIT *extra) {
97  if (v >= CAT6_MIN_VAL || v <= -CAT6_MIN_VAL) {
98    *token = CATEGORY6_TOKEN;
99    if (v >= CAT6_MIN_VAL)
100      *extra = 2 * v - 2 * CAT6_MIN_VAL;
101    else
102      *extra = -2 * v - 2 * CAT6_MIN_VAL + 1;
103    return;
104  }
105  *token = vp9_dct_cat_lt_10_value_tokens[v].token;
106  *extra = vp9_dct_cat_lt_10_value_tokens[v].extra;
107}
108static INLINE int16_t vp9_get_token(int v) {
109  if (v >= CAT6_MIN_VAL || v <= -CAT6_MIN_VAL) return 10;
110  return vp9_dct_cat_lt_10_value_tokens[v].token;
111}
112
113static INLINE int vp9_get_token_cost(int v, int16_t *token,
114                                     const uint16_t *cat6_high_table) {
115  if (v >= CAT6_MIN_VAL || v <= -CAT6_MIN_VAL) {
116    EXTRABIT extrabits;
117    *token = CATEGORY6_TOKEN;
118    extrabits = abs(v) - CAT6_MIN_VAL;
119    return vp9_cat6_low_cost[extrabits & 0xff] +
120           cat6_high_table[extrabits >> 8];
121  }
122  *token = vp9_dct_cat_lt_10_value_tokens[v].token;
123  return vp9_dct_cat_lt_10_value_cost[v];
124}
125
126#ifdef __cplusplus
127}  // extern "C"
128#endif
129
130#endif  // VP9_ENCODER_VP9_TOKENIZE_H_
131