]> git.sesse.net Git - ffmpeg/blob - libavcodec/cabac.h
optimization
[ffmpeg] / libavcodec / cabac.h
1 /*
2  * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
3  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  */
20  
21 /**
22  * @file cabac.h
23  * Context Adaptive Binary Arithmetic Coder.
24  */
25
26
27 #undef NDEBUG
28 #include <assert.h>
29
30 #define CABAC_BITS 8
31 #define CABAC_MASK ((1<<CABAC_BITS)-1)
32
33 typedef struct CABACContext{
34     int low;
35     int range;
36     int outstanding_count;
37 #ifdef STRICT_LIMITS
38     int symCount;
39 #endif
40     uint8_t lps_range[2*65][4];   ///< rangeTabLPS
41     uint8_t lps_state[2*64];      ///< transIdxLPS
42     uint8_t mps_state[2*64];      ///< transIdxMPS
43     const uint8_t *bytestream_start;
44     const uint8_t *bytestream;
45     const uint8_t *bytestream_end;
46     PutBitContext pb;
47 }CABACContext;
48
49 extern const uint8_t ff_h264_lps_range[64][4];
50 extern const uint8_t ff_h264_mps_state[64];
51 extern const uint8_t ff_h264_lps_state[64];
52 extern const uint8_t ff_h264_norm_shift[256];
53
54
55 void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size);
56 void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size);
57 void ff_init_cabac_states(CABACContext *c, uint8_t const (*lps_range)[4], 
58                           uint8_t const *mps_state, uint8_t const *lps_state, int state_count);
59
60
61 static inline void put_cabac_bit(CABACContext *c, int b){
62     put_bits(&c->pb, 1, b); 
63     for(;c->outstanding_count; c->outstanding_count--){ 
64         put_bits(&c->pb, 1, 1-b);
65     }
66 }
67
68 static inline void renorm_cabac_encoder(CABACContext *c){
69     while(c->range < 0x100){
70         //FIXME optimize
71         if(c->low<0x100){
72             put_cabac_bit(c, 0);
73         }else if(c->low<0x200){
74             c->outstanding_count++;
75             c->low -= 0x100;
76         }else{
77             put_cabac_bit(c, 1);
78             c->low -= 0x200;
79         }
80         
81         c->range+= c->range;
82         c->low += c->low;
83     }
84 }
85
86 static inline void put_cabac(CABACContext *c, uint8_t * const state, int bit){
87     int RangeLPS= c->lps_range[*state][c->range>>6];
88     
89     if(bit == ((*state)&1)){
90         c->range -= RangeLPS;
91         *state= c->mps_state[*state];
92     }else{
93         c->low += c->range - RangeLPS;
94         c->range = RangeLPS;
95         *state= c->lps_state[*state];
96     }
97     
98     renorm_cabac_encoder(c);
99
100 #ifdef STRICT_LIMITS
101     c->symCount++;
102 #endif
103 }
104
105 static inline void put_cabac_static(CABACContext *c, int RangeLPS, int bit){
106     assert(c->range > RangeLPS);
107
108     if(!bit){
109         c->range -= RangeLPS;
110     }else{
111         c->low += c->range - RangeLPS;
112         c->range = RangeLPS;
113     }
114
115     renorm_cabac_encoder(c);
116
117 #ifdef STRICT_LIMITS
118     c->symCount++;
119 #endif
120 }
121
122 /**
123  * @param bit 0 -> write zero bit, !=0 write one bit
124  */
125 static inline void put_cabac_bypass(CABACContext *c, int bit){
126     c->low += c->low;
127
128     if(bit){
129         c->low += c->range;
130     }
131 //FIXME optimize
132     if(c->low<0x200){
133         put_cabac_bit(c, 0);
134     }else if(c->low<0x400){
135         c->outstanding_count++;
136         c->low -= 0x200;
137     }else{
138         put_cabac_bit(c, 1);
139         c->low -= 0x400;
140     }
141         
142 #ifdef STRICT_LIMITS
143     c->symCount++;
144 #endif
145 }
146
147 /**
148  *
149  * @return the number of bytes written
150  */
151 static inline int put_cabac_terminate(CABACContext *c, int bit){
152     c->range -= 2;
153
154     if(!bit){
155         renorm_cabac_encoder(c);
156     }else{
157         c->low += c->range;
158         c->range= 2;
159         
160         renorm_cabac_encoder(c);
161
162         assert(c->low <= 0x1FF);
163         put_cabac_bit(c, c->low>>9);
164         put_bits(&c->pb, 2, ((c->low>>7)&3)|1);
165         
166         flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong
167     }
168         
169 #ifdef STRICT_LIMITS
170     c->symCount++;
171 #endif
172
173     return (put_bits_count(&c->pb)+7)>>3;
174 }
175
176 /**
177  * put (truncated) unary binarization.
178  */
179 static inline void put_cabac_u(CABACContext *c, uint8_t * state, int v, int max, int max_index, int truncated){
180     int i;
181     
182     assert(v <= max);
183     
184 #if 1
185     for(i=0; i<v; i++){
186         put_cabac(c, state, 1);
187         if(i < max_index) state++;
188     }
189     if(truncated==0 || v<max)
190         put_cabac(c, state, 0);
191 #else
192     if(v <= max_index){
193         for(i=0; i<v; i++){
194             put_cabac(c, state+i, 1);
195         }
196         if(truncated==0 || v<max)
197             put_cabac(c, state+i, 0);
198     }else{
199         for(i=0; i<=max_index; i++){
200             put_cabac(c, state+i, 1);
201         }
202         for(; i<v; i++){
203             put_cabac(c, state+max_index, 1);
204         }
205         if(truncated==0 || v<max)
206             put_cabac(c, state+max_index, 0);
207     }
208 #endif
209 }
210
211 /**
212  * put unary exp golomb k-th order binarization.
213  */
214 static inline void put_cabac_ueg(CABACContext *c, uint8_t * state, int v, int max, int is_signed, int k, int max_index){
215     int i;
216     
217     if(v==0)
218         put_cabac(c, state, 0);
219     else{
220         const int sign= v < 0;
221         
222         if(is_signed) v= ABS(v);
223         
224         if(v<max){
225             for(i=0; i<v; i++){
226                 put_cabac(c, state, 1);
227                 if(i < max_index) state++;
228             }
229
230             put_cabac(c, state, 0);
231         }else{
232             int m= 1<<k;
233
234             for(i=0; i<max; i++){
235                 put_cabac(c, state, 1);
236                 if(i < max_index) state++;
237             }
238
239             v -= max;
240             while(v >= m){ //FIXME optimize
241                 put_cabac_bypass(c, 1);
242                 v-= m;
243                 m+= m;
244             }
245             put_cabac_bypass(c, 0);
246             while(m>>=1){
247                 put_cabac_bypass(c, v&m);
248             }
249         }
250
251         if(is_signed)
252             put_cabac_bypass(c, sign);
253     }
254 }
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
287 static inline void renorm_cabac_decoder(CABACContext *c){
288     while(c->range < (0x200 << CABAC_BITS)){
289         c->range+= c->range;
290         c->low+= c->low;
291         if(!(c->low & CABAC_MASK))
292             refill(c);
293     }
294 }
295
296 static inline void renorm_cabac_decoder_once(CABACContext *c){
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);
302 }
303
304 static inline int get_cabac(CABACContext *c, uint8_t * const state){
305     int RangeLPS= c->lps_range[*state][c->range>>(CABAC_BITS+7)]<<(CABAC_BITS+1);
306     int bit, lps_mask;
307     
308     c->range -= RangeLPS;
309 #if 1
310     if(c->low < c->range){
311         bit= (*state)&1;
312         *state= c->mps_state[*state];
313         renorm_cabac_decoder_once(c);
314     }else{
315 //        int shift= ff_h264_norm_shift[RangeLPS>>17];
316         bit= ((*state)&1)^1;
317         c->low -= c->range;
318         *state= c->lps_state[*state];
319         c->range = RangeLPS;
320         renorm_cabac_decoder(c);
321 /*        c->range = RangeLPS<<shift;
322         c->low <<= shift;
323         if(!(c->low & 0xFFFF)){
324             refill2(c);
325         }*/
326     }
327 #else
328     lps_mask= (c->range - c->low)>>31;
329     
330     c->low -= c->range & lps_mask;
331     c->range += (RangeLPS - c->range) & lps_mask;
332     
333     bit= ((*state)^lps_mask)&1;
334     *state= c->mps_state[(*state) - (128&lps_mask)];
335     
336     lps_mask= ff_h264_norm_shift[c->range>>(CABAC_BITS+2)];
337     c->range<<= lps_mask;
338     c->low  <<= lps_mask;
339     if(!(c->low & CABAC_MASK))
340         refill2(c);
341 #endif
342
343     return bit;    
344 }
345
346 static inline int get_cabac_bypass(CABACContext *c){
347     c->low += c->low;
348
349     if(!(c->low & CABAC_MASK))
350         refill(c);
351     
352     if(c->low < c->range){
353         return 0;
354     }else{
355         c->low -= c->range;
356         return 1;
357     }
358 }
359
360 /**
361  *
362  * @return the number of bytes read or 0 if no end
363  */
364 static inline int get_cabac_terminate(CABACContext *c){
365     c->range -= 4<<CABAC_BITS;
366     if(c->low < c->range){
367         renorm_cabac_decoder_once(c);
368         return 0;
369     }else{
370         return c->bytestream - c->bytestream_start;
371     }    
372 }
373
374 /**
375  * get (truncated) unnary binarization.
376  */
377 static inline int get_cabac_u(CABACContext *c, uint8_t * state, int max, int max_index, int truncated){
378     int i;
379     
380     for(i=0; i<max; i++){ 
381         if(get_cabac(c, state)==0)
382             return i;
383             
384         if(i< max_index) state++;
385     }
386
387     return truncated ? max : -1;
388 }
389
390 /**
391  * get unary exp golomb k-th order binarization.
392  */
393 static inline int get_cabac_ueg(CABACContext *c, uint8_t * state, int max, int is_signed, int k, int max_index){
394     int i, v;
395     int m= 1<<k;
396     
397     if(get_cabac(c, state)==0) 
398         return 0;
399         
400     if(0 < max_index) state++;
401     
402     for(i=1; i<max; i++){ 
403         if(get_cabac(c, state)==0){
404             if(is_signed && get_cabac_bypass(c)){
405                 return -i;
406             }else
407                 return i;
408         }
409
410         if(i < max_index) state++;
411     }
412     
413     while(get_cabac_bypass(c)){
414         i+= m;
415         m+= m;
416     }
417     
418     v=0;
419     while(m>>=1){
420         v+= v + get_cabac_bypass(c);
421     }
422     i += v;
423
424     if(is_signed && get_cabac_bypass(c)){
425         return -i;
426     }else
427         return i;
428 }