|
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 static TOKENVALUE dct_value_tokens[DCT_MAX_VALUE * 2]; |
|
25 const TOKENVALUE *vp9_dct_value_tokens_ptr; |
|
26 static int dct_value_cost[DCT_MAX_VALUE * 2]; |
|
27 const int *vp9_dct_value_cost_ptr; |
|
28 |
|
29 static void fill_value_tokens() { |
|
30 TOKENVALUE *const t = dct_value_tokens + DCT_MAX_VALUE; |
|
31 const vp9_extra_bit *const e = vp9_extra_bits; |
|
32 |
|
33 int i = -DCT_MAX_VALUE; |
|
34 int sign = 1; |
|
35 |
|
36 do { |
|
37 if (!i) |
|
38 sign = 0; |
|
39 |
|
40 { |
|
41 const int a = sign ? -i : i; |
|
42 int eb = sign; |
|
43 |
|
44 if (a > 4) { |
|
45 int j = 4; |
|
46 |
|
47 while (++j < 11 && e[j].base_val <= a) {} |
|
48 |
|
49 t[i].token = --j; |
|
50 eb |= (a - e[j].base_val) << 1; |
|
51 } else { |
|
52 t[i].token = a; |
|
53 } |
|
54 t[i].extra = eb; |
|
55 } |
|
56 |
|
57 // initialize the cost for extra bits for all possible coefficient value. |
|
58 { |
|
59 int cost = 0; |
|
60 const vp9_extra_bit *p = &vp9_extra_bits[t[i].token]; |
|
61 |
|
62 if (p->base_val) { |
|
63 const int extra = t[i].extra; |
|
64 const int length = p->len; |
|
65 |
|
66 if (length) |
|
67 cost += treed_cost(p->tree, p->prob, extra >> 1, length); |
|
68 |
|
69 cost += vp9_cost_bit(vp9_prob_half, extra & 1); /* sign */ |
|
70 dct_value_cost[i + DCT_MAX_VALUE] = cost; |
|
71 } |
|
72 } |
|
73 } while (++i < DCT_MAX_VALUE); |
|
74 |
|
75 vp9_dct_value_tokens_ptr = dct_value_tokens + DCT_MAX_VALUE; |
|
76 vp9_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE; |
|
77 } |
|
78 |
|
79 struct tokenize_b_args { |
|
80 VP9_COMP *cpi; |
|
81 MACROBLOCKD *xd; |
|
82 TOKENEXTRA **tp; |
|
83 TX_SIZE tx_size; |
|
84 uint8_t *token_cache; |
|
85 }; |
|
86 |
|
87 static void set_entropy_context_b(int plane, int block, BLOCK_SIZE plane_bsize, |
|
88 TX_SIZE tx_size, void *arg) { |
|
89 struct tokenize_b_args* const args = arg; |
|
90 MACROBLOCKD *const xd = args->xd; |
|
91 struct macroblockd_plane *pd = &xd->plane[plane]; |
|
92 int aoff, loff; |
|
93 txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &aoff, &loff); |
|
94 set_contexts(xd, pd, plane_bsize, tx_size, pd->eobs[block] > 0, aoff, loff); |
|
95 } |
|
96 |
|
97 static void tokenize_b(int plane, int block, BLOCK_SIZE plane_bsize, |
|
98 TX_SIZE tx_size, void *arg) { |
|
99 struct tokenize_b_args* const args = arg; |
|
100 VP9_COMP *cpi = args->cpi; |
|
101 MACROBLOCKD *xd = args->xd; |
|
102 TOKENEXTRA **tp = args->tp; |
|
103 uint8_t *token_cache = args->token_cache; |
|
104 struct macroblockd_plane *pd = &xd->plane[plane]; |
|
105 MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; |
|
106 int pt; /* near block/prev token context index */ |
|
107 int c = 0, rc = 0; |
|
108 TOKENEXTRA *t = *tp; /* store tokens starting here */ |
|
109 const int eob = pd->eobs[block]; |
|
110 const PLANE_TYPE type = pd->plane_type; |
|
111 const int16_t *qcoeff_ptr = BLOCK_OFFSET(pd->qcoeff, block); |
|
112 |
|
113 const int segment_id = mbmi->segment_id; |
|
114 const int16_t *scan, *nb; |
|
115 vp9_coeff_count *const counts = cpi->coef_counts[tx_size]; |
|
116 vp9_coeff_probs_model *const coef_probs = cpi->common.fc.coef_probs[tx_size]; |
|
117 const int ref = is_inter_block(mbmi); |
|
118 const uint8_t *const band_translate = get_band_translate(tx_size); |
|
119 const int seg_eob = get_tx_eob(&cpi->common.seg, segment_id, tx_size); |
|
120 int aoff, loff; |
|
121 txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &aoff, &loff); |
|
122 |
|
123 assert((!type && !plane) || (type && plane)); |
|
124 |
|
125 pt = get_entropy_context(tx_size, pd->above_context + aoff, |
|
126 pd->left_context + loff); |
|
127 get_scan(xd, tx_size, type, block, &scan, &nb); |
|
128 c = 0; |
|
129 do { |
|
130 const int band = band_translate[c]; |
|
131 int token; |
|
132 int v = 0; |
|
133 rc = scan[c]; |
|
134 if (c) |
|
135 pt = get_coef_context(nb, token_cache, c); |
|
136 if (c < eob) { |
|
137 v = qcoeff_ptr[rc]; |
|
138 assert(-DCT_MAX_VALUE <= v && v < DCT_MAX_VALUE); |
|
139 |
|
140 t->extra = vp9_dct_value_tokens_ptr[v].extra; |
|
141 token = vp9_dct_value_tokens_ptr[v].token; |
|
142 } else { |
|
143 token = DCT_EOB_TOKEN; |
|
144 } |
|
145 |
|
146 t->token = token; |
|
147 t->context_tree = coef_probs[type][ref][band][pt]; |
|
148 t->skip_eob_node = (c > 0) && (token_cache[scan[c - 1]] == 0); |
|
149 |
|
150 assert(vp9_coef_encodings[t->token].len - t->skip_eob_node > 0); |
|
151 |
|
152 ++counts[type][ref][band][pt][token]; |
|
153 if (!t->skip_eob_node) |
|
154 ++cpi->common.counts.eob_branch[tx_size][type][ref][band][pt]; |
|
155 |
|
156 token_cache[rc] = vp9_pt_energy_class[token]; |
|
157 ++t; |
|
158 } while (c < eob && ++c < seg_eob); |
|
159 |
|
160 *tp = t; |
|
161 |
|
162 set_contexts(xd, pd, plane_bsize, tx_size, c > 0, aoff, loff); |
|
163 } |
|
164 |
|
165 struct is_skippable_args { |
|
166 MACROBLOCKD *xd; |
|
167 int *skippable; |
|
168 }; |
|
169 |
|
170 static void is_skippable(int plane, int block, |
|
171 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, |
|
172 void *argv) { |
|
173 struct is_skippable_args *args = argv; |
|
174 args->skippable[0] &= (!args->xd->plane[plane].eobs[block]); |
|
175 } |
|
176 |
|
177 int vp9_sb_is_skippable(MACROBLOCKD *xd, BLOCK_SIZE bsize) { |
|
178 int result = 1; |
|
179 struct is_skippable_args args = {xd, &result}; |
|
180 foreach_transformed_block(xd, bsize, is_skippable, &args); |
|
181 return result; |
|
182 } |
|
183 |
|
184 int vp9_is_skippable_in_plane(MACROBLOCKD *xd, BLOCK_SIZE bsize, |
|
185 int plane) { |
|
186 int result = 1; |
|
187 struct is_skippable_args args = {xd, &result}; |
|
188 foreach_transformed_block_in_plane(xd, bsize, plane, is_skippable, &args); |
|
189 return result; |
|
190 } |
|
191 |
|
192 void vp9_tokenize_sb(VP9_COMP *cpi, TOKENEXTRA **t, int dry_run, |
|
193 BLOCK_SIZE bsize) { |
|
194 VP9_COMMON *const cm = &cpi->common; |
|
195 MACROBLOCKD *const xd = &cpi->mb.e_mbd; |
|
196 MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; |
|
197 TOKENEXTRA *t_backup = *t; |
|
198 const int mb_skip_context = vp9_get_pred_context_mbskip(xd); |
|
199 const int skip_inc = !vp9_segfeature_active(&cm->seg, mbmi->segment_id, |
|
200 SEG_LVL_SKIP); |
|
201 struct tokenize_b_args arg = {cpi, xd, t, mbmi->tx_size, cpi->mb.token_cache}; |
|
202 |
|
203 mbmi->skip_coeff = vp9_sb_is_skippable(xd, bsize); |
|
204 if (mbmi->skip_coeff) { |
|
205 if (!dry_run) |
|
206 cm->counts.mbskip[mb_skip_context][1] += skip_inc; |
|
207 reset_skip_context(xd, bsize); |
|
208 if (dry_run) |
|
209 *t = t_backup; |
|
210 return; |
|
211 } |
|
212 |
|
213 if (!dry_run) { |
|
214 cm->counts.mbskip[mb_skip_context][0] += skip_inc; |
|
215 foreach_transformed_block(xd, bsize, tokenize_b, &arg); |
|
216 } else { |
|
217 foreach_transformed_block(xd, bsize, set_entropy_context_b, &arg); |
|
218 *t = t_backup; |
|
219 } |
|
220 } |
|
221 |
|
222 void vp9_tokenize_initialize() { |
|
223 fill_value_tokens(); |
|
224 } |