Parent Directory | Revision Log
Revision 677 - (view) (download)
1 : | edgomez | 451 | /***************************************************************************** |
2 : | * | ||
3 : | * XVID MPEG-4 VIDEO CODEC | ||
4 : | edgomez | 453 | * - Macro Block coding functions - |
5 : | edgomez | 451 | * |
6 : | * Copyright(C) 2002 Michael Militzer <isibaar@xvid.org> | ||
7 : | * | ||
8 : | edgomez | 655 | * This file is part of XviD, a free MPEG-4 video encoder/decoder |
9 : | edgomez | 451 | * |
10 : | edgomez | 655 | * XviD is free software; you can redistribute it and/or modify it |
11 : | * under the terms of the GNU General Public License as published by | ||
12 : | edgomez | 451 | * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 : | * | ||
24 : | edgomez | 655 | * Under section 8 of the GNU General Public License, the copyright |
25 : | * holders of XVID explicitly forbid distribution in the following | ||
26 : | * countries: | ||
27 : | edgomez | 451 | * |
28 : | edgomez | 655 | * - Japan |
29 : | * - United States of America | ||
30 : | * | ||
31 : | * Linking XviD statically or dynamically with other modules is making a | ||
32 : | * combined work based on XviD. Thus, the terms and conditions of the | ||
33 : | * GNU General Public License cover the whole combination. | ||
34 : | * | ||
35 : | * As a special exception, the copyright holders of XviD give you | ||
36 : | * permission to link XviD with independent modules that communicate with | ||
37 : | * XviD solely through the VFW1.1 and DShow interfaces, regardless of the | ||
38 : | * license terms of these independent modules, and to copy and distribute | ||
39 : | * the resulting combined work under terms of your choice, provided that | ||
40 : | * every copy of the combined work is accompanied by a complete copy of | ||
41 : | * the source code of XviD (the version of XviD used to produce the | ||
42 : | * combined work), being distributed under the terms of the GNU General | ||
43 : | * Public License plus this exception. An independent module is a module | ||
44 : | * which is not derived from or based on XviD. | ||
45 : | * | ||
46 : | * Note that people who make modified versions of XviD are not obligated | ||
47 : | * to grant this special exception for their modified versions; it is | ||
48 : | * their choice whether to do so. The GNU General Public License gives | ||
49 : | * permission to release a modified version without this exception; this | ||
50 : | * exception also makes it possible to release a modified version which | ||
51 : | * carries forward this exception. | ||
52 : | * | ||
53 : | edgomez | 677 | * $Id: mbcoding.c,v 1.34 2002-11-26 23:44:10 edgomez Exp $ |
54 : | edgomez | 655 | * |
55 : | edgomez | 451 | ****************************************************************************/ |
56 : | suxen_drol | 118 | |
57 : | Isibaar | 100 | #include <stdlib.h> |
58 : | Isibaar | 3 | #include "../portab.h" |
59 : | #include "bitstream.h" | ||
60 : | #include "zigzag.h" | ||
61 : | #include "vlc_codes.h" | ||
62 : | Isibaar | 100 | #include "mbcoding.h" |
63 : | Isibaar | 3 | |
64 : | #include "../utils/mbfunctions.h" | ||
65 : | |||
66 : | #define ABS(X) (((X)>0)?(X):-(X)) | ||
67 : | #define CLIP(X,A) (X > A) ? (A) : (X) | ||
68 : | |||
69 : | edgomez | 451 | /***************************************************************************** |
70 : | * Local data | ||
71 : | ****************************************************************************/ | ||
72 : | Isibaar | 100 | |
73 : | suxen_drol | 497 | /* msvc sp5+pp gets confused if they globals are made static */ |
74 : | VLC intra_table[524032]; | ||
75 : | VLC inter_table[524032]; | ||
76 : | Isibaar | 3 | |
77 : | edgomez | 451 | static VLC DCT3Dintra[4096]; |
78 : | static VLC DCT3Dinter[4096]; | ||
79 : | |||
80 : | /***************************************************************************** | ||
81 : | edgomez | 453 | * Vector Length Coding Initialization |
82 : | edgomez | 451 | ****************************************************************************/ |
83 : | |||
84 : | edgomez | 195 | void |
85 : | init_vlc_tables(void) | ||
86 : | Isibaar | 3 | { |
87 : | edgomez | 78 | |
88 : | Isibaar | 3 | int32_t k, l, i, intra, last; |
89 : | VLC *vlc[2]; | ||
90 : | edgomez | 465 | VLC const **coeff_ptr; |
91 : | Isibaar | 3 | VLC *vlc1, *vlc2; |
92 : | |||
93 : | vlc1 = DCT3Dintra; | ||
94 : | vlc2 = DCT3Dinter; | ||
95 : | edgomez | 195 | |
96 : | Isibaar | 100 | vlc[0] = intra_table; |
97 : | vlc[1] = inter_table; | ||
98 : | edgomez | 195 | |
99 : | edgomez | 451 | /* |
100 : | * Generate encoding vlc lookup tables | ||
101 : | * the lookup table idea is taken from the excellent fame project | ||
102 : | * by Vivien Chapellier | ||
103 : | */ | ||
104 : | edgomez | 195 | for (i = 0; i < 4; i++) { |
105 : | Isibaar | 3 | intra = i % 2; |
106 : | Isibaar | 100 | last = i / 2; |
107 : | Isibaar | 3 | |
108 : | Isibaar | 100 | coeff_ptr = coeff_vlc[last + 2 * intra]; |
109 : | edgomez | 195 | |
110 : | edgomez | 677 | for (k = -2047; k < 2048; k++) { /* level */ |
111 : | edgomez | 465 | int8_t const *max_level_ptr = max_level[last + 2 * intra]; |
112 : | int8_t const *max_run_ptr = max_run[last + 2 * intra]; | ||
113 : | edgomez | 195 | |
114 : | edgomez | 677 | for (l = 0; l < 64; l++) { /* run */ |
115 : | Isibaar | 35 | int32_t level = k; |
116 : | Isibaar | 209 | ptr_t run = l; |
117 : | edgomez | 195 | |
118 : | edgomez | 677 | if ((abs(level) <= max_level_ptr[run]) && (run <= (uint32_t) max_run_ptr[abs(level)])) { /* level < max_level and run < max_run */ |
119 : | edgomez | 195 | |
120 : | vlc[intra]->code = 0; | ||
121 : | vlc[intra]->len = 0; | ||
122 : | goto loop_end; | ||
123 : | } else { | ||
124 : | edgomez | 677 | if (level > 0) /* correct level */ |
125 : | Isibaar | 3 | level -= max_level_ptr[run]; |
126 : | else | ||
127 : | level += max_level_ptr[run]; | ||
128 : | Isibaar | 35 | |
129 : | edgomez | 195 | if ((abs(level) <= max_level_ptr[run]) && |
130 : | (run <= (uint32_t) max_run_ptr[abs(level)])) { | ||
131 : | |||
132 : | Isibaar | 100 | vlc[intra]->code = 0x06; |
133 : | vlc[intra]->len = 8; | ||
134 : | goto loop_end; | ||
135 : | } | ||
136 : | Isibaar | 3 | |
137 : | edgomez | 677 | if (level > 0) /* still here? */ |
138 : | level += max_level_ptr[run]; /* restore level */ | ||
139 : | Isibaar | 100 | else |
140 : | level -= max_level_ptr[run]; | ||
141 : | |||
142 : | edgomez | 677 | run -= max_run_ptr[abs(level)] + 1; /* and change run */ |
143 : | Isibaar | 100 | |
144 : | edgomez | 195 | if ((abs(level) <= max_level_ptr[run]) && |
145 : | (run <= (uint32_t) max_run_ptr[abs(level)])) { | ||
146 : | |||
147 : | Isibaar | 100 | vlc[intra]->code = 0x0e; |
148 : | vlc[intra]->len = 9; | ||
149 : | goto loop_end; | ||
150 : | Isibaar | 3 | } |
151 : | Isibaar | 100 | run += max_run_ptr[abs(level)] + 1; |
152 : | Isibaar | 3 | } |
153 : | Isibaar | 100 | |
154 : | edgomez | 195 | vlc[intra]->code = |
155 : | (uint32_t) ((l << 14) | (0x1e + last) << 20) | (1 << 13) | | ||
156 : | ((k & 0xfff) << 1) | 1; | ||
157 : | Isibaar | 100 | |
158 : | vlc[intra]->len = 30; | ||
159 : | Isibaar | 3 | vlc[intra]++; |
160 : | Isibaar | 100 | continue; |
161 : | |||
162 : | edgomez | 195 | loop_end: |
163 : | if (level != 0) { | ||
164 : | vlc[intra]->code = | ||
165 : | (vlc[intra]-> | ||
166 : | code << (coeff_ptr[run][abs(level) - 1].len + | ||
167 : | 1)) | (coeff_ptr[run][abs(level) - | ||
168 : | 1].code << 1); | ||
169 : | vlc[intra]->len = | ||
170 : | (coeff_ptr[run][abs(level) - 1].len + 1) + | ||
171 : | vlc[intra]->len; | ||
172 : | Isibaar | 100 | |
173 : | edgomez | 195 | if (level < 0) |
174 : | Isibaar | 100 | vlc[intra]->code += 1; |
175 : | } | ||
176 : | |||
177 : | vlc[intra]++; | ||
178 : | Isibaar | 3 | } |
179 : | } | ||
180 : | } | ||
181 : | edgomez | 78 | |
182 : | edgomez | 195 | for (i = 0; i < 4096; i++) { |
183 : | if (i >= 512) { | ||
184 : | Isibaar | 3 | *vlc1 = DCT3Dtab3[(i >> 5) - 16]; |
185 : | *vlc2 = DCT3Dtab0[(i >> 5) - 16]; | ||
186 : | edgomez | 195 | } else if (i >= 128) { |
187 : | Isibaar | 3 | *vlc1 = DCT3Dtab4[(i >> 2) - 32]; |
188 : | *vlc2 = DCT3Dtab1[(i >> 2) - 32]; | ||
189 : | edgomez | 195 | } else if (i >= 8) { |
190 : | Isibaar | 3 | *vlc1 = DCT3Dtab5[i - 8]; |
191 : | *vlc2 = DCT3Dtab2[i - 8]; | ||
192 : | edgomez | 195 | } else { |
193 : | Isibaar | 3 | *vlc1 = ERRtab[i]; |
194 : | *vlc2 = ERRtab[i]; | ||
195 : | } | ||
196 : | |||
197 : | vlc1++; | ||
198 : | vlc2++; | ||
199 : | } | ||
200 : | DCT3D[0] = DCT3Dinter; | ||
201 : | DCT3D[1] = DCT3Dintra; | ||
202 : | |||
203 : | } | ||
204 : | |||
205 : | edgomez | 453 | /***************************************************************************** |
206 : | * Local inlined functions for MB coding | ||
207 : | ****************************************************************************/ | ||
208 : | |||
209 : | edgomez | 195 | static __inline void |
210 : | CodeVector(Bitstream * bs, | ||
211 : | int32_t value, | ||
212 : | int32_t f_code, | ||
213 : | Statistics * pStat) | ||
214 : | Isibaar | 3 | { |
215 : | edgomez | 78 | |
216 : | Isibaar | 3 | const int scale_factor = 1 << (f_code - 1); |
217 : | const int cmp = scale_factor << 5; | ||
218 : | |||
219 : | edgomez | 195 | if (value < (-1 * cmp)) |
220 : | Isibaar | 3 | value += 64 * scale_factor; |
221 : | edgomez | 195 | |
222 : | if (value > (cmp - 1)) | ||
223 : | Isibaar | 3 | value -= 64 * scale_factor; |
224 : | |||
225 : | edgomez | 78 | pStat->iMvSum += value * value; |
226 : | pStat->iMvCount++; | ||
227 : | Isibaar | 3 | |
228 : | edgomez | 78 | if (value == 0) { |
229 : | edgomez | 195 | BitstreamPutBits(bs, mb_motion_table[32].code, |
230 : | mb_motion_table[32].len); | ||
231 : | edgomez | 78 | } else { |
232 : | Isibaar | 3 | uint16_t length, code, mv_res, sign; |
233 : | edgomez | 195 | |
234 : | Isibaar | 3 | length = 16 << f_code; |
235 : | f_code--; | ||
236 : | edgomez | 195 | |
237 : | Isibaar | 3 | sign = (value < 0); |
238 : | |||
239 : | edgomez | 195 | if (value >= length) |
240 : | Isibaar | 3 | value -= 2 * length; |
241 : | edgomez | 195 | else if (value < -length) |
242 : | Isibaar | 3 | value += 2 * length; |
243 : | |||
244 : | edgomez | 195 | if (sign) |
245 : | Isibaar | 3 | value = -value; |
246 : | |||
247 : | value--; | ||
248 : | mv_res = value & ((1 << f_code) - 1); | ||
249 : | code = ((value - mv_res) >> f_code) + 1; | ||
250 : | |||
251 : | edgomez | 195 | if (sign) |
252 : | Isibaar | 3 | code = -code; |
253 : | |||
254 : | code += 32; | ||
255 : | edgomez | 195 | BitstreamPutBits(bs, mb_motion_table[code].code, |
256 : | mb_motion_table[code].len); | ||
257 : | |||
258 : | if (f_code) | ||
259 : | Isibaar | 3 | BitstreamPutBits(bs, mv_res, f_code); |
260 : | edgomez | 78 | } |
261 : | |||
262 : | Isibaar | 3 | } |
263 : | |||
264 : | edgomez | 195 | static __inline void |
265 : | CodeCoeff(Bitstream * bs, | ||
266 : | const int16_t qcoeff[64], | ||
267 : | VLC * table, | ||
268 : | const uint16_t * zigzag, | ||
269 : | uint16_t intra) | ||
270 : | edgomez | 78 | { |
271 : | |||
272 : | Isibaar | 3 | uint32_t j, last; |
273 : | short v; | ||
274 : | VLC *vlc; | ||
275 : | edgomez | 195 | |
276 : | Isibaar | 3 | j = intra; |
277 : | Isibaar | 116 | last = intra; |
278 : | Isibaar | 3 | |
279 : | edgomez | 195 | while (j < 64 && (v = qcoeff[zigzag[j]]) == 0) |
280 : | j++; | ||
281 : | |||
282 : | Isibaar | 3 | do { |
283 : | Isibaar | 153 | vlc = table + 64 * 2047 + (v << 6) + j - last; |
284 : | Isibaar | 116 | last = ++j; |
285 : | Isibaar | 153 | |
286 : | edgomez | 677 | /* count zeroes */ |
287 : | edgomez | 195 | while (j < 64 && (v = qcoeff[zigzag[j]]) == 0) |
288 : | j++; | ||
289 : | |||
290 : | edgomez | 677 | /* write code */ |
291 : | edgomez | 195 | if (j != 64) { |
292 : | Isibaar | 3 | BitstreamPutBits(bs, vlc->code, vlc->len); |
293 : | } else { | ||
294 : | Isibaar | 153 | vlc += 64 * 4095; |
295 : | Isibaar | 3 | BitstreamPutBits(bs, vlc->code, vlc->len); |
296 : | break; | ||
297 : | } | ||
298 : | edgomez | 195 | } while (1); |
299 : | edgomez | 78 | |
300 : | Isibaar | 3 | } |
301 : | |||
302 : | edgomez | 453 | /***************************************************************************** |
303 : | * Local functions | ||
304 : | ****************************************************************************/ | ||
305 : | Isibaar | 3 | |
306 : | edgomez | 195 | static void |
307 : | CodeBlockIntra(const FRAMEINFO * frame, | ||
308 : | const MACROBLOCK * pMB, | ||
309 : | int16_t qcoeff[6 * 64], | ||
310 : | edgomez | 78 | Bitstream * bs, |
311 : | Statistics * pStat) | ||
312 : | Isibaar | 3 | { |
313 : | edgomez | 78 | |
314 : | Isibaar | 3 | uint32_t i, mcbpc, cbpy, bits; |
315 : | |||
316 : | cbpy = pMB->cbp >> 2; | ||
317 : | |||
318 : | edgomez | 677 | /* write mcbpc */ |
319 : | edgomez | 195 | if (frame->coding_type == I_VOP) { |
320 : | edgomez | 78 | mcbpc = ((pMB->mode >> 1) & 3) | ((pMB->cbp & 3) << 2); |
321 : | edgomez | 195 | BitstreamPutBits(bs, mcbpc_intra_tab[mcbpc].code, |
322 : | mcbpc_intra_tab[mcbpc].len); | ||
323 : | } else { | ||
324 : | edgomez | 78 | mcbpc = (pMB->mode & 7) | ((pMB->cbp & 3) << 3); |
325 : | edgomez | 195 | BitstreamPutBits(bs, mcbpc_inter_tab[mcbpc].code, |
326 : | mcbpc_inter_tab[mcbpc].len); | ||
327 : | Isibaar | 28 | } |
328 : | Isibaar | 3 | |
329 : | edgomez | 677 | /* ac prediction flag */ |
330 : | edgomez | 195 | if (pMB->acpred_directions[0]) |
331 : | edgomez | 78 | BitstreamPutBits(bs, 1, 1); |
332 : | Isibaar | 3 | else |
333 : | edgomez | 78 | BitstreamPutBits(bs, 0, 1); |
334 : | Isibaar | 3 | |
335 : | edgomez | 677 | /* write cbpy */ |
336 : | edgomez | 195 | BitstreamPutBits(bs, cbpy_tab[cbpy].code, cbpy_tab[cbpy].len); |
337 : | Isibaar | 3 | |
338 : | edgomez | 677 | /* write dquant */ |
339 : | edgomez | 195 | if (pMB->mode == MODE_INTRA_Q) |
340 : | Isibaar | 3 | BitstreamPutBits(bs, pMB->dquant, 2); |
341 : | |||
342 : | edgomez | 677 | /* write interlacing */ |
343 : | edgomez | 195 | if (frame->global_flags & XVID_INTERLACING) { |
344 : | h | 69 | BitstreamPutBit(bs, pMB->field_dct); |
345 : | } | ||
346 : | edgomez | 677 | /* code block coeffs */ |
347 : | edgomez | 195 | for (i = 0; i < 6; i++) { |
348 : | if (i < 4) | ||
349 : | BitstreamPutBits(bs, dcy_tab[qcoeff[i * 64 + 0] + 255].code, | ||
350 : | dcy_tab[qcoeff[i * 64 + 0] + 255].len); | ||
351 : | Isibaar | 3 | else |
352 : | edgomez | 195 | BitstreamPutBits(bs, dcc_tab[qcoeff[i * 64 + 0] + 255].code, |
353 : | dcc_tab[qcoeff[i * 64 + 0] + 255].len); | ||
354 : | |||
355 : | if (pMB->cbp & (1 << (5 - i))) { | ||
356 : | Isibaar | 3 | bits = BitstreamPos(bs); |
357 : | |||
358 : | edgomez | 195 | CodeCoeff(bs, &qcoeff[i * 64], intra_table, |
359 : | scan_tables[pMB->acpred_directions[i]], 1); | ||
360 : | Isibaar | 3 | |
361 : | bits = BitstreamPos(bs) - bits; | ||
362 : | pStat->iTextBits += bits; | ||
363 : | } | ||
364 : | } | ||
365 : | edgomez | 78 | |
366 : | Isibaar | 3 | } |
367 : | |||
368 : | |||
369 : | edgomez | 195 | static void |
370 : | CodeBlockInter(const FRAMEINFO * frame, | ||
371 : | const MACROBLOCK * pMB, | ||
372 : | int16_t qcoeff[6 * 64], | ||
373 : | edgomez | 78 | Bitstream * bs, |
374 : | Statistics * pStat) | ||
375 : | Isibaar | 3 | { |
376 : | edgomez | 78 | |
377 : | Isibaar | 3 | int32_t i; |
378 : | uint32_t bits, mcbpc, cbpy; | ||
379 : | |||
380 : | edgomez | 78 | mcbpc = (pMB->mode & 7) | ((pMB->cbp & 3) << 3); |
381 : | Isibaar | 3 | cbpy = 15 - (pMB->cbp >> 2); |
382 : | |||
383 : | edgomez | 677 | /* write mcbpc */ |
384 : | edgomez | 195 | BitstreamPutBits(bs, mcbpc_inter_tab[mcbpc].code, |
385 : | mcbpc_inter_tab[mcbpc].len); | ||
386 : | Isibaar | 3 | |
387 : | edgomez | 677 | /* write cbpy */ |
388 : | Isibaar | 3 | BitstreamPutBits(bs, cbpy_tab[cbpy].code, cbpy_tab[cbpy].len); |
389 : | |||
390 : | edgomez | 677 | /* write dquant */ |
391 : | edgomez | 195 | if (pMB->mode == MODE_INTER_Q) |
392 : | Isibaar | 3 | BitstreamPutBits(bs, pMB->dquant, 2); |
393 : | edgomez | 195 | |
394 : | edgomez | 677 | /* interlacing */ |
395 : | edgomez | 195 | if (frame->global_flags & XVID_INTERLACING) { |
396 : | h | 388 | if (pMB->cbp) { |
397 : | BitstreamPutBit(bs, pMB->field_dct); | ||
398 : | edgomez | 514 | DPRINTF(DPRINTF_DEBUG, "codep: field_dct: %d", pMB->field_dct); |
399 : | h | 388 | } |
400 : | h | 69 | |
401 : | edgomez | 677 | /* if inter block, write field ME flag */ |
402 : | edgomez | 195 | if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) { |
403 : | h | 69 | BitstreamPutBit(bs, pMB->field_pred); |
404 : | edgomez | 514 | DPRINTF(DPRINTF_DEBUG, "codep: field_pred: %d", pMB->field_pred); |
405 : | h | 69 | |
406 : | edgomez | 677 | /* write field prediction references */ |
407 : | edgomez | 195 | if (pMB->field_pred) { |
408 : | h | 69 | BitstreamPutBit(bs, pMB->field_for_top); |
409 : | BitstreamPutBit(bs, pMB->field_for_bot); | ||
410 : | } | ||
411 : | } | ||
412 : | } | ||
413 : | edgomez | 677 | /* code motion vector(s) */ |
414 : | edgomez | 195 | for (i = 0; i < (pMB->mode == MODE_INTER4V ? 4 : 1); i++) { |
415 : | suxen_drol | 136 | CodeVector(bs, pMB->pmvs[i].x, frame->fcode, pStat); |
416 : | CodeVector(bs, pMB->pmvs[i].y, frame->fcode, pStat); | ||
417 : | Isibaar | 3 | } |
418 : | |||
419 : | bits = BitstreamPos(bs); | ||
420 : | edgomez | 195 | |
421 : | edgomez | 677 | /* code block coeffs */ |
422 : | edgomez | 195 | for (i = 0; i < 6; i++) |
423 : | if (pMB->cbp & (1 << (5 - i))) | ||
424 : | CodeCoeff(bs, &qcoeff[i * 64], inter_table, scan_tables[0], 0); | ||
425 : | Isibaar | 3 | |
426 : | bits = BitstreamPos(bs) - bits; | ||
427 : | pStat->iTextBits += bits; | ||
428 : | edgomez | 78 | |
429 : | Isibaar | 3 | } |
430 : | |||
431 : | edgomez | 453 | /***************************************************************************** |
432 : | * Macro Block bitstream encoding functions | ||
433 : | ****************************************************************************/ | ||
434 : | Isibaar | 3 | |
435 : | edgomez | 195 | void |
436 : | MBCoding(const FRAMEINFO * frame, | ||
437 : | MACROBLOCK * pMB, | ||
438 : | int16_t qcoeff[6 * 64], | ||
439 : | Bitstream * bs, | ||
440 : | Statistics * pStat) | ||
441 : | Isibaar | 3 | { |
442 : | edgomez | 78 | |
443 : | edgomez | 195 | if (frame->coding_type == P_VOP) { |
444 : | edgomez | 677 | BitstreamPutBit(bs, 0); /* coded */ |
445 : | Isibaar | 3 | } |
446 : | |||
447 : | chl | 335 | if (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q) |
448 : | suxen_drol | 136 | CodeBlockIntra(frame, pMB, qcoeff, bs, pStat); |
449 : | Isibaar | 3 | else |
450 : | suxen_drol | 136 | CodeBlockInter(frame, pMB, qcoeff, bs, pStat); |
451 : | edgomez | 78 | |
452 : | Isibaar | 3 | } |
453 : | |||
454 : | chl | 347 | |
455 : | void | ||
456 : | MBSkip(Bitstream * bs) | ||
457 : | { | ||
458 : | edgomez | 677 | BitstreamPutBit(bs, 1); /* not coded */ |
459 : | chl | 347 | return; |
460 : | } | ||
461 : | |||
462 : | edgomez | 453 | /***************************************************************************** |
463 : | * decoding stuff starts here | ||
464 : | ****************************************************************************/ | ||
465 : | suxen_drol | 118 | |
466 : | edgomez | 453 | /* |
467 : | * For IVOP addbits == 0 | ||
468 : | * For PVOP addbits == fcode - 1 | ||
469 : | * For BVOP addbits == max(fcode,bcode) - 1 | ||
470 : | * returns true or false | ||
471 : | */ | ||
472 : | Isibaar | 3 | |
473 : | suxen_drol | 248 | int |
474 : | check_resync_marker(Bitstream * bs, int addbits) | ||
475 : | { | ||
476 : | uint32_t nbits; | ||
477 : | uint32_t code; | ||
478 : | uint32_t nbitsresyncmarker = NUMBITS_VP_RESYNC_MARKER + addbits; | ||
479 : | |||
480 : | nbits = BitstreamNumBitsToByteAlign(bs); | ||
481 : | code = BitstreamShowBits(bs, nbits); | ||
482 : | |||
483 : | if (code == (((uint32_t)1 << (nbits - 1)) - 1)) | ||
484 : | { | ||
485 : | return BitstreamShowBitsFromByteAlign(bs, nbitsresyncmarker) == RESYNC_MARKER; | ||
486 : | } | ||
487 : | |||
488 : | return 0; | ||
489 : | } | ||
490 : | |||
491 : | |||
492 : | |||
493 : | edgomez | 195 | int |
494 : | get_mcbpc_intra(Bitstream * bs) | ||
495 : | Isibaar | 3 | { |
496 : | edgomez | 78 | |
497 : | Isibaar | 3 | uint32_t index; |
498 : | edgomez | 195 | |
499 : | suxen_drol | 248 | index = BitstreamShowBits(bs, 9); |
500 : | Isibaar | 3 | index >>= 3; |
501 : | |||
502 : | BitstreamSkip(bs, mcbpc_intra_table[index].len); | ||
503 : | edgomez | 78 | |
504 : | Isibaar | 3 | return mcbpc_intra_table[index].code; |
505 : | edgomez | 78 | |
506 : | Isibaar | 3 | } |
507 : | |||
508 : | edgomez | 195 | int |
509 : | get_mcbpc_inter(Bitstream * bs) | ||
510 : | Isibaar | 3 | { |
511 : | edgomez | 78 | |
512 : | Isibaar | 3 | uint32_t index; |
513 : | suxen_drol | 248 | |
514 : | index = CLIP(BitstreamShowBits(bs, 9), 256); | ||
515 : | edgomez | 195 | |
516 : | BitstreamSkip(bs, mcbpc_inter_table[index].len); | ||
517 : | edgomez | 78 | |
518 : | Isibaar | 3 | return mcbpc_inter_table[index].code; |
519 : | edgomez | 78 | |
520 : | Isibaar | 3 | } |
521 : | |||
522 : | edgomez | 195 | int |
523 : | get_cbpy(Bitstream * bs, | ||
524 : | int intra) | ||
525 : | Isibaar | 3 | { |
526 : | edgomez | 78 | |
527 : | Isibaar | 3 | int cbpy; |
528 : | uint32_t index = BitstreamShowBits(bs, 6); | ||
529 : | |||
530 : | BitstreamSkip(bs, cbpy_table[index].len); | ||
531 : | cbpy = cbpy_table[index].code; | ||
532 : | |||
533 : | edgomez | 195 | if (!intra) |
534 : | Isibaar | 3 | cbpy = 15 - cbpy; |
535 : | |||
536 : | return cbpy; | ||
537 : | edgomez | 78 | |
538 : | Isibaar | 3 | } |
539 : | |||
540 : | edgomez | 195 | int |
541 : | get_mv_data(Bitstream * bs) | ||
542 : | Isibaar | 3 | { |
543 : | edgomez | 78 | |
544 : | Isibaar | 3 | uint32_t index; |
545 : | |||
546 : | edgomez | 195 | if (BitstreamGetBit(bs)) |
547 : | Isibaar | 3 | return 0; |
548 : | edgomez | 195 | |
549 : | Isibaar | 3 | index = BitstreamShowBits(bs, 12); |
550 : | |||
551 : | edgomez | 195 | if (index >= 512) { |
552 : | Isibaar | 3 | index = (index >> 8) - 2; |
553 : | BitstreamSkip(bs, TMNMVtab0[index].len); | ||
554 : | return TMNMVtab0[index].code; | ||
555 : | } | ||
556 : | edgomez | 195 | |
557 : | if (index >= 128) { | ||
558 : | Isibaar | 3 | index = (index >> 2) - 32; |
559 : | BitstreamSkip(bs, TMNMVtab1[index].len); | ||
560 : | return TMNMVtab1[index].code; | ||
561 : | } | ||
562 : | |||
563 : | edgomez | 195 | index -= 4; |
564 : | Isibaar | 3 | |
565 : | BitstreamSkip(bs, TMNMVtab2[index].len); | ||
566 : | return TMNMVtab2[index].code; | ||
567 : | edgomez | 78 | |
568 : | Isibaar | 3 | } |
569 : | |||
570 : | edgomez | 195 | int |
571 : | get_mv(Bitstream * bs, | ||
572 : | int fcode) | ||
573 : | Isibaar | 3 | { |
574 : | edgomez | 78 | |
575 : | Isibaar | 3 | int data; |
576 : | int res; | ||
577 : | int mv; | ||
578 : | int scale_fac = 1 << (fcode - 1); | ||
579 : | |||
580 : | data = get_mv_data(bs); | ||
581 : | edgomez | 195 | |
582 : | if (scale_fac == 1 || data == 0) | ||
583 : | Isibaar | 3 | return data; |
584 : | |||
585 : | res = BitstreamGetBits(bs, fcode - 1); | ||
586 : | mv = ((ABS(data) - 1) * scale_fac) + res + 1; | ||
587 : | edgomez | 195 | |
588 : | Isibaar | 3 | return data < 0 ? -mv : mv; |
589 : | edgomez | 78 | |
590 : | Isibaar | 3 | } |
591 : | |||
592 : | edgomez | 195 | int |
593 : | get_dc_dif(Bitstream * bs, | ||
594 : | uint32_t dc_size) | ||
595 : | Isibaar | 3 | { |
596 : | edgomez | 78 | |
597 : | Isibaar | 3 | int code = BitstreamGetBits(bs, dc_size); |
598 : | int msb = code >> (dc_size - 1); | ||
599 : | |||
600 : | edgomez | 195 | if (msb == 0) |
601 : | return (-1 * (code ^ ((1 << dc_size) - 1))); | ||
602 : | Isibaar | 3 | |
603 : | return code; | ||
604 : | edgomez | 78 | |
605 : | Isibaar | 3 | } |
606 : | |||
607 : | edgomez | 195 | int |
608 : | get_dc_size_lum(Bitstream * bs) | ||
609 : | Isibaar | 3 | { |
610 : | edgomez | 78 | |
611 : | Isibaar | 3 | int code, i; |
612 : | edgomez | 195 | |
613 : | Isibaar | 3 | code = BitstreamShowBits(bs, 11); |
614 : | |||
615 : | edgomez | 195 | for (i = 11; i > 3; i--) { |
616 : | if (code == 1) { | ||
617 : | Isibaar | 3 | BitstreamSkip(bs, i); |
618 : | return i + 1; | ||
619 : | } | ||
620 : | code >>= 1; | ||
621 : | } | ||
622 : | |||
623 : | BitstreamSkip(bs, dc_lum_tab[code].len); | ||
624 : | return dc_lum_tab[code].code; | ||
625 : | edgomez | 78 | |
626 : | Isibaar | 3 | } |
627 : | |||
628 : | |||
629 : | edgomez | 195 | int |
630 : | get_dc_size_chrom(Bitstream * bs) | ||
631 : | Isibaar | 3 | { |
632 : | edgomez | 78 | |
633 : | Isibaar | 3 | uint32_t code, i; |
634 : | edgomez | 195 | |
635 : | Isibaar | 3 | code = BitstreamShowBits(bs, 12); |
636 : | |||
637 : | edgomez | 195 | for (i = 12; i > 2; i--) { |
638 : | if (code == 1) { | ||
639 : | Isibaar | 3 | BitstreamSkip(bs, i); |
640 : | return i; | ||
641 : | } | ||
642 : | code >>= 1; | ||
643 : | } | ||
644 : | |||
645 : | return 3 - BitstreamGetBits(bs, 2); | ||
646 : | edgomez | 78 | |
647 : | Isibaar | 3 | } |
648 : | |||
649 : | edgomez | 453 | /***************************************************************************** |
650 : | * Local inlined function to "decode" written vlc codes | ||
651 : | ****************************************************************************/ | ||
652 : | |||
653 : | static __inline int | ||
654 : | get_coeff(Bitstream * bs, | ||
655 : | int *run, | ||
656 : | int *last, | ||
657 : | int intra, | ||
658 : | int short_video_header) | ||
659 : | { | ||
660 : | |||
661 : | uint32_t mode; | ||
662 : | const VLC *tab; | ||
663 : | int32_t level; | ||
664 : | |||
665 : | edgomez | 677 | if (short_video_header) /* inter-VLCs will be used for both intra and inter blocks */ |
666 : | edgomez | 453 | intra = 0; |
667 : | |||
668 : | tab = &DCT3D[intra][BitstreamShowBits(bs, 12)]; | ||
669 : | |||
670 : | if (tab->code == -1) | ||
671 : | goto error; | ||
672 : | |||
673 : | BitstreamSkip(bs, tab->len); | ||
674 : | |||
675 : | if (tab->code != ESCAPE) { | ||
676 : | if (!intra) { | ||
677 : | *run = (tab->code >> 4) & 255; | ||
678 : | level = tab->code & 15; | ||
679 : | *last = (tab->code >> 12) & 1; | ||
680 : | } else { | ||
681 : | *run = (tab->code >> 8) & 255; | ||
682 : | level = tab->code & 255; | ||
683 : | *last = (tab->code >> 16) & 1; | ||
684 : | } | ||
685 : | return BitstreamGetBit(bs) ? -level : level; | ||
686 : | } | ||
687 : | |||
688 : | if (short_video_header) { | ||
689 : | edgomez | 677 | /* escape mode 4 - H.263 type, only used if short_video_header = 1 */ |
690 : | edgomez | 453 | *last = BitstreamGetBit(bs); |
691 : | *run = BitstreamGetBits(bs, 6); | ||
692 : | level = BitstreamGetBits(bs, 8); | ||
693 : | |||
694 : | if (level == 0 || level == 128) | ||
695 : | edgomez | 514 | DPRINTF(DPRINTF_ERROR, "Illegal LEVEL for ESCAPE mode 4: %d", level); |
696 : | edgomez | 453 | |
697 : | return (level >= 128 ? -(256 - level) : level); | ||
698 : | } | ||
699 : | |||
700 : | mode = BitstreamShowBits(bs, 2); | ||
701 : | |||
702 : | if (mode < 3) { | ||
703 : | BitstreamSkip(bs, (mode == 2) ? 2 : 1); | ||
704 : | |||
705 : | tab = &DCT3D[intra][BitstreamShowBits(bs, 12)]; | ||
706 : | if (tab->code == -1) | ||
707 : | goto error; | ||
708 : | |||
709 : | BitstreamSkip(bs, tab->len); | ||
710 : | |||
711 : | if (!intra) { | ||
712 : | *run = (tab->code >> 4) & 255; | ||
713 : | level = tab->code & 15; | ||
714 : | *last = (tab->code >> 12) & 1; | ||
715 : | } else { | ||
716 : | *run = (tab->code >> 8) & 255; | ||
717 : | level = tab->code & 255; | ||
718 : | *last = (tab->code >> 16) & 1; | ||
719 : | } | ||
720 : | |||
721 : | edgomez | 677 | if (mode < 2) /* first escape mode, level is offset */ |
722 : | level += max_level[*last + (!intra << 1)][*run]; /* need to add back the max level */ | ||
723 : | else if (mode == 2) /* second escape mode, run is offset */ | ||
724 : | edgomez | 453 | *run += max_run[*last + (!intra << 1)][level] + 1; |
725 : | |||
726 : | return BitstreamGetBit(bs) ? -level : level; | ||
727 : | } | ||
728 : | edgomez | 677 | /* third escape mode - fixed length codes */ |
729 : | edgomez | 453 | BitstreamSkip(bs, 2); |
730 : | *last = BitstreamGetBits(bs, 1); | ||
731 : | *run = BitstreamGetBits(bs, 6); | ||
732 : | edgomez | 677 | BitstreamSkip(bs, 1); /* marker */ |
733 : | edgomez | 453 | level = BitstreamGetBits(bs, 12); |
734 : | edgomez | 677 | BitstreamSkip(bs, 1); /* marker */ |
735 : | edgomez | 453 | |
736 : | return (level & 0x800) ? (level | (-1 ^ 0xfff)) : level; | ||
737 : | |||
738 : | error: | ||
739 : | *run = VLC_ERROR; | ||
740 : | return 0; | ||
741 : | |||
742 : | } | ||
743 : | |||
744 : | /***************************************************************************** | ||
745 : | * MB reading functions | ||
746 : | ****************************************************************************/ | ||
747 : | |||
748 : | edgomez | 195 | void |
749 : | get_intra_block(Bitstream * bs, | ||
750 : | int16_t * block, | ||
751 : | int direction, | ||
752 : | int coeff) | ||
753 : | Isibaar | 3 | { |
754 : | edgomez | 78 | |
755 : | edgomez | 195 | const uint16_t *scan = scan_tables[direction]; |
756 : | Isibaar | 3 | int level; |
757 : | int run; | ||
758 : | int last; | ||
759 : | |||
760 : | edgomez | 195 | do { |
761 : | Isibaar | 3 | level = get_coeff(bs, &run, &last, 1, 0); |
762 : | edgomez | 195 | if (run == -1) { |
763 : | edgomez | 514 | DPRINTF(DPRINTF_DEBUG, "fatal: invalid run"); |
764 : | Isibaar | 3 | break; |
765 : | } | ||
766 : | coeff += run; | ||
767 : | edgomez | 195 | block[scan[coeff]] = level; |
768 : | suxen_drol | 252 | |
769 : | DPRINTF(DPRINTF_COEFF,"block[%i] %i", scan[coeff], level); | ||
770 : | edgomez | 677 | /*DPRINTF(DPRINTF_COEFF,"block[%i] %i %08x", scan[coeff], level, BitstreamShowBits(bs, 32)); */ |
771 : | suxen_drol | 252 | |
772 : | edgomez | 195 | if (level < -127 || level > 127) { |
773 : | edgomez | 514 | DPRINTF(DPRINTF_DEBUG, "warning: intra_overflow: %d", level); |
774 : | Isibaar | 3 | } |
775 : | coeff++; | ||
776 : | } while (!last); | ||
777 : | edgomez | 78 | |
778 : | Isibaar | 3 | } |
779 : | |||
780 : | edgomez | 195 | void |
781 : | get_inter_block(Bitstream * bs, | ||
782 : | int16_t * block) | ||
783 : | Isibaar | 3 | { |
784 : | edgomez | 78 | |
785 : | edgomez | 195 | const uint16_t *scan = scan_tables[0]; |
786 : | Isibaar | 3 | int p; |
787 : | int level; | ||
788 : | int run; | ||
789 : | int last; | ||
790 : | |||
791 : | p = 0; | ||
792 : | edgomez | 195 | do { |
793 : | Isibaar | 3 | level = get_coeff(bs, &run, &last, 0, 0); |
794 : | edgomez | 195 | if (run == -1) { |
795 : | edgomez | 514 | DPRINTF(DPRINTF_ERROR, "fatal: invalid run"); |
796 : | Isibaar | 3 | break; |
797 : | } | ||
798 : | p += run; | ||
799 : | chenm001 | 161 | |
800 : | edgomez | 195 | block[scan[p]] = level; |
801 : | suxen_drol | 252 | |
802 : | DPRINTF(DPRINTF_COEFF,"block[%i] %i", scan[p], level); | ||
803 : | |||
804 : | edgomez | 195 | if (level < -127 || level > 127) { |
805 : | edgomez | 514 | DPRINTF(DPRINTF_DEBUG, "warning: inter_overflow: %d", level); |
806 : | Isibaar | 3 | } |
807 : | p++; | ||
808 : | } while (!last); | ||
809 : | edgomez | 78 | |
810 : | Isibaar | 3 | } |
No admin address has been configured | ViewVC Help |
Powered by ViewVC 1.0.4 |