Mercurial > libavcodec.hg
comparison cabac.h @ 1287:9211fbd31353 libavcodec
CABAC
note, this is just the CABAC (de)coder not complete h264-cabac support
author | michaelni |
---|---|
date | Wed, 28 May 2003 18:44:52 +0000 |
parents | |
children | dae280b939ca |
comparison
equal
deleted
inserted
replaced
1286:9e8cbd476f59 | 1287:9211fbd31353 |
---|---|
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 typedef struct CABACContext{ | |
31 int low; | |
32 int range; | |
33 int outstanding_count; | |
34 #ifdef STRICT_LIMITS | |
35 int symCount; | |
36 #endif | |
37 uint8_t lps_range[2*64][4]; ///< rangeTabLPS | |
38 uint8_t lps_state[2*64]; ///< transIdxLPS | |
39 uint8_t mps_state[2*64]; ///< transIdxMPS | |
40 uint8_t *bytestream; | |
41 int bits_left; ///< | |
42 PutBitContext pb; | |
43 }CABACContext; | |
44 | |
45 const uint8_t ff_h264_lps_range[64][4]; | |
46 const uint8_t ff_h264_mps_state[64]; | |
47 const uint8_t ff_h264_lps_state[64]; | |
48 | |
49 void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size); | |
50 void ff_init_cabac_decoder(CABACContext *c, uint8_t *buf, int buf_size); | |
51 void ff_init_cabac_states(CABACContext *c, uint8_t const (*lps_range)[4], | |
52 uint8_t const *mps_state, uint8_t const *lps_state, int state_count); | |
53 | |
54 | |
55 static inline void put_cabac_bit(CABACContext *c, int b){ | |
56 put_bits(&c->pb, 1, b); | |
57 for(;c->outstanding_count; c->outstanding_count--){ | |
58 put_bits(&c->pb, 1, 1-b); | |
59 } | |
60 } | |
61 | |
62 static inline void renorm_cabac_encoder(CABACContext *c){ | |
63 while(c->range < 0x100){ | |
64 //FIXME optimize | |
65 if(c->low<0x100){ | |
66 put_cabac_bit(c, 0); | |
67 }else if(c->low<0x200){ | |
68 c->outstanding_count++; | |
69 c->low -= 0x100; | |
70 }else{ | |
71 put_cabac_bit(c, 1); | |
72 c->low -= 0x200; | |
73 } | |
74 | |
75 c->range+= c->range; | |
76 c->low += c->low; | |
77 } | |
78 } | |
79 | |
80 static inline void put_cabac(CABACContext *c, uint8_t * const state, int bit){ | |
81 int RangeLPS= c->lps_range[*state][((c->range)>>6)&3]; | |
82 | |
83 if(bit == ((*state)&1)){ | |
84 c->range -= RangeLPS; | |
85 *state= c->mps_state[*state]; | |
86 }else{ | |
87 c->low += c->range - RangeLPS; | |
88 c->range = RangeLPS; | |
89 *state= c->lps_state[*state]; | |
90 } | |
91 | |
92 renorm_cabac_encoder(c); | |
93 | |
94 #ifdef STRICT_LIMITS | |
95 c->symCount++; | |
96 #endif | |
97 } | |
98 | |
99 static inline void put_cabac_static(CABACContext *c, int RangeLPS, int bit){ | |
100 assert(c->range > RangeLPS); | |
101 | |
102 if(!bit){ | |
103 c->range -= RangeLPS; | |
104 }else{ | |
105 c->low += c->range - RangeLPS; | |
106 c->range = RangeLPS; | |
107 } | |
108 | |
109 renorm_cabac_encoder(c); | |
110 | |
111 #ifdef STRICT_LIMITS | |
112 c->symCount++; | |
113 #endif | |
114 } | |
115 | |
116 static inline void put_cabac_bypass(CABACContext *c, int bit){ | |
117 c->low += c->low; | |
118 | |
119 if(bit){ | |
120 c->low += c->range; | |
121 } | |
122 //FIXME optimize | |
123 if(c->low<0x200){ | |
124 put_cabac_bit(c, 0); | |
125 }else if(c->low<0x400){ | |
126 c->outstanding_count++; | |
127 c->low -= 0x200; | |
128 }else{ | |
129 put_cabac_bit(c, 1); | |
130 c->low -= 0x400; | |
131 } | |
132 | |
133 #ifdef STRICT_LIMITS | |
134 c->symCount++; | |
135 #endif | |
136 } | |
137 | |
138 static inline void put_cabac_terminate(CABACContext *c, int bit){ | |
139 c->range -= 2; | |
140 | |
141 if(!bit){ | |
142 renorm_cabac_encoder(c); | |
143 }else{ | |
144 c->low += c->range; | |
145 c->range= 2; | |
146 | |
147 renorm_cabac_encoder(c); | |
148 | |
149 assert(c->low <= 0x1FF); | |
150 put_cabac_bit(c, c->low>>9); | |
151 put_bits(&c->pb, 2, ((c->low>>7)&3)|1); | |
152 | |
153 flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong | |
154 } | |
155 | |
156 #ifdef STRICT_LIMITS | |
157 c->symCount++; | |
158 #endif | |
159 } | |
160 | |
161 static inline void renorm_cabac_decoder(CABACContext *c){ | |
162 while(c->range < 0x10000){ | |
163 c->range+= c->range; | |
164 c->low+= c->low; | |
165 if(--c->bits_left == 0){ | |
166 c->low+= *c->bytestream++; | |
167 c->bits_left= 8; | |
168 } | |
169 } | |
170 } | |
171 | |
172 static inline int get_cabac(CABACContext *c, uint8_t * const state){ | |
173 int RangeLPS= c->lps_range[*state][((c->range)>>14)&3]<<8; | |
174 int bit; | |
175 | |
176 c->range -= RangeLPS; | |
177 if(c->low < c->range){ | |
178 bit= (*state)&1; | |
179 *state= c->mps_state[*state]; | |
180 }else{ | |
181 bit= ((*state)&1)^1; | |
182 c->low -= c->range; | |
183 c->range = RangeLPS; | |
184 *state= c->lps_state[*state]; | |
185 } | |
186 renorm_cabac_decoder(c); | |
187 | |
188 return bit; | |
189 } | |
190 | |
191 static inline int get_cabac_static(CABACContext *c, int RangeLPS){ | |
192 int bit; | |
193 | |
194 c->range -= RangeLPS; | |
195 if(c->low < c->range){ | |
196 bit= 0; | |
197 }else{ | |
198 bit= 1; | |
199 c->low -= c->range; | |
200 c->range = RangeLPS; | |
201 } | |
202 renorm_cabac_decoder(c); | |
203 | |
204 return bit; | |
205 } | |
206 | |
207 static inline int get_cabac_bypass(CABACContext *c){ | |
208 c->low += c->low; | |
209 | |
210 if(--c->bits_left == 0){ | |
211 c->low+= *c->bytestream++; | |
212 c->bits_left= 8; | |
213 } | |
214 | |
215 if(c->low < c->range){ | |
216 return 0; | |
217 }else{ | |
218 c->low -= c->range; | |
219 return 1; | |
220 } | |
221 } | |
222 | |
223 static inline int get_cabac_terminate(CABACContext *c){ | |
224 c->range -= 2<<8; | |
225 if(c->low < c->range){ | |
226 renorm_cabac_decoder(c); | |
227 return 0; | |
228 }else{ | |
229 return 1; | |
230 } | |
231 } | |
232 |