blob: 1a71948cbf3de6243caafddbcf8c2e6d15b79e4a [file] [log] [blame]
John Koleszar0ea50ce2010-05-18 11:58:33 -04001/*
John Koleszarc2140b82010-09-09 08:16:39 -04002 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar0ea50ce2010-05-18 11:58:33 -04003 *
John Koleszar94c52e42010-06-18 12:39:21 -04004 * Use of this source code is governed by a BSD-style license
John Koleszar09202d82010-06-04 16:19:40 -04005 * 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
John Koleszar94c52e42010-06-18 12:39:21 -04007 * in the file PATENTS. All contributing project authors may
John Koleszar09202d82010-06-04 16:19:40 -04008 * be found in the AUTHORS file in the root of the source tree.
John Koleszar0ea50ce2010-05-18 11:58:33 -04009 */
10
11
John Koleszar02321de2011-02-10 14:41:38 -050012#include "vp8/common/type_aliases.h"
13#include "vp8/common/blockd.h"
John Koleszar0ea50ce2010-05-18 11:58:33 -040014#include "onyxd_int.h"
15#include "vpx_mem/vpx_mem.h"
16#include "vpx_ports/mem.h"
Johann96027992010-08-12 09:05:37 -040017#include "detokenize.h"
John Koleszar0ea50ce2010-05-18 11:58:33 -040018
John Koleszar0ea50ce2010-05-18 11:58:33 -040019#define BOOL_DATA UINT8
20
21#define OCB_X PREV_COEF_CONTEXTS * ENTROPY_NODES
John Koleszar429dc672011-03-17 17:07:59 -040022DECLARE_ALIGNED(16, static const unsigned char, coef_bands_x[16]) =
23{
24 0 * OCB_X, 1 * OCB_X, 2 * OCB_X, 3 * OCB_X,
25 6 * OCB_X, 4 * OCB_X, 5 * OCB_X, 6 * OCB_X,
26 6 * OCB_X, 6 * OCB_X, 6 * OCB_X, 6 * OCB_X,
27 6 * OCB_X, 6 * OCB_X, 6 * OCB_X, 7 * OCB_X
28};
John Koleszar0ea50ce2010-05-18 11:58:33 -040029#define EOB_CONTEXT_NODE 0
30#define ZERO_CONTEXT_NODE 1
31#define ONE_CONTEXT_NODE 2
32#define LOW_VAL_CONTEXT_NODE 3
33#define TWO_CONTEXT_NODE 4
34#define THREE_CONTEXT_NODE 5
35#define HIGH_LOW_CONTEXT_NODE 6
36#define CAT_ONE_CONTEXT_NODE 7
37#define CAT_THREEFOUR_CONTEXT_NODE 8
38#define CAT_THREE_CONTEXT_NODE 9
39#define CAT_FIVE_CONTEXT_NODE 10
40
Scott LaVarnway76eb4022011-07-25 17:11:24 -040041#define CAT1_MIN_VAL 5
42#define CAT2_MIN_VAL 7
43#define CAT3_MIN_VAL 11
44#define CAT4_MIN_VAL 19
45#define CAT5_MIN_VAL 35
46#define CAT6_MIN_VAL 67
John Koleszar0ea50ce2010-05-18 11:58:33 -040047
Scott LaVarnway76eb4022011-07-25 17:11:24 -040048#define CAT1_PROB0 159
49#define CAT2_PROB0 145
50#define CAT2_PROB1 165
51
52#define CAT3_PROB0 140
53#define CAT3_PROB1 148
54#define CAT3_PROB2 173
55
56#define CAT4_PROB0 135
57#define CAT4_PROB1 140
58#define CAT4_PROB2 155
59#define CAT4_PROB3 176
60
61#define CAT5_PROB0 130
62#define CAT5_PROB1 134
63#define CAT5_PROB2 141
64#define CAT5_PROB3 157
65#define CAT5_PROB4 180
66
67static const unsigned char cat6_prob[12] =
68{ 129, 130, 133, 140, 153, 177, 196, 230, 243, 254, 254, 0 };
John Koleszar0ea50ce2010-05-18 11:58:33 -040069
70
71void vp8_reset_mb_tokens_context(MACROBLOCKD *x)
72{
Yunqing Wangd33bf3d2010-05-28 14:34:39 -040073 /* Clear entropy contexts for Y2 blocks */
Scott LaVarnway76eb4022011-07-25 17:11:24 -040074 if (x->mode_info_context->mbmi.mode != B_PRED &&
75 x->mode_info_context->mbmi.mode != SPLITMV)
John Koleszar0ea50ce2010-05-18 11:58:33 -040076 {
Scott LaVarnwaye85e6312010-08-31 10:49:57 -040077 vpx_memset(x->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
78 vpx_memset(x->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
79 }
80 else
81 {
82 vpx_memset(x->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)-1);
83 vpx_memset(x->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)-1);
John Koleszar0ea50ce2010-05-18 11:58:33 -040084 }
John Koleszar0ea50ce2010-05-18 11:58:33 -040085}
Johann96027992010-08-12 09:05:37 -040086
Scott LaVarnwaya25f6a92011-07-19 09:17:25 -040087DECLARE_ALIGNED(16, extern const unsigned char, vp8_norm[256]);
Timothy B. Terriberryc17b62e2010-05-05 17:58:19 -040088#define FILL \
89 if(count < 0) \
90 VP8DX_BOOL_DECODER_FILL(count, value, bufptr, bufend);
91
John Koleszar0ea50ce2010-05-18 11:58:33 -040092#define NORMALIZE \
93 /*if(range < 0x80)*/ \
94 { \
Scott LaVarnwaya25f6a92011-07-19 09:17:25 -040095 shift = vp8_norm[range]; \
John Koleszar0ea50ce2010-05-18 11:58:33 -040096 range <<= shift; \
97 value <<= shift; \
98 count -= shift; \
John Koleszar0ea50ce2010-05-18 11:58:33 -040099 }
100
101#define DECODE_AND_APPLYSIGN(value_to_sign) \
102 split = (range + 1) >> 1; \
Timothy B. Terriberryc17b62e2010-05-05 17:58:19 -0400103 bigsplit = (VP8_BD_VALUE)split << (VP8_BD_VALUE_SIZE - 8); \
104 FILL \
105 if ( value < bigsplit ) \
John Koleszar0ea50ce2010-05-18 11:58:33 -0400106 { \
107 range = split; \
108 v= value_to_sign; \
109 } \
110 else \
111 { \
112 range = range-split; \
Timothy B. Terriberryc17b62e2010-05-05 17:58:19 -0400113 value = value-bigsplit; \
John Koleszar0ea50ce2010-05-18 11:58:33 -0400114 v = -value_to_sign; \
115 } \
116 range +=range; \
117 value +=value; \
Timothy B. Terriberryc17b62e2010-05-05 17:58:19 -0400118 count--;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400119
120#define DECODE_AND_BRANCH_IF_ZERO(probability,branch) \
121 { \
122 split = 1 + ((( probability*(range-1) ) )>> 8); \
Timothy B. Terriberryc17b62e2010-05-05 17:58:19 -0400123 bigsplit = (VP8_BD_VALUE)split << (VP8_BD_VALUE_SIZE - 8); \
124 FILL \
125 if ( value < bigsplit ) \
John Koleszar0ea50ce2010-05-18 11:58:33 -0400126 { \
127 range = split; \
128 NORMALIZE \
129 goto branch; \
130 } \
Timothy B. Terriberryc17b62e2010-05-05 17:58:19 -0400131 value -= bigsplit; \
John Koleszar0ea50ce2010-05-18 11:58:33 -0400132 range = range - split; \
133 NORMALIZE \
134 }
135
136#define DECODE_AND_LOOP_IF_ZERO(probability,branch) \
137 { \
138 split = 1 + ((( probability*(range-1) ) ) >> 8); \
Timothy B. Terriberryc17b62e2010-05-05 17:58:19 -0400139 bigsplit = (VP8_BD_VALUE)split << (VP8_BD_VALUE_SIZE - 8); \
140 FILL \
141 if ( value < bigsplit ) \
John Koleszar0ea50ce2010-05-18 11:58:33 -0400142 { \
143 range = split; \
144 NORMALIZE \
145 Prob = coef_probs; \
146 if(c<15) {\
147 ++c; \
John Koleszar429dc672011-03-17 17:07:59 -0400148 Prob += coef_bands_x[c]; \
John Koleszar0ea50ce2010-05-18 11:58:33 -0400149 goto branch; \
150 } goto BLOCK_FINISHED; /*for malformed input */\
151 } \
Timothy B. Terriberryc17b62e2010-05-05 17:58:19 -0400152 value -= bigsplit; \
John Koleszar0ea50ce2010-05-18 11:58:33 -0400153 range = range - split; \
154 NORMALIZE \
155 }
156
157#define DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val) \
158 DECODE_AND_APPLYSIGN(val) \
159 Prob = coef_probs + (ENTROPY_NODES*2); \
160 if(c < 15){\
161 qcoeff_ptr [ scan[c] ] = (INT16) v; \
162 ++c; \
163 goto DO_WHILE; }\
Scott LaVarnway76eb4022011-07-25 17:11:24 -0400164 qcoeff_ptr [ 15 ] = (INT16) v; \
John Koleszar0ea50ce2010-05-18 11:58:33 -0400165 goto BLOCK_FINISHED;
166
167
Scott LaVarnway76eb4022011-07-25 17:11:24 -0400168#define DECODE_EXTRABIT_AND_ADJUST_VAL(prob, bits_count)\
169 split = 1 + (((range-1) * prob) >> 8); \
Timothy B. Terriberryc17b62e2010-05-05 17:58:19 -0400170 bigsplit = (VP8_BD_VALUE)split << (VP8_BD_VALUE_SIZE - 8); \
171 FILL \
172 if(value >= bigsplit)\
John Koleszar0ea50ce2010-05-18 11:58:33 -0400173 {\
174 range = range-split;\
Timothy B. Terriberryc17b62e2010-05-05 17:58:19 -0400175 value = value-bigsplit;\
John Koleszar0ea50ce2010-05-18 11:58:33 -0400176 val += ((UINT16)1<<bits_count);\
177 }\
178 else\
179 {\
180 range = split;\
181 }\
182 NORMALIZE
183
184int vp8_decode_mb_tokens(VP8D_COMP *dx, MACROBLOCKD *x)
185{
Scott LaVarnwaye85e6312010-08-31 10:49:57 -0400186 ENTROPY_CONTEXT *A = (ENTROPY_CONTEXT *)x->above_context;
187 ENTROPY_CONTEXT *L = (ENTROPY_CONTEXT *)x->left_context;
Gaute Strokkenes15f03c22011-04-04 16:47:22 +0100188 const FRAME_CONTEXT * const fc = &dx->common.fc;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400189
190 BOOL_DECODER *bc = x->current_bc;
191
Fritz Koenig93c32a52010-08-20 10:58:19 -0700192 char *eobs = x->eobs;
193
John Koleszar0ea50ce2010-05-18 11:58:33 -0400194 ENTROPY_CONTEXT *a;
195 ENTROPY_CONTEXT *l;
196 int i;
197
198 int eobtotal = 0;
199
200 register int count;
201
202 const BOOL_DATA *bufptr;
Timothy B. Terriberryc17b62e2010-05-05 17:58:19 -0400203 const BOOL_DATA *bufend;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400204 register unsigned int range;
Timothy B. Terriberryc17b62e2010-05-05 17:58:19 -0400205 VP8_BD_VALUE value;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400206 const int *scan;
207 register unsigned int shift;
208 UINT32 split;
Timothy B. Terriberryc17b62e2010-05-05 17:58:19 -0400209 VP8_BD_VALUE bigsplit;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400210 INT16 *qcoeff_ptr;
211
212 const vp8_prob *coef_probs;
213 int type;
214 int stop;
215 INT16 val, bits_count;
216 INT16 c;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400217 INT16 v;
218 const vp8_prob *Prob;
219
John Koleszar0ea50ce2010-05-18 11:58:33 -0400220 type = 3;
221 i = 0;
222 stop = 16;
223
Scott LaVarnwaye85e6312010-08-31 10:49:57 -0400224 scan = vp8_default_zig_zag1d;
225 qcoeff_ptr = &x->qcoeff[0];
226
Scott LaVarnway76eb4022011-07-25 17:11:24 -0400227 if (x->mode_info_context->mbmi.mode != B_PRED &&
228 x->mode_info_context->mbmi.mode != SPLITMV)
John Koleszar0ea50ce2010-05-18 11:58:33 -0400229 {
230 i = 24;
231 stop = 24;
232 type = 1;
Scott LaVarnwaye85e6312010-08-31 10:49:57 -0400233 qcoeff_ptr += 24*16;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400234 eobtotal -= 16;
235 }
John Koleszar0ea50ce2010-05-18 11:58:33 -0400236
Timothy B. Terriberryc17b62e2010-05-05 17:58:19 -0400237 bufend = bc->user_buffer_end;
238 bufptr = bc->user_buffer;
239 value = bc->value;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400240 count = bc->count;
241 range = bc->range;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400242
243
Gaute Strokkenes15f03c22011-04-04 16:47:22 +0100244 coef_probs = fc->coef_probs [type] [ 0 ] [0];
John Koleszar0ea50ce2010-05-18 11:58:33 -0400245
246BLOCK_LOOP:
Scott LaVarnwaye85e6312010-08-31 10:49:57 -0400247 a = A + vp8_block2above[i];
248 l = L + vp8_block2left[i];
249
John Koleszar0ea50ce2010-05-18 11:58:33 -0400250 c = (INT16)(!type);
251
Timothy B. Terriberryc4d7e5e2010-10-27 16:04:02 -0700252 /*Dest = ((A)!=0) + ((B)!=0);*/
Scott LaVarnwaye85e6312010-08-31 10:49:57 -0400253 VP8_COMBINEENTROPYCONTEXTS(v, *a, *l);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400254 Prob = coef_probs;
Scott LaVarnwaye85e6312010-08-31 10:49:57 -0400255 Prob += v * ENTROPY_NODES;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400256
257DO_WHILE:
John Koleszar429dc672011-03-17 17:07:59 -0400258 Prob += coef_bands_x[c];
John Koleszar0ea50ce2010-05-18 11:58:33 -0400259 DECODE_AND_BRANCH_IF_ZERO(Prob[EOB_CONTEXT_NODE], BLOCK_FINISHED);
260
261CHECK_0_:
262 DECODE_AND_LOOP_IF_ZERO(Prob[ZERO_CONTEXT_NODE], CHECK_0_);
263 DECODE_AND_BRANCH_IF_ZERO(Prob[ONE_CONTEXT_NODE], ONE_CONTEXT_NODE_0_);
Scott LaVarnway76eb4022011-07-25 17:11:24 -0400264 DECODE_AND_BRANCH_IF_ZERO(Prob[LOW_VAL_CONTEXT_NODE],
265 LOW_VAL_CONTEXT_NODE_0_);
266 DECODE_AND_BRANCH_IF_ZERO(Prob[HIGH_LOW_CONTEXT_NODE],
267 HIGH_LOW_CONTEXT_NODE_0_);
268 DECODE_AND_BRANCH_IF_ZERO(Prob[CAT_THREEFOUR_CONTEXT_NODE],
269 CAT_THREEFOUR_CONTEXT_NODE_0_);
270 DECODE_AND_BRANCH_IF_ZERO(Prob[CAT_FIVE_CONTEXT_NODE],
271 CAT_FIVE_CONTEXT_NODE_0_);
272
273 val = CAT6_MIN_VAL;
274 bits_count = 10;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400275
276 do
277 {
Scott LaVarnway76eb4022011-07-25 17:11:24 -0400278 DECODE_EXTRABIT_AND_ADJUST_VAL(cat6_prob[bits_count], bits_count);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400279 bits_count -- ;
280 }
281 while (bits_count >= 0);
282
283 DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val);
284
285CAT_FIVE_CONTEXT_NODE_0_:
Scott LaVarnway76eb4022011-07-25 17:11:24 -0400286 val = CAT5_MIN_VAL;
287 DECODE_EXTRABIT_AND_ADJUST_VAL(CAT5_PROB4, 4);
288 DECODE_EXTRABIT_AND_ADJUST_VAL(CAT5_PROB3, 3);
289 DECODE_EXTRABIT_AND_ADJUST_VAL(CAT5_PROB2, 2);
290 DECODE_EXTRABIT_AND_ADJUST_VAL(CAT5_PROB1, 1);
291 DECODE_EXTRABIT_AND_ADJUST_VAL(CAT5_PROB0, 0);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400292 DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val);
293
294CAT_THREEFOUR_CONTEXT_NODE_0_:
Scott LaVarnway76eb4022011-07-25 17:11:24 -0400295 DECODE_AND_BRANCH_IF_ZERO(Prob[CAT_THREE_CONTEXT_NODE],
296 CAT_THREE_CONTEXT_NODE_0_);
297 val = CAT4_MIN_VAL;
298 DECODE_EXTRABIT_AND_ADJUST_VAL(CAT4_PROB3, 3);
299 DECODE_EXTRABIT_AND_ADJUST_VAL(CAT4_PROB2, 2);
300 DECODE_EXTRABIT_AND_ADJUST_VAL(CAT4_PROB1, 1);
301 DECODE_EXTRABIT_AND_ADJUST_VAL(CAT4_PROB0, 0);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400302 DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val);
303
304CAT_THREE_CONTEXT_NODE_0_:
Scott LaVarnway76eb4022011-07-25 17:11:24 -0400305 val = CAT3_MIN_VAL;
306 DECODE_EXTRABIT_AND_ADJUST_VAL(CAT3_PROB2, 2);
307 DECODE_EXTRABIT_AND_ADJUST_VAL(CAT3_PROB1, 1);
308 DECODE_EXTRABIT_AND_ADJUST_VAL(CAT3_PROB0, 0);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400309 DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val);
310
311HIGH_LOW_CONTEXT_NODE_0_:
Scott LaVarnway76eb4022011-07-25 17:11:24 -0400312 DECODE_AND_BRANCH_IF_ZERO(Prob[CAT_ONE_CONTEXT_NODE],
313 CAT_ONE_CONTEXT_NODE_0_);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400314
Scott LaVarnway76eb4022011-07-25 17:11:24 -0400315 val = CAT2_MIN_VAL;
316 DECODE_EXTRABIT_AND_ADJUST_VAL(CAT2_PROB1, 1);
317 DECODE_EXTRABIT_AND_ADJUST_VAL(CAT2_PROB0, 0);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400318 DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val);
319
320CAT_ONE_CONTEXT_NODE_0_:
Scott LaVarnway76eb4022011-07-25 17:11:24 -0400321 val = CAT1_MIN_VAL;
322 DECODE_EXTRABIT_AND_ADJUST_VAL(CAT1_PROB0, 0);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400323 DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val);
324
325LOW_VAL_CONTEXT_NODE_0_:
326 DECODE_AND_BRANCH_IF_ZERO(Prob[TWO_CONTEXT_NODE], TWO_CONTEXT_NODE_0_);
327 DECODE_AND_BRANCH_IF_ZERO(Prob[THREE_CONTEXT_NODE], THREE_CONTEXT_NODE_0_);
328 DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(4);
329
330THREE_CONTEXT_NODE_0_:
331 DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(3);
332
333TWO_CONTEXT_NODE_0_:
334 DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(2);
335
336ONE_CONTEXT_NODE_0_:
337 DECODE_AND_APPLYSIGN(1);
338 Prob = coef_probs + ENTROPY_NODES;
339
340 if (c < 15)
341 {
342 qcoeff_ptr [ scan[c] ] = (INT16) v;
343 ++c;
344 goto DO_WHILE;
345 }
346
Scott LaVarnway76eb4022011-07-25 17:11:24 -0400347 qcoeff_ptr [ 15 ] = (INT16) v;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400348BLOCK_FINISHED:
Timothy B. Terriberryc4d7e5e2010-10-27 16:04:02 -0700349 *a = *l = ((eobs[i] = c) != !type); /* any nonzero data? */
Fritz Koenig93c32a52010-08-20 10:58:19 -0700350 eobtotal += c;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400351 qcoeff_ptr += 16;
352
353 i++;
354
355 if (i < stop)
356 goto BLOCK_LOOP;
357
358 if (i == 25)
359 {
John Koleszar0ea50ce2010-05-18 11:58:33 -0400360 type = 0;
361 i = 0;
362 stop = 16;
Gaute Strokkenes15f03c22011-04-04 16:47:22 +0100363 coef_probs = fc->coef_probs [type] [ 0 ] [0];
Scott LaVarnwaye85e6312010-08-31 10:49:57 -0400364 qcoeff_ptr -= (24*16 + 16);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400365 goto BLOCK_LOOP;
366 }
367
368 if (i == 16)
369 {
370 type = 2;
Gaute Strokkenes15f03c22011-04-04 16:47:22 +0100371 coef_probs = fc->coef_probs [type] [ 0 ] [0];
John Koleszar0ea50ce2010-05-18 11:58:33 -0400372 stop = 24;
373 goto BLOCK_LOOP;
374 }
375
Timothy B. Terriberryc17b62e2010-05-05 17:58:19 -0400376 FILL
377 bc->user_buffer = bufptr;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400378 bc->value = value;
Timothy B. Terriberryc17b62e2010-05-05 17:58:19 -0400379 bc->count = count;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400380 bc->range = range;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400381 return eobtotal;
382
383}