comparison cabac.h @ 2323:1c39d9786efd libavcodec

optimization
author michael
date Tue, 26 Oct 2004 03:12:21 +0000
parents 48d9f86fb047
children e25782262d7d
comparison
equal deleted inserted replaced
2322:4140f2e78ebc 2323:1c39d9786efd
24 */ 24 */
25 25
26 26
27 #undef NDEBUG 27 #undef NDEBUG
28 #include <assert.h> 28 #include <assert.h>
29
30 #define CABAC_BITS 8
31 #define CABAC_MASK ((1<<CABAC_BITS)-1)
29 32
30 typedef struct CABACContext{ 33 typedef struct CABACContext{
31 int low; 34 int low;
32 int range; 35 int range;
33 int outstanding_count; 36 int outstanding_count;
34 #ifdef STRICT_LIMITS 37 #ifdef STRICT_LIMITS
35 int symCount; 38 int symCount;
36 #endif 39 #endif
37 uint8_t lps_range[2*64][4]; ///< rangeTabLPS 40 uint8_t lps_range[2*65][4]; ///< rangeTabLPS
38 uint8_t lps_state[2*64]; ///< transIdxLPS 41 uint8_t lps_state[2*64]; ///< transIdxLPS
39 uint8_t mps_state[2*64]; ///< transIdxMPS 42 uint8_t mps_state[2*64]; ///< transIdxMPS
40 const uint8_t *bytestream_start; 43 const uint8_t *bytestream_start;
41 const uint8_t *bytestream; 44 const uint8_t *bytestream;
42 const uint8_t *bytestream_end; 45 const uint8_t *bytestream_end;
43 int bits_left; ///<
44 PutBitContext pb; 46 PutBitContext pb;
45 }CABACContext; 47 }CABACContext;
46 48
47 extern const uint8_t ff_h264_lps_range[64][4]; 49 extern const uint8_t ff_h264_lps_range[64][4];
48 extern const uint8_t ff_h264_mps_state[64]; 50 extern const uint8_t ff_h264_mps_state[64];
49 extern const uint8_t ff_h264_lps_state[64]; 51 extern const uint8_t ff_h264_lps_state[64];
52 extern const uint8_t ff_h264_norm_shift[256];
53
50 54
51 void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size); 55 void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size);
52 void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size); 56 void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size);
53 void ff_init_cabac_states(CABACContext *c, uint8_t const (*lps_range)[4], 57 void ff_init_cabac_states(CABACContext *c, uint8_t const (*lps_range)[4],
54 uint8_t const *mps_state, uint8_t const *lps_state, int state_count); 58 uint8_t const *mps_state, uint8_t const *lps_state, int state_count);
78 c->low += c->low; 82 c->low += c->low;
79 } 83 }
80 } 84 }
81 85
82 static inline void put_cabac(CABACContext *c, uint8_t * const state, int bit){ 86 static inline void put_cabac(CABACContext *c, uint8_t * const state, int bit){
83 int RangeLPS= c->lps_range[*state][((c->range)>>6)&3]; 87 int RangeLPS= c->lps_range[*state][c->range>>6];
84 88
85 if(bit == ((*state)&1)){ 89 if(bit == ((*state)&1)){
86 c->range -= RangeLPS; 90 c->range -= RangeLPS;
87 *state= c->mps_state[*state]; 91 *state= c->mps_state[*state];
88 }else{ 92 }else{
247 if(is_signed) 251 if(is_signed)
248 put_cabac_bypass(c, sign); 252 put_cabac_bypass(c, sign);
249 } 253 }
250 } 254 }
251 255
256 static void refill(CABACContext *c){
257 if(c->bytestream < c->bytestream_end)
258 #if CABAC_BITS == 16
259 c->low+= ((c->bytestream[0]<<9) + (c->bytestream[1])<<1);
260 #else
261 c->low+= c->bytestream[0]<<1;
262 #endif
263 c->low -= CABAC_MASK;
264 c->bytestream+= CABAC_BITS/8;
265 }
266
267 static void refill2(CABACContext *c){
268 int i, x;
269
270 x= c->low ^ (c->low-1);
271 i= 8 - ff_h264_norm_shift[x>>(CABAC_BITS+1)];
272
273 x= -CABAC_MASK;
274
275 if(c->bytestream < c->bytestream_end)
276 #if CABAC_BITS == 16
277 x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1);
278 #else
279 x+= c->bytestream[0]<<1;
280 #endif
281
282 c->low += x<<i;
283 c->bytestream+= CABAC_BITS/8;
284 }
285
286
252 static inline void renorm_cabac_decoder(CABACContext *c){ 287 static inline void renorm_cabac_decoder(CABACContext *c){
253 while(c->range < 0x10000){ 288 while(c->range < (0x200 << CABAC_BITS)){
254 c->range+= c->range; 289 c->range+= c->range;
255 c->low+= c->low; 290 c->low+= c->low;
256 if(--c->bits_left == 0){ 291 if(!(c->low & CABAC_MASK))
257 if(c->bytestream < c->bytestream_end) 292 refill(c);
258 c->low+= *c->bytestream; 293 }
259 c->bytestream++; 294 }
260 c->bits_left= 8; 295
261 } 296 static inline void renorm_cabac_decoder_once(CABACContext *c){
262 } 297 int mask= (c->range - (0x200 << CABAC_BITS))>>31;
298 c->range+= c->range&mask;
299 c->low += c->low &mask;
300 if(!(c->low & CABAC_MASK))
301 refill(c);
263 } 302 }
264 303
265 static inline int get_cabac(CABACContext *c, uint8_t * const state){ 304 static inline int get_cabac(CABACContext *c, uint8_t * const state){
266 int RangeLPS= c->lps_range[*state][((c->range)>>14)&3]<<8; 305 int RangeLPS= c->lps_range[*state][c->range>>(CABAC_BITS+7)]<<(CABAC_BITS+1);
267 int bit; 306 int bit, lps_mask;
268 307
269 c->range -= RangeLPS; 308 c->range -= RangeLPS;
309 #if 1
270 if(c->low < c->range){ 310 if(c->low < c->range){
271 bit= (*state)&1; 311 bit= (*state)&1;
272 *state= c->mps_state[*state]; 312 *state= c->mps_state[*state];
273 }else{ 313 renorm_cabac_decoder_once(c);
314 }else{
315 // int shift= ff_h264_norm_shift[RangeLPS>>17];
274 bit= ((*state)&1)^1; 316 bit= ((*state)&1)^1;
275 c->low -= c->range; 317 c->low -= c->range;
318 *state= c->lps_state[*state];
276 c->range = RangeLPS; 319 c->range = RangeLPS;
277 *state= c->lps_state[*state]; 320 renorm_cabac_decoder(c);
278 } 321 /* c->range = RangeLPS<<shift;
279 renorm_cabac_decoder(c); 322 c->low <<= shift;
280 323 if(!(c->low & 0xFFFF)){
281 return bit; 324 refill2(c);
282 } 325 }*/
283 326 }
284 static inline int get_cabac_static(CABACContext *c, int RangeLPS){ 327 #else
285 int bit; 328 lps_mask= (c->range - c->low)>>31;
286 329
287 c->range -= RangeLPS; 330 c->low -= c->range & lps_mask;
288 if(c->low < c->range){ 331 c->range += (RangeLPS - c->range) & lps_mask;
289 bit= 0; 332
290 }else{ 333 bit= ((*state)^lps_mask)&1;
291 bit= 1; 334 *state= c->mps_state[(*state) - (128&lps_mask)];
292 c->low -= c->range; 335
293 c->range = RangeLPS; 336 lps_mask= ff_h264_norm_shift[c->range>>(CABAC_BITS+2)];
294 } 337 c->range<<= lps_mask;
295 renorm_cabac_decoder(c); 338 c->low <<= lps_mask;
296 339 if(!(c->low & CABAC_MASK))
340 refill2(c);
341 #endif
342
297 return bit; 343 return bit;
298 } 344 }
299 345
300 static inline int get_cabac_bypass(CABACContext *c){ 346 static inline int get_cabac_bypass(CABACContext *c){
301 c->low += c->low; 347 c->low += c->low;
302 348
303 if(--c->bits_left == 0){ 349 if(!(c->low & CABAC_MASK))
304 if(c->bytestream < c->bytestream_end) 350 refill(c);
305 c->low+= *c->bytestream;
306 c->bytestream++;
307 c->bits_left= 8;
308 }
309 351
310 if(c->low < c->range){ 352 if(c->low < c->range){
311 return 0; 353 return 0;
312 }else{ 354 }else{
313 c->low -= c->range; 355 c->low -= c->range;
318 /** 360 /**
319 * 361 *
320 * @return the number of bytes read or 0 if no end 362 * @return the number of bytes read or 0 if no end
321 */ 363 */
322 static inline int get_cabac_terminate(CABACContext *c){ 364 static inline int get_cabac_terminate(CABACContext *c){
323 c->range -= 2<<8; 365 c->range -= 4<<CABAC_BITS;
324 if(c->low < c->range){ 366 if(c->low < c->range){
325 renorm_cabac_decoder(c); 367 renorm_cabac_decoder_once(c);
326 return 0; 368 return 0;
327 }else{ 369 }else{
328 return c->bytestream - c->bytestream_start; 370 return c->bytestream - c->bytestream_start;
329 } 371 }
330 } 372 }