Parent Directory | Revision Log
Revision 790 - (view) (download)
1 : | suxen_drol | 118 | /****************************************************************************** |
2 : | * * | ||
3 : | * This file is part of XviD, a free MPEG-4 video encoder/decoder * | ||
4 : | * * | ||
5 : | * XviD is an implementation of a part of one or more MPEG-4 Video tools * | ||
6 : | * as specified in ISO/IEC 14496-2 standard. Those intending to use this * | ||
7 : | * software module in hardware or software products are advised that its * | ||
8 : | * use may infringe existing patents or copyrights, and any such use * | ||
9 : | * would be at such party's own risk. The original developer of this * | ||
10 : | * software module and his/her company, and subsequent editors and their * | ||
11 : | * companies, will have no liability for use of this software or * | ||
12 : | * modifications or derivatives thereof. * | ||
13 : | * * | ||
14 : | * XviD is free software; you can redistribute it and/or modify it * | ||
15 : | * under the terms of the GNU General Public License as published by * | ||
16 : | * the Free Software Foundation; either version 2 of the License, or * | ||
17 : | * (at your option) any later version. * | ||
18 : | * * | ||
19 : | * XviD is distributed in the hope that it will be useful, but * | ||
20 : | * WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
21 : | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | ||
22 : | * GNU General Public License for more details. * | ||
23 : | * * | ||
24 : | * You should have received a copy of the GNU General Public License * | ||
25 : | * along with this program; if not, write to the Free Software * | ||
26 : | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * | ||
27 : | * * | ||
28 : | ******************************************************************************/ | ||
29 : | |||
30 : | /****************************************************************************** | ||
31 : | * * | ||
32 : | Isibaar | 153 | * mbcoding.c * |
33 : | suxen_drol | 118 | * * |
34 : | Isibaar | 153 | * Copyright (C) 2002 - Michael Militzer <isibaar@xvid.org> * |
35 : | suxen_drol | 118 | * * |
36 : | * For more information visit the XviD homepage: http://www.xvid.org * | ||
37 : | * * | ||
38 : | ******************************************************************************/ | ||
39 : | |||
40 : | /****************************************************************************** | ||
41 : | * * | ||
42 : | * Revision history: * | ||
43 : | * * | ||
44 : | edgomez | 790 | * 28.10.2002 GMC support - gruel * |
45 : | suxen_drol | 248 | * 28.06.2002 added check_resync_marker() * |
46 : | Isibaar | 153 | * 14.04.2002 bframe encoding * |
47 : | suxen_drol | 118 | * 08.03.2002 initial version; isibaar * |
48 : | * * | ||
49 : | ******************************************************************************/ | ||
50 : | |||
51 : | |||
52 : | chl | 769 | #include <stdio.h> |
53 : | Isibaar | 100 | #include <stdlib.h> |
54 : | Isibaar | 3 | #include "../portab.h" |
55 : | suxen_drol | 760 | #include "../global.h" |
56 : | Isibaar | 3 | #include "bitstream.h" |
57 : | #include "zigzag.h" | ||
58 : | #include "vlc_codes.h" | ||
59 : | Isibaar | 100 | #include "mbcoding.h" |
60 : | Isibaar | 3 | |
61 : | #include "../utils/mbfunctions.h" | ||
62 : | |||
63 : | edgomez | 790 | /* #define BIGLUT */ |
64 : | Isibaar | 100 | |
65 : | edgomez | 790 | #ifdef BIGLUT |
66 : | #define LEVELOFFSET 2048 | ||
67 : | #else | ||
68 : | #define LEVELOFFSET 32 | ||
69 : | #endif | ||
70 : | Isibaar | 3 | |
71 : | edgomez | 790 | static REVERSE_EVENT DCT3D[2][4096]; |
72 : | |||
73 : | #ifdef BIGLUT | ||
74 : | static VLC coeff_VLC[2][2][4096][64]; | ||
75 : | static VLC *intra_table, *inter_table; | ||
76 : | #else | ||
77 : | static VLC coeff_VLC[2][2][64][64]; | ||
78 : | #endif | ||
79 : | |||
80 : | chl | 619 | /* not really MB related, but VLCs are only available here */ |
81 : | suxen_drol | 622 | void bs_put_spritetrajectory(Bitstream * bs, const int val) |
82 : | chl | 619 | { |
83 : | const int code = sprite_trajectory_code[val+16384].code; | ||
84 : | const int len = sprite_trajectory_code[val+16384].len; | ||
85 : | const int code2 = sprite_trajectory_len[len].code; | ||
86 : | const int len2 = sprite_trajectory_len[len].len; | ||
87 : | |||
88 : | // printf("GMC=%d Code/Len = %d / %d ",val, code,len); | ||
89 : | // printf("Code2 / Len2 = %d / %d \n",code2,len2); | ||
90 : | |||
91 : | BitstreamPutBits(bs, code2, len2); | ||
92 : | if (len) BitstreamPutBits(bs, code, len); | ||
93 : | } | ||
94 : | |||
95 : | suxen_drol | 631 | int bs_get_spritetrajectory(Bitstream * bs) |
96 : | { | ||
97 : | int i; | ||
98 : | for (i = 0; i < 12; i++) | ||
99 : | { | ||
100 : | if (BitstreamShowBits(bs, sprite_trajectory_len[i].len) == sprite_trajectory_len[i].code) | ||
101 : | { | ||
102 : | BitstreamSkip(bs, sprite_trajectory_len[i].len); | ||
103 : | return i; | ||
104 : | } | ||
105 : | } | ||
106 : | return -1; | ||
107 : | } | ||
108 : | chl | 619 | |
109 : | edgomez | 195 | void |
110 : | init_vlc_tables(void) | ||
111 : | Isibaar | 3 | { |
112 : | edgomez | 790 | uint32_t i, j, k, intra, last, run, run_esc, level, level_esc, escape, escape_len, offset, limit; |
113 : | int32_t l; | ||
114 : | edgomez | 78 | |
115 : | edgomez | 790 | #ifdef BIGLUT |
116 : | intra_table = coeff_VLC[1]; | ||
117 : | inter_table = coeff_VLC[0]; | ||
118 : | #endif | ||
119 : | Isibaar | 3 | |
120 : | edgomez | 195 | |
121 : | edgomez | 790 | for (intra = 0; intra < 2; intra++) |
122 : | for (i = 0; i < 4096; i++) | ||
123 : | DCT3D[intra][i].event.level = 0; | ||
124 : | edgomez | 195 | |
125 : | edgomez | 790 | for (intra = 0; intra < 2; intra++) |
126 : | for (last = 0; last < 2; last++) | ||
127 : | { | ||
128 : | for (run = 0; run < 63 + last; run++) | ||
129 : | for (level = 0; level < 32 << intra; level++) | ||
130 : | { | ||
131 : | #ifdef BIGLUT | ||
132 : | offset = LEVELOFFSET; | ||
133 : | #else | ||
134 : | offset = !intra * LEVELOFFSET; | ||
135 : | #endif | ||
136 : | coeff_VLC[intra][last][level + offset][run].len = 128; | ||
137 : | } | ||
138 : | } | ||
139 : | Isibaar | 3 | |
140 : | edgomez | 790 | for (intra = 0; intra < 2; intra++) |
141 : | for (i = 0; i < 102; i++) | ||
142 : | { | ||
143 : | #ifdef BIGLUT | ||
144 : | offset = LEVELOFFSET; | ||
145 : | #else | ||
146 : | offset = !intra * LEVELOFFSET; | ||
147 : | #endif | ||
148 : | for (j = 0; j < 1 << (12 - coeff_tab[intra][i].vlc.len); j++) | ||
149 : | { | ||
150 : | DCT3D[intra][(coeff_tab[intra][i].vlc.code << (12 - coeff_tab[intra][i].vlc.len)) | j].len = coeff_tab[intra][i].vlc.len; | ||
151 : | DCT3D[intra][(coeff_tab[intra][i].vlc.code << (12 - coeff_tab[intra][i].vlc.len)) | j].event = coeff_tab[intra][i].event; | ||
152 : | } | ||
153 : | edgomez | 195 | |
154 : | edgomez | 790 | coeff_VLC[intra][coeff_tab[intra][i].event.last][coeff_tab[intra][i].event.level + offset][coeff_tab[intra][i].event.run].code |
155 : | = coeff_tab[intra][i].vlc.code << 1; | ||
156 : | coeff_VLC[intra][coeff_tab[intra][i].event.last][coeff_tab[intra][i].event.level + offset][coeff_tab[intra][i].event.run].len | ||
157 : | = coeff_tab[intra][i].vlc.len + 1; | ||
158 : | #ifndef BIGLUT | ||
159 : | if (!intra) | ||
160 : | #endif | ||
161 : | { | ||
162 : | coeff_VLC[intra][coeff_tab[intra][i].event.last][offset - coeff_tab[intra][i].event.level][coeff_tab[intra][i].event.run].code | ||
163 : | = (coeff_tab[intra][i].vlc.code << 1) | 1; | ||
164 : | coeff_VLC[intra][coeff_tab[intra][i].event.last][offset - coeff_tab[intra][i].event.level][coeff_tab[intra][i].event.run].len | ||
165 : | = coeff_tab[intra][i].vlc.len + 1; | ||
166 : | } | ||
167 : | } | ||
168 : | edgomez | 195 | |
169 : | edgomez | 790 | for (intra = 0; intra < 2; intra++) |
170 : | for (last = 0; last < 2; last++) | ||
171 : | for (run = 0; run < 63 + last; run++) | ||
172 : | { | ||
173 : | for (level = 1; level < 32 << intra; level++) | ||
174 : | { | ||
175 : | if (level <= max_level[intra][last][run] && run <= max_run[intra][last][level]) | ||
176 : | continue; | ||
177 : | edgomez | 195 | |
178 : | edgomez | 790 | #ifdef BIGLUT |
179 : | offset = LEVELOFFSET; | ||
180 : | #else | ||
181 : | offset = !intra * LEVELOFFSET; | ||
182 : | #endif | ||
183 : | level_esc = level - max_level[intra][last][run]; | ||
184 : | run_esc = run - 1 - max_run[intra][last][level]; | ||
185 : | /*use this test to use shorter esc2 codes when possible | ||
186 : | if (level_esc <= max_level[intra][last][run] && run <= max_run[intra][last][level_esc] | ||
187 : | && !(coeff_VLC[intra][last][level_esc + offset][run].len + 7 + 1 | ||
188 : | > coeff_VLC[intra][last][level + offset][run_esc].code + 7 + 2))*/ | ||
189 : | edgomez | 195 | |
190 : | edgomez | 790 | if (level_esc <= max_level[intra][last][run] && run <= max_run[intra][last][level_esc]) |
191 : | { | ||
192 : | escape = ESCAPE1; | ||
193 : | escape_len = 7 + 1; | ||
194 : | run_esc = run; | ||
195 : | } | ||
196 : | Isibaar | 3 | else |
197 : | edgomez | 790 | { |
198 : | if (level <= max_level[intra][last][run_esc] && run_esc <= max_run[intra][last][level]) | ||
199 : | { | ||
200 : | escape = ESCAPE2; | ||
201 : | escape_len = 7 + 2; | ||
202 : | level_esc = level; | ||
203 : | } | ||
204 : | else | ||
205 : | { | ||
206 : | #ifndef BIGLUT | ||
207 : | if (!intra) | ||
208 : | #endif | ||
209 : | { | ||
210 : | coeff_VLC[intra][last][level + offset][run].code | ||
211 : | = (ESCAPE3 << 21) | (last << 20) | (run << 14) | (1 << 13) | ((level & 0xfff) << 1) | 1; | ||
212 : | coeff_VLC[intra][last][level + offset][run].len = 30; | ||
213 : | coeff_VLC[intra][last][offset - level][run].code | ||
214 : | = (ESCAPE3 << 21) | (last << 20) | (run << 14) | (1 << 13) | ((-level & 0xfff) << 1) | 1; | ||
215 : | coeff_VLC[intra][last][offset - level][run].len = 30; | ||
216 : | } | ||
217 : | continue; | ||
218 : | } | ||
219 : | Isibaar | 100 | } |
220 : | Isibaar | 3 | |
221 : | edgomez | 790 | coeff_VLC[intra][last][level + offset][run].code |
222 : | = (escape << coeff_VLC[intra][last][level_esc + offset][run_esc].len) | ||
223 : | | coeff_VLC[intra][last][level_esc + offset][run_esc].code; | ||
224 : | coeff_VLC[intra][last][level + offset][run].len | ||
225 : | = coeff_VLC[intra][last][level_esc + offset][run_esc].len + escape_len; | ||
226 : | #ifndef BIGLUT | ||
227 : | if (!intra) | ||
228 : | #endif | ||
229 : | { | ||
230 : | coeff_VLC[intra][last][offset - level][run].code | ||
231 : | = (escape << coeff_VLC[intra][last][level_esc + offset][run_esc].len) | ||
232 : | | coeff_VLC[intra][last][level_esc + offset][run_esc].code | 1; | ||
233 : | coeff_VLC[intra][last][offset - level][run].len | ||
234 : | = coeff_VLC[intra][last][level_esc + offset][run_esc].len + escape_len; | ||
235 : | Isibaar | 3 | } |
236 : | } | ||
237 : | Isibaar | 100 | |
238 : | edgomez | 790 | #ifdef BIGLUT |
239 : | for (level = 32 << intra; level < 2048; level++) | ||
240 : | { | ||
241 : | coeff_VLC[intra][last][level + offset][run].code | ||
242 : | = (ESCAPE3 << 21) | (last << 20) | (run << 14) | (1 << 13) | ((level & 0xfff) << 1) | 1; | ||
243 : | coeff_VLC[intra][last][level + offset][run].len = 30; | ||
244 : | Isibaar | 100 | |
245 : | edgomez | 790 | coeff_VLC[intra][last][offset - level][run].code |
246 : | = (ESCAPE3 << 21) | (last << 20) | (run << 14) | (1 << 13) | ((-level & 0xfff) << 1) | 1; | ||
247 : | coeff_VLC[intra][last][offset - level][run].len = 30; | ||
248 : | Isibaar | 100 | } |
249 : | edgomez | 790 | #else |
250 : | if (!intra) | ||
251 : | { | ||
252 : | coeff_VLC[intra][last][0][run].code | ||
253 : | = (ESCAPE3 << 21) | (last << 20) | (run << 14) | (1 << 13) | ((-32 & 0xfff) << 1) | 1; | ||
254 : | coeff_VLC[intra][last][0][run].len = 30; | ||
255 : | } | ||
256 : | #endif | ||
257 : | Isibaar | 3 | } |
258 : | chl | 619 | /* init sprite_trajectory tables */ |
259 : | /* even if GMC is not specified (it might be used later...) */ | ||
260 : | |||
261 : | sprite_trajectory_code[0+16384].code = 0; | ||
262 : | sprite_trajectory_code[0+16384].len = 0; | ||
263 : | for (k=0;k<14;k++) | ||
264 : | { | ||
265 : | int limit = (1<<k); | ||
266 : | |||
267 : | edgomez | 790 | for (l=-(2*limit-1); l <= -limit; l++) |
268 : | chl | 619 | { |
269 : | edgomez | 790 | sprite_trajectory_code[i+16384].code = (2*limit-1)+l; |
270 : | chl | 619 | sprite_trajectory_code[i+16384].len = k+1; |
271 : | } | ||
272 : | |||
273 : | edgomez | 790 | for (l=limit; l<= 2*limit-1; l++) |
274 : | chl | 619 | { |
275 : | edgomez | 790 | sprite_trajectory_code[i+16384].code = l; |
276 : | chl | 619 | sprite_trajectory_code[i+16384].len = k+1; |
277 : | } | ||
278 : | } | ||
279 : | Isibaar | 3 | } |
280 : | |||
281 : | edgomez | 195 | static __inline void |
282 : | CodeVector(Bitstream * bs, | ||
283 : | int32_t value, | ||
284 : | int32_t f_code, | ||
285 : | Statistics * pStat) | ||
286 : | Isibaar | 3 | { |
287 : | edgomez | 78 | |
288 : | Isibaar | 3 | const int scale_factor = 1 << (f_code - 1); |
289 : | const int cmp = scale_factor << 5; | ||
290 : | |||
291 : | edgomez | 195 | if (value < (-1 * cmp)) |
292 : | Isibaar | 3 | value += 64 * scale_factor; |
293 : | edgomez | 195 | |
294 : | if (value > (cmp - 1)) | ||
295 : | Isibaar | 3 | value -= 64 * scale_factor; |
296 : | |||
297 : | edgomez | 78 | pStat->iMvSum += value * value; |
298 : | pStat->iMvCount++; | ||
299 : | Isibaar | 3 | |
300 : | edgomez | 78 | if (value == 0) { |
301 : | edgomez | 195 | BitstreamPutBits(bs, mb_motion_table[32].code, |
302 : | mb_motion_table[32].len); | ||
303 : | edgomez | 78 | } else { |
304 : | Isibaar | 3 | uint16_t length, code, mv_res, sign; |
305 : | edgomez | 195 | |
306 : | Isibaar | 3 | length = 16 << f_code; |
307 : | f_code--; | ||
308 : | edgomez | 195 | |
309 : | Isibaar | 3 | sign = (value < 0); |
310 : | |||
311 : | edgomez | 195 | if (value >= length) |
312 : | Isibaar | 3 | value -= 2 * length; |
313 : | edgomez | 195 | else if (value < -length) |
314 : | Isibaar | 3 | value += 2 * length; |
315 : | |||
316 : | edgomez | 195 | if (sign) |
317 : | Isibaar | 3 | value = -value; |
318 : | |||
319 : | value--; | ||
320 : | mv_res = value & ((1 << f_code) - 1); | ||
321 : | code = ((value - mv_res) >> f_code) + 1; | ||
322 : | |||
323 : | edgomez | 195 | if (sign) |
324 : | Isibaar | 3 | code = -code; |
325 : | |||
326 : | code += 32; | ||
327 : | edgomez | 195 | BitstreamPutBits(bs, mb_motion_table[code].code, |
328 : | mb_motion_table[code].len); | ||
329 : | |||
330 : | if (f_code) | ||
331 : | Isibaar | 3 | BitstreamPutBits(bs, mv_res, f_code); |
332 : | edgomez | 78 | } |
333 : | |||
334 : | Isibaar | 3 | } |
335 : | |||
336 : | edgomez | 790 | #ifdef BIGLUT |
337 : | Isibaar | 3 | |
338 : | edgomez | 195 | static __inline void |
339 : | CodeCoeff(Bitstream * bs, | ||
340 : | const int16_t qcoeff[64], | ||
341 : | VLC * table, | ||
342 : | const uint16_t * zigzag, | ||
343 : | uint16_t intra) | ||
344 : | edgomez | 78 | { |
345 : | |||
346 : | Isibaar | 3 | uint32_t j, last; |
347 : | short v; | ||
348 : | VLC *vlc; | ||
349 : | edgomez | 195 | |
350 : | Isibaar | 3 | j = intra; |
351 : | Isibaar | 116 | last = intra; |
352 : | Isibaar | 3 | |
353 : | edgomez | 195 | while (j < 64 && (v = qcoeff[zigzag[j]]) == 0) |
354 : | j++; | ||
355 : | |||
356 : | Isibaar | 3 | do { |
357 : | edgomez | 790 | vlc = table + 64 * 2048 + (v << 6) + j - last; |
358 : | Isibaar | 116 | last = ++j; |
359 : | Isibaar | 153 | |
360 : | edgomez | 790 | /* count zeroes */ |
361 : | edgomez | 195 | while (j < 64 && (v = qcoeff[zigzag[j]]) == 0) |
362 : | j++; | ||
363 : | |||
364 : | edgomez | 790 | /* write code */ |
365 : | edgomez | 195 | if (j != 64) { |
366 : | Isibaar | 3 | BitstreamPutBits(bs, vlc->code, vlc->len); |
367 : | } else { | ||
368 : | edgomez | 790 | vlc += 64 * 4096; |
369 : | Isibaar | 3 | BitstreamPutBits(bs, vlc->code, vlc->len); |
370 : | break; | ||
371 : | } | ||
372 : | edgomez | 195 | } while (1); |
373 : | edgomez | 78 | |
374 : | Isibaar | 3 | } |
375 : | |||
376 : | edgomez | 790 | #else |
377 : | Isibaar | 3 | |
378 : | chl | 530 | static __inline void |
379 : | edgomez | 790 | CodeCoeffInter(Bitstream * bs, |
380 : | const int16_t qcoeff[64], | ||
381 : | const uint16_t * zigzag) | ||
382 : | { | ||
383 : | uint32_t i, run, prev_run, code, len; | ||
384 : | int32_t level, prev_level, level_shifted; | ||
385 : | |||
386 : | i = 0; | ||
387 : | run = 0; | ||
388 : | |||
389 : | while (!(level = qcoeff[zigzag[i++]])) | ||
390 : | run++; | ||
391 : | |||
392 : | prev_level = level; | ||
393 : | prev_run = run; | ||
394 : | run = 0; | ||
395 : | |||
396 : | while (i < 64) | ||
397 : | { | ||
398 : | if ((level = qcoeff[zigzag[i++]]) != 0) | ||
399 : | { | ||
400 : | level_shifted = prev_level + 32; | ||
401 : | if (!(level_shifted & -64)) | ||
402 : | { | ||
403 : | code = coeff_VLC[0][0][level_shifted][prev_run].code; | ||
404 : | len = coeff_VLC[0][0][level_shifted][prev_run].len; | ||
405 : | } | ||
406 : | else | ||
407 : | { | ||
408 : | code = (ESCAPE3 << 21) | (prev_run << 14) | (1 << 13) | ((prev_level & 0xfff) << 1) | 1; | ||
409 : | len = 30; | ||
410 : | } | ||
411 : | BitstreamPutBits(bs, code, len); | ||
412 : | prev_level = level; | ||
413 : | prev_run = run; | ||
414 : | run = 0; | ||
415 : | } | ||
416 : | else | ||
417 : | run++; | ||
418 : | } | ||
419 : | |||
420 : | level_shifted = prev_level + 32; | ||
421 : | if (!(level_shifted & -64)) | ||
422 : | { | ||
423 : | code = coeff_VLC[0][1][level_shifted][prev_run].code; | ||
424 : | len = coeff_VLC[0][1][level_shifted][prev_run].len; | ||
425 : | } | ||
426 : | else | ||
427 : | { | ||
428 : | code = (ESCAPE3 << 21) | (1 << 20) | (prev_run << 14) | (1 << 13) | ((prev_level & 0xfff) << 1) | 1; | ||
429 : | len = 30; | ||
430 : | } | ||
431 : | BitstreamPutBits(bs, code, len); | ||
432 : | } | ||
433 : | |||
434 : | static __inline void | ||
435 : | CodeCoeffIntra(Bitstream * bs, | ||
436 : | const int16_t qcoeff[64], | ||
437 : | const uint16_t * zigzag) | ||
438 : | { | ||
439 : | uint32_t i, abs_level, run, prev_run, code, len; | ||
440 : | int32_t level, prev_level; | ||
441 : | |||
442 : | i = 1; | ||
443 : | run = 0; | ||
444 : | |||
445 : | while (!(level = qcoeff[zigzag[i++]])) | ||
446 : | run++; | ||
447 : | |||
448 : | prev_level = level; | ||
449 : | prev_run = run; | ||
450 : | run = 0; | ||
451 : | |||
452 : | while (i < 64) | ||
453 : | { | ||
454 : | if ((level = qcoeff[zigzag[i++]]) != 0) | ||
455 : | { | ||
456 : | abs_level = ABS(prev_level); | ||
457 : | abs_level = abs_level < 64 ? abs_level : 0; | ||
458 : | code = coeff_VLC[1][0][abs_level][prev_run].code; | ||
459 : | len = coeff_VLC[1][0][abs_level][prev_run].len; | ||
460 : | if (len != 128) | ||
461 : | code |= (prev_level < 0); | ||
462 : | else | ||
463 : | { | ||
464 : | code = (ESCAPE3 << 21) | (prev_run << 14) | (1 << 13) | ((prev_level & 0xfff) << 1) | 1; | ||
465 : | len = 30; | ||
466 : | } | ||
467 : | BitstreamPutBits(bs, code, len); | ||
468 : | prev_level = level; | ||
469 : | prev_run = run; | ||
470 : | run = 0; | ||
471 : | } | ||
472 : | else | ||
473 : | run++; | ||
474 : | } | ||
475 : | |||
476 : | abs_level = ABS(prev_level); | ||
477 : | abs_level = abs_level < 64 ? abs_level : 0; | ||
478 : | code = coeff_VLC[1][1][abs_level][prev_run].code; | ||
479 : | len = coeff_VLC[1][1][abs_level][prev_run].len; | ||
480 : | if (len != 128) | ||
481 : | code |= (prev_level < 0); | ||
482 : | else | ||
483 : | { | ||
484 : | code = (ESCAPE3 << 21) | (1 << 20) | (prev_run << 14) | (1 << 13) | ((prev_level & 0xfff) << 1) | 1; | ||
485 : | len = 30; | ||
486 : | } | ||
487 : | BitstreamPutBits(bs, code, len); | ||
488 : | } | ||
489 : | |||
490 : | #endif | ||
491 : | |||
492 : | static __inline void | ||
493 : | chl | 619 | CodeBlockIntra(const FRAMEINFO * const frame, |
494 : | edgomez | 195 | const MACROBLOCK * pMB, |
495 : | int16_t qcoeff[6 * 64], | ||
496 : | edgomez | 78 | Bitstream * bs, |
497 : | Statistics * pStat) | ||
498 : | Isibaar | 3 | { |
499 : | edgomez | 78 | |
500 : | Isibaar | 3 | uint32_t i, mcbpc, cbpy, bits; |
501 : | |||
502 : | cbpy = pMB->cbp >> 2; | ||
503 : | |||
504 : | edgomez | 78 | // write mcbpc |
505 : | edgomez | 195 | if (frame->coding_type == I_VOP) { |
506 : | edgomez | 78 | mcbpc = ((pMB->mode >> 1) & 3) | ((pMB->cbp & 3) << 2); |
507 : | edgomez | 195 | BitstreamPutBits(bs, mcbpc_intra_tab[mcbpc].code, |
508 : | mcbpc_intra_tab[mcbpc].len); | ||
509 : | } else { | ||
510 : | edgomez | 78 | mcbpc = (pMB->mode & 7) | ((pMB->cbp & 3) << 3); |
511 : | edgomez | 195 | BitstreamPutBits(bs, mcbpc_inter_tab[mcbpc].code, |
512 : | mcbpc_inter_tab[mcbpc].len); | ||
513 : | Isibaar | 28 | } |
514 : | Isibaar | 3 | |
515 : | // ac prediction flag | ||
516 : | edgomez | 195 | if (pMB->acpred_directions[0]) |
517 : | edgomez | 78 | BitstreamPutBits(bs, 1, 1); |
518 : | Isibaar | 3 | else |
519 : | edgomez | 78 | BitstreamPutBits(bs, 0, 1); |
520 : | Isibaar | 3 | |
521 : | edgomez | 78 | // write cbpy |
522 : | edgomez | 195 | BitstreamPutBits(bs, cbpy_tab[cbpy].code, cbpy_tab[cbpy].len); |
523 : | Isibaar | 3 | |
524 : | // write dquant | ||
525 : | edgomez | 195 | if (pMB->mode == MODE_INTRA_Q) |
526 : | Isibaar | 3 | BitstreamPutBits(bs, pMB->dquant, 2); |
527 : | |||
528 : | h | 69 | // write interlacing |
529 : | edgomez | 195 | if (frame->global_flags & XVID_INTERLACING) { |
530 : | h | 69 | BitstreamPutBit(bs, pMB->field_dct); |
531 : | } | ||
532 : | Isibaar | 3 | // code block coeffs |
533 : | edgomez | 195 | for (i = 0; i < 6; i++) { |
534 : | if (i < 4) | ||
535 : | BitstreamPutBits(bs, dcy_tab[qcoeff[i * 64 + 0] + 255].code, | ||
536 : | dcy_tab[qcoeff[i * 64 + 0] + 255].len); | ||
537 : | Isibaar | 3 | else |
538 : | edgomez | 195 | BitstreamPutBits(bs, dcc_tab[qcoeff[i * 64 + 0] + 255].code, |
539 : | dcc_tab[qcoeff[i * 64 + 0] + 255].len); | ||
540 : | |||
541 : | if (pMB->cbp & (1 << (5 - i))) { | ||
542 : | h | 543 | const uint16_t *scan_table = |
543 : | frame->global_flags & XVID_ALTERNATESCAN ? | ||
544 : | scan_tables[2] : scan_tables[pMB->acpred_directions[i]]; | ||
545 : | |||
546 : | Isibaar | 3 | bits = BitstreamPos(bs); |
547 : | |||
548 : | edgomez | 790 | #ifdef BIGLUT |
549 : | h | 543 | CodeCoeff(bs, &qcoeff[i * 64], intra_table, scan_table, 1); |
550 : | edgomez | 790 | #else |
551 : | CodeCoeffIntra(bs, &qcoeff[i * 64], scan_table); | ||
552 : | #endif | ||
553 : | Isibaar | 3 | |
554 : | bits = BitstreamPos(bs) - bits; | ||
555 : | pStat->iTextBits += bits; | ||
556 : | } | ||
557 : | } | ||
558 : | edgomez | 78 | |
559 : | Isibaar | 3 | } |
560 : | |||
561 : | |||
562 : | edgomez | 195 | static void |
563 : | chl | 619 | CodeBlockInter(const FRAMEINFO * const frame, |
564 : | edgomez | 195 | const MACROBLOCK * pMB, |
565 : | int16_t qcoeff[6 * 64], | ||
566 : | edgomez | 78 | Bitstream * bs, |
567 : | Statistics * pStat) | ||
568 : | Isibaar | 3 | { |
569 : | edgomez | 78 | |
570 : | Isibaar | 3 | int32_t i; |
571 : | uint32_t bits, mcbpc, cbpy; | ||
572 : | |||
573 : | edgomez | 78 | mcbpc = (pMB->mode & 7) | ((pMB->cbp & 3) << 3); |
574 : | Isibaar | 3 | cbpy = 15 - (pMB->cbp >> 2); |
575 : | |||
576 : | // write mcbpc | ||
577 : | edgomez | 195 | BitstreamPutBits(bs, mcbpc_inter_tab[mcbpc].code, |
578 : | mcbpc_inter_tab[mcbpc].len); | ||
579 : | Isibaar | 3 | |
580 : | chl | 619 | if ( (frame->coding_type == S_VOP) && (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) ) |
581 : | chl | 769 | BitstreamPutBit(bs, pMB->mcsel); // mcsel: '0'=local motion, '1'=GMC |
582 : | chl | 619 | |
583 : | Isibaar | 3 | // write cbpy |
584 : | BitstreamPutBits(bs, cbpy_tab[cbpy].code, cbpy_tab[cbpy].len); | ||
585 : | |||
586 : | // write dquant | ||
587 : | edgomez | 195 | if (pMB->mode == MODE_INTER_Q) |
588 : | Isibaar | 3 | BitstreamPutBits(bs, pMB->dquant, 2); |
589 : | edgomez | 195 | |
590 : | h | 69 | // interlacing |
591 : | edgomez | 195 | if (frame->global_flags & XVID_INTERLACING) { |
592 : | h | 388 | if (pMB->cbp) { |
593 : | BitstreamPutBit(bs, pMB->field_dct); | ||
594 : | suxen_drol | 721 | DPRINTF(DPRINTF_MB,"codep: field_dct: %i", pMB->field_dct); |
595 : | h | 388 | } |
596 : | h | 69 | |
597 : | // if inter block, write field ME flag | ||
598 : | edgomez | 195 | if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) { |
599 : | h | 69 | BitstreamPutBit(bs, pMB->field_pred); |
600 : | suxen_drol | 721 | DPRINTF(DPRINTF_MB,"codep: field_pred: %i", pMB->field_pred); |
601 : | h | 69 | |
602 : | // write field prediction references | ||
603 : | edgomez | 195 | if (pMB->field_pred) { |
604 : | h | 69 | BitstreamPutBit(bs, pMB->field_for_top); |
605 : | BitstreamPutBit(bs, pMB->field_for_bot); | ||
606 : | } | ||
607 : | } | ||
608 : | } | ||
609 : | chl | 619 | // code motion vector(s) if motion is local |
610 : | chl | 769 | if (!pMB->mcsel) |
611 : | chl | 619 | for (i = 0; i < (pMB->mode == MODE_INTER4V ? 4 : 1); i++) { |
612 : | CodeVector(bs, pMB->pmvs[i].x, frame->fcode, pStat); | ||
613 : | CodeVector(bs, pMB->pmvs[i].y, frame->fcode, pStat); | ||
614 : | } | ||
615 : | Isibaar | 3 | |
616 : | bits = BitstreamPos(bs); | ||
617 : | edgomez | 195 | |
618 : | Isibaar | 3 | // code block coeffs |
619 : | edgomez | 195 | for (i = 0; i < 6; i++) |
620 : | if (pMB->cbp & (1 << (5 - i))) | ||
621 : | h | 543 | { |
622 : | const uint16_t *scan_table = | ||
623 : | frame->global_flags & XVID_ALTERNATESCAN ? | ||
624 : | scan_tables[2] : scan_tables[0]; | ||
625 : | Isibaar | 3 | |
626 : | edgomez | 790 | #ifdef BIGLUT |
627 : | h | 543 | CodeCoeff(bs, &qcoeff[i * 64], inter_table, scan_table, 0); |
628 : | edgomez | 790 | #else |
629 : | CodeCoeffInter(bs, &qcoeff[i * 64], scan_table); | ||
630 : | #endif | ||
631 : | h | 543 | } |
632 : | |||
633 : | Isibaar | 3 | bits = BitstreamPos(bs) - bits; |
634 : | pStat->iTextBits += bits; | ||
635 : | } | ||
636 : | |||
637 : | |||
638 : | edgomez | 195 | void |
639 : | chl | 619 | MBCoding(const FRAMEINFO * const frame, |
640 : | edgomez | 195 | MACROBLOCK * pMB, |
641 : | int16_t qcoeff[6 * 64], | ||
642 : | Bitstream * bs, | ||
643 : | Statistics * pStat) | ||
644 : | Isibaar | 3 | { |
645 : | chl | 619 | if (frame->coding_type != I_VOP) |
646 : | BitstreamPutBit(bs, 0); // not_coded | ||
647 : | |||
648 : | chl | 335 | if (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q) |
649 : | suxen_drol | 136 | CodeBlockIntra(frame, pMB, qcoeff, bs, pStat); |
650 : | Isibaar | 3 | else |
651 : | suxen_drol | 136 | CodeBlockInter(frame, pMB, qcoeff, bs, pStat); |
652 : | edgomez | 78 | |
653 : | Isibaar | 3 | } |
654 : | |||
655 : | chl | 530 | /* |
656 : | // moved to mbcoding.h so that in can be 'static __inline' | ||
657 : | chl | 347 | void |
658 : | MBSkip(Bitstream * bs) | ||
659 : | { | ||
660 : | BitstreamPutBit(bs, 1); // not coded | ||
661 : | } | ||
662 : | chl | 530 | */ |
663 : | chl | 347 | |
664 : | suxen_drol | 118 | /*************************************************************** |
665 : | * bframe encoding start | ||
666 : | ***************************************************************/ | ||
667 : | Isibaar | 3 | |
668 : | suxen_drol | 118 | /* |
669 : | mbtype | ||
670 : | 0 1b direct(h263) mvdb | ||
671 : | 1 01b interpolate mc+q dbquant, mvdf, mvdb | ||
672 : | 2 001b backward mc+q dbquant, mvdb | ||
673 : | 3 0001b forward mc+q dbquant, mvdf | ||
674 : | */ | ||
675 : | |||
676 : | chl | 530 | static __inline void |
677 : | edgomez | 195 | put_bvop_mbtype(Bitstream * bs, |
678 : | int value) | ||
679 : | suxen_drol | 118 | { |
680 : | edgomez | 195 | switch (value) { |
681 : | chl | 530 | case MODE_FORWARD: |
682 : | BitstreamPutBit(bs, 0); | ||
683 : | case MODE_BACKWARD: | ||
684 : | BitstreamPutBit(bs, 0); | ||
685 : | case MODE_INTERPOLATE: | ||
686 : | BitstreamPutBit(bs, 0); | ||
687 : | case MODE_DIRECT: | ||
688 : | BitstreamPutBit(bs, 1); | ||
689 : | default: | ||
690 : | break; | ||
691 : | suxen_drol | 118 | } |
692 : | } | ||
693 : | |||
694 : | /* | ||
695 : | dbquant | ||
696 : | -2 10b | ||
697 : | 0 0b | ||
698 : | +2 11b | ||
699 : | */ | ||
700 : | |||
701 : | chl | 530 | static __inline void |
702 : | edgomez | 195 | put_bvop_dbquant(Bitstream * bs, |
703 : | int value) | ||
704 : | suxen_drol | 118 | { |
705 : | edgomez | 195 | switch (value) { |
706 : | case 0: | ||
707 : | BitstreamPutBit(bs, 0); | ||
708 : | return; | ||
709 : | suxen_drol | 118 | |
710 : | edgomez | 195 | case -2: |
711 : | BitstreamPutBit(bs, 1); | ||
712 : | BitstreamPutBit(bs, 0); | ||
713 : | return; | ||
714 : | suxen_drol | 118 | |
715 : | edgomez | 195 | case 2: |
716 : | BitstreamPutBit(bs, 1); | ||
717 : | BitstreamPutBit(bs, 1); | ||
718 : | return; | ||
719 : | |||
720 : | default:; // invalid | ||
721 : | suxen_drol | 118 | } |
722 : | } | ||
723 : | |||
724 : | |||
725 : | |||
726 : | edgomez | 195 | void |
727 : | MBCodingBVOP(const MACROBLOCK * mb, | ||
728 : | const int16_t qcoeff[6 * 64], | ||
729 : | const int32_t fcode, | ||
730 : | const int32_t bcode, | ||
731 : | Bitstream * bs, | ||
732 : | h | 543 | Statistics * pStat, |
733 : | int direction) | ||
734 : | suxen_drol | 118 | { |
735 : | chl | 530 | int vcode = fcode; |
736 : | unsigned int i; | ||
737 : | suxen_drol | 118 | |
738 : | /* ------------------------------------------------------------------ | ||
739 : | chl | 313 | when a block is skipped it is decoded DIRECT(0,0) |
740 : | hence is interpolated from forward & backward frames | ||
741 : | suxen_drol | 118 | ------------------------------------------------------------------ */ |
742 : | |||
743 : | chl | 313 | if (mb->mode == MODE_DIRECT_NONE_MV) { |
744 : | edgomez | 195 | BitstreamPutBit(bs, 1); // skipped |
745 : | suxen_drol | 118 | return; |
746 : | } | ||
747 : | |||
748 : | BitstreamPutBit(bs, 0); // not skipped | ||
749 : | |||
750 : | edgomez | 195 | if (mb->cbp == 0) { |
751 : | BitstreamPutBit(bs, 1); // cbp == 0 | ||
752 : | } else { | ||
753 : | BitstreamPutBit(bs, 0); // cbp == xxx | ||
754 : | suxen_drol | 118 | } |
755 : | |||
756 : | put_bvop_mbtype(bs, mb->mode); | ||
757 : | |||
758 : | edgomez | 195 | if (mb->cbp) { |
759 : | suxen_drol | 118 | BitstreamPutBits(bs, mb->cbp, 6); |
760 : | } | ||
761 : | |||
762 : | edgomez | 195 | if (mb->mode != MODE_DIRECT && mb->cbp != 0) { |
763 : | put_bvop_dbquant(bs, 0); // todo: mb->dquant = 0 | ||
764 : | suxen_drol | 118 | } |
765 : | |||
766 : | chl | 530 | switch (mb->mode) { |
767 : | case MODE_INTERPOLATE: | ||
768 : | CodeVector(bs, mb->pmvs[1].x, vcode, pStat); //forward vector of interpolate mode | ||
769 : | CodeVector(bs, mb->pmvs[1].y, vcode, pStat); | ||
770 : | case MODE_BACKWARD: | ||
771 : | vcode = bcode; | ||
772 : | case MODE_FORWARD: | ||
773 : | CodeVector(bs, mb->pmvs[0].x, vcode, pStat); | ||
774 : | CodeVector(bs, mb->pmvs[0].y, vcode, pStat); | ||
775 : | break; | ||
776 : | case MODE_DIRECT: | ||
777 : | CodeVector(bs, mb->pmvs[3].x, 1, pStat); // fcode is always 1 for delta vector | ||
778 : | CodeVector(bs, mb->pmvs[3].y, 1, pStat); // prediction is always (0,0) | ||
779 : | default: break; | ||
780 : | suxen_drol | 118 | } |
781 : | |||
782 : | edgomez | 195 | for (i = 0; i < 6; i++) { |
783 : | if (mb->cbp & (1 << (5 - i))) { | ||
784 : | edgomez | 790 | #ifdef BIGLUT |
785 : | CodeCoeff(bs, &qcoeff[i * 64], inter_table, scan_tables[0], 0); | ||
786 : | #else | ||
787 : | CodeCoeffInter(bs, &qcoeff[i * 64], scan_tables[0]); | ||
788 : | #endif | ||
789 : | suxen_drol | 118 | } |
790 : | edgomez | 195 | } |
791 : | suxen_drol | 118 | } |
792 : | |||
793 : | |||
794 : | |||
795 : | Isibaar | 3 | /*************************************************************** |
796 : | edgomez | 15 | * decoding stuff starts here * |
797 : | ***************************************************************/ | ||
798 : | Isibaar | 3 | |
799 : | suxen_drol | 248 | |
800 : | // for IVOP addbits == 0 | ||
801 : | // for PVOP addbits == fcode - 1 | ||
802 : | // for BVOP addbits == max(fcode,bcode) - 1 | ||
803 : | // returns true or false | ||
804 : | int | ||
805 : | check_resync_marker(Bitstream * bs, int addbits) | ||
806 : | { | ||
807 : | uint32_t nbits; | ||
808 : | uint32_t code; | ||
809 : | uint32_t nbitsresyncmarker = NUMBITS_VP_RESYNC_MARKER + addbits; | ||
810 : | |||
811 : | nbits = BitstreamNumBitsToByteAlign(bs); | ||
812 : | code = BitstreamShowBits(bs, nbits); | ||
813 : | |||
814 : | if (code == (((uint32_t)1 << (nbits - 1)) - 1)) | ||
815 : | { | ||
816 : | return BitstreamShowBitsFromByteAlign(bs, nbitsresyncmarker) == RESYNC_MARKER; | ||
817 : | } | ||
818 : | |||
819 : | return 0; | ||
820 : | } | ||
821 : | |||
822 : | |||
823 : | |||
824 : | edgomez | 195 | int |
825 : | get_mcbpc_intra(Bitstream * bs) | ||
826 : | Isibaar | 3 | { |
827 : | edgomez | 78 | |
828 : | Isibaar | 3 | uint32_t index; |
829 : | edgomez | 195 | |
830 : | suxen_drol | 248 | index = BitstreamShowBits(bs, 9); |
831 : | Isibaar | 3 | index >>= 3; |
832 : | |||
833 : | BitstreamSkip(bs, mcbpc_intra_table[index].len); | ||
834 : | edgomez | 78 | |
835 : | Isibaar | 3 | return mcbpc_intra_table[index].code; |
836 : | edgomez | 78 | |
837 : | Isibaar | 3 | } |
838 : | |||
839 : | edgomez | 195 | int |
840 : | get_mcbpc_inter(Bitstream * bs) | ||
841 : | Isibaar | 3 | { |
842 : | edgomez | 78 | |
843 : | Isibaar | 3 | uint32_t index; |
844 : | suxen_drol | 248 | |
845 : | suxen_drol | 760 | index = MIN(BitstreamShowBits(bs, 9), 256); |
846 : | edgomez | 195 | |
847 : | BitstreamSkip(bs, mcbpc_inter_table[index].len); | ||
848 : | edgomez | 78 | |
849 : | Isibaar | 3 | return mcbpc_inter_table[index].code; |
850 : | edgomez | 78 | |
851 : | Isibaar | 3 | } |
852 : | |||
853 : | edgomez | 195 | int |
854 : | get_cbpy(Bitstream * bs, | ||
855 : | int intra) | ||
856 : | Isibaar | 3 | { |
857 : | edgomez | 78 | |
858 : | Isibaar | 3 | int cbpy; |
859 : | uint32_t index = BitstreamShowBits(bs, 6); | ||
860 : | |||
861 : | BitstreamSkip(bs, cbpy_table[index].len); | ||
862 : | cbpy = cbpy_table[index].code; | ||
863 : | |||
864 : | edgomez | 195 | if (!intra) |
865 : | Isibaar | 3 | cbpy = 15 - cbpy; |
866 : | |||
867 : | return cbpy; | ||
868 : | edgomez | 78 | |
869 : | Isibaar | 3 | } |
870 : | |||
871 : | chl | 530 | static __inline int |
872 : | edgomez | 195 | get_mv_data(Bitstream * bs) |
873 : | Isibaar | 3 | { |
874 : | edgomez | 78 | |
875 : | Isibaar | 3 | uint32_t index; |
876 : | |||
877 : | edgomez | 195 | if (BitstreamGetBit(bs)) |
878 : | Isibaar | 3 | return 0; |
879 : | edgomez | 195 | |
880 : | Isibaar | 3 | index = BitstreamShowBits(bs, 12); |
881 : | |||
882 : | edgomez | 195 | if (index >= 512) { |
883 : | Isibaar | 3 | index = (index >> 8) - 2; |
884 : | BitstreamSkip(bs, TMNMVtab0[index].len); | ||
885 : | return TMNMVtab0[index].code; | ||
886 : | } | ||
887 : | edgomez | 195 | |
888 : | if (index >= 128) { | ||
889 : | Isibaar | 3 | index = (index >> 2) - 32; |
890 : | BitstreamSkip(bs, TMNMVtab1[index].len); | ||
891 : | return TMNMVtab1[index].code; | ||
892 : | } | ||
893 : | |||
894 : | edgomez | 195 | index -= 4; |
895 : | Isibaar | 3 | |
896 : | BitstreamSkip(bs, TMNMVtab2[index].len); | ||
897 : | return TMNMVtab2[index].code; | ||
898 : | edgomez | 78 | |
899 : | Isibaar | 3 | } |
900 : | |||
901 : | edgomez | 195 | int |
902 : | get_mv(Bitstream * bs, | ||
903 : | int fcode) | ||
904 : | Isibaar | 3 | { |
905 : | edgomez | 78 | |
906 : | Isibaar | 3 | int data; |
907 : | int res; | ||
908 : | int mv; | ||
909 : | int scale_fac = 1 << (fcode - 1); | ||
910 : | |||
911 : | data = get_mv_data(bs); | ||
912 : | edgomez | 195 | |
913 : | if (scale_fac == 1 || data == 0) | ||
914 : | Isibaar | 3 | return data; |
915 : | |||
916 : | res = BitstreamGetBits(bs, fcode - 1); | ||
917 : | mv = ((ABS(data) - 1) * scale_fac) + res + 1; | ||
918 : | edgomez | 195 | |
919 : | Isibaar | 3 | return data < 0 ? -mv : mv; |
920 : | edgomez | 78 | |
921 : | Isibaar | 3 | } |
922 : | |||
923 : | edgomez | 195 | int |
924 : | get_dc_dif(Bitstream * bs, | ||
925 : | uint32_t dc_size) | ||
926 : | Isibaar | 3 | { |
927 : | edgomez | 78 | |
928 : | Isibaar | 3 | int code = BitstreamGetBits(bs, dc_size); |
929 : | int msb = code >> (dc_size - 1); | ||
930 : | |||
931 : | edgomez | 195 | if (msb == 0) |
932 : | return (-1 * (code ^ ((1 << dc_size) - 1))); | ||
933 : | Isibaar | 3 | |
934 : | return code; | ||
935 : | edgomez | 78 | |
936 : | Isibaar | 3 | } |
937 : | |||
938 : | edgomez | 195 | int |
939 : | get_dc_size_lum(Bitstream * bs) | ||
940 : | Isibaar | 3 | { |
941 : | edgomez | 78 | |
942 : | Isibaar | 3 | int code, i; |
943 : | edgomez | 195 | |
944 : | Isibaar | 3 | code = BitstreamShowBits(bs, 11); |
945 : | |||
946 : | edgomez | 195 | for (i = 11; i > 3; i--) { |
947 : | if (code == 1) { | ||
948 : | Isibaar | 3 | BitstreamSkip(bs, i); |
949 : | return i + 1; | ||
950 : | } | ||
951 : | code >>= 1; | ||
952 : | } | ||
953 : | |||
954 : | BitstreamSkip(bs, dc_lum_tab[code].len); | ||
955 : | return dc_lum_tab[code].code; | ||
956 : | edgomez | 78 | |
957 : | Isibaar | 3 | } |
958 : | |||
959 : | |||
960 : | edgomez | 195 | int |
961 : | get_dc_size_chrom(Bitstream * bs) | ||
962 : | Isibaar | 3 | { |
963 : | edgomez | 78 | |
964 : | Isibaar | 3 | uint32_t code, i; |
965 : | edgomez | 195 | |
966 : | Isibaar | 3 | code = BitstreamShowBits(bs, 12); |
967 : | |||
968 : | edgomez | 195 | for (i = 12; i > 2; i--) { |
969 : | if (code == 1) { | ||
970 : | Isibaar | 3 | BitstreamSkip(bs, i); |
971 : | return i; | ||
972 : | } | ||
973 : | code >>= 1; | ||
974 : | } | ||
975 : | |||
976 : | return 3 - BitstreamGetBits(bs, 2); | ||
977 : | edgomez | 78 | |
978 : | Isibaar | 3 | } |
979 : | |||
980 : | edgomez | 790 | static __inline int |
981 : | get_coeff(Bitstream * bs, | ||
982 : | int *run, | ||
983 : | int *last, | ||
984 : | int intra, | ||
985 : | int short_video_header) | ||
986 : | { | ||
987 : | |||
988 : | uint32_t mode; | ||
989 : | int32_t level; | ||
990 : | REVERSE_EVENT *reverse_event; | ||
991 : | |||
992 : | if (short_video_header) /* inter-VLCs will be used for both intra and inter blocks */ | ||
993 : | intra = 0; | ||
994 : | |||
995 : | if (BitstreamShowBits(bs, 7) != ESCAPE) { | ||
996 : | reverse_event = &DCT3D[intra][BitstreamShowBits(bs, 12)]; | ||
997 : | |||
998 : | if ((level = reverse_event->event.level) == 0) | ||
999 : | goto error; | ||
1000 : | |||
1001 : | *last = reverse_event->event.last; | ||
1002 : | *run = reverse_event->event.run; | ||
1003 : | |||
1004 : | BitstreamSkip(bs, reverse_event->len); | ||
1005 : | |||
1006 : | return BitstreamGetBits(bs, 1) ? -level : level; | ||
1007 : | } | ||
1008 : | |||
1009 : | BitstreamSkip(bs, 7); | ||
1010 : | |||
1011 : | if (short_video_header) { | ||
1012 : | /* escape mode 4 - H.263 type, only used if short_video_header = 1 */ | ||
1013 : | *last = BitstreamGetBit(bs); | ||
1014 : | *run = BitstreamGetBits(bs, 6); | ||
1015 : | level = BitstreamGetBits(bs, 8); | ||
1016 : | |||
1017 : | if (level == 0 || level == 128) | ||
1018 : | DPRINTF(DPRINTF_ERROR, "Illegal LEVEL for ESCAPE mode 4: %d", level); | ||
1019 : | |||
1020 : | return (level << 24) >> 24; | ||
1021 : | } | ||
1022 : | |||
1023 : | mode = BitstreamShowBits(bs, 2); | ||
1024 : | |||
1025 : | if (mode < 3) { | ||
1026 : | BitstreamSkip(bs, (mode == 2) ? 2 : 1); | ||
1027 : | |||
1028 : | reverse_event = &DCT3D[intra][BitstreamShowBits(bs, 12)]; | ||
1029 : | |||
1030 : | if ((level = reverse_event->event.level) == 0) | ||
1031 : | goto error; | ||
1032 : | |||
1033 : | *last = reverse_event->event.last; | ||
1034 : | *run = reverse_event->event.run; | ||
1035 : | |||
1036 : | BitstreamSkip(bs, reverse_event->len); | ||
1037 : | |||
1038 : | if (mode < 2) /* first escape mode, level is offset */ | ||
1039 : | level += max_level[intra][*last][*run]; | ||
1040 : | else /* second escape mode, run is offset */ | ||
1041 : | *run += max_run[intra][*last][level] + 1; | ||
1042 : | |||
1043 : | return BitstreamGetBits(bs, 1) ? -level : level; | ||
1044 : | } | ||
1045 : | |||
1046 : | /* third escape mode - fixed length codes */ | ||
1047 : | BitstreamSkip(bs, 2); | ||
1048 : | *last = BitstreamGetBits(bs, 1); | ||
1049 : | *run = BitstreamGetBits(bs, 6); | ||
1050 : | BitstreamSkip(bs, 1); /* marker */ | ||
1051 : | level = BitstreamGetBits(bs, 12); | ||
1052 : | BitstreamSkip(bs, 1); /* marker */ | ||
1053 : | |||
1054 : | return (level << 20) >> 20; | ||
1055 : | |||
1056 : | error: | ||
1057 : | *run = VLC_ERROR; | ||
1058 : | return 0; | ||
1059 : | } | ||
1060 : | |||
1061 : | edgomez | 195 | void |
1062 : | get_intra_block(Bitstream * bs, | ||
1063 : | int16_t * block, | ||
1064 : | int direction, | ||
1065 : | int coeff) | ||
1066 : | Isibaar | 3 | { |
1067 : | edgomez | 78 | |
1068 : | edgomez | 195 | const uint16_t *scan = scan_tables[direction]; |
1069 : | chl | 530 | int level, run, last; |
1070 : | Isibaar | 3 | |
1071 : | edgomez | 195 | do { |
1072 : | Isibaar | 3 | level = get_coeff(bs, &run, &last, 1, 0); |
1073 : | edgomez | 195 | if (run == -1) { |
1074 : | suxen_drol | 721 | DPRINTF(DPRINTF_ERROR,"fatal: invalid run"); |
1075 : | Isibaar | 3 | break; |
1076 : | } | ||
1077 : | coeff += run; | ||
1078 : | edgomez | 195 | block[scan[coeff]] = level; |
1079 : | suxen_drol | 252 | |
1080 : | DPRINTF(DPRINTF_COEFF,"block[%i] %i", scan[coeff], level); | ||
1081 : | //DPRINTF(DPRINTF_COEFF,"block[%i] %i %08x", scan[coeff], level, BitstreamShowBits(bs, 32)); | ||
1082 : | |||
1083 : | suxen_drol | 759 | if (level < -2047 || level > 2047) { |
1084 : | suxen_drol | 721 | DPRINTF(DPRINTF_ERROR,"warning: intra_overflow %i", level); |
1085 : | Isibaar | 3 | } |
1086 : | coeff++; | ||
1087 : | } while (!last); | ||
1088 : | edgomez | 78 | |
1089 : | Isibaar | 3 | } |
1090 : | |||
1091 : | edgomez | 195 | void |
1092 : | get_inter_block(Bitstream * bs, | ||
1093 : | h | 543 | int16_t * block, |
1094 : | int direction) | ||
1095 : | Isibaar | 3 | { |
1096 : | edgomez | 78 | |
1097 : | h | 543 | const uint16_t *scan = scan_tables[direction]; |
1098 : | Isibaar | 3 | int p; |
1099 : | int level; | ||
1100 : | int run; | ||
1101 : | int last; | ||
1102 : | |||
1103 : | p = 0; | ||
1104 : | edgomez | 195 | do { |
1105 : | Isibaar | 3 | level = get_coeff(bs, &run, &last, 0, 0); |
1106 : | edgomez | 195 | if (run == -1) { |
1107 : | suxen_drol | 721 | DPRINTF(DPRINTF_ERROR,"fatal: invalid run"); |
1108 : | Isibaar | 3 | break; |
1109 : | } | ||
1110 : | p += run; | ||
1111 : | chenm001 | 161 | |
1112 : | edgomez | 195 | block[scan[p]] = level; |
1113 : | suxen_drol | 252 | |
1114 : | DPRINTF(DPRINTF_COEFF,"block[%i] %i", scan[p], level); | ||
1115 : | // DPRINTF(DPRINTF_COEFF,"block[%i] %i %08x", scan[p], level, BitstreamShowBits(bs, 32)); | ||
1116 : | |||
1117 : | suxen_drol | 759 | if (level < -2047 || level > 2047) { |
1118 : | suxen_drol | 721 | DPRINTF(DPRINTF_ERROR,"warning: inter overflow %i", level); |
1119 : | Isibaar | 3 | } |
1120 : | p++; | ||
1121 : | } while (!last); | ||
1122 : | edgomez | 78 | |
1123 : | Isibaar | 3 | } |
No admin address has been configured | ViewVC Help |
Powered by ViewVC 1.0.4 |