Mercurial > libavcodec.hg
annotate cabac.h @ 2497:69adfbbdcdeb libavcodec
- samples from mplayer ftp in the "adv" profile seem to have profile=2,
which isn't the advanced one; and indeed, using adv. profile parser fails.
Using normal parser works, and that's what is done
- attempt at taking care of stride for NORM2 bitplane decoding
- duplication of much code from msmpeg4.c; this code isn't yet used, but
goes down as far as the block layer (mainly Transform Type stuff, the
remains are wild editing without checking). Unusable yet, and lacks the AC
decoding (but a step further in bitstream parsing)
patch by anonymous
author | michael |
---|---|
date | Fri, 04 Feb 2005 02:20:38 +0000 |
parents | 1c39d9786efd |
children | e25782262d7d |
rev | line source |
---|---|
1287 | 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 | |
2323 | 30 #define CABAC_BITS 8 |
31 #define CABAC_MASK ((1<<CABAC_BITS)-1) | |
32 | |
1287 | 33 typedef struct CABACContext{ |
34 int low; | |
35 int range; | |
36 int outstanding_count; | |
37 #ifdef STRICT_LIMITS | |
38 int symCount; | |
39 #endif | |
2323 | 40 uint8_t lps_range[2*65][4]; ///< rangeTabLPS |
1287 | 41 uint8_t lps_state[2*64]; ///< transIdxLPS |
42 uint8_t mps_state[2*64]; ///< transIdxMPS | |
2024
f65d87bfdd5a
some of the warning fixes by (Michael Roitzsch <mroi at users dot sourceforge dot net>)
michael
parents:
1787
diff
changeset
|
43 const uint8_t *bytestream_start; |
f65d87bfdd5a
some of the warning fixes by (Michael Roitzsch <mroi at users dot sourceforge dot net>)
michael
parents:
1787
diff
changeset
|
44 const uint8_t *bytestream; |
2116 | 45 const uint8_t *bytestream_end; |
1287 | 46 PutBitContext pb; |
47 }CABACContext; | |
48 | |
1301 | 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]; | |
2323 | 52 extern const uint8_t ff_h264_norm_shift[256]; |
53 | |
1287 | 54 |
55 void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size); | |
2024
f65d87bfdd5a
some of the warning fixes by (Michael Roitzsch <mroi at users dot sourceforge dot net>)
michael
parents:
1787
diff
changeset
|
56 void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size); |
1287 | 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){ | |
2323 | 87 int RangeLPS= c->lps_range[*state][c->range>>6]; |
1287 | 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 | |
1290 | 122 /** |
123 * @param bit 0 -> write zero bit, !=0 write one bit | |
124 */ | |
1287 | 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 | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
1298
diff
changeset
|
147 /** |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
1298
diff
changeset
|
148 * |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
1298
diff
changeset
|
149 * @return the number of bytes written |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
1298
diff
changeset
|
150 */ |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
1298
diff
changeset
|
151 static inline int put_cabac_terminate(CABACContext *c, int bit){ |
1287 | 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 | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
1298
diff
changeset
|
172 |
1787 | 173 return (put_bits_count(&c->pb)+7)>>3; |
1287 | 174 } |
175 | |
1290 | 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 */ | |
1298 | 214 static inline void put_cabac_ueg(CABACContext *c, uint8_t * state, int v, int max, int is_signed, int k, int max_index){ |
1290 | 215 int i; |
216 | |
217 if(v==0) | |
218 put_cabac(c, state, 0); | |
219 else{ | |
1298 | 220 const int sign= v < 0; |
221 | |
222 if(is_signed) v= ABS(v); | |
223 | |
1290 | 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 | |
2323 | 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 | |
1287 | 287 static inline void renorm_cabac_decoder(CABACContext *c){ |
2323 | 288 while(c->range < (0x200 << CABAC_BITS)){ |
1287 | 289 c->range+= c->range; |
290 c->low+= c->low; | |
2323 | 291 if(!(c->low & CABAC_MASK)) |
292 refill(c); | |
1287 | 293 } |
294 } | |
295 | |
2323 | 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 | |
1287 | 304 static inline int get_cabac(CABACContext *c, uint8_t * const state){ |
2323 | 305 int RangeLPS= c->lps_range[*state][c->range>>(CABAC_BITS+7)]<<(CABAC_BITS+1); |
306 int bit, lps_mask; | |
1287 | 307 |
308 c->range -= RangeLPS; | |
2323 | 309 #if 1 |
1287 | 310 if(c->low < c->range){ |
311 bit= (*state)&1; | |
312 *state= c->mps_state[*state]; | |
2323 | 313 renorm_cabac_decoder_once(c); |
1287 | 314 }else{ |
2323 | 315 // int shift= ff_h264_norm_shift[RangeLPS>>17]; |
1287 | 316 bit= ((*state)&1)^1; |
317 c->low -= c->range; | |
2323 | 318 *state= c->lps_state[*state]; |
1287 | 319 c->range = RangeLPS; |
2323 | 320 renorm_cabac_decoder(c); |
321 /* c->range = RangeLPS<<shift; | |
322 c->low <<= shift; | |
323 if(!(c->low & 0xFFFF)){ | |
324 refill2(c); | |
325 }*/ | |
1287 | 326 } |
2323 | 327 #else |
328 lps_mask= (c->range - c->low)>>31; | |
1287 | 329 |
2323 | 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)]; | |
1287 | 335 |
2323 | 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 | |
1287 | 343 return bit; |
344 } | |
345 | |
346 static inline int get_cabac_bypass(CABACContext *c){ | |
347 c->low += c->low; | |
348 | |
2323 | 349 if(!(c->low & CABAC_MASK)) |
350 refill(c); | |
1287 | 351 |
352 if(c->low < c->range){ | |
353 return 0; | |
354 }else{ | |
355 c->low -= c->range; | |
356 return 1; | |
357 } | |
358 } | |
359 | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
1298
diff
changeset
|
360 /** |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
1298
diff
changeset
|
361 * |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
1298
diff
changeset
|
362 * @return the number of bytes read or 0 if no end |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
1298
diff
changeset
|
363 */ |
1287 | 364 static inline int get_cabac_terminate(CABACContext *c){ |
2323 | 365 c->range -= 4<<CABAC_BITS; |
1287 | 366 if(c->low < c->range){ |
2323 | 367 renorm_cabac_decoder_once(c); |
1287 | 368 return 0; |
369 }else{ | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
1298
diff
changeset
|
370 return c->bytestream - c->bytestream_start; |
1287 | 371 } |
372 } | |
373 | |
1290 | 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 } |