]> git.sesse.net Git - x264/blob - common/bs.h
More --me tesa optimizations
[x264] / common / bs.h
1 /*****************************************************************************
2  * bs.h :
3  *****************************************************************************
4  * Copyright (C) 2003-2008 x264 project
5  *
6  * Authors: Loren Merritt <lorenm@u.washington.edu>
7  *          Fiona Glaser <fiona@x264.com>
8  *          Laurent Aimar <fenrir@via.ecp.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 #ifndef X264_BS_H
26 #define X264_BS_H
27
28 typedef struct
29 {
30     uint8_t i_bits;
31     uint8_t i_size;
32 } vlc_t;
33
34 typedef struct
35 {
36     uint16_t i_bits;
37     uint8_t  i_size;
38     /* Next level table to use */
39     uint8_t  i_next;
40 } vlc_large_t;
41
42 typedef struct bs_s
43 {
44     uint8_t *p_start;
45     uint8_t *p;
46     uint8_t *p_end;
47
48     intptr_t cur_bits;
49     int     i_left;    /* i_count number of available bits */
50     int     i_bits_encoded; /* RD only */
51 } bs_t;
52
53 typedef struct
54 {
55     int     last;
56     int16_t level[16];
57     uint8_t run[16];
58 } x264_run_level_t;
59
60 extern const vlc_t x264_coeff0_token[5];
61 extern const vlc_t x264_coeff_token[5][16*4];
62 extern const vlc_t x264_total_zeros[15][16];
63 extern const vlc_t x264_total_zeros_dc[3][4];
64 extern const vlc_t x264_run_before[7][16];
65
66 /* A larger level table size theoretically could help a bit at extremely
67  * high bitrates, but the cost in cache is usually too high for it to be
68  * useful.
69  * This size appears to be optimal for QP18 encoding on a Nehalem CPU.
70  * FIXME: Do further testing? */
71 #define LEVEL_TABLE_SIZE 128
72 extern vlc_large_t x264_level_token[7][LEVEL_TABLE_SIZE];
73
74 static inline void bs_init( bs_t *s, void *p_data, int i_data )
75 {
76     int offset = ((intptr_t)p_data & 3);
77     s->p       = s->p_start = (uint8_t*)p_data - offset;
78     s->p_end   = (uint8_t*)p_data + i_data;
79     s->i_left  = (WORD_SIZE - offset)*8;
80     s->cur_bits = endian_fix32(*(uint32_t *)(s->p));
81     s->cur_bits >>= (4-offset)*8;
82 }
83 static inline int bs_pos( bs_t *s )
84 {
85     return( 8 * (s->p - s->p_start) + (WORD_SIZE*8) - s->i_left );
86 }
87
88 /* Write the rest of cur_bits to the bitstream; results in a bitstream no longer 32-bit aligned. */
89 static inline void bs_flush( bs_t *s )
90 {
91     M32( s->p ) = endian_fix32( s->cur_bits << (s->i_left&31) );
92     s->p += WORD_SIZE - s->i_left / 8;
93     s->i_left = WORD_SIZE*8;
94 }
95
96 static inline void bs_write( bs_t *s, int i_count, uint32_t i_bits )
97 {
98     if( WORD_SIZE == 8 )
99     {
100         s->cur_bits = (s->cur_bits << i_count) | i_bits;
101         s->i_left -= i_count;
102         if( s->i_left <= 32 )
103         {
104 #ifdef WORDS_BIGENDIAN
105             M32( s->p ) = s->cur_bits >> (32 - s->i_left);
106 #else
107             M32( s->p ) = endian_fix( s->cur_bits << s->i_left );
108 #endif
109             s->i_left += 32;
110             s->p += 4;
111         }
112     }
113     else
114     {
115         if( i_count < s->i_left )
116         {
117             s->cur_bits = (s->cur_bits << i_count) | i_bits;
118             s->i_left -= i_count;
119         }
120         else
121         {
122             i_count -= s->i_left;
123             s->cur_bits = (s->cur_bits << s->i_left) | (i_bits >> i_count);
124             M32( s->p ) = endian_fix( s->cur_bits );
125             s->p += 4;
126             s->cur_bits = i_bits;
127             s->i_left = 32 - i_count;
128         }
129     }
130 }
131
132 /* Special case to eliminate branch in normal bs_write. */
133 /* Golomb never writes an even-size code, so this is only used in slice headers. */
134 static inline void bs_write32( bs_t *s, uint32_t i_bits )
135 {
136     bs_write( s, 16, i_bits >> 16 );
137     bs_write( s, 16, i_bits );
138 }
139
140 static inline void bs_write1( bs_t *s, uint32_t i_bit )
141 {
142     s->cur_bits <<= 1;
143     s->cur_bits |= i_bit;
144     s->i_left--;
145     if( s->i_left == WORD_SIZE*8-32 )
146     {
147         M32( s->p ) = endian_fix32( s->cur_bits );
148         s->p += 4;
149         s->i_left = WORD_SIZE*8;
150     }
151 }
152
153 static inline void bs_align_0( bs_t *s )
154 {
155     bs_write( s, s->i_left&7, 0 );
156     bs_flush( s );
157 }
158 static inline void bs_align_1( bs_t *s )
159 {
160     bs_write( s, s->i_left&7, (1 << (s->i_left&7)) - 1 );
161     bs_flush( s );
162 }
163 static inline void bs_align_10( bs_t *s )
164 {
165     if( s->i_left&7 )
166         bs_write( s, s->i_left&7, 1 << ( (s->i_left&7) - 1 ) );
167 }
168
169 /* golomb functions */
170
171 static const uint8_t x264_ue_size_tab[256] =
172 {
173      1, 1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7,
174      9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
175     11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
176     11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
177     13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
178     13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
179     13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
180     13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
181     15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
182     15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
183     15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
184     15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
185     15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
186     15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
187     15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
188     15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
189 };
190
191 static inline void bs_write_ue_big( bs_t *s, unsigned int val )
192 {
193     int size = 0;
194     int tmp = ++val;
195     if( tmp >= 0x10000 )
196     {
197         size = 32;
198         tmp >>= 16;
199     }
200     if( tmp >= 0x100 )
201     {
202         size += 16;
203         tmp >>= 8;
204     }
205     size += x264_ue_size_tab[tmp];
206     bs_write( s, size>>1, 0 );
207     bs_write( s, (size>>1)+1, val );
208 }
209
210 /* Only works on values under 255. */
211 static inline void bs_write_ue( bs_t *s, int val )
212 {
213     bs_write( s, x264_ue_size_tab[val+1], val+1 );
214 }
215
216 static inline void bs_write_se( bs_t *s, int val )
217 {
218     int size = 0;
219     /* Faster than (val <= 0 ? -val*2+1 : val*2) */
220     /* 4 instructions on x86, 3 on ARM */
221     int tmp = 1 - val*2;
222     if( tmp < 0 ) tmp = val*2;
223     val = tmp;
224
225     if( tmp >= 0x100 )
226     {
227         size = 16;
228         tmp >>= 8;
229     }
230     size += x264_ue_size_tab[tmp];
231     bs_write( s, size, val );
232 }
233
234 static inline void bs_write_te( bs_t *s, int x, int val )
235 {
236     if( x == 1 )
237         bs_write1( s, 1^val );
238     else //if( x > 1 )
239         bs_write_ue( s, val );
240 }
241
242 static inline void bs_rbsp_trailing( bs_t *s )
243 {
244     bs_write1( s, 1 );
245     bs_write( s, s->i_left&7, 0  );
246 }
247
248 static inline int bs_size_ue( unsigned int val )
249 {
250     return x264_ue_size_tab[val+1];
251 }
252
253 static inline int bs_size_ue_big( unsigned int val )
254 {
255     if( val < 255 )
256         return x264_ue_size_tab[val+1];
257     else
258         return x264_ue_size_tab[(val+1)>>8] + 16;
259 }
260
261 static inline int bs_size_se( int val )
262 {
263     int tmp = 1 - val*2;
264     if( tmp < 0 ) tmp = val*2;
265     if( tmp < 256 )
266         return x264_ue_size_tab[tmp];
267     else
268         return x264_ue_size_tab[tmp>>8]+16;
269 }
270
271 static inline int bs_size_te( int x, int val )
272 {
273     if( x == 1 )
274         return 1;
275     else //if( x > 1 )
276         return x264_ue_size_tab[val+1];
277 }
278
279 #endif