Mercurial > libavcodec.hg
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 } |