]> git.sesse.net Git - ffmpeg/blob - libavcodec/cabac.h
several x86 renorm_cabac_decoder_once optimizations
[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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 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 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 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 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 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 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 #if 0 /* all use commented */
268 static void refill2(CABACContext *c){
269     int i, x;
270
271     x= c->low ^ (c->low-1);
272     i= 8 - ff_h264_norm_shift[x>>(CABAC_BITS+1)];
273
274     x= -CABAC_MASK;
275
276     if(c->bytestream < c->bytestream_end)
277 #if CABAC_BITS == 16
278         x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1);
279 #else
280         x+= c->bytestream[0]<<1;
281 #endif
282
283     c->low += x<<i;
284     c->bytestream+= CABAC_BITS/8;
285 }
286 #endif
287
288 static inline void renorm_cabac_decoder(CABACContext *c){
289     while(c->range < (0x200 << CABAC_BITS)){
290         c->range+= c->range;
291         c->low+= c->low;
292         if(!(c->low & CABAC_MASK))
293             refill(c);
294     }
295 }
296
297 static inline void renorm_cabac_decoder_once(CABACContext *c){
298 #ifdef ARCH_X86
299     int temp;
300 #if 0
301     //P3:683
302     asm(
303         "lea -0x20000(%0), %2       \n\t"
304         "shr $31, %2                \n\t"  //FIXME 31->63 for x86-64
305         "shl %%cl, %0               \n\t"
306         "shl %%cl, %1               \n\t"
307         : "+r"(c->range), "+r"(c->low), "+c"(temp)
308     );
309 #elif 0
310     //P3:680
311     asm(
312         "cmp $0x20000, %0           \n\t"
313         "setb %%cl                  \n\t"  //FIXME 31->63 for x86-64
314         "shl %%cl, %0               \n\t"
315         "shl %%cl, %1               \n\t"
316         : "+r"(c->range), "+r"(c->low), "+c"(temp)
317     );
318 #elif 1
319     int temp2;
320     //P3:665
321     asm(
322         "lea -0x20000(%0), %%eax    \n\t"
323         "cdq                        \n\t"
324         "mov %0, %%eax              \n\t"
325         "and %%edx, %0              \n\t"
326         "and %1, %%edx              \n\t"
327         "add %%eax, %0              \n\t"
328         "add %%edx, %1              \n\t"
329         : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2)
330     );
331 #elif 0
332     int temp2;
333     //P3:673
334     asm(
335         "cmp $0x20000, %0           \n\t"
336         "sbb %%edx, %%edx           \n\t"
337         "mov %0, %%eax              \n\t"
338         "and %%edx, %0              \n\t"
339         "and %1, %%edx              \n\t"
340         "add %%eax, %0              \n\t"
341         "add %%edx, %1              \n\t"
342         : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2)
343     );
344 #else
345     int temp2;
346     //P3:677
347     asm(
348         "cmp $0x20000, %0           \n\t"
349         "lea (%0, %0), %%eax        \n\t"
350         "lea (%1, %1), %%edx        \n\t"
351         "cmovb %%eax, %0            \n\t"
352         "cmovb %%edx, %1            \n\t"
353         : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2)
354     );
355 #endif
356 #else
357     //P3:675
358     int shift= (uint32_t)(c->range - (0x200 << CABAC_BITS))>>31;
359     c->range<<= shift;
360     c->low  <<= shift;
361 #endif
362     if(!(c->low & CABAC_MASK))
363         refill(c);
364 }
365
366 static int get_cabac(CABACContext *c, uint8_t * const state){
367     //FIXME gcc generates duplicate load/stores for c->low and c->range
368 START_TIMER
369     int s = *state;
370     int RangeLPS= c->lps_range[s][c->range>>(CABAC_BITS+7)]<<(CABAC_BITS+1);
371     int bit, lps_mask attribute_unused;
372
373     c->range -= RangeLPS;
374 #if 1
375     if(c->low < c->range){
376         bit= s&1;
377         *state= c->mps_state[s];
378         renorm_cabac_decoder_once(c);
379     }else{
380 //        int shift= ff_h264_norm_shift[RangeLPS>>17];
381         bit= (s&1)^1;
382         c->low -= c->range;
383         *state= c->lps_state[s];
384         c->range = RangeLPS;
385         renorm_cabac_decoder(c);
386 /*        c->range = RangeLPS<<shift;
387         c->low <<= shift;
388         if(!(c->low & 0xFFFF)){
389             refill2(c);
390         }*/
391     }
392 #else
393     lps_mask= (c->range - c->low)>>31;
394
395     c->low -= c->range & lps_mask;
396     c->range += (RangeLPS - c->range) & lps_mask;
397
398     bit= (s^lps_mask)&1;
399     *state= c->mps_state[s - (128&lps_mask)];
400
401     lps_mask= ff_h264_norm_shift[c->range>>(CABAC_BITS+2)];
402     c->range<<= lps_mask;
403     c->low  <<= lps_mask;
404     if(!(c->low & CABAC_MASK))
405         refill2(c);
406 #endif
407 STOP_TIMER("get_cabac")
408     return bit;
409 }
410
411 static int get_cabac_bypass(CABACContext *c){
412     c->low += c->low;
413
414     if(!(c->low & CABAC_MASK))
415         refill(c);
416
417     if(c->low < c->range){
418         return 0;
419     }else{
420         c->low -= c->range;
421         return 1;
422     }
423 }
424
425 /**
426  *
427  * @return the number of bytes read or 0 if no end
428  */
429 static int get_cabac_terminate(CABACContext *c){
430     c->range -= 4<<CABAC_BITS;
431     if(c->low < c->range){
432         renorm_cabac_decoder_once(c);
433         return 0;
434     }else{
435         return c->bytestream - c->bytestream_start;
436     }
437 }
438
439 /**
440  * get (truncated) unnary binarization.
441  */
442 static int get_cabac_u(CABACContext *c, uint8_t * state, int max, int max_index, int truncated){
443     int i;
444
445     for(i=0; i<max; i++){
446         if(get_cabac(c, state)==0)
447             return i;
448
449         if(i< max_index) state++;
450     }
451
452     return truncated ? max : -1;
453 }
454
455 /**
456  * get unary exp golomb k-th order binarization.
457  */
458 static int get_cabac_ueg(CABACContext *c, uint8_t * state, int max, int is_signed, int k, int max_index){
459     int i, v;
460     int m= 1<<k;
461
462     if(get_cabac(c, state)==0)
463         return 0;
464
465     if(0 < max_index) state++;
466
467     for(i=1; i<max; i++){
468         if(get_cabac(c, state)==0){
469             if(is_signed && get_cabac_bypass(c)){
470                 return -i;
471             }else
472                 return i;
473         }
474
475         if(i < max_index) state++;
476     }
477
478     while(get_cabac_bypass(c)){
479         i+= m;
480         m+= m;
481     }
482
483     v=0;
484     while(m>>=1){
485         v+= v + get_cabac_bypass(c);
486     }
487     i += v;
488
489     if(is_signed && get_cabac_bypass(c)){
490         return -i;
491     }else
492         return i;
493 }