author | kergoth <kergoth> | 2002-01-25 22:14:26 (UTC) |
---|---|---|
committer | kergoth <kergoth> | 2002-01-25 22:14:26 (UTC) |
commit | 15318cad33835e4e2dc620d033e43cd930676cdd (patch) (unidiff) | |
tree | c2fa0399a2c47fda8e2cd0092c73a809d17f68eb /core/multimedia/opieplayer/libmpeg3/video | |
download | opie-15318cad33835e4e2dc620d033e43cd930676cdd.zip opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.gz opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.bz2 |
Initial revision
Diffstat (limited to 'core/multimedia/opieplayer/libmpeg3/video') (more/less context) (ignore whitespace changes)
23 files changed, 7920 insertions, 0 deletions
diff --git a/core/multimedia/opieplayer/libmpeg3/video/Makefile b/core/multimedia/opieplayer/libmpeg3/video/Makefile new file mode 100644 index 0000000..46d8407 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/Makefile | |||
@@ -0,0 +1,32 @@ | |||
1 | include ../global_config | ||
2 | export CFLAGS | ||
3 | export CFLAGS_lessopt | ||
4 | |||
5 | OBJS = \ | ||
6 | getpicture.o \ | ||
7 | headers.o \ | ||
8 | idct.o \ | ||
9 | macroblocks.o \ | ||
10 | mmxtest.o \ | ||
11 | motion.o \ | ||
12 | mpeg3video.o \ | ||
13 | output.o \ | ||
14 | reconstruct.o \ | ||
15 | seek.o \ | ||
16 | slice.o \ | ||
17 | vlc.o | ||
18 | |||
19 | |||
20 | all: $(OBJS) $(MMXOBJS2) | ||
21 | |||
22 | .c.o: | ||
23 | $(CC) -c `./c_flags` -o $@ $< | ||
24 | |||
25 | .s.o: | ||
26 | $(NASM) -f elf $*.s | ||
27 | |||
28 | .S.o: | ||
29 | $(CC) -S `./c_flags` $*.S | ||
30 | |||
31 | clean: | ||
32 | rm -f *.o | ||
diff --git a/core/multimedia/opieplayer/libmpeg3/video/c_flags b/core/multimedia/opieplayer/libmpeg3/video/c_flags new file mode 100755 index 0000000..d7943d0 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/c_flags | |||
@@ -0,0 +1 @@ | |||
echo $CFLAGS | |||
diff --git a/core/multimedia/opieplayer/libmpeg3/video/getpicture.c b/core/multimedia/opieplayer/libmpeg3/video/getpicture.c new file mode 100644 index 0000000..4f67484 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/getpicture.c | |||
@@ -0,0 +1,767 @@ | |||
1 | #include "../libmpeg3.h" | ||
2 | #include "../mpeg3protos.h" | ||
3 | #include "mpeg3video.h" | ||
4 | #include "vlc.h" | ||
5 | |||
6 | #include <stdio.h> | ||
7 | #include <stdlib.h> | ||
8 | #include <string.h> | ||
9 | |||
10 | int mpeg3video_get_cbp(mpeg3_slice_t *slice) | ||
11 | { | ||
12 | int code; | ||
13 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
14 | |||
15 | if((code = mpeg3slice_showbits9(slice_buffer)) >= 128) | ||
16 | { | ||
17 | code >>= 4; | ||
18 | mpeg3slice_flushbits(slice_buffer, mpeg3_CBPtab0[code].len); | ||
19 | return mpeg3_CBPtab0[code].val; | ||
20 | } | ||
21 | |||
22 | if(code >= 8) | ||
23 | { | ||
24 | code >>= 1; | ||
25 | mpeg3slice_flushbits(slice_buffer, mpeg3_CBPtab1[code].len); | ||
26 | return mpeg3_CBPtab1[code].val; | ||
27 | } | ||
28 | |||
29 | if(code < 1) | ||
30 | { | ||
31 | /* fprintf(stderr,"mpeg3video_get_cbp: invalid coded_block_pattern code\n"); */ | ||
32 | slice->fault = 1; | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | mpeg3slice_flushbits(slice_buffer, mpeg3_CBPtab2[code].len); | ||
37 | return mpeg3_CBPtab2[code].val; | ||
38 | } | ||
39 | |||
40 | |||
41 | /* set block to zero */ | ||
42 | int mpeg3video_clearblock(mpeg3_slice_t *slice, int comp, int size) | ||
43 | { | ||
44 | slice->sparse[comp] = 1; | ||
45 | |||
46 | /* Compiler error */ | ||
47 | /* | ||
48 | * for(i = 0; i < size; i++) | ||
49 | * { | ||
50 | * bzero(slice->block[comp] + sizeof(short) * 64 * i, sizeof(short) * 64); | ||
51 | * } | ||
52 | */ | ||
53 | |||
54 | if(size == 6) | ||
55 | { | ||
56 | bzero(slice->block[comp], sizeof(short) * 64 * 6); | ||
57 | } | ||
58 | else | ||
59 | { | ||
60 | printf("mpeg3video_clearblock size = %d\n", size); | ||
61 | memset(slice->block[comp], 0, sizeof(short) * 64 * size); | ||
62 | } | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | static inline int mpeg3video_getdclum(mpeg3_slice_buffer_t *slice_buffer) | ||
67 | { | ||
68 | int code, size, val; | ||
69 | /* decode length */ | ||
70 | code = mpeg3slice_showbits5(slice_buffer); | ||
71 | |||
72 | if(code < 31) | ||
73 | { | ||
74 | size = mpeg3_DClumtab0[code].val; | ||
75 | mpeg3slice_flushbits(slice_buffer, mpeg3_DClumtab0[code].len); | ||
76 | } | ||
77 | else | ||
78 | { | ||
79 | code = mpeg3slice_showbits9(slice_buffer) - 0x1f0; | ||
80 | size = mpeg3_DClumtab1[code].val; | ||
81 | mpeg3slice_flushbits(slice_buffer, mpeg3_DClumtab1[code].len); | ||
82 | } | ||
83 | |||
84 | if(size == 0) val = 0; | ||
85 | else | ||
86 | { | ||
87 | val = mpeg3slice_getbits(slice_buffer, size); | ||
88 | if((val & (1 << (size - 1))) == 0) val -= (1 << size) - 1; | ||
89 | } | ||
90 | |||
91 | return val; | ||
92 | } | ||
93 | |||
94 | |||
95 | int mpeg3video_getdcchrom(mpeg3_slice_buffer_t *slice_buffer) | ||
96 | { | ||
97 | int code, size, val; | ||
98 | |||
99 | /* decode length */ | ||
100 | code = mpeg3slice_showbits5(slice_buffer); | ||
101 | |||
102 | if(code < 31) | ||
103 | { | ||
104 | size = mpeg3_DCchromtab0[code].val; | ||
105 | mpeg3slice_flushbits(slice_buffer, mpeg3_DCchromtab0[code].len); | ||
106 | } | ||
107 | else | ||
108 | { | ||
109 | code = mpeg3slice_showbits(slice_buffer, 10) - 0x3e0; | ||
110 | size = mpeg3_DCchromtab1[code].val; | ||
111 | mpeg3slice_flushbits(slice_buffer, mpeg3_DCchromtab1[code].len); | ||
112 | } | ||
113 | |||
114 | if(size == 0) val = 0; | ||
115 | else | ||
116 | { | ||
117 | val = mpeg3slice_getbits(slice_buffer, size); | ||
118 | if((val & (1 << (size - 1))) == 0) val -= (1 << size) - 1; | ||
119 | } | ||
120 | |||
121 | return val; | ||
122 | } | ||
123 | |||
124 | |||
125 | /* decode one intra coded MPEG-1 block */ | ||
126 | |||
127 | int mpeg3video_getintrablock(mpeg3_slice_t *slice, | ||
128 | mpeg3video_t *video, | ||
129 | int comp, | ||
130 | int dc_dct_pred[]) | ||
131 | { | ||
132 | int val, i, j, sign; | ||
133 | unsigned int code; | ||
134 | mpeg3_DCTtab_t *tab = 0; | ||
135 | short *bp = slice->block[comp]; | ||
136 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
137 | |||
138 | /* decode DC coefficients */ | ||
139 | if(comp < 4) | ||
140 | bp[0] = (dc_dct_pred[0] += mpeg3video_getdclum(slice_buffer)) << 3; | ||
141 | else | ||
142 | if(comp == 4) | ||
143 | bp[0] = (dc_dct_pred[1] += mpeg3video_getdcchrom(slice_buffer)) << 3; | ||
144 | else | ||
145 | bp[0] = (dc_dct_pred[2] += mpeg3video_getdcchrom(slice_buffer)) << 3; | ||
146 | |||
147 | #ifdef HAVE_MMX | ||
148 | if(video->have_mmx) | ||
149 | bp[0] <<= 4; | ||
150 | #endif | ||
151 | |||
152 | if(slice->fault) return 1; | ||
153 | |||
154 | /* decode AC coefficients */ | ||
155 | for(i = 1; ; i++) | ||
156 | { | ||
157 | code = mpeg3slice_showbits16(slice_buffer); | ||
158 | if(code >= 16384) | ||
159 | tab = &mpeg3_DCTtabnext[(code >> 12) - 4]; | ||
160 | else | ||
161 | if(code >= 1024) tab = &mpeg3_DCTtab0[(code >> 8) - 4]; | ||
162 | else | ||
163 | if(code >= 512) tab = &mpeg3_DCTtab1[(code >> 6) - 8]; | ||
164 | else | ||
165 | if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16]; | ||
166 | else | ||
167 | if(code >= 128) tab = &mpeg3_DCTtab3[(code >> 3) - 16]; | ||
168 | else | ||
169 | if(code >= 64) tab = &mpeg3_DCTtab4[(code >> 2) - 16]; | ||
170 | else | ||
171 | if(code >= 32) tab = &mpeg3_DCTtab5[(code >> 1) - 16]; | ||
172 | else | ||
173 | if(code >= 16) tab = &mpeg3_DCTtab6[code - 16]; | ||
174 | else | ||
175 | { | ||
176 | /* fprintf(stderr, "mpeg3video_getintrablock: invalid Huffman code\n"); */ | ||
177 | slice->fault = 1; | ||
178 | return 1; | ||
179 | } | ||
180 | |||
181 | mpeg3slice_flushbits(slice_buffer, tab->len); | ||
182 | |||
183 | if(tab->run == 64) break; /* end_of_block */ | ||
184 | |||
185 | if(tab->run == 65) | ||
186 | { | ||
187 | /* escape */ | ||
188 | i += mpeg3slice_getbits(slice_buffer, 6); | ||
189 | |||
190 | if((val = mpeg3slice_getbits(slice_buffer, 8)) == 0) | ||
191 | val = mpeg3slice_getbits(slice_buffer, 8); | ||
192 | else | ||
193 | if(val == 128) | ||
194 | val = mpeg3slice_getbits(slice_buffer, 8) - 256; | ||
195 | else | ||
196 | if(val > 128) | ||
197 | val -= 256; | ||
198 | |||
199 | if((sign = (val < 0)) != 0) val= -val; | ||
200 | } | ||
201 | else | ||
202 | { | ||
203 | i += tab->run; | ||
204 | val = tab->level; | ||
205 | sign = mpeg3slice_getbit(slice_buffer); | ||
206 | } | ||
207 | |||
208 | if(i < 64) | ||
209 | j = video->mpeg3_zigzag_scan_table[i]; | ||
210 | else | ||
211 | { | ||
212 | slice->fault = 1; | ||
213 | return 1; | ||
214 | } | ||
215 | |||
216 | |||
217 | #ifdef HAVE_MMX | ||
218 | if(video->have_mmx) | ||
219 | { | ||
220 | val = (val * slice->quant_scale * video->intra_quantizer_matrix[j]) << 1; | ||
221 | val = (val - 16) | 16; | ||
222 | } | ||
223 | else | ||
224 | #endif | ||
225 | { | ||
226 | val = (val * slice->quant_scale * video->intra_quantizer_matrix[j]) >> 3; | ||
227 | val = (val - 1) | 1; | ||
228 | } | ||
229 | |||
230 | bp[j] = sign ? -val : val; | ||
231 | } | ||
232 | |||
233 | if(j != 0) | ||
234 | { | ||
235 | /* not a sparse matrix ! */ | ||
236 | slice->sparse[comp] = 0; | ||
237 | } | ||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | |||
242 | /* decode one non-intra coded MPEG-1 block */ | ||
243 | |||
244 | int mpeg3video_getinterblock(mpeg3_slice_t *slice, | ||
245 | mpeg3video_t *video, | ||
246 | int comp) | ||
247 | { | ||
248 | int val, i, j, sign; | ||
249 | unsigned int code; | ||
250 | mpeg3_DCTtab_t *tab; | ||
251 | short *bp = slice->block[comp]; | ||
252 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
253 | |||
254 | /* decode AC coefficients */ | ||
255 | for(i = 0; ; i++) | ||
256 | { | ||
257 | code = mpeg3slice_showbits16(slice_buffer); | ||
258 | if(code >= 16384) | ||
259 | { | ||
260 | if(i == 0) | ||
261 | tab = &mpeg3_DCTtabfirst[(code >> 12) - 4]; | ||
262 | else | ||
263 | tab = &mpeg3_DCTtabnext[(code >> 12) - 4]; | ||
264 | } | ||
265 | else | ||
266 | if(code >= 1024) tab = &mpeg3_DCTtab0[(code >> 8) - 4]; | ||
267 | else | ||
268 | if(code >= 512) tab = &mpeg3_DCTtab1[(code >> 6) - 8]; | ||
269 | else | ||
270 | if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16]; | ||
271 | else | ||
272 | if(code >= 128) tab = &mpeg3_DCTtab3[(code >> 3) - 16]; | ||
273 | else | ||
274 | if(code >= 64) tab = &mpeg3_DCTtab4[(code >> 2) - 16]; | ||
275 | else | ||
276 | if(code >= 32) tab = &mpeg3_DCTtab5[(code >> 1) - 16]; | ||
277 | else | ||
278 | if(code >= 16) tab = &mpeg3_DCTtab6[code - 16]; | ||
279 | else | ||
280 | { | ||
281 | // invalid Huffman code | ||
282 | slice->fault = 1; | ||
283 | return 1; | ||
284 | } | ||
285 | |||
286 | mpeg3slice_flushbits(slice_buffer, tab->len); | ||
287 | |||
288 | /* end of block */ | ||
289 | if(tab->run == 64) | ||
290 | break; | ||
291 | |||
292 | if(tab->run == 65) | ||
293 | { | ||
294 | /* escape */ | ||
295 | i += mpeg3slice_getbits(slice_buffer, 6); | ||
296 | if((val = mpeg3slice_getbits(slice_buffer, 8)) == 0) | ||
297 | val = mpeg3slice_getbits(slice_buffer, 8); | ||
298 | else | ||
299 | if(val == 128) | ||
300 | val = mpeg3slice_getbits(slice_buffer, 8) - 256; | ||
301 | else | ||
302 | if(val > 128) | ||
303 | val -= 256; | ||
304 | |||
305 | if((sign = (val < 0)) != 0) val = -val; | ||
306 | } | ||
307 | else | ||
308 | { | ||
309 | i += tab->run; | ||
310 | val = tab->level; | ||
311 | sign = mpeg3slice_getbit(slice_buffer); | ||
312 | } | ||
313 | |||
314 | j = video->mpeg3_zigzag_scan_table[i]; | ||
315 | |||
316 | #ifdef HAVE_MMX | ||
317 | if(video->have_mmx) | ||
318 | { | ||
319 | val = (((val << 1)+1) * slice->quant_scale * video->non_intra_quantizer_matrix[j]); | ||
320 | val = (val - 16) | 16; | ||
321 | } | ||
322 | else | ||
323 | #endif | ||
324 | { | ||
325 | val = (((val << 1)+1) * slice->quant_scale * video->non_intra_quantizer_matrix[j]) >> 4; | ||
326 | val = (val - 1) | 1; | ||
327 | } | ||
328 | |||
329 | bp[j] = sign ? -val : val; | ||
330 | } | ||
331 | |||
332 | if(j != 0) | ||
333 | { | ||
334 | /* not a sparse matrix ! */ | ||
335 | slice->sparse[comp] = 0; | ||
336 | } | ||
337 | return 0; | ||
338 | } | ||
339 | |||
340 | |||
341 | /* decode one intra coded MPEG-2 block */ | ||
342 | int mpeg3video_getmpg2intrablock(mpeg3_slice_t *slice, | ||
343 | mpeg3video_t *video, | ||
344 | int comp, | ||
345 | int dc_dct_pred[]) | ||
346 | { | ||
347 | int val, i, j, sign, nc; | ||
348 | unsigned int code; | ||
349 | mpeg3_DCTtab_t *tab; | ||
350 | short *bp; | ||
351 | int *qmat; | ||
352 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
353 | |||
354 | /* with data partitioning, data always goes to base layer */ | ||
355 | bp = slice->block[comp]; | ||
356 | |||
357 | qmat = (comp < 4 || video->chroma_format == CHROMA420) | ||
358 | ? video->intra_quantizer_matrix | ||
359 | : video->chroma_intra_quantizer_matrix; | ||
360 | |||
361 | /* decode DC coefficients */ | ||
362 | if(comp < 4) | ||
363 | val = (dc_dct_pred[0] += mpeg3video_getdclum(slice_buffer)); | ||
364 | else | ||
365 | if((comp & 1) == 0) | ||
366 | val = (dc_dct_pred[1] += mpeg3video_getdcchrom(slice_buffer)); | ||
367 | else | ||
368 | val = (dc_dct_pred[2] += mpeg3video_getdcchrom(slice_buffer)); | ||
369 | |||
370 | if(slice->fault) return 1; | ||
371 | #ifdef HAVE_MMX | ||
372 | if(video->have_mmx) | ||
373 | bp[0] = val << (7 - video->dc_prec); | ||
374 | else | ||
375 | #endif | ||
376 | bp[0] = val << (3 - video->dc_prec); | ||
377 | |||
378 | nc = 0; | ||
379 | |||
380 | /* decode AC coefficients */ | ||
381 | for(i = 1; ; i++) | ||
382 | { | ||
383 | code = mpeg3slice_showbits16(slice_buffer); | ||
384 | |||
385 | if(code >= 16384 && !video->intravlc) | ||
386 | tab = &mpeg3_DCTtabnext[(code >> 12) - 4]; | ||
387 | else | ||
388 | if(code >= 1024) | ||
389 | { | ||
390 | if(video->intravlc) | ||
391 | tab = &mpeg3_DCTtab0a[(code >> 8) - 4]; | ||
392 | else | ||
393 | tab = &mpeg3_DCTtab0[(code >> 8) - 4]; | ||
394 | } | ||
395 | else | ||
396 | if(code >= 512) | ||
397 | { | ||
398 | if(video->intravlc) | ||
399 | tab = &mpeg3_DCTtab1a[(code >> 6) - 8]; | ||
400 | else | ||
401 | tab = &mpeg3_DCTtab1[(code >> 6) - 8]; | ||
402 | } | ||
403 | else | ||
404 | if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16]; | ||
405 | else | ||
406 | if(code >= 128) tab = &mpeg3_DCTtab3[(code >> 3) - 16]; | ||
407 | else | ||
408 | if(code >= 64) tab = &mpeg3_DCTtab4[(code >> 2) - 16]; | ||
409 | else | ||
410 | if(code >= 32) tab = &mpeg3_DCTtab5[(code >> 1) - 16]; | ||
411 | else | ||
412 | if(code >= 16) tab = &mpeg3_DCTtab6[code - 16]; | ||
413 | else | ||
414 | { | ||
415 | /* fprintf(stderr,"mpeg3video_getmpg2intrablock: invalid Huffman code\n"); */ | ||
416 | slice->fault = 1; | ||
417 | return 1; | ||
418 | } | ||
419 | |||
420 | mpeg3slice_flushbits(slice_buffer, tab->len); | ||
421 | |||
422 | /* end_of_block */ | ||
423 | if(tab->run == 64) | ||
424 | break; | ||
425 | |||
426 | if(tab->run == 65) | ||
427 | { | ||
428 | /* escape */ | ||
429 | i += mpeg3slice_getbits(slice_buffer, 6); | ||
430 | |||
431 | val = mpeg3slice_getbits(slice_buffer, 12); | ||
432 | if((val & 2047) == 0) | ||
433 | { | ||
434 | // invalid signed_level (escape) | ||
435 | slice->fault = 1; | ||
436 | return 1; | ||
437 | } | ||
438 | if((sign = (val >= 2048)) != 0) val = 4096 - val; | ||
439 | } | ||
440 | else | ||
441 | { | ||
442 | i += tab->run; | ||
443 | val = tab->level; | ||
444 | sign = mpeg3slice_getbit(slice_buffer); | ||
445 | } | ||
446 | |||
447 | j = (video->altscan ? video->mpeg3_alternate_scan_table : video->mpeg3_zigzag_scan_table)[i]; | ||
448 | |||
449 | #ifdef HAVE_MMX | ||
450 | if(video->have_mmx) | ||
451 | val = (val * slice->quant_scale * qmat[j]); | ||
452 | else | ||
453 | #endif | ||
454 | val = (val * slice->quant_scale * qmat[j]) >> 4; | ||
455 | |||
456 | bp[j] = sign ? -val : val; | ||
457 | nc++; | ||
458 | } | ||
459 | |||
460 | if(j != 0) | ||
461 | { | ||
462 | /* not a sparse matrix ! */ | ||
463 | slice->sparse[comp] = 0; | ||
464 | } | ||
465 | return 1; | ||
466 | } | ||
467 | |||
468 | |||
469 | /* decode one non-intra coded MPEG-2 block */ | ||
470 | |||
471 | int mpeg3video_getmpg2interblock(mpeg3_slice_t *slice, | ||
472 | mpeg3video_t *video, | ||
473 | int comp) | ||
474 | { | ||
475 | int val, i, j, sign, nc; | ||
476 | unsigned int code; | ||
477 | mpeg3_DCTtab_t *tab; | ||
478 | short *bp; | ||
479 | int *qmat; | ||
480 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
481 | |||
482 | /* with data partitioning, data always goes to base layer */ | ||
483 | bp = slice->block[comp]; | ||
484 | |||
485 | qmat = (comp < 4 || video->chroma_format == CHROMA420) | ||
486 | ? video->non_intra_quantizer_matrix | ||
487 | : video->chroma_non_intra_quantizer_matrix; | ||
488 | |||
489 | nc = 0; | ||
490 | |||
491 | /* decode AC coefficients */ | ||
492 | for(i = 0; ; i++) | ||
493 | { | ||
494 | code = mpeg3slice_showbits16(slice_buffer); | ||
495 | if(code >= 16384) | ||
496 | { | ||
497 | if(i == 0) tab = &mpeg3_DCTtabfirst[(code >> 12) - 4]; | ||
498 | else tab = &mpeg3_DCTtabnext[(code >> 12) - 4]; | ||
499 | } | ||
500 | else | ||
501 | if(code >= 1024) tab = &mpeg3_DCTtab0[(code >> 8) - 4]; | ||
502 | else | ||
503 | if(code >= 512) tab = &mpeg3_DCTtab1[(code >> 6) - 8]; | ||
504 | else | ||
505 | if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16]; | ||
506 | else | ||
507 | if(code >= 128) tab = &mpeg3_DCTtab3[(code >> 3) - 16]; | ||
508 | else | ||
509 | if(code >= 64) tab = &mpeg3_DCTtab4[(code >> 2) - 16]; | ||
510 | else | ||
511 | if(code >= 32) tab = &mpeg3_DCTtab5[(code >> 1) - 16]; | ||
512 | else | ||
513 | if(code >= 16) tab = &mpeg3_DCTtab6[code - 16]; | ||
514 | else | ||
515 | { | ||
516 | // invalid Huffman code | ||
517 | slice->fault = 1; | ||
518 | return 1; | ||
519 | } | ||
520 | |||
521 | mpeg3slice_flushbits(slice_buffer, tab->len); | ||
522 | |||
523 | /* end_of_block */ | ||
524 | if(tab->run == 64) | ||
525 | break; | ||
526 | |||
527 | if(tab->run == 65) | ||
528 | { | ||
529 | /* escape */ | ||
530 | i += mpeg3slice_getbits(slice_buffer, 6); | ||
531 | val = mpeg3slice_getbits(slice_buffer, 12); | ||
532 | if((val & 2047) == 0) | ||
533 | { | ||
534 | /* fprintf(stderr, "mpeg3video_getmpg2interblock: invalid signed_level (escape)\n"); */ | ||
535 | slice->fault = 1; | ||
536 | return 1; | ||
537 | } | ||
538 | if((sign = (val >= 2048)) != 0) val = 4096 - val; | ||
539 | } | ||
540 | else | ||
541 | { | ||
542 | i += tab->run; | ||
543 | val = tab->level; | ||
544 | sign = mpeg3slice_getbit(slice_buffer); | ||
545 | } | ||
546 | |||
547 | j = (video->altscan ? video->mpeg3_alternate_scan_table : video->mpeg3_zigzag_scan_table)[i]; | ||
548 | |||
549 | #ifdef HAVE_MMX | ||
550 | if(video->have_mmx) | ||
551 | val = (((val << 1)+1) * slice->quant_scale * qmat[j]) >> 1; | ||
552 | else | ||
553 | #endif | ||
554 | val = (((val << 1)+1) * slice->quant_scale * qmat[j]) >> 5; | ||
555 | |||
556 | bp[j] = sign ? (-val) : val ; | ||
557 | nc++; | ||
558 | } | ||
559 | |||
560 | if(j != 0) | ||
561 | { | ||
562 | slice->sparse[comp] = 0; | ||
563 | } | ||
564 | return 0; | ||
565 | } | ||
566 | |||
567 | |||
568 | /* decode all macroblocks of the current picture */ | ||
569 | int mpeg3video_get_macroblocks(mpeg3video_t *video, int framenum) | ||
570 | { | ||
571 | unsigned int code; | ||
572 | mpeg3_slice_buffer_t *slice_buffer; /* Buffer being loaded */ | ||
573 | int i; | ||
574 | int current_buffer; | ||
575 | mpeg3_bits_t *vstream = video->vstream; | ||
576 | |||
577 | /* Load every slice into a buffer array */ | ||
578 | video->total_slice_buffers = 0; | ||
579 | current_buffer = 0; | ||
580 | while(!mpeg3bits_eof(vstream) && | ||
581 | mpeg3bits_showbits32_noptr(vstream) >= MPEG3_SLICE_MIN_START && | ||
582 | mpeg3bits_showbits32_noptr(vstream) <= MPEG3_SLICE_MAX_START) | ||
583 | { | ||
584 | /* Initialize the buffer */ | ||
585 | if(current_buffer >= video->slice_buffers_initialized) | ||
586 | mpeg3_new_slice_buffer(&(video->slice_buffers[video->slice_buffers_initialized++])); | ||
587 | slice_buffer = &(video->slice_buffers[current_buffer]); | ||
588 | slice_buffer->buffer_size = 0; | ||
589 | slice_buffer->current_position = 0; | ||
590 | slice_buffer->bits_size = 0; | ||
591 | slice_buffer->done = 0; | ||
592 | |||
593 | /* Read the slice into the buffer including the slice start code */ | ||
594 | do | ||
595 | { | ||
596 | /* Expand buffer */ | ||
597 | if(slice_buffer->buffer_allocation <= slice_buffer->buffer_size) | ||
598 | mpeg3_expand_slice_buffer(slice_buffer); | ||
599 | |||
600 | /* Load 1 char into buffer */ | ||
601 | slice_buffer->data[slice_buffer->buffer_size++] = mpeg3bits_getbyte_noptr(vstream); | ||
602 | }while(!mpeg3bits_eof(vstream) && | ||
603 | mpeg3bits_showbits24_noptr(vstream) != MPEG3_PACKET_START_CODE_PREFIX); | ||
604 | |||
605 | /* Pad the buffer to get the last macroblock */ | ||
606 | if(slice_buffer->buffer_allocation <= slice_buffer->buffer_size + 4) | ||
607 | mpeg3_expand_slice_buffer(slice_buffer); | ||
608 | |||
609 | slice_buffer->data[slice_buffer->buffer_size++] = 0; | ||
610 | slice_buffer->data[slice_buffer->buffer_size++] = 0; | ||
611 | slice_buffer->data[slice_buffer->buffer_size++] = 1; | ||
612 | slice_buffer->data[slice_buffer->buffer_size++] = 0; | ||
613 | slice_buffer->bits_size = 0; | ||
614 | |||
615 | pthread_mutex_lock(&(slice_buffer->completion_lock)); fflush(stdout); | ||
616 | current_buffer++; | ||
617 | video->total_slice_buffers++; | ||
618 | } | ||
619 | |||
620 | /* Run the slice decoders */ | ||
621 | if(video->total_slice_buffers > 0) | ||
622 | { | ||
623 | for(i = 0; i < video->total_slice_decoders; i++) | ||
624 | { | ||
625 | if(i == 0 && video->total_slice_decoders > 1) | ||
626 | { | ||
627 | video->slice_decoders[i].current_buffer = 0; | ||
628 | video->slice_decoders[i].buffer_step = 1; | ||
629 | video->slice_decoders[i].last_buffer = (video->total_slice_buffers - 1); | ||
630 | } | ||
631 | else | ||
632 | if(i == 1) | ||
633 | { | ||
634 | video->slice_decoders[i].current_buffer = video->total_slice_buffers - 1; | ||
635 | video->slice_decoders[i].buffer_step = -1; | ||
636 | video->slice_decoders[i].last_buffer = 0; | ||
637 | } | ||
638 | else | ||
639 | { | ||
640 | video->slice_decoders[i].current_buffer = i; | ||
641 | video->slice_decoders[i].buffer_step = 1; | ||
642 | video->slice_decoders[i].last_buffer = video->total_slice_buffers - 1; | ||
643 | } | ||
644 | pthread_mutex_unlock(&(video->slice_decoders[i].input_lock)); | ||
645 | } | ||
646 | } | ||
647 | |||
648 | /* Wait for the slice decoders to finish */ | ||
649 | if(video->total_slice_buffers > 0) | ||
650 | { | ||
651 | for(i = 0; i < video->total_slice_buffers; i++) | ||
652 | { | ||
653 | pthread_mutex_lock(&(video->slice_buffers[i].completion_lock)); | ||
654 | pthread_mutex_unlock(&(video->slice_buffers[i].completion_lock)); | ||
655 | } | ||
656 | } | ||
657 | return 0; | ||
658 | } | ||
659 | |||
660 | int mpeg3video_allocate_decoders(mpeg3video_t *video, int decoder_count) | ||
661 | { | ||
662 | int i; | ||
663 | mpeg3_t *file = video->file; | ||
664 | /* Get the slice decoders */ | ||
665 | if(video->total_slice_decoders != file->cpus) | ||
666 | { | ||
667 | for(i = 0; i < video->total_slice_decoders; i++) | ||
668 | { | ||
669 | mpeg3_delete_slice_decoder(&video->slice_decoders[i]); | ||
670 | } | ||
671 | |||
672 | for(i = 0; i < file->cpus && i < MPEG3_MAX_CPUS; i++) | ||
673 | { | ||
674 | mpeg3_new_slice_decoder(video, &(video->slice_decoders[i])); | ||
675 | video->slice_decoders[i].thread_number = i; | ||
676 | } | ||
677 | |||
678 | video->total_slice_decoders = file->cpus; | ||
679 | } | ||
680 | return 0; | ||
681 | } | ||
682 | |||
683 | /* decode one frame or field picture */ | ||
684 | |||
685 | int mpeg3video_getpicture(mpeg3video_t *video, int framenum) | ||
686 | { | ||
687 | int i, result = 0; | ||
688 | mpeg3_t *file = video->file; | ||
689 | |||
690 | if(video->pict_struct == FRAME_PICTURE && video->secondfield) | ||
691 | { | ||
692 | /* recover from illegal number of field pictures */ | ||
693 | video->secondfield = 0; | ||
694 | } | ||
695 | |||
696 | if(!video->mpeg2) | ||
697 | { | ||
698 | video->current_repeat = video->repeat_count = 0; | ||
699 | } | ||
700 | |||
701 | mpeg3video_allocate_decoders(video, file->cpus); | ||
702 | |||
703 | for(i = 0; i < 3; i++) | ||
704 | { | ||
705 | if(video->pict_type == B_TYPE) | ||
706 | { | ||
707 | video->newframe[i] = video->auxframe[i]; | ||
708 | } | ||
709 | else | ||
710 | { | ||
711 | if(!video->secondfield && !video->current_repeat) | ||
712 | { | ||
713 | /* Swap refframes for I frames */ | ||
714 | unsigned char* tmp = video->oldrefframe[i]; | ||
715 | video->oldrefframe[i] = video->refframe[i]; | ||
716 | video->refframe[i] = tmp; | ||
717 | } | ||
718 | |||
719 | video->newframe[i] = video->refframe[i]; | ||
720 | } | ||
721 | |||
722 | if(video->pict_struct == BOTTOM_FIELD) | ||
723 | { | ||
724 | /* Only used if fields are in different pictures */ | ||
725 | video->newframe[i] += (i == 0) ? video->coded_picture_width : video->chrom_width; | ||
726 | } | ||
727 | } | ||
728 | |||
729 | /* The problem is when a B frame lands on the first repeat and is skipped, */ | ||
730 | /* the second repeat goes for the same bitmap as the skipped repeat, */ | ||
731 | /* so it picks up a frame from 3 frames back. */ | ||
732 | /* The first repeat must consititutively read a B frame if its B frame is going to be */ | ||
733 | /* used in a later repeat. */ | ||
734 | if(!video->current_repeat) | ||
735 | if(!(video->skip_bframes && video->pict_type == B_TYPE) || | ||
736 | (video->repeat_count >= 100 + 100 * video->skip_bframes)) | ||
737 | result = mpeg3video_get_macroblocks(video, framenum); | ||
738 | |||
739 | /* Set the frame to display */ | ||
740 | video->output_src = 0; | ||
741 | if(framenum > -1 && !result) | ||
742 | { | ||
743 | if(video->pict_struct == FRAME_PICTURE || video->secondfield) | ||
744 | { | ||
745 | if(video->pict_type == B_TYPE) | ||
746 | { | ||
747 | video->output_src = video->auxframe; | ||
748 | } | ||
749 | else | ||
750 | { | ||
751 | video->output_src = video->oldrefframe; | ||
752 | } | ||
753 | } | ||
754 | else | ||
755 | { | ||
756 | mpeg3video_display_second_field(video); | ||
757 | } | ||
758 | } | ||
759 | |||
760 | if(video->mpeg2) | ||
761 | { | ||
762 | video->current_repeat += 100; | ||
763 | } | ||
764 | |||
765 | if(video->pict_struct != FRAME_PICTURE) video->secondfield = !video->secondfield; | ||
766 | return result; | ||
767 | } | ||
diff --git a/core/multimedia/opieplayer/libmpeg3/video/headers.c b/core/multimedia/opieplayer/libmpeg3/video/headers.c new file mode 100644 index 0000000..5274530 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/headers.c | |||
@@ -0,0 +1,492 @@ | |||
1 | #include "../mpeg3demux.h" | ||
2 | #include "../libmpeg3.h" | ||
3 | #include "../mpeg3protos.h" | ||
4 | #include "mpeg3video.h" | ||
5 | |||
6 | #include <stdio.h> | ||
7 | #include <stdlib.h> | ||
8 | |||
9 | int mpeg3video_getseqhdr(mpeg3video_t *video) | ||
10 | { | ||
11 | int i; | ||
12 | mpeg3_t *file = video->file; | ||
13 | |||
14 | int aspect_ratio, picture_rate, vbv_buffer_size; | ||
15 | int constrained_parameters_flag; | ||
16 | int load_intra_quantizer_matrix, load_non_intra_quantizer_matrix; | ||
17 | |||
18 | video->horizontal_size = mpeg3bits_getbits(video->vstream, 12); | ||
19 | video->vertical_size = mpeg3bits_getbits(video->vstream, 12); | ||
20 | aspect_ratio = mpeg3bits_getbits(video->vstream, 4); | ||
21 | video->framerate_code = mpeg3bits_getbits(video->vstream, 4); | ||
22 | video->bitrate = mpeg3bits_getbits(video->vstream, 18); | ||
23 | mpeg3bits_getbit_noptr(video->vstream); /* marker bit (=1) */ | ||
24 | vbv_buffer_size = mpeg3bits_getbits(video->vstream, 10); | ||
25 | constrained_parameters_flag = mpeg3bits_getbit_noptr(video->vstream); | ||
26 | video->frame_rate = mpeg3_frame_rate_table[video->framerate_code]; | ||
27 | |||
28 | load_intra_quantizer_matrix = mpeg3bits_getbit_noptr(video->vstream); | ||
29 | if(load_intra_quantizer_matrix) | ||
30 | { | ||
31 | for(i = 0; i < 64; i++) | ||
32 | video->intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream); | ||
33 | } | ||
34 | else | ||
35 | { | ||
36 | for(i = 0; i < 64; i++) | ||
37 | video->intra_quantizer_matrix[i] = mpeg3_default_intra_quantizer_matrix[i]; | ||
38 | } | ||
39 | |||
40 | load_non_intra_quantizer_matrix = mpeg3bits_getbit_noptr(video->vstream); | ||
41 | if(load_non_intra_quantizer_matrix) | ||
42 | { | ||
43 | for(i = 0; i < 64; i++) | ||
44 | video->non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream); | ||
45 | } | ||
46 | else | ||
47 | { | ||
48 | for(i = 0; i < 64; i++) | ||
49 | video->non_intra_quantizer_matrix[i] = 16; | ||
50 | } | ||
51 | |||
52 | /* copy luminance to chrominance matrices */ | ||
53 | for(i = 0; i < 64; i++) | ||
54 | { | ||
55 | video->chroma_intra_quantizer_matrix[i] = video->intra_quantizer_matrix[i]; | ||
56 | video->chroma_non_intra_quantizer_matrix[i] = video->non_intra_quantizer_matrix[i]; | ||
57 | } | ||
58 | |||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | |||
63 | /* decode sequence extension */ | ||
64 | |||
65 | int mpeg3video_sequence_extension(mpeg3video_t *video) | ||
66 | { | ||
67 | int prof_lev; | ||
68 | int horizontal_size_extension, vertical_size_extension; | ||
69 | int bit_rate_extension, vbv_buffer_size_extension, low_delay; | ||
70 | int frame_rate_extension_n, frame_rate_extension_d; | ||
71 | int pos = 0; | ||
72 | |||
73 | video->mpeg2 = 1; | ||
74 | video->scalable_mode = SC_NONE; /* unless overwritten by seq. scal. ext. */ | ||
75 | prof_lev = mpeg3bits_getbyte_noptr(video->vstream); | ||
76 | video->prog_seq = mpeg3bits_getbit_noptr(video->vstream); | ||
77 | video->chroma_format = mpeg3bits_getbits(video->vstream, 2); | ||
78 | horizontal_size_extension = mpeg3bits_getbits(video->vstream, 2); | ||
79 | vertical_size_extension = mpeg3bits_getbits(video->vstream, 2); | ||
80 | bit_rate_extension = mpeg3bits_getbits(video->vstream, 12); | ||
81 | mpeg3bits_getbit_noptr(video->vstream); | ||
82 | vbv_buffer_size_extension = mpeg3bits_getbyte_noptr(video->vstream); | ||
83 | low_delay = mpeg3bits_getbit_noptr(video->vstream); | ||
84 | frame_rate_extension_n = mpeg3bits_getbits(video->vstream, 2); | ||
85 | frame_rate_extension_d = mpeg3bits_getbits(video->vstream, 5); | ||
86 | video->horizontal_size = (horizontal_size_extension << 12) | (video->horizontal_size & 0x0fff); | ||
87 | video->vertical_size = (vertical_size_extension << 12) | (video->vertical_size & 0x0fff); | ||
88 | } | ||
89 | |||
90 | |||
91 | /* decode sequence display extension */ | ||
92 | |||
93 | int mpeg3video_sequence_display_extension(mpeg3video_t *video) | ||
94 | { | ||
95 | int colour_primaries = 0, transfer_characteristics = 0; | ||
96 | int display_horizontal_size, display_vertical_size; | ||
97 | int pos = 0; | ||
98 | int video_format = mpeg3bits_getbits(video->vstream, 3); | ||
99 | int colour_description = mpeg3bits_getbit_noptr(video->vstream); | ||
100 | |||
101 | if(colour_description) | ||
102 | { | ||
103 | colour_primaries = mpeg3bits_getbyte_noptr(video->vstream); | ||
104 | transfer_characteristics = mpeg3bits_getbyte_noptr(video->vstream); | ||
105 | video->matrix_coefficients = mpeg3bits_getbyte_noptr(video->vstream); | ||
106 | } | ||
107 | |||
108 | display_horizontal_size = mpeg3bits_getbits(video->vstream, 14); | ||
109 | mpeg3bits_getbit_noptr(video->vstream); | ||
110 | display_vertical_size = mpeg3bits_getbits(video->vstream, 14); | ||
111 | } | ||
112 | |||
113 | |||
114 | /* decode quant matrix entension */ | ||
115 | |||
116 | int mpeg3video_quant_matrix_extension(mpeg3video_t *video) | ||
117 | { | ||
118 | int i; | ||
119 | int load_intra_quantiser_matrix, load_non_intra_quantiser_matrix; | ||
120 | int load_chroma_intra_quantiser_matrix; | ||
121 | int load_chroma_non_intra_quantiser_matrix; | ||
122 | int pos = 0; | ||
123 | |||
124 | if((load_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0) | ||
125 | { | ||
126 | for(i = 0; i < 64; i++) | ||
127 | { | ||
128 | video->chroma_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] | ||
129 | = video->intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] | ||
130 | = mpeg3bits_getbyte_noptr(video->vstream); | ||
131 | } | ||
132 | } | ||
133 | |||
134 | if((load_non_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0) | ||
135 | { | ||
136 | for (i = 0; i < 64; i++) | ||
137 | { | ||
138 | video->chroma_non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] | ||
139 | = video->non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] | ||
140 | = mpeg3bits_getbyte_noptr(video->vstream); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | if((load_chroma_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0) | ||
145 | { | ||
146 | for(i = 0; i < 64; i++) | ||
147 | video->chroma_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream); | ||
148 | } | ||
149 | |||
150 | if((load_chroma_non_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0) | ||
151 | { | ||
152 | for(i = 0; i < 64; i++) | ||
153 | video->chroma_non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream); | ||
154 | } | ||
155 | } | ||
156 | |||
157 | |||
158 | /* decode sequence scalable extension */ | ||
159 | |||
160 | int mpeg3video_sequence_scalable_extension(mpeg3video_t *video) | ||
161 | { | ||
162 | int layer_id; | ||
163 | |||
164 | video->scalable_mode = mpeg3bits_getbits(video->vstream, 2) + 1; /* add 1 to make SC_DP != SC_NONE */ | ||
165 | layer_id = mpeg3bits_getbits(video->vstream, 4); | ||
166 | |||
167 | if(video->scalable_mode == SC_SPAT) | ||
168 | { | ||
169 | video->llw = mpeg3bits_getbits(video->vstream, 14); /* lower_layer_prediction_horizontal_size */ | ||
170 | mpeg3bits_getbit_noptr(video->vstream); | ||
171 | video->llh = mpeg3bits_getbits(video->vstream, 14); /* lower_layer_prediction_vertical_size */ | ||
172 | video->hm = mpeg3bits_getbits(video->vstream, 5); | ||
173 | video->hn = mpeg3bits_getbits(video->vstream, 5); | ||
174 | video->vm = mpeg3bits_getbits(video->vstream, 5); | ||
175 | video->vn = mpeg3bits_getbits(video->vstream, 5); | ||
176 | } | ||
177 | |||
178 | if(video->scalable_mode == SC_TEMP) | ||
179 | fprintf(stderr, "mpeg3video_sequence_scalable_extension: temporal scalability not implemented\n"); | ||
180 | } | ||
181 | |||
182 | |||
183 | /* decode picture display extension */ | ||
184 | |||
185 | int mpeg3video_picture_display_extension(mpeg3video_t *video) | ||
186 | { | ||
187 | int n, i; | ||
188 | short frame_centre_horizontal_offset[3]; | ||
189 | short frame_centre_vertical_offset[3]; | ||
190 | |||
191 | if(video->prog_seq || video->pict_struct != FRAME_PICTURE) | ||
192 | n = 1; | ||
193 | else | ||
194 | n = video->repeatfirst ? 3 : 2; | ||
195 | |||
196 | for(i = 0; i < n; i++) | ||
197 | { | ||
198 | frame_centre_horizontal_offset[i] = (short)mpeg3bits_getbits(video->vstream, 16); | ||
199 | mpeg3bits_getbit_noptr(video->vstream); | ||
200 | frame_centre_vertical_offset[i] = (short)mpeg3bits_getbits(video->vstream, 16); | ||
201 | mpeg3bits_getbit_noptr(video->vstream); | ||
202 | } | ||
203 | } | ||
204 | |||
205 | |||
206 | /* decode picture coding extension */ | ||
207 | |||
208 | int mpeg3video_picture_coding_extension(mpeg3video_t *video) | ||
209 | { | ||
210 | int chroma_420_type, composite_display_flag; | ||
211 | int v_axis = 0, field_sequence = 0, sub_carrier = 0, burst_amplitude = 0, sub_carrier_phase = 0; | ||
212 | |||
213 | video->h_forw_r_size = mpeg3bits_getbits(video->vstream, 4) - 1; | ||
214 | video->v_forw_r_size = mpeg3bits_getbits(video->vstream, 4) - 1; | ||
215 | video->h_back_r_size = mpeg3bits_getbits(video->vstream, 4) - 1; | ||
216 | video->v_back_r_size = mpeg3bits_getbits(video->vstream, 4) - 1; | ||
217 | video->dc_prec = mpeg3bits_getbits(video->vstream, 2); | ||
218 | video->pict_struct = mpeg3bits_getbits(video->vstream, 2); | ||
219 | video->topfirst = mpeg3bits_getbit_noptr(video->vstream); | ||
220 | video->frame_pred_dct = mpeg3bits_getbit_noptr(video->vstream); | ||
221 | video->conceal_mv = mpeg3bits_getbit_noptr(video->vstream); | ||
222 | video->qscale_type = mpeg3bits_getbit_noptr(video->vstream); | ||
223 | video->intravlc = mpeg3bits_getbit_noptr(video->vstream); | ||
224 | video->altscan = mpeg3bits_getbit_noptr(video->vstream); | ||
225 | video->repeatfirst = mpeg3bits_getbit_noptr(video->vstream); | ||
226 | chroma_420_type = mpeg3bits_getbit_noptr(video->vstream); | ||
227 | video->prog_frame = mpeg3bits_getbit_noptr(video->vstream); | ||
228 | |||
229 | if(video->repeat_count > 100) | ||
230 | video->repeat_count = 0; | ||
231 | video->repeat_count += 100; | ||
232 | |||
233 | video->current_repeat = 0; | ||
234 | |||
235 | if(video->prog_seq) | ||
236 | { | ||
237 | if(video->repeatfirst) | ||
238 | { | ||
239 | if(video->topfirst) | ||
240 | video->repeat_count += 200; | ||
241 | else | ||
242 | video->repeat_count += 100; | ||
243 | } | ||
244 | } | ||
245 | else | ||
246 | if(video->prog_frame) | ||
247 | { | ||
248 | if(video->repeatfirst) | ||
249 | { | ||
250 | video->repeat_count += 50; | ||
251 | } | ||
252 | } | ||
253 | |||
254 | /*printf("mpeg3video_picture_coding_extension %d\n", video->repeat_count); */ | ||
255 | composite_display_flag = mpeg3bits_getbit_noptr(video->vstream); | ||
256 | |||
257 | if(composite_display_flag) | ||
258 | { | ||
259 | v_axis = mpeg3bits_getbit_noptr(video->vstream); | ||
260 | field_sequence = mpeg3bits_getbits(video->vstream, 3); | ||
261 | sub_carrier = mpeg3bits_getbit_noptr(video->vstream); | ||
262 | burst_amplitude = mpeg3bits_getbits(video->vstream, 7); | ||
263 | sub_carrier_phase = mpeg3bits_getbyte_noptr(video->vstream); | ||
264 | } | ||
265 | } | ||
266 | |||
267 | |||
268 | /* decode picture spatial scalable extension */ | ||
269 | |||
270 | int mpeg3video_picture_spatial_scalable_extension(mpeg3video_t *video) | ||
271 | { | ||
272 | video->pict_scal = 1; /* use spatial scalability in this picture */ | ||
273 | |||
274 | video->lltempref = mpeg3bits_getbits(video->vstream, 10); | ||
275 | mpeg3bits_getbit_noptr(video->vstream); | ||
276 | video->llx0 = mpeg3bits_getbits(video->vstream, 15); | ||
277 | if(video->llx0 >= 16384) video->llx0 -= 32768; | ||
278 | mpeg3bits_getbit_noptr(video->vstream); | ||
279 | video->lly0 = mpeg3bits_getbits(video->vstream, 15); | ||
280 | if(video->lly0 >= 16384) video->lly0 -= 32768; | ||
281 | video->stwc_table_index = mpeg3bits_getbits(video->vstream, 2); | ||
282 | video->llprog_frame = mpeg3bits_getbit_noptr(video->vstream); | ||
283 | video->llfieldsel = mpeg3bits_getbit_noptr(video->vstream); | ||
284 | } | ||
285 | |||
286 | |||
287 | /* decode picture temporal scalable extension | ||
288 | * | ||
289 | * not implemented | ||
290 | * | ||
291 | */ | ||
292 | |||
293 | int mpeg3video_picture_temporal_scalable_extension(mpeg3video_t *video) | ||
294 | { | ||
295 | fprintf(stderr, "mpeg3video_picture_temporal_scalable_extension: temporal scalability not supported\n"); | ||
296 | } | ||
297 | |||
298 | |||
299 | /* decode extension and user data */ | ||
300 | |||
301 | int mpeg3video_ext_user_data(mpeg3video_t *video) | ||
302 | { | ||
303 | int code = mpeg3bits_next_startcode(video->vstream); | ||
304 | |||
305 | |||
306 | while(code == MPEG3_EXT_START_CODE || code == MPEG3_USER_START_CODE && | ||
307 | !mpeg3bits_eof(video->vstream)) | ||
308 | { | ||
309 | mpeg3bits_refill(video->vstream); | ||
310 | |||
311 | if(code == MPEG3_EXT_START_CODE) | ||
312 | { | ||
313 | int ext_id = mpeg3bits_getbits(video->vstream, 4); | ||
314 | switch(ext_id) | ||
315 | { | ||
316 | case SEQ_ID: | ||
317 | mpeg3video_sequence_extension(video); | ||
318 | break; | ||
319 | case DISP_ID: | ||
320 | mpeg3video_sequence_display_extension(video); | ||
321 | break; | ||
322 | case QUANT_ID: | ||
323 | mpeg3video_quant_matrix_extension(video); | ||
324 | break; | ||
325 | case SEQSCAL_ID: | ||
326 | mpeg3video_sequence_scalable_extension(video); | ||
327 | break; | ||
328 | case PANSCAN_ID: | ||
329 | mpeg3video_picture_display_extension(video); | ||
330 | break; | ||
331 | case CODING_ID: | ||
332 | mpeg3video_picture_coding_extension(video); | ||
333 | break; | ||
334 | case SPATSCAL_ID: | ||
335 | mpeg3video_picture_spatial_scalable_extension(video); | ||
336 | break; | ||
337 | case TEMPSCAL_ID: | ||
338 | mpeg3video_picture_temporal_scalable_extension(video); | ||
339 | break; | ||
340 | default: | ||
341 | fprintf(stderr,"mpeg3video_ext_user_data: reserved extension start code ID %d\n", ext_id); | ||
342 | break; | ||
343 | } | ||
344 | } | ||
345 | code = mpeg3bits_next_startcode(video->vstream); | ||
346 | } | ||
347 | } | ||
348 | |||
349 | |||
350 | /* decode group of pictures header */ | ||
351 | |||
352 | int mpeg3video_getgophdr(mpeg3video_t *video) | ||
353 | { | ||
354 | int drop_flag, closed_gop, broken_link; | ||
355 | |||
356 | drop_flag = mpeg3bits_getbit_noptr(video->vstream); | ||
357 | video->gop_timecode.hour = mpeg3bits_getbits(video->vstream, 5); | ||
358 | video->gop_timecode.minute = mpeg3bits_getbits(video->vstream, 6); | ||
359 | mpeg3bits_getbit_noptr(video->vstream); | ||
360 | video->gop_timecode.second = mpeg3bits_getbits(video->vstream, 6); | ||
361 | video->gop_timecode.frame = mpeg3bits_getbits(video->vstream, 6); | ||
362 | closed_gop = mpeg3bits_getbit_noptr(video->vstream); | ||
363 | broken_link = mpeg3bits_getbit_noptr(video->vstream); | ||
364 | |||
365 | /* | ||
366 | * printf("%d:%d:%d:%d %d %d %d\n", video->gop_timecode.hour, video->gop_timecode.minute, video->gop_timecode.second, video->gop_timecode.frame, | ||
367 | * drop_flag, closed_gop, broken_link); | ||
368 | */ | ||
369 | return mpeg3bits_error(video->vstream); | ||
370 | } | ||
371 | |||
372 | /* decode picture header */ | ||
373 | |||
374 | int mpeg3video_getpicturehdr(mpeg3video_t *video) | ||
375 | { | ||
376 | int temp_ref, vbv_delay; | ||
377 | |||
378 | video->pict_scal = 0; /* unless overwritten by pict. spat. scal. ext. */ | ||
379 | |||
380 | temp_ref = mpeg3bits_getbits(video->vstream, 10); | ||
381 | video->pict_type = mpeg3bits_getbits(video->vstream, 3); | ||
382 | vbv_delay = mpeg3bits_getbits(video->vstream, 16); | ||
383 | |||
384 | if(video->pict_type == P_TYPE || video->pict_type == B_TYPE) | ||
385 | { | ||
386 | video->full_forw = mpeg3bits_getbit_noptr(video->vstream); | ||
387 | video->forw_r_size = mpeg3bits_getbits(video->vstream, 3) - 1; | ||
388 | } | ||
389 | |||
390 | if(video->pict_type == B_TYPE) | ||
391 | { | ||
392 | video->full_back = mpeg3bits_getbit_noptr(video->vstream); | ||
393 | video->back_r_size = mpeg3bits_getbits(video->vstream, 3) - 1; | ||
394 | } | ||
395 | |||
396 | /* get extra bit picture */ | ||
397 | while(mpeg3bits_getbit_noptr(video->vstream) && | ||
398 | !mpeg3bits_eof(video->vstream)) mpeg3bits_getbyte_noptr(video->vstream); | ||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | |||
403 | int mpeg3video_get_header(mpeg3video_t *video, int dont_repeat) | ||
404 | { | ||
405 | unsigned int code; | ||
406 | |||
407 | /* a sequence header should be found before returning from `getheader' the */ | ||
408 | /* first time (this is to set horizontal/vertical size properly) */ | ||
409 | |||
410 | /* Repeat the frame until it's less than 1 count from repeat_count */ | ||
411 | if(video->repeat_count - video->current_repeat >= 100 && !dont_repeat) | ||
412 | { | ||
413 | return 0; | ||
414 | } | ||
415 | |||
416 | if(dont_repeat) | ||
417 | { | ||
418 | video->repeat_count = 0; | ||
419 | video->current_repeat = 0; | ||
420 | } | ||
421 | else | ||
422 | video->repeat_count -= video->current_repeat; | ||
423 | |||
424 | while(1) | ||
425 | { | ||
426 | /* look for startcode */ | ||
427 | code = mpeg3bits_next_startcode(video->vstream); | ||
428 | if(mpeg3bits_eof(video->vstream)) return 1; | ||
429 | if(code != MPEG3_SEQUENCE_END_CODE) mpeg3bits_refill(video->vstream); | ||
430 | |||
431 | switch(code) | ||
432 | { | ||
433 | case MPEG3_SEQUENCE_START_CODE: | ||
434 | video->found_seqhdr = 1; | ||
435 | mpeg3video_getseqhdr(video); | ||
436 | mpeg3video_ext_user_data(video); | ||
437 | break; | ||
438 | |||
439 | case MPEG3_GOP_START_CODE: | ||
440 | mpeg3video_getgophdr(video); | ||
441 | mpeg3video_ext_user_data(video); | ||
442 | break; | ||
443 | |||
444 | case MPEG3_PICTURE_START_CODE: | ||
445 | mpeg3video_getpicturehdr(video); | ||
446 | mpeg3video_ext_user_data(video); | ||
447 | if(video->found_seqhdr) return 0; /* Exit here */ | ||
448 | break; | ||
449 | |||
450 | case MPEG3_SEQUENCE_END_CODE: | ||
451 | // Continue until the end | ||
452 | mpeg3bits_refill(video->vstream); | ||
453 | break; | ||
454 | |||
455 | default: | ||
456 | break; | ||
457 | } | ||
458 | } | ||
459 | return 1; /* Shouldn't be reached. */ | ||
460 | } | ||
461 | |||
462 | int mpeg3video_ext_bit_info(mpeg3_slice_buffer_t *slice_buffer) | ||
463 | { | ||
464 | while(mpeg3slice_getbit(slice_buffer)) mpeg3slice_getbyte(slice_buffer); | ||
465 | return 0; | ||
466 | } | ||
467 | |||
468 | /* decode slice header */ | ||
469 | int mpeg3video_getslicehdr(mpeg3_slice_t *slice, mpeg3video_t *video) | ||
470 | { | ||
471 | int slice_vertical_position_extension, intra_slice; | ||
472 | int qs; | ||
473 | |||
474 | slice_vertical_position_extension = (video->mpeg2 && video->vertical_size > 2800) ? | ||
475 | mpeg3slice_getbits(slice->slice_buffer, 3) : 0; | ||
476 | |||
477 | if(video->scalable_mode == SC_DP) slice->pri_brk = mpeg3slice_getbits(slice->slice_buffer, 7); | ||
478 | |||
479 | qs = mpeg3slice_getbits(slice->slice_buffer, 5); | ||
480 | slice->quant_scale = video->mpeg2 ? (video->qscale_type ? mpeg3_non_linear_mquant_table[qs] : (qs << 1)) : qs; | ||
481 | |||
482 | if(mpeg3slice_getbit(slice->slice_buffer)) | ||
483 | { | ||
484 | intra_slice = mpeg3slice_getbit(slice->slice_buffer); | ||
485 | mpeg3slice_getbits(slice->slice_buffer, 7); | ||
486 | mpeg3video_ext_bit_info(slice->slice_buffer); | ||
487 | } | ||
488 | else | ||
489 | intra_slice = 0; | ||
490 | |||
491 | return slice_vertical_position_extension; | ||
492 | } | ||
diff --git a/core/multimedia/opieplayer/libmpeg3/video/idct.c b/core/multimedia/opieplayer/libmpeg3/video/idct.c new file mode 100644 index 0000000..c79f90a --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/idct.c | |||
@@ -0,0 +1,160 @@ | |||
1 | #include "idct.h" | ||
2 | #include <stdlib.h> | ||
3 | |||
4 | /**********************************************************/ | ||
5 | /* inverse two dimensional DCT, Chen-Wang algorithm */ | ||
6 | /* (cf. IEEE ASSP-32, pp. 803-816, Aug. 1984) */ | ||
7 | /* 32-bit integer arithmetic (8 bit coefficients) */ | ||
8 | /* 11 mults, 29 adds per DCT */ | ||
9 | /* sE, 18.8.91 */ | ||
10 | /**********************************************************/ | ||
11 | /* coefficients extended to 12 bit for IEEE1180-1990 */ | ||
12 | /* compliance sE, 2.1.94 */ | ||
13 | /**********************************************************/ | ||
14 | |||
15 | /* this code assumes >> to be a two's-complement arithmetic */ | ||
16 | /* right shift: (-2)>>1 == -1 , (-3)>>1 == -2 */ | ||
17 | |||
18 | #define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */ | ||
19 | #define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */ | ||
20 | #define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */ | ||
21 | #define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */ | ||
22 | #define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */ | ||
23 | #define W7 565 /* 2048*sqrt(2)*cos(7*pi/16) */ | ||
24 | |||
25 | /* row (horizontal) IDCT | ||
26 | * | ||
27 | * 7 pi 1 | ||
28 | * dst[k] = sum c[l] * src[l] * cos( -- * ( k + - ) * l ) | ||
29 | * l=0 8 2 | ||
30 | * | ||
31 | * where: c[0] = 128 | ||
32 | * c[1..7] = 128*sqrt(2) | ||
33 | */ | ||
34 | |||
35 | int mpeg3video_idctrow(short *blk) | ||
36 | { | ||
37 | int x0, x1, x2, x3, x4, x5, x6, x7, x8; | ||
38 | |||
39 | /* shortcut */ | ||
40 | if (!((x1 = blk[4]<<11) | (x2 = blk[6]) | (x3 = blk[2]) | | ||
41 | (x4 = blk[1]) | (x5 = blk[7]) | (x6 = blk[5]) | (x7 = blk[3]))) | ||
42 | { | ||
43 | blk[0]=blk[1]=blk[2]=blk[3]=blk[4]=blk[5]=blk[6]=blk[7]=blk[0]<<3; | ||
44 | return 0; | ||
45 | } | ||
46 | |||
47 | x0 = (blk[0]<<11) + 128; /* for proper rounding in the fourth stage */ | ||
48 | |||
49 | /* first stage */ | ||
50 | x8 = W7*(x4+x5); | ||
51 | x4 = x8 + (W1-W7)*x4; | ||
52 | x5 = x8 - (W1+W7)*x5; | ||
53 | x8 = W3*(x6+x7); | ||
54 | x6 = x8 - (W3-W5)*x6; | ||
55 | x7 = x8 - (W3+W5)*x7; | ||
56 | |||
57 | /* second stage */ | ||
58 | x8 = x0 + x1; | ||
59 | x0 -= x1; | ||
60 | x1 = W6*(x3+x2); | ||
61 | x2 = x1 - (W2+W6)*x2; | ||
62 | x3 = x1 + (W2-W6)*x3; | ||
63 | x1 = x4 + x6; | ||
64 | x4 -= x6; | ||
65 | x6 = x5 + x7; | ||
66 | x5 -= x7; | ||
67 | |||
68 | /* third stage */ | ||
69 | x7 = x8 + x3; | ||
70 | x8 -= x3; | ||
71 | x3 = x0 + x2; | ||
72 | x0 -= x2; | ||
73 | x2 = (181*(x4+x5)+128)>>8; | ||
74 | x4 = (181*(x4-x5)+128)>>8; | ||
75 | |||
76 | /* fourth stage */ | ||
77 | blk[0] = (x7+x1)>>8; | ||
78 | blk[1] = (x3+x2)>>8; | ||
79 | blk[2] = (x0+x4)>>8; | ||
80 | blk[3] = (x8+x6)>>8; | ||
81 | blk[4] = (x8-x6)>>8; | ||
82 | blk[5] = (x0-x4)>>8; | ||
83 | blk[6] = (x3-x2)>>8; | ||
84 | blk[7] = (x7-x1)>>8; | ||
85 | |||
86 | return 1; | ||
87 | } | ||
88 | |||
89 | /* column (vertical) IDCT | ||
90 | * | ||
91 | * 7 pi 1 | ||
92 | * dst[8*k] = sum c[l] * src[8*l] * cos( -- * ( k + - ) * l ) | ||
93 | * l=0 8 2 | ||
94 | * | ||
95 | * where: c[0] = 1/1024 | ||
96 | * c[1..7] = (1/1024)*sqrt(2) | ||
97 | */ | ||
98 | |||
99 | int mpeg3video_idctcol(short *blk) | ||
100 | { | ||
101 | int x0, x1, x2, x3, x4, x5, x6, x7, x8; | ||
102 | |||
103 | /* shortcut */ | ||
104 | if (!((x1 = (blk[8 * 4]<<8)) | (x2 = blk[8 * 6]) | (x3 = blk[8 * 2]) | | ||
105 | (x4 = blk[8*1]) | (x5 = blk[8 * 7]) | (x6 = blk[8 * 5]) | (x7 = blk[8 * 3]))){ | ||
106 | blk[8*0]=blk[8*1]=blk[8 * 2]=blk[8 * 3]=blk[8 * 4]=blk[8 * 5]=blk[8 * 6]=blk[8 * 7]= | ||
107 | (blk[8*0]+32)>>6; | ||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | x0 = (blk[8*0]<<8) + 8192; | ||
112 | |||
113 | /* first stage */ | ||
114 | x8 = W7*(x4+x5) + 4; | ||
115 | x4 = (x8+(W1-W7)*x4)>>3; | ||
116 | x5 = (x8-(W1+W7)*x5)>>3; | ||
117 | x8 = W3*(x6+x7) + 4; | ||
118 | x6 = (x8-(W3-W5)*x6)>>3; | ||
119 | x7 = (x8-(W3+W5)*x7)>>3; | ||
120 | |||
121 | /* second stage */ | ||
122 | x8 = x0 + x1; | ||
123 | x0 -= x1; | ||
124 | x1 = W6*(x3+x2) + 4; | ||
125 | x2 = (x1-(W2+W6)*x2)>>3; | ||
126 | x3 = (x1+(W2-W6)*x3)>>3; | ||
127 | x1 = x4 + x6; | ||
128 | x4 -= x6; | ||
129 | x6 = x5 + x7; | ||
130 | x5 -= x7; | ||
131 | |||
132 | /* third stage */ | ||
133 | x7 = x8 + x3; | ||
134 | x8 -= x3; | ||
135 | x3 = x0 + x2; | ||
136 | x0 -= x2; | ||
137 | x2 = (181 * (x4 + x5) + 128) >> 8; | ||
138 | x4 = (181 * (x4 - x5) + 128) >> 8; | ||
139 | |||
140 | /* fourth stage */ | ||
141 | blk[8 * 0] = (x7 + x1) >> 14; | ||
142 | blk[8 * 1] = (x3 + x2) >> 14; | ||
143 | blk[8 * 2] = (x0 + x4) >> 14; | ||
144 | blk[8 * 3] = (x8 + x6) >> 14; | ||
145 | blk[8 * 4] = (x8 - x6) >> 14; | ||
146 | blk[8 * 5] = (x0 - x4) >> 14; | ||
147 | blk[8 * 6] = (x3 - x2) >> 14; | ||
148 | blk[8 * 7] = (x7 - x1) >> 14; | ||
149 | |||
150 | return 1; | ||
151 | } | ||
152 | |||
153 | |||
154 | /* two dimensional inverse discrete cosine transform */ | ||
155 | void mpeg3video_idct_conversion(short* block) | ||
156 | { | ||
157 | int i; | ||
158 | for(i = 0; i < 8; i++) mpeg3video_idctrow(block + 8 * i); | ||
159 | for(i = 0; i < 8; i++) mpeg3video_idctcol(block + i); | ||
160 | } | ||
diff --git a/core/multimedia/opieplayer/libmpeg3/video/idct.h b/core/multimedia/opieplayer/libmpeg3/video/idct.h new file mode 100644 index 0000000..f0aa1d8 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/idct.h | |||
@@ -0,0 +1,24 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | #ifndef IDCT_H | ||
21 | #define IDCT_H | ||
22 | |||
23 | |||
24 | #endif | ||
diff --git a/core/multimedia/opieplayer/libmpeg3/video/layerdata.h b/core/multimedia/opieplayer/libmpeg3/video/layerdata.h new file mode 100644 index 0000000..3ef0f90 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/layerdata.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | #ifndef LAYERDATA_H | ||
21 | #define LAYERDATA_H | ||
22 | |||
23 | typedef struct | ||
24 | { | ||
25 | /* sequence header */ | ||
26 | int intra_quantizer_matrix[64], non_intra_quantizer_matrix[64]; | ||
27 | int chroma_intra_quantizer_matrix[64], chroma_non_intra_quantizer_matrix[64]; | ||
28 | int mpeg2; | ||
29 | int qscale_type, altscan; /* picture coding extension */ | ||
30 | int pict_scal; /* picture spatial scalable extension */ | ||
31 | int scalable_mode; /* sequence scalable extension */ | ||
32 | } mpeg3_layerdata_t; | ||
33 | |||
34 | |||
35 | #endif | ||
diff --git a/core/multimedia/opieplayer/libmpeg3/video/macroblocks.c b/core/multimedia/opieplayer/libmpeg3/video/macroblocks.c new file mode 100644 index 0000000..11e17c1 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/macroblocks.c | |||
@@ -0,0 +1,338 @@ | |||
1 | #include "../libmpeg3.h" | ||
2 | #include "../mpeg3protos.h" | ||
3 | #include "mpeg3video.h" | ||
4 | #include "slice.h" | ||
5 | #include "vlc.h" | ||
6 | |||
7 | #include <stdio.h> | ||
8 | |||
9 | int mpeg3video_get_macroblock_address(mpeg3_slice_t *slice) | ||
10 | { | ||
11 | int code, val = 0; | ||
12 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
13 | |||
14 | while((code = mpeg3slice_showbits(slice_buffer, 11)) < 24) | ||
15 | { | ||
16 | /* Is not macroblock_stuffing */ | ||
17 | if(code != 15) | ||
18 | { | ||
19 | /* Is macroblock_escape */ | ||
20 | if(code == 8) | ||
21 | { | ||
22 | val += 33; | ||
23 | } | ||
24 | else | ||
25 | { | ||
26 | /* fprintf(stderr, "mpeg3video_get_macroblock_address: invalid macroblock_address_increment code\n"); */ | ||
27 | slice->fault = 1; | ||
28 | return 1; | ||
29 | } | ||
30 | } | ||
31 | |||
32 | mpeg3slice_flushbits(slice_buffer, 11); | ||
33 | } | ||
34 | |||
35 | if(code >= 1024) | ||
36 | { | ||
37 | mpeg3slice_flushbit(slice_buffer); | ||
38 | return val + 1; | ||
39 | } | ||
40 | |||
41 | if(code >= 128) | ||
42 | { | ||
43 | code >>= 6; | ||
44 | mpeg3slice_flushbits(slice_buffer, mpeg3_MBAtab1[code].len); | ||
45 | return val + mpeg3_MBAtab1[code].val; | ||
46 | } | ||
47 | |||
48 | code -= 24; | ||
49 | mpeg3slice_flushbits(slice_buffer, mpeg3_MBAtab2[code].len); | ||
50 | |||
51 | return val + mpeg3_MBAtab2[code].val; | ||
52 | } | ||
53 | |||
54 | /* macroblock_type for pictures with spatial scalability */ | ||
55 | |||
56 | static inline int mpeg3video_getsp_imb_type(mpeg3_slice_t *slice) | ||
57 | { | ||
58 | // ### This looks wrong. | ||
59 | // slice_buffer is used without being initialised and slice is not used | ||
60 | //mpeg3_slice_buffer_t *slice_buffer = slice_buffer; | ||
61 | // I think this would make more sense and might be what is intended | ||
62 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
63 | unsigned int code = mpeg3slice_showbits(slice_buffer, 4); | ||
64 | if(!code) | ||
65 | { | ||
66 | /* fprintf(stderr,"mpeg3video_getsp_imb_type: invalid macroblock_type code\n"); */ | ||
67 | slice->fault = 1; | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | mpeg3slice_flushbits(slice_buffer, mpeg3_spIMBtab[code].len); | ||
72 | return mpeg3_spIMBtab[code].val; | ||
73 | } | ||
74 | |||
75 | static inline int mpeg3video_getsp_pmb_type(mpeg3_slice_t *slice) | ||
76 | { | ||
77 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
78 | int code = mpeg3slice_showbits(slice_buffer, 7); | ||
79 | if(code < 2) | ||
80 | { | ||
81 | /* fprintf(stderr,"mpeg3video_getsp_pmb_type: invalid macroblock_type code\n"); */ | ||
82 | slice->fault = 1; | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | if(code >= 16) | ||
87 | { | ||
88 | code >>= 3; | ||
89 | mpeg3slice_flushbits(slice_buffer, mpeg3_spPMBtab0[code].len); | ||
90 | |||
91 | return mpeg3_spPMBtab0[code].val; | ||
92 | } | ||
93 | |||
94 | mpeg3slice_flushbits(slice_buffer, mpeg3_spPMBtab1[code].len); | ||
95 | return mpeg3_spPMBtab1[code].val; | ||
96 | } | ||
97 | |||
98 | static inline int mpeg3video_getsp_bmb_type(mpeg3_slice_t *slice) | ||
99 | { | ||
100 | mpeg3_VLCtab_t *p; | ||
101 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
102 | int code = mpeg3slice_showbits9(slice_buffer); | ||
103 | |||
104 | if(code >= 64) | ||
105 | p = &mpeg3_spBMBtab0[(code >> 5) - 2]; | ||
106 | else | ||
107 | if(code >= 16) | ||
108 | p = &mpeg3_spBMBtab1[(code >> 2) - 4]; | ||
109 | else | ||
110 | if(code >= 8) | ||
111 | p = &mpeg3_spBMBtab2[code - 8]; | ||
112 | else | ||
113 | { | ||
114 | /* fprintf(stderr,"mpeg3video_getsp_bmb_type: invalid macroblock_type code\n"); */ | ||
115 | slice->fault = 1; | ||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | mpeg3slice_flushbits(slice_buffer, p->len); | ||
120 | return p->val; | ||
121 | } | ||
122 | |||
123 | static inline int mpeg3video_get_imb_type(mpeg3_slice_t *slice) | ||
124 | { | ||
125 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
126 | if(mpeg3slice_getbit(slice_buffer)) | ||
127 | { | ||
128 | return 1; | ||
129 | } | ||
130 | |||
131 | if(!mpeg3slice_getbit(slice_buffer)) | ||
132 | { | ||
133 | /* fprintf(stderr,"mpeg3video_get_imb_type: invalid macroblock_type code\n"); */ | ||
134 | slice->fault = 1; | ||
135 | } | ||
136 | |||
137 | return 17; | ||
138 | } | ||
139 | |||
140 | static inline int mpeg3video_get_pmb_type(mpeg3_slice_t *slice) | ||
141 | { | ||
142 | int code; | ||
143 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
144 | |||
145 | if((code = mpeg3slice_showbits(slice_buffer, 6)) >= 8) | ||
146 | { | ||
147 | code >>= 3; | ||
148 | mpeg3slice_flushbits(slice_buffer, mpeg3_PMBtab0[code].len); | ||
149 | return mpeg3_PMBtab0[code].val; | ||
150 | } | ||
151 | |||
152 | if(code == 0) | ||
153 | { | ||
154 | /* fprintf(stderr,"mpeg3video_get_pmb_type: invalid macroblock_type code\n"); */ | ||
155 | slice->fault = 1; | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | mpeg3slice_flushbits(slice_buffer, mpeg3_PMBtab1[code].len); | ||
160 | return mpeg3_PMBtab1[code].val; | ||
161 | } | ||
162 | |||
163 | static inline int mpeg3video_get_bmb_type(mpeg3_slice_t *slice) | ||
164 | { | ||
165 | int code; | ||
166 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
167 | |||
168 | if((code = mpeg3slice_showbits(slice_buffer, 6)) >= 8) | ||
169 | { | ||
170 | code >>= 2; | ||
171 | mpeg3slice_flushbits(slice_buffer, mpeg3_BMBtab0[code].len); | ||
172 | return mpeg3_BMBtab0[code].val; | ||
173 | } | ||
174 | |||
175 | if(code == 0) | ||
176 | { | ||
177 | /* fprintf(stderr,"mpeg3video_get_bmb_type: invalid macroblock_type code\n"); */ | ||
178 | slice->fault = 1; | ||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | mpeg3slice_flushbits(slice_buffer, mpeg3_BMBtab1[code].len); | ||
183 | |||
184 | return mpeg3_BMBtab1[code].val; | ||
185 | } | ||
186 | |||
187 | static inline int mpeg3video_get_dmb_type(mpeg3_slice_t *slice) | ||
188 | { | ||
189 | if(!mpeg3slice_getbit(slice->slice_buffer)) | ||
190 | { | ||
191 | /* fprintf(stderr,"mpeg3video_get_dmb_type: invalid macroblock_type code\n"); */ | ||
192 | slice->fault=1; | ||
193 | } | ||
194 | |||
195 | return 1; | ||
196 | } | ||
197 | |||
198 | |||
199 | static inline int mpeg3video_get_snrmb_type(mpeg3_slice_t *slice) | ||
200 | { | ||
201 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
202 | int code = mpeg3slice_showbits(slice_buffer, 3); | ||
203 | |||
204 | if(code == 0) | ||
205 | { | ||
206 | /* fprintf(stderr,"mpeg3video_get_snrmb_type: invalid macroblock_type code\n"); */ | ||
207 | slice->fault = 1; | ||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | mpeg3slice_flushbits(slice_buffer, mpeg3_SNRMBtab[code].len); | ||
212 | return mpeg3_SNRMBtab[code].val; | ||
213 | } | ||
214 | |||
215 | int mpeg3video_get_mb_type(mpeg3_slice_t *slice, mpeg3video_t *video) | ||
216 | { | ||
217 | if(video->scalable_mode == SC_SNR) | ||
218 | { | ||
219 | return mpeg3video_get_snrmb_type(slice); | ||
220 | } | ||
221 | else | ||
222 | { | ||
223 | switch(video->pict_type) | ||
224 | { | ||
225 | case I_TYPE: return video->pict_scal ? mpeg3video_getsp_imb_type(slice) : mpeg3video_get_imb_type(slice); | ||
226 | case P_TYPE: return video->pict_scal ? mpeg3video_getsp_pmb_type(slice) : mpeg3video_get_pmb_type(slice); | ||
227 | case B_TYPE: return video->pict_scal ? mpeg3video_getsp_bmb_type(slice) : mpeg3video_get_bmb_type(slice); | ||
228 | case D_TYPE: return mpeg3video_get_dmb_type(slice); | ||
229 | default: | ||
230 | /*fprintf(stderr, "mpeg3video_getmbtype: unknown coding type\n"); */ | ||
231 | break; | ||
232 | /* MPEG-1 only, not implemented */ | ||
233 | } | ||
234 | } | ||
235 | |||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | int mpeg3video_macroblock_modes(mpeg3_slice_t *slice, | ||
240 | mpeg3video_t *video, | ||
241 | int *pmb_type, | ||
242 | int *pstwtype, | ||
243 | int *pstwclass, | ||
244 | int *pmotion_type, | ||
245 | int *pmv_count, | ||
246 | int *pmv_format, | ||
247 | int *pdmv, | ||
248 | int *pmvscale, | ||
249 | int *pdct_type) | ||
250 | { | ||
251 | int mb_type; | ||
252 | int stwtype, stwcode, stwclass; | ||
253 | int motion_type = 0, mv_count, mv_format, dmv, mvscale; | ||
254 | int dct_type; | ||
255 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
256 | static unsigned char stwc_table[3][4] | ||
257 | = { {6,3,7,4}, {2,1,5,4}, {2,5,7,4} }; | ||
258 | static unsigned char stwclass_table[9] | ||
259 | = {0, 1, 2, 1, 1, 2, 3, 3, 4}; | ||
260 | |||
261 | /* get macroblock_type */ | ||
262 | mb_type = mpeg3video_get_mb_type(slice, video); | ||
263 | |||
264 | if(slice->fault) return 1; | ||
265 | |||
266 | /* get spatial_temporal_weight_code */ | ||
267 | if(mb_type & MB_WEIGHT) | ||
268 | { | ||
269 | if(video->stwc_table_index == 0) | ||
270 | stwtype = 4; | ||
271 | else | ||
272 | { | ||
273 | stwcode = mpeg3slice_getbits2(slice_buffer); | ||
274 | stwtype = stwc_table[video->stwc_table_index - 1][stwcode]; | ||
275 | } | ||
276 | } | ||
277 | else | ||
278 | stwtype = (mb_type & MB_CLASS4) ? 8 : 0; | ||
279 | |||
280 | /* derive spatial_temporal_weight_class (Table 7-18) */ | ||
281 | stwclass = stwclass_table[stwtype]; | ||
282 | |||
283 | /* get frame/field motion type */ | ||
284 | if(mb_type & (MB_FORWARD | MB_BACKWARD)) | ||
285 | { | ||
286 | if(video->pict_struct == FRAME_PICTURE) | ||
287 | { | ||
288 | /* frame_motion_type */ | ||
289 | motion_type = video->frame_pred_dct ? MC_FRAME : mpeg3slice_getbits2(slice_buffer); | ||
290 | } | ||
291 | else | ||
292 | { | ||
293 | /* field_motion_type */ | ||
294 | motion_type = mpeg3slice_getbits2(slice_buffer); | ||
295 | } | ||
296 | } | ||
297 | else | ||
298 | if((mb_type & MB_INTRA) && video->conceal_mv) | ||
299 | { | ||
300 | /* concealment motion vectors */ | ||
301 | motion_type = (video->pict_struct == FRAME_PICTURE) ? MC_FRAME : MC_FIELD; | ||
302 | } | ||
303 | |||
304 | /* derive mv_count, mv_format and dmv, (table 6-17, 6-18) */ | ||
305 | if(video->pict_struct == FRAME_PICTURE) | ||
306 | { | ||
307 | mv_count = (motion_type == MC_FIELD && stwclass < 2) ? 2 : 1; | ||
308 | mv_format = (motion_type == MC_FRAME) ? MV_FRAME : MV_FIELD; | ||
309 | } | ||
310 | else | ||
311 | { | ||
312 | mv_count = (motion_type == MC_16X8) ? 2 : 1; | ||
313 | mv_format = MV_FIELD; | ||
314 | } | ||
315 | |||
316 | dmv = (motion_type == MC_DMV); /* dual prime */ | ||
317 | |||
318 | /* field mv predictions in frame pictures have to be scaled */ | ||
319 | mvscale = ((mv_format == MV_FIELD) && (video->pict_struct == FRAME_PICTURE)); | ||
320 | |||
321 | /* get dct_type (frame DCT / field DCT) */ | ||
322 | dct_type = (video->pict_struct == FRAME_PICTURE) && | ||
323 | (!video->frame_pred_dct) && | ||
324 | (mb_type & (MB_PATTERN | MB_INTRA)) ? | ||
325 | mpeg3slice_getbit(slice_buffer) : 0; | ||
326 | |||
327 | /* return values */ | ||
328 | *pmb_type = mb_type; | ||
329 | *pstwtype = stwtype; | ||
330 | *pstwclass = stwclass; | ||
331 | *pmotion_type = motion_type; | ||
332 | *pmv_count = mv_count; | ||
333 | *pmv_format = mv_format; | ||
334 | *pdmv = dmv; | ||
335 | *pmvscale = mvscale; | ||
336 | *pdct_type = dct_type; | ||
337 | return 0; | ||
338 | } | ||
diff --git a/core/multimedia/opieplayer/libmpeg3/video/mmxidct.S b/core/multimedia/opieplayer/libmpeg3/video/mmxidct.S new file mode 100644 index 0000000..9c3bebe --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/mmxidct.S | |||
@@ -0,0 +1,675 @@ | |||
1 | /* | ||
2 | * the input data is tranposed and each 16 bit element in the 8x8 matrix | ||
3 | * is left aligned: | ||
4 | * for example in 11...1110000 format | ||
5 | * If the iDCT is of I macroblock then 0.5 needs to be added to the;DC Component | ||
6 | * (element[0][0] of the matrix) | ||
7 | */ | ||
8 | |||
9 | /* extrn re_matrix */ | ||
10 | |||
11 | /* constants */ | ||
12 | |||
13 | .data | ||
14 | .align 16 | ||
15 | .type preSC, @object | ||
16 | preSC: .short 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520 | ||
17 | .short 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270 | ||
18 | .short 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906 | ||
19 | .short 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315 | ||
20 | .short 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520 | ||
21 | .short 12873, 17855, 16819, 15137, 25746, 20228, 13933, 7103 | ||
22 | .short 17734, 24598, 23170, 20853, 17734, 13933, 9597, 4892 | ||
23 | .short 18081, 25080, 23624, 21261, 18081, 14206, 9785, 4988 | ||
24 | .sizepreSC, 128 | ||
25 | .align 8 | ||
26 | .typex0005000200010001, @object | ||
27 | .sizex0005000200010001, 8 | ||
28 | x0005000200010001: | ||
29 | .long0x00010001, 0x00050002 | ||
30 | .align 8 | ||
31 | .typex0040000000000000, @object | ||
32 | .sizex0040000000000000, 8 | ||
33 | x0040000000000000: | ||
34 | .long0, 0x00400000 | ||
35 | .align 8 | ||
36 | .typex5a825a825a825a82, @object | ||
37 | .sizex5a825a825a825a82, 8 | ||
38 | x5a825a825a825a82: | ||
39 | .long0x5a825a82, 0x5a825a82 | ||
40 | .align 8 | ||
41 | .typex539f539f539f539f, @object | ||
42 | .sizex539f539f539f539f, 8 | ||
43 | x539f539f539f539f: | ||
44 | .long0x539f539f, 0x539f539f | ||
45 | .align 8 | ||
46 | .typex4546454645464546, @object | ||
47 | .sizex4546454645464546, 8 | ||
48 | x4546454645464546: | ||
49 | .long0x45464546, 0x45464546 | ||
50 | .align 8 | ||
51 | .typex61f861f861f861f8, @object | ||
52 | .sizex61f861f861f861f8, 8 | ||
53 | x61f861f861f861f8: | ||
54 | .long0x61f861f8, 0x61f861f8 | ||
55 | /* Static variables */ | ||
56 | .align 8 | ||
57 | .type x0, @object | ||
58 | .size x0, 8 | ||
59 | x0: | ||
60 | .long 0, 0 | ||
61 | /* Procedure */ | ||
62 | |||
63 | |||
64 | .align 8 | ||
65 | .text | ||
66 | .align 4 | ||
67 | .globl IDCT_mmx | ||
68 | .type IDCT_mmx, @function | ||
69 | IDCT_mmx: | ||
70 | pushl %ebp | ||
71 | movl %esp, %ebp | ||
72 | pushl %ebx | ||
73 | pushl %ecx | ||
74 | pushl %edx | ||
75 | pushl %esi | ||
76 | pushl %edi | ||
77 | |||
78 | pushl $0 /* allocate the temp variables */ | ||
79 | pushl $0 | ||
80 | pushl $0 | ||
81 | pushl $0 | ||
82 | pushl $0 | ||
83 | pushl $0 | ||
84 | pushl $0 | ||
85 | pushl $0 | ||
86 | |||
87 | movl 8(%ebp), %esi /* source matrix */ | ||
88 | leal preSC, %ecx | ||
89 | /* column 0: even part | ||
90 | * use V4, V12, V0, V8 to produce V22..V25 | ||
91 | */ | ||
92 | movq 8*12(%ecx), %mm0 /* maybe the first mul can be done together */ | ||
93 | /* with the dequantization in iHuff module */ | ||
94 | pmulhw 8*12(%esi), %mm0 /* V12 */ | ||
95 | movq 8*4(%ecx), %mm1 | ||
96 | pmulhw 8*4(%esi), %mm1 /* V4 */ | ||
97 | movq (%ecx), %mm3 | ||
98 | psraw $1, %mm0 /* t64=t66 */ | ||
99 | pmulhw (%esi), %mm3 /* V0 */ | ||
100 | movq 8*8(%ecx), %mm5 /* duplicate V4 */ | ||
101 | movq %mm1, %mm2 /* added 11/1/96 */ | ||
102 | pmulhw 8*8(%esi),%mm5 /* V8 */ | ||
103 | psubsw %mm0, %mm1 /* V16 */ | ||
104 | pmulhw x5a825a825a825a82, %mm1/* 23170 ->V18 */ | ||
105 | paddsw %mm0, %mm2 /* V17 */ | ||
106 | movq %mm2, %mm0 /* duplicate V17 */ | ||
107 | psraw $1, %mm2 /* t75=t82 */ | ||
108 | psraw $2, %mm0 /* t72 */ | ||
109 | movq %mm3, %mm4 /* duplicate V0 */ | ||
110 | paddsw %mm5, %mm3 /* V19 */ | ||
111 | psubsw %mm5, %mm4 /* V20 ;mm5 free */ | ||
112 | /* moved from the block below */ | ||
113 | movq 8*10(%ecx), %mm7 | ||
114 | psraw $1, %mm3 /* t74=t81 */ | ||
115 | movq %mm3, %mm6 /* duplicate t74=t81 */ | ||
116 | psraw $2, %mm4 /* t77=t79 */ | ||
117 | psubsw %mm0, %mm1 /* V21 ; mm0 free */ | ||
118 | paddsw %mm2, %mm3 /* V22 */ | ||
119 | movq %mm1, %mm5 /* duplicate V21 */ | ||
120 | paddsw %mm4, %mm1 /* V23 */ | ||
121 | movq %mm3, 8*4(%esi) /* V22 */ | ||
122 | psubsw %mm5, %mm4 /* V24; mm5 free */ | ||
123 | movq %mm1, 8*12(%esi) /* V23 */ | ||
124 | psubsw %mm2, %mm6 /* V25; mm2 free */ | ||
125 | movq %mm4, (%esi) /* V24 */ | ||
126 | /* keep mm6 alive all along the next block */ | ||
127 | /* movq %mm6, 8*8(%esi) V25 */ | ||
128 | /* column 0: odd part | ||
129 | * use V2, V6, V10, V14 to produce V31, V39, V40, V41 | ||
130 | */ | ||
131 | /* moved above: movq 8*10(%ecx), %mm7 */ | ||
132 | |||
133 | pmulhw 8*10(%esi), %mm7 /* V10 */ | ||
134 | movq 8*6(%ecx), %mm0 | ||
135 | pmulhw 8*6(%esi), %mm0 /* V6 */ | ||
136 | movq 8*2(%ecx), %mm5 | ||
137 | movq %mm7, %mm3 /* duplicate V10 */ | ||
138 | pmulhw 8*2(%esi), %mm5 /* V2 */ | ||
139 | movq 8*14(%ecx), %mm4 | ||
140 | psubsw %mm0, %mm7 /* V26 */ | ||
141 | pmulhw 8*14(%esi), %mm4 /* V14 */ | ||
142 | paddsw %mm0, %mm3 /* V29 ; free mm0 */ | ||
143 | movq %mm7, %mm1 /* duplicate V26 */ | ||
144 | psraw $1, %mm3 /* t91=t94 */ | ||
145 | pmulhw x539f539f539f539f,%mm7/* V33 */ | ||
146 | psraw $1, %mm1 /* t96 */ | ||
147 | movq %mm5, %mm0 /* duplicate V2 */ | ||
148 | psraw $2, %mm4 /* t85=t87 */ | ||
149 | paddsw %mm4,%mm5 /* V27 */ | ||
150 | psubsw %mm4, %mm0 /* V28 ; free mm4 */ | ||
151 | movq %mm0, %mm2 /* duplicate V28 */ | ||
152 | psraw $1, %mm5 /* t90=t93 */ | ||
153 | pmulhw x4546454645464546,%mm0/* V35 */ | ||
154 | psraw $1, %mm2 /* t97 */ | ||
155 | movq %mm5, %mm4 /* duplicate t90=t93 */ | ||
156 | psubsw %mm2, %mm1 /* V32 ; free mm2 */ | ||
157 | pmulhw x61f861f861f861f8,%mm1/* V36 */ | ||
158 | psllw $1, %mm7 /* t107 */ | ||
159 | paddsw %mm3, %mm5 /* V31 */ | ||
160 | psubsw %mm3, %mm4 /* V30 ; free mm3 */ | ||
161 | pmulhw x5a825a825a825a82,%mm4/* V34 */ | ||
162 | nop | ||
163 | psubsw %mm1, %mm0 /* V38 */ | ||
164 | psubsw %mm7, %mm1 /* V37 ; free mm7 */ | ||
165 | psllw $1, %mm1 /* t114 */ | ||
166 | /* move from the next block */ | ||
167 | movq %mm6, %mm3 /* duplicate V25 */ | ||
168 | /* move from the next block */ | ||
169 | movq 8*4(%esi), %mm7 /* V22 */ | ||
170 | psllw $1, %mm0 /* t110 */ | ||
171 | psubsw %mm5, %mm0 /* V39 (mm5 needed for next block) */ | ||
172 | psllw $2, %mm4 /* t112 */ | ||
173 | /* moved from the next block */ | ||
174 | movq 8*12(%esi), %mm2 /* V23 */ | ||
175 | psubsw %mm0, %mm4 /* V40 */ | ||
176 | paddsw %mm4, %mm1 /* V41; free mm0 */ | ||
177 | /* moved from the next block */ | ||
178 | psllw $1, %mm2 /* t117=t125 */ | ||
179 | /* column 0: output butterfly */ | ||
180 | /* moved above: | ||
181 | * movq %mm6, %mm3 duplicate V25 | ||
182 | * movq 8*4(%esi), %mm7 V22 | ||
183 | * movq 8*12(%esi), %mm2 V23 | ||
184 | * psllw $1, %mm2 t117=t125 | ||
185 | */ | ||
186 | psubsw %mm1, %mm6 /* tm6 */ | ||
187 | paddsw %mm1, %mm3 /* tm8; free mm1 */ | ||
188 | movq %mm7, %mm1 /* duplicate V22 */ | ||
189 | paddsw %mm5, %mm7 /* tm0 */ | ||
190 | movq %mm3, 8*8(%esi) /* tm8; free mm3 */ | ||
191 | psubsw %mm5, %mm1 /* tm14; free mm5 */ | ||
192 | movq %mm6, 8*6(%esi) /* tm6; free mm6 */ | ||
193 | movq %mm2, %mm3 /* duplicate t117=t125 */ | ||
194 | movq (%esi), %mm6 /* V24 */ | ||
195 | paddsw %mm0, %mm2 /* tm2 */ | ||
196 | movq %mm7, (%esi) /* tm0; free mm7 */ | ||
197 | psubsw %mm0, %mm3 /* tm12; free mm0 */ | ||
198 | movq %mm1, 8*14(%esi) /* tm14; free mm1 */ | ||
199 | psllw $1, %mm6 /* t119=t123 */ | ||
200 | movq %mm2, 8*2(%esi) /* tm2; free mm2 */ | ||
201 | movq %mm6, %mm0 /* duplicate t119=t123 */ | ||
202 | movq %mm3, 8*12(%esi) /* tm12; free mm3 */ | ||
203 | paddsw %mm4, %mm6 /* tm4 */ | ||
204 | /* moved from next block */ | ||
205 | movq 8*5(%ecx), %mm1 | ||
206 | psubsw %mm4, %mm0 /* tm10; free mm4 */ | ||
207 | /* moved from next block */ | ||
208 | pmulhw 8*5(%esi), %mm1 /* V5 */ | ||
209 | movq %mm6, 8*4(%esi) /* tm4; free mm6 */ | ||
210 | movq %mm0, 8*10(%esi) /* tm10; free mm0 */ | ||
211 | /* column 1: even part | ||
212 | * use V5, V13, V1, V9 to produce V56..V59 | ||
213 | */ | ||
214 | /* moved to prev block: | ||
215 | *movq 8*5(%ecx), %mm1 | ||
216 | * pmulhw 8*5(%esi), %mm1 V5 | ||
217 | */ | ||
218 | movq 8*13(%ecx), %mm7 | ||
219 | psllw $1, %mm1 /* t128=t130 */ | ||
220 | pmulhw 8*13(%esi), %mm7 /* V13 */ | ||
221 | movq %mm1, %mm2 /* duplicate t128=t130 */ | ||
222 | movq 8(%ecx), %mm3 | ||
223 | pmulhw 8(%esi), %mm3 /* V1 */ | ||
224 | movq 8*9(%ecx), %mm5 | ||
225 | psubsw %mm7, %mm1 /* V50 */ | ||
226 | pmulhw 8*9(%esi), %mm5 /* V9 */ | ||
227 | paddsw %mm7, %mm2 /* V51 */ | ||
228 | pmulhw x5a825a825a825a82, %mm1/* 23170 ->V52 */ | ||
229 | movq %mm2, %mm6 /* duplicate V51 */ | ||
230 | psraw $1, %mm2 /* t138=t144 */ | ||
231 | movq %mm3, %mm4 /* duplicate V1 */ | ||
232 | psraw $2, %mm6 /* t136 */ | ||
233 | paddsw %mm5, %mm3 /* V53 */ | ||
234 | psubsw %mm5, %mm4 /* V54 ;mm5 free */ | ||
235 | movq %mm3, %mm7 /* duplicate V53 */ | ||
236 | /* moved from next block */ | ||
237 | movq 8*11(%ecx), %mm0 | ||
238 | psraw $1, %mm4 /* t140=t142 */ | ||
239 | psubsw %mm6, %mm1 /* V55 ; mm6 free */ | ||
240 | paddsw %mm2, %mm3 /* V56 */ | ||
241 | movq %mm4, %mm5 /* duplicate t140=t142 */ | ||
242 | paddsw %mm1, %mm4 /* V57 */ | ||
243 | movq %mm3, 8*5(%esi) /* V56 */ | ||
244 | psubsw %mm1, %mm5 /* V58; mm1 free */ | ||
245 | movq %mm4, 8*13(%esi) /* V57 */ | ||
246 | psubsw %mm2, %mm7 /* V59; mm2 free */ | ||
247 | movq %mm5, 8*9(%esi) /* V58 */ | ||
248 | /* keep mm7 alive all along the next block | ||
249 | * movq %mm7, 8(%esi) V59 | ||
250 | * moved above | ||
251 | *movq 8*11(%ecx), %mm0 | ||
252 | */ | ||
253 | pmulhw 8*11(%esi), %mm0 /* V11 */ | ||
254 | movq 8*7(%ecx), %mm6 | ||
255 | pmulhw 8*7(%esi), %mm6 /* V7 */ | ||
256 | movq 8*15(%ecx), %mm4 | ||
257 | movq %mm0, %mm3 /* duplicate V11 */ | ||
258 | pmulhw 8*15(%esi), %mm4 /* V15 */ | ||
259 | movq 8*3(%ecx), %mm5 | ||
260 | psllw $1, %mm6 /* t146=t152 */ | ||
261 | pmulhw 8*3(%esi), %mm5 /* V3 */ | ||
262 | paddsw %mm6, %mm0 /* V63 */ | ||
263 | /* note that V15 computation has a correction step: | ||
264 | * this is a 'magic' constant that rebiases the results to be closer to the | ||
265 | * expected result. this magic constant can be refined to reduce the error | ||
266 | * even more by doing the correction step in a later stage when the number | ||
267 | * is actually multiplied by 16 | ||
268 | */ | ||
269 | paddw x0005000200010001, %mm4 | ||
270 | psubsw %mm6, %mm3 /* V60 ; free mm6 */ | ||
271 | psraw $1, %mm0 /* t154=t156 */ | ||
272 | movq %mm3, %mm1 /* duplicate V60 */ | ||
273 | pmulhw x539f539f539f539f, %mm1/* V67 */ | ||
274 | movq %mm5, %mm6 /* duplicate V3 */ | ||
275 | psraw $2, %mm4 /* t148=t150 */ | ||
276 | paddsw %mm4, %mm5 /* V61 */ | ||
277 | psubsw %mm4, %mm6 /* V62 ; free mm4 */ | ||
278 | movq %mm5, %mm4 /* duplicate V61 */ | ||
279 | psllw $1, %mm1 /* t169 */ | ||
280 | paddsw %mm0, %mm5 /* V65 -> result */ | ||
281 | psubsw %mm0, %mm4 /* V64 ; free mm0 */ | ||
282 | pmulhw x5a825a825a825a82, %mm4/* V68 */ | ||
283 | psraw $1, %mm3 /* t158 */ | ||
284 | psubsw %mm6, %mm3 /* V66 */ | ||
285 | movq %mm5, %mm2 /* duplicate V65 */ | ||
286 | pmulhw x61f861f861f861f8, %mm3/* V70 */ | ||
287 | psllw $1, %mm6 /* t165 */ | ||
288 | pmulhw x4546454645464546, %mm6/* V69 */ | ||
289 | psraw $1, %mm2 /* t172 */ | ||
290 | /* moved from next block */ | ||
291 | movq 8*5(%esi), %mm0 /* V56 */ | ||
292 | psllw $1, %mm4 /* t174 */ | ||
293 | /* moved from next block */ | ||
294 | psraw $1, %mm0 /* t177=t188 */ | ||
295 | nop | ||
296 | psubsw %mm3, %mm6 /* V72 */ | ||
297 | psubsw %mm1, %mm3 /* V71 ; free mm1 */ | ||
298 | psubsw %mm2, %mm6 /* V73 ; free mm2 */ | ||
299 | /* moved from next block */ | ||
300 | psraw $1, %mm5 /* t178=t189 */ | ||
301 | psubsw %mm6, %mm4 /* V74 */ | ||
302 | /* moved from next block */ | ||
303 | movq %mm0, %mm1 /* duplicate t177=t188 */ | ||
304 | paddsw %mm4, %mm3 /* V75 */ | ||
305 | /* moved from next block */ | ||
306 | paddsw %mm5, %mm0 /* tm1 */ | ||
307 | /* location | ||
308 | * 5 - V56 | ||
309 | * 13 - V57 | ||
310 | * 9 - V58 | ||
311 | * X - V59, mm7 | ||
312 | * X - V65, mm5 | ||
313 | * X - V73, mm6 | ||
314 | * X - V74, mm4 | ||
315 | * X - V75, mm3 | ||
316 | * free mm0, mm1 & mm2 | ||
317 | * moved above | ||
318 | * movq 8*5(%esi), %mm0 V56 | ||
319 | * psllw $1, %mm0 t177=t188 ! new !! | ||
320 | * psllw $1, %mm5 t178=t189 ! new !! | ||
321 | * movq %mm0, %mm1 duplicate t177=t188 | ||
322 | * paddsw %mm5, %mm0 tm1 | ||
323 | */ | ||
324 | movq 8*13(%esi), %mm2 /* V57 */ | ||
325 | psubsw %mm5, %mm1 /* tm15; free mm5 */ | ||
326 | movq %mm0, 8(%esi) /* tm1; free mm0 */ | ||
327 | psraw $1, %mm7 /* t182=t184 ! new !! */ | ||
328 | /* save the store as used directly in the transpose | ||
329 | * movq %mm1, 120(%esi) tm15; free mm1 | ||
330 | */ | ||
331 | movq %mm7, %mm5 /* duplicate t182=t184 */ | ||
332 | psubsw %mm3, %mm7 /* tm7 */ | ||
333 | paddsw %mm3, %mm5 /* tm9; free mm3 */ | ||
334 | movq 8*9(%esi), %mm0 /* V58 */ | ||
335 | movq %mm2, %mm3 /* duplicate V57 */ | ||
336 | movq %mm7, 8*7(%esi) /* tm7; free mm7 */ | ||
337 | psubsw %mm6, %mm3 /* tm13 */ | ||
338 | paddsw %mm6, %mm2 /* tm3 ; free mm6 */ | ||
339 | /* moved up from the transpose */ | ||
340 | movq %mm3, %mm7 | ||
341 | /* moved up from the transpose */ | ||
342 | punpcklwd %mm1, %mm3 | ||
343 | movq %mm0, %mm6 /* duplicate V58 */ | ||
344 | movq %mm2, 8*3(%esi) /* tm3; free mm2 */ | ||
345 | paddsw %mm4, %mm0 /* tm5 */ | ||
346 | psubsw %mm4, %mm6 /* tm11; free mm4 */ | ||
347 | /* moved up from the transpose */ | ||
348 | punpckhwd %mm1, %mm7 | ||
349 | movq %mm0, 8*5(%esi) /* tm5; free mm0 */ | ||
350 | /* moved up from the transpose */ | ||
351 | movq %mm5, %mm2 | ||
352 | /* transpose - M4 part | ||
353 | * --------- --------- | ||
354 | * | M1 | M2 | | M1'| M3'| | ||
355 | * --------- --> --------- | ||
356 | * | M3 | M4 | | M2'| M4'| | ||
357 | * --------- --------- | ||
358 | * Two alternatives: use full mmword approach so the following code can be | ||
359 | * scheduled before the transpose is done without stores, or use the faster | ||
360 | * half mmword stores (when possible) | ||
361 | */ | ||
362 | movd %mm3, 8*9+4(%esi) /* MS part of tmt9 */ | ||
363 | punpcklwd %mm6, %mm5 | ||
364 | movd %mm7, 8*13+4(%esi) /* MS part of tmt13 */ | ||
365 | punpckhwd %mm6, %mm2 | ||
366 | movd %mm5, 8*9(%esi) /* LS part of tmt9 */ | ||
367 | punpckhdq %mm3, %mm5 /* free mm3 */ | ||
368 | movd %mm2, 8*13(%esi) /* LS part of tmt13 */ | ||
369 | punpckhdq %mm7, %mm2 /* free mm7 */ | ||
370 | /* moved up from the M3 transpose */ | ||
371 | movq 8*8(%esi), %mm0 | ||
372 | /* moved up from the M3 transpose */ | ||
373 | movq 8*10(%esi), %mm1 | ||
374 | /* moved up from the M3 transpose */ | ||
375 | movq %mm0, %mm3 | ||
376 | /* shuffle the rest of the data, and write it with 2 mmword writes */ | ||
377 | movq %mm5, 8*11(%esi) /* tmt11 */ | ||
378 | /* moved up from the M3 transpose */ | ||
379 | punpcklwd %mm1, %mm0 | ||
380 | movq %mm2, 8*15(%esi) /* tmt15 */ | ||
381 | /* moved up from the M3 transpose */ | ||
382 | punpckhwd %mm1, %mm3 | ||
383 | /* transpose - M3 part | ||
384 | * moved up to previous code section | ||
385 | *movq 8*8(%esi), %mm0 | ||
386 | *movq 8*10(%esi), %mm1 | ||
387 | *movq %mm0, %mm3 | ||
388 | *punpcklwd %mm1, %mm0 | ||
389 | *punpckhwd %mm1, %mm3 | ||
390 | */ | ||
391 | movq 8*12(%esi), %mm6 | ||
392 | movq 8*14(%esi), %mm4 | ||
393 | movq %mm6, %mm2 | ||
394 | /* shuffle the data and write the lower parts of the transposed in 4 dwords */ | ||
395 | punpcklwd %mm4, %mm6 | ||
396 | movq %mm0, %mm1 | ||
397 | punpckhdq %mm6, %mm1 | ||
398 | movq %mm3, %mm7 | ||
399 | punpckhwd %mm4, %mm2 /* free mm4 */ | ||
400 | punpckldq %mm6, %mm0 /* free mm6 */ | ||
401 | /* moved from next block */ | ||
402 | movq 8*13(%esi), %mm4 /* tmt13 */ | ||
403 | punpckldq %mm2, %mm3 | ||
404 | punpckhdq %mm2, %mm7 /* free mm2 */ | ||
405 | /* moved from next block */ | ||
406 | movq %mm3, %mm5 /* duplicate tmt5 */ | ||
407 | /* column 1: even part (after transpose) | ||
408 | * moved above | ||
409 | * movq %mm3, %mm5 duplicate tmt5 | ||
410 | * movq 8*13(%esi), %mm4 tmt13 | ||
411 | */ | ||
412 | psubsw %mm4, %mm3 /* V134 */ | ||
413 | pmulhw x5a825a825a825a82, %mm3/* 23170 ->V136 */ | ||
414 | movq 8*9(%esi), %mm6 /* tmt9 */ | ||
415 | paddsw %mm4, %mm5 /* V135 ; mm4 free */ | ||
416 | movq %mm0, %mm4 /* duplicate tmt1 */ | ||
417 | paddsw %mm6, %mm0 /* V137 */ | ||
418 | psubsw %mm6, %mm4 /* V138 ; mm6 free */ | ||
419 | psllw $2, %mm3 /* t290 */ | ||
420 | psubsw %mm5, %mm3 /* V139 */ | ||
421 | movq %mm0, %mm6 /* duplicate V137 */ | ||
422 | paddsw %mm5, %mm0 /* V140 */ | ||
423 | movq %mm4, %mm2 /* duplicate V138 */ | ||
424 | paddsw %mm3, %mm2 /* V141 */ | ||
425 | psubsw %mm3, %mm4 /* V142 ; mm3 free */ | ||
426 | movq %mm0, 8*9(%esi) /* V140 */ | ||
427 | psubsw %mm5, %mm6 /* V143 ; mm5 free */ | ||
428 | /* moved from next block */ | ||
429 | movq 8*11(%esi), %mm0 /* tmt11 */ | ||
430 | movq %mm2, 8*13(%esi) /* V141 */ | ||
431 | /* moved from next block */ | ||
432 | movq %mm0, %mm2 /* duplicate tmt11 */ | ||
433 | /* column 1: odd part (after transpose) */ | ||
434 | /* moved up to the prev block | ||
435 | * movq 8*11(%esi), %mm0 tmt11 | ||
436 | * movq %mm0, %mm2 duplicate tmt11 | ||
437 | */ | ||
438 | movq 8*15(%esi), %mm5 /* tmt15 */ | ||
439 | psubsw %mm7, %mm0 /* V144 */ | ||
440 | movq %mm0, %mm3 /* duplicate V144 */ | ||
441 | paddsw %mm7, %mm2 /* V147 ; free mm7 */ | ||
442 | pmulhw x539f539f539f539f, %mm0/* 21407-> V151 */ | ||
443 | movq %mm1, %mm7 /* duplicate tmt3 */ | ||
444 | paddsw %mm5, %mm7 /* V145 */ | ||
445 | psubsw %mm5, %mm1 /* V146 ; free mm5 */ | ||
446 | psubsw %mm1, %mm3 /* V150 */ | ||
447 | movq %mm7, %mm5 /* duplicate V145 */ | ||
448 | pmulhw x4546454645464546, %mm1/* 17734-> V153 */ | ||
449 | psubsw %mm2, %mm5 /* V148 */ | ||
450 | pmulhw x61f861f861f861f8, %mm3/* 25080-> V154 */ | ||
451 | psllw $2, %mm0 /* t311 */ | ||
452 | pmulhw x5a825a825a825a82, %mm5/* 23170-> V152 */ | ||
453 | paddsw %mm2, %mm7 /* V149 ; free mm2 */ | ||
454 | psllw $1, %mm1 /* t313 */ | ||
455 | nop/* without the nop - freeze here for one clock */ | ||
456 | movq %mm3, %mm2 /* duplicate V154 */ | ||
457 | psubsw %mm0, %mm3 /* V155 ; free mm0 */ | ||
458 | psubsw %mm2, %mm1 /* V156 ; free mm2 */ | ||
459 | /* moved from the next block */ | ||
460 | movq %mm6, %mm2 /* duplicate V143 */ | ||
461 | /* moved from the next block */ | ||
462 | movq 8*13(%esi), %mm0 /* V141 */ | ||
463 | psllw $1, %mm1 /* t315 */ | ||
464 | psubsw %mm7, %mm1 /* V157 (keep V149) */ | ||
465 | psllw $2, %mm5 /* t317 */ | ||
466 | psubsw %mm1, %mm5 /* V158 */ | ||
467 | psllw $1, %mm3 /* t319 */ | ||
468 | paddsw %mm5, %mm3 /* V159 */ | ||
469 | /* column 1: output butterfly (after transform) | ||
470 | * moved to the prev block | ||
471 | * movq %mm6, %mm2 duplicate V143 | ||
472 | * movq 8*13(%esi), %mm0 V141 | ||
473 | */ | ||
474 | psubsw %mm3, %mm2 /* V163 */ | ||
475 | paddsw %mm3, %mm6 /* V164 ; free mm3 */ | ||
476 | movq %mm4, %mm3 /* duplicate V142 */ | ||
477 | psubsw %mm5, %mm4 /* V165 ; free mm5 */ | ||
478 | movq %mm2, (%esp) /* out7 */ | ||
479 | psraw $4, %mm6 | ||
480 | psraw $4, %mm4 | ||
481 | paddsw %mm5, %mm3 /* V162 */ | ||
482 | movq 8*9(%esi), %mm2 /* V140 */ | ||
483 | movq %mm0, %mm5 /* duplicate V141 */ | ||
484 | /* in order not to perculate this line up, | ||
485 | * we read 72(%esi) very near to this location | ||
486 | */ | ||
487 | movq %mm6, 8*9(%esi) /* out9 */ | ||
488 | paddsw %mm1, %mm0 /* V161 */ | ||
489 | movq %mm3, 8(%esp) /* out5 */ | ||
490 | psubsw %mm1, %mm5 /* V166 ; free mm1 */ | ||
491 | movq %mm4, 8*11(%esi) /* out11 */ | ||
492 | psraw $4, %mm5 | ||
493 | movq %mm0, 16(%esp) /* out3 */ | ||
494 | movq %mm2, %mm4 /* duplicate V140 */ | ||
495 | movq %mm5, 8*13(%esi) /* out13 */ | ||
496 | paddsw %mm7, %mm2 /* V160 */ | ||
497 | /* moved from the next block */ | ||
498 | movq 8(%esi), %mm0 | ||
499 | psubsw %mm7, %mm4 /* V167 ; free mm7 */ | ||
500 | /* moved from the next block */ | ||
501 | movq 8*3(%esi), %mm7 | ||
502 | psraw $4, %mm4 | ||
503 | movq %mm2, 24(%esp) /* out1 */ | ||
504 | /* moved from the next block */ | ||
505 | movq %mm0, %mm1 | ||
506 | movq %mm4, 8*15(%esi) /* out15 */ | ||
507 | /* moved from the next block */ | ||
508 | punpcklwd %mm7, %mm0 | ||
509 | /* transpose - M2 parts | ||
510 | * moved up to the prev block | ||
511 | *movq 8(%esi), %mm0 | ||
512 | *movq 8*3(%esi), %mm7 | ||
513 | *movq %mm0, %mm1 | ||
514 | *punpcklwd %mm7, %mm0 | ||
515 | */ | ||
516 | movq 8*5(%esi), %mm5 | ||
517 | punpckhwd %mm7, %mm1 | ||
518 | movq 8*7(%esi), %mm4 | ||
519 | movq %mm5, %mm3 | ||
520 | /* shuffle the data and write the lower parts of the trasposed in 4 dwords */ | ||
521 | movd %mm0, 8*8(%esi) /* LS part of tmt8 */ | ||
522 | punpcklwd %mm4, %mm5 | ||
523 | movd %mm1, 8*12(%esi) /* LS part of tmt12 */ | ||
524 | punpckhwd %mm4, %mm3 | ||
525 | movd %mm5, 8*8+4(%esi) /* MS part of tmt8 */ | ||
526 | punpckhdq %mm5, %mm0 /* tmt10 */ | ||
527 | movd %mm3, 8*12+4(%esi) /* MS part of tmt12 */ | ||
528 | punpckhdq %mm3, %mm1 /* tmt14 */ | ||
529 | /* transpose - M1 parts */ | ||
530 | movq (%esi), %mm7 | ||
531 | movq 8*2(%esi), %mm2 | ||
532 | movq %mm7, %mm6 | ||
533 | movq 8*4(%esi), %mm5 | ||
534 | punpcklwd %mm2, %mm7 | ||
535 | movq 8*6(%esi), %mm4 | ||
536 | punpckhwd %mm2, %mm6 /* free mm2 */ | ||
537 | movq %mm5, %mm3 | ||
538 | punpcklwd %mm4, %mm5 | ||
539 | punpckhwd %mm4, %mm3 /* free mm4 */ | ||
540 | movq %mm7, %mm2 | ||
541 | movq %mm6, %mm4 | ||
542 | punpckldq %mm5, %mm7 /* tmt0 */ | ||
543 | punpckhdq %mm5, %mm2 /* tmt2 ; free mm5 */ | ||
544 | /* shuffle the rest of the data, and write it with 2 mmword writes */ | ||
545 | punpckldq %mm3, %mm6 /* tmt4 */ | ||
546 | /* moved from next block */ | ||
547 | movq %mm2, %mm5 /* duplicate tmt2 */ | ||
548 | punpckhdq %mm3, %mm4 /* tmt6 ; free mm3 */ | ||
549 | /* moved from next block */ | ||
550 | movq %mm0, %mm3 /* duplicate tmt10 */ | ||
551 | /* column 0: odd part (after transpose) | ||
552 | *moved up to prev block | ||
553 | * movq %mm0, %mm3 duplicate tmt10 | ||
554 | * movq %mm2, %mm5 duplicate tmt2 | ||
555 | */ | ||
556 | psubsw %mm4, %mm0 /* V110 */ | ||
557 | paddsw %mm4, %mm3 /* V113 ; free mm4 */ | ||
558 | movq %mm0, %mm4 /* duplicate V110 */ | ||
559 | paddsw %mm1, %mm2 /* V111 */ | ||
560 | pmulhw x539f539f539f539f, %mm0/* 21407-> V117 */ | ||
561 | psubsw %mm1, %mm5 /* V112 ; free mm1 */ | ||
562 | psubsw %mm5, %mm4 /* V116 */ | ||
563 | movq %mm2, %mm1 /* duplicate V111 */ | ||
564 | pmulhw x4546454645464546, %mm5/* 17734-> V119 */ | ||
565 | psubsw %mm3, %mm2 /* V114 */ | ||
566 | pmulhw x61f861f861f861f8, %mm4/* 25080-> V120 */ | ||
567 | paddsw %mm3, %mm1 /* V115 ; free mm3 */ | ||
568 | pmulhw x5a825a825a825a82, %mm2/* 23170-> V118 */ | ||
569 | psllw $2, %mm0 /* t266 */ | ||
570 | movq %mm1, (%esi) /* save V115 */ | ||
571 | psllw $1, %mm5 /* t268 */ | ||
572 | psubsw %mm4, %mm5 /* V122 */ | ||
573 | psubsw %mm0, %mm4 /* V121 ; free mm0 */ | ||
574 | psllw $1, %mm5 /* t270 */ | ||
575 | psubsw %mm1, %mm5 /* V123 ; free mm1 */ | ||
576 | psllw $2, %mm2 /* t272 */ | ||
577 | psubsw %mm5, %mm2 /* V124 (keep V123) */ | ||
578 | psllw $1, %mm4 /* t274 */ | ||
579 | movq %mm5, 8*2(%esi) /* save V123 ; free mm5 */ | ||
580 | paddsw %mm2, %mm4 /* V125 (keep V124) */ | ||
581 | /* column 0: even part (after transpose) */ | ||
582 | movq 8*12(%esi), %mm0 /* tmt12 */ | ||
583 | movq %mm6, %mm3 /* duplicate tmt4 */ | ||
584 | psubsw %mm0, %mm6 /* V100 */ | ||
585 | paddsw %mm0, %mm3 /* V101 ; free mm0 */ | ||
586 | pmulhw x5a825a825a825a82, %mm6/* 23170 ->V102 */ | ||
587 | movq %mm7, %mm5 /* duplicate tmt0 */ | ||
588 | movq 8*8(%esi), %mm1 /* tmt8 */ | ||
589 | paddsw %mm1, %mm7 /* V103 */ | ||
590 | psubsw %mm1, %mm5 /* V104 ; free mm1 */ | ||
591 | movq %mm7, %mm0 /* duplicate V103 */ | ||
592 | psllw $2, %mm6 /* t245 */ | ||
593 | paddsw %mm3, %mm7 /* V106 */ | ||
594 | movq %mm5, %mm1 /* duplicate V104 */ | ||
595 | psubsw %mm3, %mm6 /* V105 */ | ||
596 | psubsw %mm3, %mm0 /* V109; free mm3 */ | ||
597 | paddsw %mm6, %mm5 /* V107 */ | ||
598 | psubsw %mm6, %mm1 /* V108 ; free mm6 */ | ||
599 | /* column 0: output butterfly (after transform) */ | ||
600 | movq %mm1, %mm3 /* duplicate V108 */ | ||
601 | paddsw %mm2, %mm1 /* out4 */ | ||
602 | psraw $4, %mm1 | ||
603 | psubsw %mm2, %mm3 /* out10 ; free mm2 */ | ||
604 | psraw $4, %mm3 | ||
605 | movq %mm0, %mm6 /* duplicate V109 */ | ||
606 | movq %mm1, 8*4(%esi) /* out4 ; free mm1 */ | ||
607 | psubsw %mm4, %mm0 /* out6 */ | ||
608 | movq %mm3, 8*10(%esi) /* out10 ; free mm3 */ | ||
609 | psraw $4, %mm0 | ||
610 | paddsw %mm4, %mm6 /* out8 ; free mm4 */ | ||
611 | movq %mm7, %mm1 /* duplicate V106 */ | ||
612 | movq %mm0, 8*6(%esi) /* out6 ; free mm0 */ | ||
613 | psraw $4, %mm6 | ||
614 | movq (%esi), %mm4 /* V115 */ | ||
615 | movq %mm6, 8*8(%esi) /* out8 ; free mm6 */ | ||
616 | movq %mm5, %mm2 /* duplicate V107 */ | ||
617 | movq 8*2(%esi), %mm3 /* V123 */ | ||
618 | paddsw %mm4, %mm7 /* out0 */ | ||
619 | /* moved up from next block */ | ||
620 | movq 16(%esp), %mm0 | ||
621 | psraw $4, %mm7 | ||
622 | /* moved up from next block */ | ||
623 | movq 8(%esp), %mm6 | ||
624 | psubsw %mm4, %mm1 /* out14 ; free mm4 */ | ||
625 | paddsw %mm3, %mm5 /* out2 */ | ||
626 | psraw $4, %mm1 | ||
627 | movq %mm7, (%esi) /* out0 ; free mm7 */ | ||
628 | psraw $4, %mm5 | ||
629 | movq %mm1, 8*14(%esi) /* out14 ; free mm1 */ | ||
630 | psubsw %mm3, %mm2 /* out12 ; free mm3 */ | ||
631 | movq %mm5, 8*2(%esi) /* out2 ; free mm5 */ | ||
632 | psraw $4, %mm2 | ||
633 | /* moved up to the prev block */ | ||
634 | movq (%esp), %mm4 | ||
635 | /* moved up to the prev block */ | ||
636 | psraw $4, %mm0 | ||
637 | movq %mm2, 8*12(%esi) /* out12 ; free mm2 */ | ||
638 | /* moved up to the prev block */ | ||
639 | psraw $4, %mm6 | ||
640 | /* move back the data to its correct place | ||
641 | * moved up to the prev block | ||
642 | *movq 16(%esp), %mm0 | ||
643 | *movq 8(%esp), %mm6 | ||
644 | *movq (%esp), %mm4 | ||
645 | *psraw $4, %mm0 | ||
646 | *psraw $4, %mm6 | ||
647 | */ | ||
648 | movq 24(%esp), %mm1 | ||
649 | psraw $4, %mm4 | ||
650 | movq %mm0, 8*3(%esi) /* out3 */ | ||
651 | psraw $4, %mm1 | ||
652 | movq %mm6, 8*5(%esi) /* out5 */ | ||
653 | movq %mm4, 8*7(%esi) /* out7 */ | ||
654 | movq %mm1, 8(%esi) /* out1 */ | ||
655 | |||
656 | popl %edi /* Pop off the temp variables */ | ||
657 | popl %edi | ||
658 | popl %edi | ||
659 | popl %edi | ||
660 | popl %edi | ||
661 | popl %edi | ||
662 | popl %edi | ||
663 | popl %edi | ||
664 | |||
665 | popl %edi /* Pop off the old variables */ | ||
666 | popl %esi | ||
667 | popl %edx | ||
668 | popl %ecx | ||
669 | popl %ebx | ||
670 | movl %ebp, %esp | ||
671 | popl %ebp | ||
672 | |||
673 | ret | ||
674 | .Lfe1: | ||
675 | .size IDCT_mmx,.Lfe1-IDCT_mmx | ||
diff --git a/core/multimedia/opieplayer/libmpeg3/video/mmxtest.c b/core/multimedia/opieplayer/libmpeg3/video/mmxtest.c new file mode 100644 index 0000000..567f139 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/mmxtest.c | |||
@@ -0,0 +1,35 @@ | |||
1 | #include "../libmpeg3.h" | ||
2 | #include "../mpeg3protos.h" | ||
3 | |||
4 | #include <stdio.h> | ||
5 | #include <string.h> | ||
6 | |||
7 | int mpeg3_mmx_test() | ||
8 | { | ||
9 | int result = 0; | ||
10 | FILE *proc; | ||
11 | char string[MPEG3_STRLEN]; | ||
12 | |||
13 | |||
14 | #ifdef HAVE_MMX | ||
15 | if(!(proc = fopen(MPEG3_PROC_CPUINFO, "r"))) | ||
16 | { | ||
17 | return 0; | ||
18 | } | ||
19 | |||
20 | while(!feof(proc)) | ||
21 | { | ||
22 | fgets(string, MPEG3_STRLEN, proc); | ||
23 | /* Got the flags line */ | ||
24 | if(!strncmp(string, "flags", 5)) | ||
25 | { | ||
26 | char *needle; | ||
27 | needle = strstr(string, "mmx"); | ||
28 | if(!needle) return 0; | ||
29 | if(!strncmp(needle, "mmx", 3)) return 1; | ||
30 | } | ||
31 | } | ||
32 | #endif | ||
33 | |||
34 | return 0; | ||
35 | } | ||
diff --git a/core/multimedia/opieplayer/libmpeg3/video/motion.c b/core/multimedia/opieplayer/libmpeg3/video/motion.c new file mode 100644 index 0000000..4d2f681 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/motion.c | |||
@@ -0,0 +1,230 @@ | |||
1 | #include "mpeg3video.h" | ||
2 | #include "../libmpeg3.h" | ||
3 | #include "../mpeg3protos.h" | ||
4 | #include "vlc.h" | ||
5 | |||
6 | #include <stdio.h> | ||
7 | |||
8 | |||
9 | /* calculate motion vector component */ | ||
10 | |||
11 | static inline void mpeg3video_calc_mv(int *pred, int r_size, int motion_code, int motion_r, int full_pel_vector) | ||
12 | { | ||
13 | int lim = 16 << r_size; | ||
14 | int vec = full_pel_vector ? (*pred >> 1) : (*pred); | ||
15 | |||
16 | if(motion_code > 0) | ||
17 | { | ||
18 | vec += ((motion_code - 1) << r_size) + motion_r + 1; | ||
19 | if(vec >= lim) vec -= lim + lim; | ||
20 | } | ||
21 | else | ||
22 | if(motion_code < 0) | ||
23 | { | ||
24 | vec -= ((-motion_code - 1) << r_size) + motion_r + 1; | ||
25 | if(vec < -lim) vec += lim + lim; | ||
26 | } | ||
27 | *pred = full_pel_vector ? (vec << 1) : vec; | ||
28 | } | ||
29 | |||
30 | |||
31 | /* | ||
32 | int *dmvector, * differential motion vector * | ||
33 | int mvx, int mvy * decoded mv components (always in field format) * | ||
34 | */ | ||
35 | void mpeg3video_calc_dmv(mpeg3video_t *video, | ||
36 | int DMV[][2], | ||
37 | int *dmvector, | ||
38 | int mvx, | ||
39 | int mvy) | ||
40 | { | ||
41 | if(video->pict_struct == FRAME_PICTURE) | ||
42 | { | ||
43 | if(video->topfirst) | ||
44 | { | ||
45 | /* vector for prediction of top field from bottom field */ | ||
46 | DMV[0][0] = ((mvx + (mvx>0)) >> 1) + dmvector[0]; | ||
47 | DMV[0][1] = ((mvy + (mvy>0)) >> 1) + dmvector[1] - 1; | ||
48 | |||
49 | /* vector for prediction of bottom field from top field */ | ||
50 | DMV[1][0] = ((3 * mvx + (mvx > 0)) >> 1) + dmvector[0]; | ||
51 | DMV[1][1] = ((3 * mvy + (mvy > 0)) >> 1) + dmvector[1] + 1; | ||
52 | } | ||
53 | else | ||
54 | { | ||
55 | /* vector for prediction of top field from bottom field */ | ||
56 | DMV[0][0] = ((3 * mvx + (mvx>0)) >> 1) + dmvector[0]; | ||
57 | DMV[0][1] = ((3 * mvy + (mvy>0)) >> 1) + dmvector[1] - 1; | ||
58 | |||
59 | /* vector for prediction of bottom field from top field */ | ||
60 | DMV[1][0] = ((mvx + (mvx>0)) >> 1) + dmvector[0]; | ||
61 | DMV[1][1] = ((mvy + (mvy>0)) >> 1) + dmvector[1] + 1; | ||
62 | } | ||
63 | } | ||
64 | else | ||
65 | { | ||
66 | /* vector for prediction from field of opposite 'parity' */ | ||
67 | DMV[0][0] = ((mvx + (mvx > 0)) >> 1) + dmvector[0]; | ||
68 | DMV[0][1] = ((mvy + (mvy > 0)) >> 1) + dmvector[1]; | ||
69 | |||
70 | /* correct for vertical field shift */ | ||
71 | if(video->pict_struct == TOP_FIELD) | ||
72 | DMV[0][1]--; | ||
73 | else | ||
74 | DMV[0][1]++; | ||
75 | } | ||
76 | } | ||
77 | |||
78 | static inline int mpeg3video_get_mv(mpeg3_slice_t *slice) | ||
79 | { | ||
80 | int code; | ||
81 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
82 | |||
83 | if(mpeg3slice_getbit(slice_buffer)) | ||
84 | { | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | if((code = mpeg3slice_showbits9(slice_buffer)) >= 64) | ||
89 | { | ||
90 | code >>= 6; | ||
91 | mpeg3slice_flushbits(slice_buffer, mpeg3_MVtab0[code].len); | ||
92 | return mpeg3slice_getbit(slice_buffer) ? -mpeg3_MVtab0[code].val : mpeg3_MVtab0[code].val; | ||
93 | } | ||
94 | |||
95 | if(code >= 24) | ||
96 | { | ||
97 | code >>= 3; | ||
98 | mpeg3slice_flushbits(slice_buffer, mpeg3_MVtab1[code].len); | ||
99 | return mpeg3slice_getbit(slice_buffer) ? -mpeg3_MVtab1[code].val : mpeg3_MVtab1[code].val; | ||
100 | } | ||
101 | |||
102 | if((code -= 12) < 0) | ||
103 | { | ||
104 | /* fprintf(stdout,"mpeg3video_get_mv: invalid motion_vector code\n"); */ | ||
105 | slice->fault = 1; | ||
106 | return 1; | ||
107 | } | ||
108 | |||
109 | mpeg3slice_flushbits(slice_buffer, mpeg3_MVtab2[code].len); | ||
110 | return mpeg3slice_getbit(slice_buffer) ? -mpeg3_MVtab2[code].val : mpeg3_MVtab2[code].val; | ||
111 | } | ||
112 | |||
113 | /* get differential motion vector (for dual prime prediction) */ | ||
114 | |||
115 | static inline int mpeg3video_get_dmv(mpeg3_slice_t *slice) | ||
116 | { | ||
117 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
118 | if(mpeg3slice_getbit(slice_buffer)) | ||
119 | { | ||
120 | return mpeg3slice_getbit(slice_buffer) ? -1 : 1; | ||
121 | } | ||
122 | else | ||
123 | { | ||
124 | return 0; | ||
125 | } | ||
126 | } | ||
127 | |||
128 | |||
129 | |||
130 | /* get and decode motion vector and differential motion vector */ | ||
131 | |||
132 | void mpeg3video_motion_vector(mpeg3_slice_t *slice, | ||
133 | mpeg3video_t *video, | ||
134 | int *PMV, | ||
135 | int *dmvector, | ||
136 | int h_r_size, | ||
137 | int v_r_size, | ||
138 | int dmv, | ||
139 | int mvscale, | ||
140 | int full_pel_vector) | ||
141 | { | ||
142 | int motion_r; | ||
143 | int motion_code = mpeg3video_get_mv(slice); | ||
144 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
145 | |||
146 | if(slice->fault) return; | ||
147 | motion_r = (h_r_size != 0 && motion_code != 0) ? mpeg3slice_getbits(slice_buffer, h_r_size) : 0; | ||
148 | |||
149 | mpeg3video_calc_mv(&PMV[0], h_r_size, motion_code, motion_r, full_pel_vector); | ||
150 | |||
151 | if(dmv) dmvector[0] = mpeg3video_get_dmv(slice); | ||
152 | |||
153 | motion_code = mpeg3video_get_mv(slice); | ||
154 | if(slice->fault) return; | ||
155 | motion_r = (v_r_size != 0 && motion_code != 0) ? mpeg3slice_getbits(slice_buffer, v_r_size) : 0; | ||
156 | |||
157 | /* DIV 2 */ | ||
158 | if(mvscale) PMV[1] >>= 1; | ||
159 | |||
160 | mpeg3video_calc_mv(&PMV[1], v_r_size, motion_code, motion_r, full_pel_vector); | ||
161 | |||
162 | if(mvscale) PMV[1] <<= 1; | ||
163 | if(dmv) dmvector[1] = mpeg3video_get_dmv(slice); | ||
164 | } | ||
165 | |||
166 | int mpeg3video_motion_vectors(mpeg3_slice_t *slice, | ||
167 | mpeg3video_t *video, | ||
168 | int PMV[2][2][2], | ||
169 | int dmvector[2], | ||
170 | int mv_field_sel[2][2], | ||
171 | int s, | ||
172 | int mv_count, | ||
173 | int mv_format, | ||
174 | int h_r_size, | ||
175 | int v_r_size, | ||
176 | int dmv, | ||
177 | int mvscale) | ||
178 | { | ||
179 | int result = 0; | ||
180 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
181 | if(mv_count == 1) | ||
182 | { | ||
183 | if(mv_format == MV_FIELD && !dmv) | ||
184 | { | ||
185 | mv_field_sel[1][s] = mv_field_sel[0][s] = mpeg3slice_getbit(slice_buffer); | ||
186 | } | ||
187 | |||
188 | mpeg3video_motion_vector(slice, | ||
189 | video, | ||
190 | PMV[0][s], | ||
191 | dmvector, | ||
192 | h_r_size, | ||
193 | v_r_size, | ||
194 | dmv, | ||
195 | mvscale, | ||
196 | 0); | ||
197 | if(slice->fault) return 1; | ||
198 | |||
199 | /* update other motion vector predictors */ | ||
200 | PMV[1][s][0] = PMV[0][s][0]; | ||
201 | PMV[1][s][1] = PMV[0][s][1]; | ||
202 | } | ||
203 | else | ||
204 | { | ||
205 | mv_field_sel[0][s] = mpeg3slice_getbit(slice_buffer); | ||
206 | mpeg3video_motion_vector(slice, | ||
207 | video, | ||
208 | PMV[0][s], | ||
209 | dmvector, | ||
210 | h_r_size, | ||
211 | v_r_size, | ||
212 | dmv, | ||
213 | mvscale, | ||
214 | 0); | ||
215 | if(slice->fault) return 1; | ||
216 | |||
217 | mv_field_sel[1][s] = mpeg3slice_getbit(slice_buffer); | ||
218 | mpeg3video_motion_vector(slice, | ||
219 | video, | ||
220 | PMV[1][s], | ||
221 | dmvector, | ||
222 | h_r_size, | ||
223 | v_r_size, | ||
224 | dmv, | ||
225 | mvscale, | ||
226 | 0); | ||
227 | if(slice->fault) return 1; | ||
228 | } | ||
229 | return 0; | ||
230 | } | ||
diff --git a/core/multimedia/opieplayer/libmpeg3/video/mpeg3video.c b/core/multimedia/opieplayer/libmpeg3/video/mpeg3video.c new file mode 100644 index 0000000..a9f113e --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/mpeg3video.c | |||
@@ -0,0 +1,597 @@ | |||
1 | #include "../libmpeg3.h" | ||
2 | #include "../mpeg3protos.h" | ||
3 | #include "mpeg3video.h" | ||
4 | #include "mpeg3videoprotos.h" | ||
5 | #include <stdlib.h> | ||
6 | |||
7 | unsigned char mpeg3_zig_zag_scan_mmx[64] = | ||
8 | { | ||
9 | 0*8+0 /* 0*/, 1*8+0 /* 1*/, 0*8+1 /* 8*/, 0*8+2 /*16*/, 1*8+1 /* 9*/, 2*8+0 /* 2*/, 3*8+0 /* 3*/, 2*8+1 /*10*/, | ||
10 | 1*8+2 /*17*/, 0*8+3 /*24*/, 0*8+4 /*32*/, 1*8+3 /*25*/, 2*8+2 /*18*/, 3*8+1 /*11*/, 4*8+0 /* 4*/, 5*8+0 /* 5*/, | ||
11 | 4*8+1 /*12*/, 5*8+2 /*19*/, 2*8+3 /*26*/, 1*8+4 /*33*/, 0*8+5 /*40*/, 0*8+6 /*48*/, 1*8+5 /*41*/, 2*8+4 /*34*/, | ||
12 | 3*8+3 /*27*/, 4*8+2 /*20*/, 5*8+1 /*13*/, 6*8+0 /* 6*/, 7*8+0 /* 7*/, 6*8+1 /*14*/, 5*8+2 /*21*/, 4*8+3 /*28*/, | ||
13 | 3*8+4 /*35*/, 2*8+5 /*42*/, 1*8+6 /*49*/, 0*8+7 /*56*/, 1*8+7 /*57*/, 2*8+6 /*50*/, 3*8+5 /*43*/, 4*8+4 /*36*/, | ||
14 | 5*8+3 /*29*/, 6*8+2 /*22*/, 7*8+1 /*15*/, 7*8+2 /*23*/, 6*8+3 /*30*/, 5*8+4 /*37*/, 4*8+5 /*44*/, 3*8+6 /*51*/, | ||
15 | 2*8+7 /*58*/, 3*8+7 /*59*/, 4*8+6 /*52*/, 5*8+5 /*45*/, 6*8+4 /*38*/, 7*8+3 /*31*/, 7*8+4 /*39*/, 6*8+5 /*46*/, | ||
16 | 7*8+6 /*53*/, 4*8+7 /*60*/, 5*8+7 /*61*/, 6*8+6 /*54*/, 7*8+5 /*47*/, 7*8+6 /*55*/, 6*8+7 /*62*/, 7*8+7 /*63*/ | ||
17 | }; | ||
18 | |||
19 | /* alternate scan */ | ||
20 | unsigned char mpeg3_alternate_scan_mmx[64] = | ||
21 | { | ||
22 | 0*8+0 /*0 */, 0*8+1 /* 8*/, 0*8+2 /*16*/, 0*8+3 /*24*/, 1*8+0 /* 1*/, 1*8+1 /* 9*/, 2*8+0 /* 2*/, 2*8+1 /*10*/, | ||
23 | 1*8+2 /*17*/, 1*8+3 /*25*/, 0*8+4 /*32*/, 0*8+5 /*40*/, 0*8+6 /*48*/, 0*8+7 /*56*/, 1*8+7 /*57*/, 1*8+6 /*49*/, | ||
24 | 1*8+5 /*41*/, 1*8+4 /*33*/, 2*8+3 /*26*/, 2*8+2 /*18*/, 3*8+0 /* 3*/, 3*8+1 /*11*/, 4*8+0 /* 4*/, 4*8+1 /*12*/, | ||
25 | 3*8+2 /*19*/, 3*8+3 /*27*/, 2*8+4 /*34*/, 2*8+5 /*42*/, 2*8+6 /*50*/, 2*8+7 /*58*/, 3*8+4 /*35*/, 3*8+5 /*43*/, | ||
26 | 3*8+6 /*51*/, 3*8+7 /*59*/, 4*8+2 /*20*/, 4*8+3 /*28*/, 5*8+0 /* 5*/, 5*8+1 /*13*/, 6*8+0 /* 6*/, 6*8+1 /*14*/, | ||
27 | 5*8+2 /*21*/, 5*8+3 /*29*/, 4*8+4 /*36*/, 4*8+5 /*44*/, 4*8+6 /*52*/, 4*8+7 /*60*/, 5*8+4 /*37*/, 5*8+5 /*45*/, | ||
28 | 5*8+6 /*53*/, 5*8+7 /*61*/, 6*8+2 /*22*/, 6*8+3 /*30*/, 7*8+0 /* 7*/, 7*8+1 /*15*/, 7*8+2 /*23*/, 7*8+3 /*31*/, | ||
29 | 6*8+4 /*38*/, 6*8+5 /*46*/, 6*8+6 /*54*/, 6*8+7 /*62*/, 7*8+4 /*39*/, 7*8+5 /*47*/, 7*8+6 /*55*/, 7*8+6 /*63*/ | ||
30 | }; | ||
31 | |||
32 | |||
33 | |||
34 | /* zig-zag scan */ | ||
35 | unsigned char mpeg3_zig_zag_scan_nommx[64] = | ||
36 | { | ||
37 | 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, | ||
38 | 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, | ||
39 | 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, | ||
40 | 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 | ||
41 | }; | ||
42 | |||
43 | /* alternate scan */ | ||
44 | unsigned char mpeg3_alternate_scan_nommx[64] = | ||
45 | { | ||
46 | 0, 8, 16, 24, 1, 9, 2, 10, 17, 25, 32, 40, 48, 56, 57, 49, | ||
47 | 41, 33, 26, 18, 3, 11, 4, 12, 19, 27, 34, 42, 50, 58, 35, 43, | ||
48 | 51, 59, 20, 28, 5, 13, 6, 14, 21, 29, 36, 44, 52, 60, 37, 45, | ||
49 | 53, 61, 22, 30, 7, 15, 23, 31, 38, 46, 54, 62, 39, 47, 55, 63 | ||
50 | }; | ||
51 | |||
52 | /* default intra quantization matrix */ | ||
53 | unsigned char mpeg3_default_intra_quantizer_matrix[64] = | ||
54 | { | ||
55 | 8, 16, 19, 22, 26, 27, 29, 34, | ||
56 | 16, 16, 22, 24, 27, 29, 34, 37, | ||
57 | 19, 22, 26, 27, 29, 34, 34, 38, | ||
58 | 22, 22, 26, 27, 29, 34, 37, 40, | ||
59 | 22, 26, 27, 29, 32, 35, 40, 48, | ||
60 | 26, 27, 29, 32, 35, 40, 48, 58, | ||
61 | 26, 27, 29, 34, 38, 46, 56, 69, | ||
62 | 27, 29, 35, 38, 46, 56, 69, 83 | ||
63 | }; | ||
64 | |||
65 | unsigned char mpeg3_non_linear_mquant_table[32] = | ||
66 | { | ||
67 | 0, 1, 2, 3, 4, 5, 6, 7, | ||
68 | 8, 10, 12, 14, 16, 18, 20, 22, | ||
69 | 24, 28, 32, 36, 40, 44, 48, 52, | ||
70 | 56, 64, 72, 80, 88, 96, 104, 112 | ||
71 | }; | ||
72 | |||
73 | double mpeg3_frame_rate_table[16] = | ||
74 | { | ||
75 | 0.0, /* Pad */ | ||
76 | 24000.0/1001.0, /* Official frame rates */ | ||
77 | 24.0, | ||
78 | 25.0, | ||
79 | 30000.0/1001.0, | ||
80 | 30.0, | ||
81 | 50.0, | ||
82 | ((60.0*1000.0)/1001.0), | ||
83 | 60.0, | ||
84 | |||
85 | 1, /* Unofficial economy rates */ | ||
86 | 5, | ||
87 | 10, | ||
88 | 12, | ||
89 | 15, | ||
90 | 0, | ||
91 | 0, | ||
92 | }; | ||
93 | |||
94 | int mpeg3video_initdecoder(mpeg3video_t *video) | ||
95 | { | ||
96 | int blk_cnt_tab[3] = {6, 8, 12}; | ||
97 | int cc; | ||
98 | int i; | ||
99 | long size[4], padding[2]; /* Size of Y, U, and V buffers */ | ||
100 | |||
101 | if(!video->mpeg2) | ||
102 | { | ||
103 | /* force MPEG-1 parameters */ | ||
104 | video->prog_seq = 1; | ||
105 | video->prog_frame = 1; | ||
106 | video->pict_struct = FRAME_PICTURE; | ||
107 | video->frame_pred_dct = 1; | ||
108 | video->chroma_format = CHROMA420; | ||
109 | video->matrix_coefficients = 5; | ||
110 | } | ||
111 | |||
112 | /* Get dimensions rounded to nearest multiple of coded macroblocks */ | ||
113 | video->mb_width = (video->horizontal_size + 15) / 16; | ||
114 | video->mb_height = (video->mpeg2 && !video->prog_seq) ? | ||
115 | (2 * ((video->vertical_size + 31) / 32)) : | ||
116 | ((video->vertical_size + 15) / 16); | ||
117 | video->coded_picture_width = 16 * video->mb_width; | ||
118 | video->coded_picture_height = 16 * video->mb_height; | ||
119 | video->chrom_width = (video->chroma_format == CHROMA444) ? | ||
120 | video->coded_picture_width : | ||
121 | (video->coded_picture_width >> 1); | ||
122 | video->chrom_height = (video->chroma_format != CHROMA420) ? | ||
123 | video->coded_picture_height : | ||
124 | (video->coded_picture_height >> 1); | ||
125 | video->blk_cnt = blk_cnt_tab[video->chroma_format - 1]; | ||
126 | |||
127 | /* Get sizes of YUV buffers */ | ||
128 | padding[0] = 16 * video->coded_picture_width; | ||
129 | size[0] = video->coded_picture_width * video->coded_picture_height + padding[0] * 2; | ||
130 | |||
131 | padding[1] = 16 * video->chrom_width; | ||
132 | size[1] = video->chrom_width * video->chrom_height + 2 * padding[1]; | ||
133 | |||
134 | size[2] = (video->llw * video->llh); | ||
135 | size[3] = (video->llw * video->llh) / 4; | ||
136 | |||
137 | /* Allocate contiguous fragments for YUV buffers for hardware YUV decoding */ | ||
138 | video->yuv_buffer[0] = (unsigned char*)calloc(1, (size[0] + padding[0]) + 2 * (size[1] + padding[1])); | ||
139 | video->yuv_buffer[1] = (unsigned char*)calloc(1, (size[0] + padding[0]) + 2 * (size[1] + padding[1])); | ||
140 | video->yuv_buffer[2] = (unsigned char*)calloc(1, (size[0] + padding[0]) + 2 * (size[1] + padding[1])); | ||
141 | |||
142 | if(video->scalable_mode == SC_SPAT) | ||
143 | { | ||
144 | video->yuv_buffer[3] = (unsigned char*)calloc(1, size[2] + 2 * size[3]); | ||
145 | video->yuv_buffer[4] = (unsigned char*)calloc(1, size[2] + 2 * size[3]); | ||
146 | } | ||
147 | |||
148 | /* Direct pointers to areas of contiguous fragments in YVU order per Microsoft */ | ||
149 | for(cc = 0; cc < 3; cc++) | ||
150 | { | ||
151 | video->llframe0[cc] = 0; | ||
152 | video->llframe1[cc] = 0; | ||
153 | video->newframe[cc] = 0; | ||
154 | } | ||
155 | |||
156 | video->refframe[0] = video->yuv_buffer[0]; | ||
157 | video->oldrefframe[0] = video->yuv_buffer[1]; | ||
158 | video->auxframe[0] = video->yuv_buffer[2]; | ||
159 | video->refframe[2] = video->yuv_buffer[0] + size[0] + padding[0]; | ||
160 | video->oldrefframe[2] = video->yuv_buffer[1] + size[0] + padding[0]; | ||
161 | video->auxframe[2] = video->yuv_buffer[2] + size[0] + padding[0]; | ||
162 | video->refframe[1] = video->yuv_buffer[0] + size[0] + padding[0] + size[1] + padding[1]; | ||
163 | video->oldrefframe[1] = video->yuv_buffer[1] + size[0] + padding[0] + size[1] + padding[1]; | ||
164 | video->auxframe[1] = video->yuv_buffer[2] + size[0] + padding[0] + size[1] + padding[1]; | ||
165 | |||
166 | if(video->scalable_mode == SC_SPAT) | ||
167 | { | ||
168 | /* this assumes lower layer is 4:2:0 */ | ||
169 | video->llframe0[0] = video->yuv_buffer[3] + padding[0] ; | ||
170 | video->llframe1[0] = video->yuv_buffer[4] + padding[0] ; | ||
171 | video->llframe0[2] = video->yuv_buffer[3] + padding[1] + size[2] ; | ||
172 | video->llframe1[2] = video->yuv_buffer[4] + padding[1] + size[2] ; | ||
173 | video->llframe0[1] = video->yuv_buffer[3] + padding[1] + size[2] + size[3]; | ||
174 | video->llframe1[1] = video->yuv_buffer[4] + padding[1] + size[2] + size[3]; | ||
175 | } | ||
176 | |||
177 | /* Initialize the YUV tables for software YUV decoding */ | ||
178 | video->cr_to_r = (long*)malloc(sizeof(long) * 256); | ||
179 | video->cr_to_g = (long*)malloc(sizeof(long) * 256); | ||
180 | video->cb_to_g = (long*)malloc(sizeof(long) * 256); | ||
181 | video->cb_to_b = (long*)malloc(sizeof(long) * 256); | ||
182 | video->cr_to_r_ptr = video->cr_to_r + 128; | ||
183 | video->cr_to_g_ptr = video->cr_to_g + 128; | ||
184 | video->cb_to_g_ptr = video->cb_to_g + 128; | ||
185 | video->cb_to_b_ptr = video->cb_to_b + 128; | ||
186 | |||
187 | for(i = -128; i < 128; i++) | ||
188 | { | ||
189 | video->cr_to_r_ptr[i] = (long)( 1.371 * 65536 * i); | ||
190 | video->cr_to_g_ptr[i] = (long)(-0.698 * 65536 * i); | ||
191 | video->cb_to_g_ptr[i] = (long)(-0.336 * 65536 * i); | ||
192 | video->cb_to_b_ptr[i] = (long)( 1.732 * 65536 * i); | ||
193 | } | ||
194 | |||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | int mpeg3video_deletedecoder(mpeg3video_t *video) | ||
199 | { | ||
200 | int i, padding; | ||
201 | |||
202 | free(video->yuv_buffer[0]); | ||
203 | free(video->yuv_buffer[1]); | ||
204 | free(video->yuv_buffer[2]); | ||
205 | |||
206 | if(video->llframe0[0]) | ||
207 | { | ||
208 | free(video->yuv_buffer[3]); | ||
209 | free(video->yuv_buffer[4]); | ||
210 | } | ||
211 | |||
212 | free(video->cr_to_r); | ||
213 | free(video->cr_to_g); | ||
214 | free(video->cb_to_g); | ||
215 | free(video->cb_to_b); | ||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | void mpeg3video_init_scantables(mpeg3video_t *video) | ||
220 | { | ||
221 | #ifdef HAVE_MMX | ||
222 | if(video->have_mmx) | ||
223 | { | ||
224 | video->mpeg3_zigzag_scan_table = mpeg3_zig_zag_scan_mmx; | ||
225 | video->mpeg3_alternate_scan_table = mpeg3_alternate_scan_mmx; | ||
226 | } | ||
227 | else | ||
228 | #endif | ||
229 | { | ||
230 | video->mpeg3_zigzag_scan_table = mpeg3_zig_zag_scan_nommx; | ||
231 | video->mpeg3_alternate_scan_table = mpeg3_alternate_scan_nommx; | ||
232 | } | ||
233 | } | ||
234 | |||
235 | mpeg3video_t* mpeg3video_allocate_struct(mpeg3_t *file, mpeg3_vtrack_t *track) | ||
236 | { | ||
237 | int i; | ||
238 | mpeg3video_t *video = (mpeg3video_t*)calloc(1, sizeof(mpeg3video_t)); | ||
239 | pthread_mutexattr_t mutex_attr; | ||
240 | |||
241 | video->file = file; | ||
242 | video->track = track; | ||
243 | video->vstream = mpeg3bits_new_stream(file, track->demuxer); | ||
244 | video->last_number = -1; | ||
245 | |||
246 | /* First frame is all green */ | ||
247 | video->framenum = -1; | ||
248 | video->have_mmx = file->have_mmx; | ||
249 | |||
250 | video->percentage_seek = -1; | ||
251 | video->frame_seek = -1; | ||
252 | |||
253 | mpeg3video_init_scantables(video); | ||
254 | mpeg3video_init_output(); | ||
255 | |||
256 | pthread_mutexattr_init(&mutex_attr); | ||
257 | pthread_mutex_init(&(video->test_lock), &mutex_attr); | ||
258 | pthread_mutex_init(&(video->slice_lock), &mutex_attr); | ||
259 | return video; | ||
260 | } | ||
261 | |||
262 | int mpeg3video_delete_struct(mpeg3video_t *video) | ||
263 | { | ||
264 | int i; | ||
265 | mpeg3bits_delete_stream(video->vstream); | ||
266 | pthread_mutex_destroy(&(video->test_lock)); | ||
267 | pthread_mutex_destroy(&(video->slice_lock)); | ||
268 | if(video->x_table) | ||
269 | { | ||
270 | free(video->x_table); | ||
271 | free(video->y_table); | ||
272 | } | ||
273 | if(video->total_slice_decoders) | ||
274 | { | ||
275 | for(i = 0; i < video->total_slice_decoders; i++) | ||
276 | mpeg3_delete_slice_decoder(&video->slice_decoders[i]); | ||
277 | } | ||
278 | for(i = 0; i < video->slice_buffers_initialized; i++) | ||
279 | mpeg3_delete_slice_buffer(&(video->slice_buffers[i])); | ||
280 | |||
281 | free(video); | ||
282 | } | ||
283 | |||
284 | |||
285 | int mpeg3video_read_frame_backend(mpeg3video_t *video, int skip_bframes) | ||
286 | { | ||
287 | int result = 0; | ||
288 | |||
289 | if(mpeg3bits_eof(video->vstream)) result = 1; | ||
290 | |||
291 | if(!result) result = mpeg3video_get_header(video, 0); | ||
292 | |||
293 | //printf("frame type %d\n", video->pict_type); | ||
294 | /* skip_bframes is the number of bframes we can skip successfully. */ | ||
295 | /* This is in case a skipped B-frame is repeated and the second repeat happens */ | ||
296 | /* to be a B frame we need. */ | ||
297 | video->skip_bframes = skip_bframes; | ||
298 | |||
299 | if(!result) | ||
300 | result = mpeg3video_getpicture(video, video->framenum); | ||
301 | |||
302 | #ifdef HAVE_MMX | ||
303 | if(video->have_mmx) | ||
304 | __asm__ __volatile__ ("emms"); | ||
305 | #endif | ||
306 | |||
307 | if(!result) | ||
308 | { | ||
309 | video->last_number = video->framenum; | ||
310 | video->framenum++; | ||
311 | } | ||
312 | return result; | ||
313 | } | ||
314 | |||
315 | int* mpeg3video_get_scaletable(int input_w, int output_w) | ||
316 | { | ||
317 | int *result = (int*)malloc(sizeof(int) * output_w); | ||
318 | float i; | ||
319 | float scale = (float)input_w / output_w; | ||
320 | for(i = 0; i < output_w; i++) | ||
321 | { | ||
322 | result[(int)i] = (int)(scale * i); | ||
323 | } | ||
324 | return result; | ||
325 | } | ||
326 | |||
327 | /* Get the first frame read. */ | ||
328 | int mpeg3video_get_firstframe(mpeg3video_t *video) | ||
329 | { | ||
330 | int result = 0; | ||
331 | if(video->framenum < 0) | ||
332 | { | ||
333 | video->repeat_count = video->current_repeat = 0; | ||
334 | result = mpeg3video_read_frame_backend(video, 0); | ||
335 | mpeg3bits_seek_byte(video->vstream, 0); | ||
336 | mpeg3video_match_refframes(video); | ||
337 | } | ||
338 | return result; | ||
339 | } | ||
340 | |||
341 | |||
342 | /* ======================================================================= */ | ||
343 | /* ENTRY POINTS */ | ||
344 | /* ======================================================================= */ | ||
345 | |||
346 | |||
347 | |||
348 | mpeg3video_t* mpeg3video_new(mpeg3_t *file, mpeg3_vtrack_t *track) | ||
349 | { | ||
350 | mpeg3video_t *video; | ||
351 | int result = 0; | ||
352 | |||
353 | video = mpeg3video_allocate_struct(file, track); | ||
354 | result = mpeg3video_get_header(video, 1); | ||
355 | |||
356 | if(!result) | ||
357 | { | ||
358 | int hour, minute, second, frame; | ||
359 | int gop_found; | ||
360 | |||
361 | mpeg3video_initdecoder(video); | ||
362 | video->decoder_initted = 1; | ||
363 | track->width = video->horizontal_size; | ||
364 | track->height = video->vertical_size; | ||
365 | track->frame_rate = video->frame_rate; | ||
366 | |||
367 | /* Get the length of the file from an elementary stream */ | ||
368 | if(file->is_video_stream) | ||
369 | { | ||
370 | /* Load the first GOP */ | ||
371 | mpeg3bits_seek_start(video->vstream); | ||
372 | result = mpeg3video_next_code(video->vstream, MPEG3_GOP_START_CODE); | ||
373 | if(!result) mpeg3bits_getbits(video->vstream, 32); | ||
374 | if(!result) result = mpeg3video_getgophdr(video); | ||
375 | |||
376 | hour = video->gop_timecode.hour; | ||
377 | minute = video->gop_timecode.minute; | ||
378 | second = video->gop_timecode.second; | ||
379 | frame = video->gop_timecode.frame; | ||
380 | video->first_frame = (long)(hour * 3600 * video->frame_rate + | ||
381 | minute * 60 * video->frame_rate + | ||
382 | second * video->frame_rate + | ||
383 | frame); | ||
384 | |||
385 | /* GOPs always have 16 frames */ | ||
386 | video->frames_per_gop = 16; | ||
387 | |||
388 | /* Read the last GOP in the file by seeking backward. */ | ||
389 | mpeg3bits_seek_end(video->vstream); | ||
390 | mpeg3bits_start_reverse(video->vstream); | ||
391 | result = mpeg3video_prev_code(video->vstream, MPEG3_GOP_START_CODE); | ||
392 | mpeg3bits_start_forward(video->vstream); | ||
393 | mpeg3bits_getbits(video->vstream, 8); | ||
394 | if(!result) result = mpeg3video_getgophdr(video); | ||
395 | |||
396 | hour = video->gop_timecode.hour; | ||
397 | minute = video->gop_timecode.minute; | ||
398 | second = video->gop_timecode.second; | ||
399 | frame = video->gop_timecode.frame; | ||
400 | |||
401 | video->last_frame = (long)(hour * 3600 * video->frame_rate + | ||
402 | minute * 60 * video->frame_rate + | ||
403 | second * video->frame_rate + | ||
404 | frame); | ||
405 | |||
406 | /* Count number of frames to end */ | ||
407 | while(!result) | ||
408 | { | ||
409 | result = mpeg3video_next_code(video->vstream, MPEG3_PICTURE_START_CODE); | ||
410 | if(!result) | ||
411 | { | ||
412 | mpeg3bits_getbyte_noptr(video->vstream); | ||
413 | video->last_frame++; | ||
414 | } | ||
415 | } | ||
416 | |||
417 | track->total_frames = video->last_frame - video->first_frame + 1; | ||
418 | mpeg3bits_seek_start(video->vstream); | ||
419 | } | ||
420 | else | ||
421 | { | ||
422 | /* Gross approximation from a multiplexed file. */ | ||
423 | video->first_frame = 0; | ||
424 | track->total_frames = video->last_frame = | ||
425 | (long)(mpeg3demux_length(video->vstream->demuxer) * | ||
426 | video->frame_rate); | ||
427 | video->first_frame = 0; | ||
428 | } | ||
429 | |||
430 | video->maxframe = track->total_frames; | ||
431 | mpeg3bits_seek_start(video->vstream); | ||
432 | } | ||
433 | else | ||
434 | { | ||
435 | mpeg3video_delete(video); | ||
436 | video = 0; | ||
437 | } | ||
438 | |||
439 | return video; | ||
440 | } | ||
441 | |||
442 | int mpeg3video_delete(mpeg3video_t *video) | ||
443 | { | ||
444 | if(video->decoder_initted) | ||
445 | { | ||
446 | mpeg3video_deletedecoder(video); | ||
447 | } | ||
448 | mpeg3video_delete_struct(video); | ||
449 | return 0; | ||
450 | } | ||
451 | |||
452 | int mpeg3video_set_cpus(mpeg3video_t *video, int cpus) | ||
453 | { | ||
454 | return 0; | ||
455 | } | ||
456 | |||
457 | int mpeg3video_set_mmx(mpeg3video_t *video, int use_mmx) | ||
458 | { | ||
459 | video->have_mmx = use_mmx; | ||
460 | mpeg3video_init_scantables(video); | ||
461 | return 0; | ||
462 | } | ||
463 | |||
464 | int mpeg3video_seek_percentage(mpeg3video_t *video, double percentage) | ||
465 | { | ||
466 | video->percentage_seek = percentage; | ||
467 | return 0; | ||
468 | } | ||
469 | |||
470 | int mpeg3video_previous_frame(mpeg3video_t *video) | ||
471 | { | ||
472 | if(mpeg3bits_tell_percentage(video->vstream) <= 0) return 1; | ||
473 | mpeg3bits_start_reverse(video->vstream); | ||
474 | mpeg3video_prev_code(video->vstream, MPEG3_PICTURE_START_CODE); | ||
475 | mpeg3bits_getbits_reverse(video->vstream, 32); | ||
476 | |||
477 | if(mpeg3bits_bof(video->vstream)) mpeg3bits_seek_percentage(video->vstream, 0); | ||
478 | mpeg3bits_start_forward(video->vstream); | ||
479 | video->repeat_count = 0; | ||
480 | return 0; | ||
481 | } | ||
482 | |||
483 | int mpeg3video_seek_frame(mpeg3video_t *video, long frame) | ||
484 | { | ||
485 | video->frame_seek = frame; | ||
486 | return 0; | ||
487 | } | ||
488 | |||
489 | /* Read all the way up to and including the next picture start code */ | ||
490 | int mpeg3video_read_raw(mpeg3video_t *video, unsigned char *output, long *size, long max_size) | ||
491 | { | ||
492 | unsigned MPEG3_INT32 code = 0; | ||
493 | mpeg3_bits_t *vstream = video->vstream; | ||
494 | |||
495 | *size = 0; | ||
496 | while(code != MPEG3_PICTURE_START_CODE && | ||
497 | code != MPEG3_SEQUENCE_END_CODE && | ||
498 | *size < max_size && | ||
499 | !mpeg3bits_eof(vstream)) | ||
500 | { | ||
501 | code <<= 8; | ||
502 | *output = mpeg3bits_getbyte_noptr(vstream); | ||
503 | code |= *output++; | ||
504 | (*size)++; | ||
505 | } | ||
506 | return mpeg3bits_eof(vstream); | ||
507 | } | ||
508 | |||
509 | int mpeg3video_read_frame(mpeg3video_t *video, | ||
510 | long frame_number, | ||
511 | unsigned char **output_rows, | ||
512 | int in_x, | ||
513 | int in_y, | ||
514 | int in_w, | ||
515 | int in_h, | ||
516 | int out_w, | ||
517 | int out_h, | ||
518 | int color_model) | ||
519 | { | ||
520 | int result = 0; | ||
521 | |||
522 | video->want_yvu = 0; | ||
523 | video->output_rows = output_rows; | ||
524 | video->color_model = color_model; | ||
525 | |||
526 | /* Get scaling tables */ | ||
527 | if(video->out_w != out_w || video->out_h != out_h || | ||
528 | video->in_w != in_w || video->in_h != in_h || | ||
529 | video->in_x != in_x || video->in_y != in_y) | ||
530 | { | ||
531 | if(video->x_table) | ||
532 | { | ||
533 | free(video->x_table); | ||
534 | free(video->y_table); | ||
535 | video->x_table = 0; | ||
536 | video->y_table = 0; | ||
537 | } | ||
538 | } | ||
539 | |||
540 | video->out_w = out_w; | ||
541 | video->out_h = out_h; | ||
542 | video->in_w = in_w; | ||
543 | video->in_h = in_h; | ||
544 | video->in_x = in_x; | ||
545 | video->in_y = in_y; | ||
546 | |||
547 | if(!video->x_table) | ||
548 | { | ||
549 | video->x_table = mpeg3video_get_scaletable(video->in_w, video->out_w); | ||
550 | video->y_table = mpeg3video_get_scaletable(video->in_h, video->out_h); | ||
551 | } | ||
552 | |||
553 | mpeg3video_get_firstframe(video); | ||
554 | |||
555 | if(!result) result = mpeg3video_seek(video); | ||
556 | |||
557 | if(!result) result = mpeg3video_read_frame_backend(video, 0); | ||
558 | |||
559 | if(video->output_src) mpeg3video_present_frame(video); | ||
560 | |||
561 | video->percentage_seek = -1; | ||
562 | return result; | ||
563 | } | ||
564 | |||
565 | int mpeg3video_read_yuvframe(mpeg3video_t *video, | ||
566 | long frame_number, | ||
567 | char *y_output, | ||
568 | char *u_output, | ||
569 | char *v_output, | ||
570 | int in_x, | ||
571 | int in_y, | ||
572 | int in_w, | ||
573 | int in_h) | ||
574 | { | ||
575 | int result = 0; | ||
576 | |||
577 | video->want_yvu = 1; | ||
578 | video->y_output = y_output; | ||
579 | video->u_output = u_output; | ||
580 | video->v_output = v_output; | ||
581 | video->in_x = in_x; | ||
582 | video->in_y = in_y; | ||
583 | video->in_w = in_w; | ||
584 | video->in_h = in_h; | ||
585 | |||
586 | mpeg3video_get_firstframe(video); | ||
587 | |||
588 | if(!result) result = mpeg3video_seek(video); | ||
589 | |||
590 | if(!result) result = mpeg3video_read_frame_backend(video, 0); | ||
591 | |||
592 | if(video->output_src) mpeg3video_present_frame(video); | ||
593 | |||
594 | video->want_yvu = 0; | ||
595 | video->percentage_seek = -1; | ||
596 | return result; | ||
597 | } | ||
diff --git a/core/multimedia/opieplayer/libmpeg3/video/mpeg3video.h b/core/multimedia/opieplayer/libmpeg3/video/mpeg3video.h new file mode 100644 index 0000000..2db62b0 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/mpeg3video.h | |||
@@ -0,0 +1,180 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | #ifndef MPEGVIDEO_H | ||
21 | #define MPEGVIDEO_H | ||
22 | |||
23 | #include "../bitstream.h" | ||
24 | #include "../mpeg3private.inc" | ||
25 | #include "idct.h" | ||
26 | #include "slice.h" | ||
27 | #include "../timecode.h" | ||
28 | |||
29 | /* zig-zag scan */ | ||
30 | extern unsigned char mpeg3_zig_zag_scan_nommx[64]; | ||
31 | extern unsigned char mpeg3_zig_zag_scan_mmx[64]; | ||
32 | |||
33 | /* alternate scan */ | ||
34 | extern unsigned char mpeg3_alternate_scan_nommx[64]; | ||
35 | extern unsigned char mpeg3_alternate_scan_mmx[64]; | ||
36 | |||
37 | /* default intra quantization matrix */ | ||
38 | extern unsigned char mpeg3_default_intra_quantizer_matrix[64]; | ||
39 | |||
40 | /* Frame rate table must agree with the one in the encoder */ | ||
41 | extern double mpeg3_frame_rate_table[16]; | ||
42 | |||
43 | /* non-linear quantization coefficient table */ | ||
44 | extern unsigned char mpeg3_non_linear_mquant_table[32]; | ||
45 | |||
46 | #define CHROMA420 1 /* chroma_format */ | ||
47 | #define CHROMA422 2 | ||
48 | #define CHROMA444 3 | ||
49 | |||
50 | #define TOP_FIELD 1 /* picture structure */ | ||
51 | #define BOTTOM_FIELD 2 | ||
52 | #define FRAME_PICTURE 3 | ||
53 | |||
54 | #define SEQ_ID 1 /* extension start code IDs */ | ||
55 | #define DISP_ID 2 | ||
56 | #define QUANT_ID 3 | ||
57 | #define SEQSCAL_ID 5 | ||
58 | #define PANSCAN_ID 7 | ||
59 | #define CODING_ID 8 | ||
60 | #define SPATSCAL_ID 9 | ||
61 | #define TEMPSCAL_ID 10 | ||
62 | |||
63 | #define ERROR (-1) | ||
64 | |||
65 | #define SC_NONE 0 /* scalable_mode */ | ||
66 | #define SC_DP 1 | ||
67 | #define SC_SPAT 2 | ||
68 | #define SC_SNR 3 | ||
69 | #define SC_TEMP 4 | ||
70 | |||
71 | #define I_TYPE 1 /* picture coding type */ | ||
72 | #define P_TYPE 2 | ||
73 | #define B_TYPE 3 | ||
74 | #define D_TYPE 4 | ||
75 | |||
76 | #define MB_INTRA 1 /* macroblock type */ | ||
77 | #define MB_PATTERN 2 | ||
78 | #define MB_BACKWARD 4 | ||
79 | #define MB_FORWARD 8 | ||
80 | #define MB_QUANT 16 | ||
81 | #define MB_WEIGHT 32 | ||
82 | #define MB_CLASS4 64 | ||
83 | |||
84 | #define MC_FIELD 1 /* motion_type */ | ||
85 | #define MC_FRAME 2 | ||
86 | #define MC_16X8 2 | ||
87 | #define MC_DMV 3 | ||
88 | |||
89 | #define MV_FIELD 0 /* mv_format */ | ||
90 | #define MV_FRAME 1 | ||
91 | |||
92 | #define CLIP(x) ((x) >= 0 ? ((x) < 255 ? (x) : 255) : 0) | ||
93 | |||
94 | /* Statically allocate as little as possible so a fake video struct */ | ||
95 | /* can be used for reading the GOP headers. */ | ||
96 | |||
97 | struct mpeg3video_rec | ||
98 | { | ||
99 | struct mpeg3_rec* file; | ||
100 | struct mpeg3_vtrack_rec* track; | ||
101 | |||
102 | /* ================================= Seeking variables ========================= */ | ||
103 | mpeg3_bits_t *vstream; | ||
104 | int decoder_initted; | ||
105 | unsigned char **output_rows; /* Output frame buffer supplied by user */ | ||
106 | int in_x, in_y, in_w, in_h, out_w, out_h; /* Output dimensions */ | ||
107 | int *x_table, *y_table; /* Location of every output pixel in the input */ | ||
108 | int color_model; | ||
109 | int want_yvu; /* Want to return a YUV frame */ | ||
110 | char *y_output, *u_output, *v_output; /* Output pointers for a YUV frame */ | ||
111 | |||
112 | mpeg3_slice_t slice_decoders[MPEG3_MAX_CPUS]; /* One slice decoder for every CPU */ | ||
113 | int total_slice_decoders; /* Total slice decoders in use */ | ||
114 | mpeg3_slice_buffer_t slice_buffers[MPEG3_MAX_CPUS]; /* Buffers for holding the slice data */ | ||
115 | int total_slice_buffers; /* Total buffers in the array to be decompressed */ | ||
116 | int slice_buffers_initialized; /* Total buffers initialized in the array */ | ||
117 | pthread_mutex_t slice_lock; /* Lock slice array while getting the next buffer */ | ||
118 | pthread_mutex_t test_lock; | ||
119 | |||
120 | int blockreadsize; | ||
121 | long maxframe; /* Max value of frame num to read */ | ||
122 | double percentage_seek; /* Perform a percentage seek before the next frame is read */ | ||
123 | int frame_seek; /* Perform a frame seek before the next frame is read */ | ||
124 | long framenum; /* Number of the next frame to be decoded */ | ||
125 | long last_number; /* Last framenum rendered */ | ||
126 | int found_seqhdr; | ||
127 | long bitrate; | ||
128 | mpeg3_timecode_t gop_timecode; /* Timecode for the last GOP header read. */ | ||
129 | |||
130 | /* These are only available from elementary streams. */ | ||
131 | long frames_per_gop; /* Frames per GOP after the first GOP. */ | ||
132 | long first_gop_frames; /* Frames in the first GOP. */ | ||
133 | long first_frame; /* Number of first frame stored in timecode */ | ||
134 | long last_frame; /* Last frame in file */ | ||
135 | |||
136 | /* ================================= Compression variables ===================== */ | ||
137 | /* Malloced frame buffers. 2 refframes are swapped in and out. */ | ||
138 | /* while only 1 auxframe is used. */ | ||
139 | unsigned char *yuv_buffer[5]; /* Make YVU buffers contiguous for all frames */ | ||
140 | unsigned char *oldrefframe[3], *refframe[3], *auxframe[3]; | ||
141 | unsigned char *llframe0[3], *llframe1[3]; | ||
142 | unsigned char *mpeg3_zigzag_scan_table; | ||
143 | unsigned char *mpeg3_alternate_scan_table; | ||
144 | // Source for the next frame presentation | ||
145 | unsigned char **output_src; | ||
146 | /* Pointers to frame buffers. */ | ||
147 | unsigned char *newframe[3]; | ||
148 | int horizontal_size, vertical_size, mb_width, mb_height; | ||
149 | int coded_picture_width, coded_picture_height; | ||
150 | int chroma_format, chrom_width, chrom_height, blk_cnt; | ||
151 | int pict_type; | ||
152 | int forw_r_size, back_r_size, full_forw, full_back; | ||
153 | int prog_seq, prog_frame; | ||
154 | int h_forw_r_size, v_forw_r_size, h_back_r_size, v_back_r_size; | ||
155 | int dc_prec, pict_struct, topfirst, frame_pred_dct, conceal_mv; | ||
156 | int intravlc; | ||
157 | int repeatfirst; | ||
158 | int repeat_count; /* Number of times to repeat the current frame * 100 since floating point is impossible in MMX */ | ||
159 | int current_repeat; /* Number of times the current frame has been repeated * 100 */ | ||
160 | int secondfield; | ||
161 | int skip_bframes; | ||
162 | int stwc_table_index, llw, llh, hm, hn, vm, vn; | ||
163 | int lltempref, llx0, lly0, llprog_frame, llfieldsel; | ||
164 | int matrix_coefficients; | ||
165 | int framerate_code; | ||
166 | float frame_rate; | ||
167 | long *cr_to_r, *cr_to_g, *cb_to_g, *cb_to_b; | ||
168 | long *cr_to_r_ptr, *cr_to_g_ptr, *cb_to_g_ptr, *cb_to_b_ptr; | ||
169 | int have_mmx; | ||
170 | int intra_quantizer_matrix[64], non_intra_quantizer_matrix[64]; | ||
171 | int chroma_intra_quantizer_matrix[64], chroma_non_intra_quantizer_matrix[64]; | ||
172 | int mpeg2; | ||
173 | int qscale_type, altscan; /* picture coding extension */ | ||
174 | int pict_scal; /* picture spatial scalable extension */ | ||
175 | int scalable_mode; /* sequence scalable extension */ | ||
176 | }; | ||
177 | |||
178 | typedef struct mpeg3video_rec mpeg3video_t; | ||
179 | |||
180 | #endif | ||
diff --git a/core/multimedia/opieplayer/libmpeg3/video/mpeg3videoprotos.h b/core/multimedia/opieplayer/libmpeg3/video/mpeg3videoprotos.h new file mode 100644 index 0000000..e48d6cd --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/mpeg3videoprotos.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | #ifndef MPEG3VIDEOPROTOS_H | ||
21 | #define MPEG3VIDEOPROTOS_H | ||
22 | |||
23 | void mpeg3video_idct_conversion(short* block); | ||
24 | unsigned int mpeg3slice_showbits(mpeg3_slice_buffer_t *slice_buffer, int bits); | ||
25 | |||
26 | #endif | ||
diff --git a/core/multimedia/opieplayer/libmpeg3/video/output.c b/core/multimedia/opieplayer/libmpeg3/video/output.c new file mode 100644 index 0000000..919a0ff --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/output.c | |||
@@ -0,0 +1,993 @@ | |||
1 | #include "../libmpeg3.h" | ||
2 | #include "../mpeg3protos.h" | ||
3 | #include "mpeg3video.h" | ||
4 | #include <string.h> | ||
5 | |||
6 | static LONGLONG mpeg3_MMX_0 = 0L; | ||
7 | static unsigned long mpeg3_MMX_10w[] = {0x00100010, 0x00100010}; /*dd 00010 0010h, 000100010h */ | ||
8 | static unsigned long mpeg3_MMX_80w[] = {0x00800080, 0x00800080}; /*dd 00080 0080h, 000800080h */ | ||
9 | |||
10 | static unsigned long mpeg3_MMX_00FFw[] = {0x00ff00ff, 0x00ff00ff}; /*dd 000FF 00FFh, 000FF00FFh */ | ||
11 | |||
12 | static unsigned short mpeg3_MMX_Ublucoeff[] = {0x81, 0x81, 0x81, 0x81}; /*dd 00081 0081h, 000810081h */ | ||
13 | static unsigned short mpeg3_MMX_Vredcoeff[] = {0x66, 0x66, 0x66, 0x66}; /*dd 00066 0066h, 000660066h */ | ||
14 | |||
15 | static unsigned short mpeg3_MMX_Ugrncoeff[] = {0xffe8, 0xffe8, 0xffe8, 0xffe8}; /*dd 0FFE7 FFE7h, 0FFE7FFE7h */ | ||
16 | static unsigned short mpeg3_MMX_Vgrncoeff[] = {0xffcd, 0xffcd, 0xffcd, 0xffcd}; /*dd 0FFCC FFCCh, 0FFCCFFCCh */ | ||
17 | |||
18 | static unsigned short mpeg3_MMX_Ycoeff[] = {0x4a, 0x4a, 0x4a, 0x4a}; /*dd 0004A 004Ah, 0004A004Ah */ | ||
19 | |||
20 | static unsigned short mpeg3_MMX_redmask[] = {0xf800, 0xf800, 0xf800, 0xf800}; /*dd 07c00 7c00h, 07c007c00h */ | ||
21 | |||
22 | static unsigned short mpeg3_MMX_grnmask[] = {0x7e0, 0x7e0, 0x7e0, 0x7e0}; /*dd 003e0 03e0h, 003e003e0h */ | ||
23 | |||
24 | static unsigned char mpeg3_601_to_rgb[256]; | ||
25 | |||
26 | /* Algorithm */ | ||
27 | /* r = (int)(*y + 1.371 * (*cr - 128)); */ | ||
28 | /* g = (int)(*y - 0.698 * (*cr - 128) - 0.336 * (*cb - 128)); */ | ||
29 | /* b = (int)(*y + 1.732 * (*cb - 128)); */ | ||
30 | |||
31 | #ifdef HAVE_MMX | ||
32 | inline void mpeg3video_rgb16_mmx(unsigned char *lum, | ||
33 | unsigned char *cr, | ||
34 | unsigned char *cb, | ||
35 | unsigned char *out, | ||
36 | int rows, | ||
37 | int cols, | ||
38 | int mod) | ||
39 | { | ||
40 | unsigned short *row1; | ||
41 | int x; | ||
42 | unsigned char *y; | ||
43 | int col1; | ||
44 | |||
45 | row1 = (unsigned short *)out; | ||
46 | col1 = cols + mod; | ||
47 | mod += cols + mod; | ||
48 | mod *= 2; | ||
49 | y = lum + cols * rows; | ||
50 | x = 0; | ||
51 | |||
52 | __asm__ __volatile__( | ||
53 | ".align 8\n" | ||
54 | "1:\n" | ||
55 | "movd (%1), %%mm0\n" /* 4 Cb 0 0 0 0 u3 u2 u1 u0 */ | ||
56 | "pxor %%mm7, %%mm7\n" | ||
57 | "movd (%0), %%mm1\n" /* 4 Cr 0 0 0 0 v3 v2 v1 v0 */ | ||
58 | "punpcklbw %%mm7, %%mm0\n" /* 4 W cb 0 u3 0 u2 0 u1 0 u0 */ | ||
59 | "punpcklbw %%mm7, %%mm1\n" /* 4 W cr 0 v3 0 v2 0 v1 0 v0 */ | ||
60 | |||
61 | "psubw mpeg3_MMX_80w, %%mm0\n" | ||
62 | "psubw mpeg3_MMX_80w, %%mm1\n" | ||
63 | "movq %%mm0, %%mm2\n" /* Cb 0 u3 0 u2 0 u1 0 u0 */ | ||
64 | "movq %%mm1, %%mm3\n" /* Cr */ | ||
65 | "pmullw mpeg3_MMX_Ugrncoeff, %%mm2\n" /* Cb2green 0 R3 0 R2 0 R1 0 R0 */ | ||
66 | "movq (%2), %%mm6\n" /* L1 l7 L6 L5 L4 L3 L2 L1 L0 */ | ||
67 | "pmullw mpeg3_MMX_Ublucoeff, %%mm0\n" /* Cb2blue */ | ||
68 | "pand mpeg3_MMX_00FFw, %%mm6\n" /* L1 00 L6 00 L4 00 L2 00 L0 */ | ||
69 | "pmullw mpeg3_MMX_Vgrncoeff, %%mm3\n" /* Cr2green */ | ||
70 | "movq (%2), %%mm7\n" /* L2 */ | ||
71 | "pmullw mpeg3_MMX_Vredcoeff, %%mm1\n" /* Cr2red */ | ||
72 | "psrlw $8, %%mm7\n" /* L2 00 L7 00 L5 00 L3 00 L1 */ | ||
73 | "pmullw mpeg3_MMX_Ycoeff, %%mm6\n" /* lum1 */ | ||
74 | "paddw %%mm3, %%mm2\n" /* Cb2green + Cr2green == green */ | ||
75 | "pmullw mpeg3_MMX_Ycoeff, %%mm7\n" /* lum2 */ | ||
76 | |||
77 | "movq %%mm6, %%mm4\n" /* lum1 */ | ||
78 | "paddw %%mm0, %%mm6\n" /* lum1 +blue 00 B6 00 B4 00 B2 00 B0 */ | ||
79 | "movq %%mm4, %%mm5\n" /* lum1 */ | ||
80 | "paddw %%mm1, %%mm4\n" /* lum1 +red 00 R6 00 R4 00 R2 00 R0 */ | ||
81 | "paddw %%mm2, %%mm5\n" /* lum1 +green 00 G6 00 G4 00 G2 00 G0 */ | ||
82 | "psraw $6, %%mm4\n" /* R1 0 .. 64 */ | ||
83 | "movq %%mm7, %%mm3\n" /* lum2 00 L7 00 L5 00 L3 00 L1 */ | ||
84 | "psraw $6, %%mm5\n" /* G1 - .. + */ | ||
85 | "paddw %%mm0, %%mm7\n" /* Lum2 +blue 00 B7 00 B5 00 B3 00 B1 */ | ||
86 | "psraw $6, %%mm6\n" /* B1 0 .. 64 */ | ||
87 | "packuswb %%mm4, %%mm4\n" /* R1 R1 */ | ||
88 | "packuswb %%mm5, %%mm5\n" /* G1 G1 */ | ||
89 | "packuswb %%mm6, %%mm6\n" /* B1 B1 */ | ||
90 | "punpcklbw %%mm4, %%mm4\n" | ||
91 | "punpcklbw %%mm5, %%mm5\n" | ||
92 | |||
93 | "pand mpeg3_MMX_redmask, %%mm4\n" | ||
94 | "psllw $3, %%mm5\n" /* GREEN 1 */ | ||
95 | "punpcklbw %%mm6, %%mm6\n" | ||
96 | "pand mpeg3_MMX_grnmask, %%mm5\n" | ||
97 | "pand mpeg3_MMX_redmask, %%mm6\n" | ||
98 | "por %%mm5, %%mm4\n" /* */ | ||
99 | "psrlw $11, %%mm6\n" /* BLUE 1 */ | ||
100 | "movq %%mm3, %%mm5\n" /* lum2 */ | ||
101 | "paddw %%mm1, %%mm3\n" /* lum2 +red 00 R7 00 R5 00 R3 00 R1 */ | ||
102 | "paddw %%mm2, %%mm5\n" /* lum2 +green 00 G7 00 G5 00 G3 00 G1 */ | ||
103 | "psraw $6, %%mm3\n" /* R2 */ | ||
104 | "por %%mm6, %%mm4\n" /* MM4 */ | ||
105 | "psraw $6, %%mm5\n" /* G2 */ | ||
106 | "movq (%2, %3), %%mm6\n" /* L3 */ | ||
107 | "psraw $6, %%mm7\n" | ||
108 | "packuswb %%mm3, %%mm3\n" | ||
109 | "packuswb %%mm5, %%mm5\n" | ||
110 | "packuswb %%mm7, %%mm7\n" | ||
111 | "pand mpeg3_MMX_00FFw, %%mm6\n" /* L3 */ | ||
112 | "punpcklbw %%mm3, %%mm3\n" | ||
113 | "punpcklbw %%mm5, %%mm5\n" | ||
114 | "pmullw mpeg3_MMX_Ycoeff, %%mm6\n" /* lum3 */ | ||
115 | "punpcklbw %%mm7, %%mm7\n" | ||
116 | "psllw $3, %%mm5\n" /* GREEN 2 */ | ||
117 | "pand mpeg3_MMX_redmask, %%mm7\n" | ||
118 | "pand mpeg3_MMX_redmask, %%mm3\n" | ||
119 | "psrlw $11, %%mm7\n" /* BLUE 2 */ | ||
120 | "pand mpeg3_MMX_grnmask, %%mm5\n" | ||
121 | "por %%mm7, %%mm3\n" | ||
122 | "movq (%2,%3), %%mm7\n" /* L4 */ | ||
123 | "por %%mm5, %%mm3\n" /* */ | ||
124 | "psrlw $8, %%mm7\n" /* L4 */ | ||
125 | "movq %%mm4, %%mm5\n" | ||
126 | "punpcklwd %%mm3, %%mm4\n" | ||
127 | "pmullw mpeg3_MMX_Ycoeff, %%mm7\n" /* lum4 */ | ||
128 | "punpckhwd %%mm3, %%mm5\n" | ||
129 | |||
130 | "movq %%mm4, (%4)\n" | ||
131 | "movq %%mm5, 8(%4)\n" | ||
132 | |||
133 | "movq %%mm6, %%mm4\n" /* Lum3 */ | ||
134 | "paddw %%mm0, %%mm6\n" /* Lum3 +blue */ | ||
135 | |||
136 | "movq %%mm4, %%mm5\n" /* Lum3 */ | ||
137 | "paddw %%mm1, %%mm4\n" /* Lum3 +red */ | ||
138 | "paddw %%mm2, %%mm5\n" /* Lum3 +green */ | ||
139 | "psraw $6, %%mm4\n" | ||
140 | "movq %%mm7, %%mm3\n"/* Lum4 */ | ||
141 | "psraw $6, %%mm5\n" | ||
142 | "paddw %%mm0, %%mm7\n" /* Lum4 +blue */ | ||
143 | "psraw $6, %%mm6\n" /* Lum3 +blue */ | ||
144 | "movq %%mm3, %%mm0\n" /* Lum4 */ | ||
145 | "packuswb %%mm4, %%mm4\n" | ||
146 | "paddw %%mm1, %%mm3\n" /* Lum4 +red */ | ||
147 | "packuswb %%mm5, %%mm5\n" | ||
148 | "paddw %%mm2, %%mm0\n" /* Lum4 +green */ | ||
149 | "packuswb %%mm6, %%mm6\n" | ||
150 | "punpcklbw %%mm4, %%mm4\n" | ||
151 | "punpcklbw %%mm5, %%mm5\n" | ||
152 | "punpcklbw %%mm6, %%mm6\n" | ||
153 | "psllw $3, %%mm5\n" /* GREEN 3 */ | ||
154 | "pand mpeg3_MMX_redmask, %%mm4\n" | ||
155 | "psraw $6, %%mm3\n" /* psr 6 */ | ||
156 | "psraw $6, %%mm0\n" | ||
157 | "pand mpeg3_MMX_redmask, %%mm6\n" /* BLUE */ | ||
158 | "pand mpeg3_MMX_grnmask, %%mm5\n" | ||
159 | "psrlw $11, %%mm6\n" /* BLUE 3 */ | ||
160 | "por %%mm5, %%mm4\n" | ||
161 | "psraw $6, %%mm7\n" | ||
162 | "por %%mm6, %%mm4\n" | ||
163 | "packuswb %%mm3, %%mm3\n" | ||
164 | "packuswb %%mm0, %%mm0\n" | ||
165 | "packuswb %%mm7, %%mm7\n" | ||
166 | "punpcklbw %%mm3, %%mm3\n" | ||
167 | "punpcklbw %%mm0, %%mm0\n" | ||
168 | "punpcklbw %%mm7, %%mm7\n" | ||
169 | "pand mpeg3_MMX_redmask, %%mm3\n" | ||
170 | "pand mpeg3_MMX_redmask, %%mm7\n" /* BLUE */ | ||
171 | "psllw $3, %%mm0\n" /* GREEN 4 */ | ||
172 | "psrlw $11, %%mm7\n" | ||
173 | "pand mpeg3_MMX_grnmask, %%mm0\n" | ||
174 | "por %%mm7, %%mm3\n" | ||
175 | "addl $8, %6\n" | ||
176 | "por %%mm0, %%mm3\n" | ||
177 | |||
178 | "movq %%mm4, %%mm5\n" | ||
179 | |||
180 | "punpcklwd %%mm3, %%mm4\n" | ||
181 | "punpckhwd %%mm3, %%mm5\n" | ||
182 | |||
183 | "movq %%mm4, (%4,%5,2)\n" | ||
184 | "movq %%mm5, 8(%4,%5,2)\n" | ||
185 | |||
186 | "addl $8, %2\n" | ||
187 | "addl $4, %0\n" | ||
188 | "addl $4, %1\n" | ||
189 | "cmpl %3, %6\n" | ||
190 | "leal 16(%4), %4\n" | ||
191 | "jl 1b\n" | ||
192 | "addl %3, %2\n" /* lum += cols */ | ||
193 | "addl %7, %4\n" /* row1 += mod */ | ||
194 | "movl $0, %6\n" | ||
195 | "cmpl %8, %2\n" | ||
196 | "jl 1b\n" | ||
197 | : : "r" (cr), | ||
198 | "r" (cb), | ||
199 | "r" (lum), | ||
200 | "r" (cols), | ||
201 | "r" (row1) , | ||
202 | "r" (col1), | ||
203 | "m" (x), | ||
204 | "m" (mod), | ||
205 | "m" (y) | ||
206 | ); | ||
207 | } | ||
208 | |||
209 | static unsigned LONGLONG mpeg3_MMX_U_80 = 0x0000008000800000LL; | ||
210 | static unsigned LONGLONG mpeg3_MMX_V_80 = 0x0000000000800080LL; | ||
211 | static LONGLONG mpeg3_MMX_U_COEF = 0x00000058ffd30000LL; | ||
212 | static LONGLONG mpeg3_MMX_V_COEF = 0x00000000ffea006fLL; | ||
213 | static LONGLONG mpeg3_MMX_601_Y_COEF = 0x0000004800480048LL; | ||
214 | static LONGLONG mpeg3_MMX_601_Y_DIFF = 0x0000000000000010LL; | ||
215 | |||
216 | inline void mpeg3_bgra32_mmx(unsigned long y, | ||
217 | unsigned long u, | ||
218 | unsigned long v, | ||
219 | unsigned long *output) | ||
220 | { | ||
221 | asm(" | ||
222 | /* Output will be 0x00rrggbb with the 00 trailing so this can also be used */ | ||
223 | /* for bgr24. */ | ||
224 | movd (%0), %%mm0; /* Load y 0x00000000000000yy */ | ||
225 | movd (%1), %%mm1; /* Load u 0x00000000000000cr */ | ||
226 | movq %%mm0, %%mm3; /* Copy y to temp */ | ||
227 | psllq $16, %%mm1; /* Shift u 0x0000000000cr0000 */ | ||
228 | movd (%2), %%mm2; /* Load v 0x00000000000000cb */ | ||
229 | psllq $16, %%mm3; /* Shift y */ | ||
230 | movq %%mm1, %%mm4; /* Copy u to temp */ | ||
231 | por %%mm3, %%mm0; /* Overlay new y byte 0x0000000000yy00yy */ | ||
232 | psllq $16, %%mm4; /* Shift u */ | ||
233 | movq %%mm2, %%mm5; /* Copy v to temp */ | ||
234 | psllq $16, %%mm3; /* Shift y */ | ||
235 | por %%mm4, %%mm1; /* Overlay new u byte 0x000000cr00cr0000 */ | ||
236 | psllq $16, %%mm5; /* Shift v */ | ||
237 | por %%mm3, %%mm0; /* Overlay new y byte 0x000000yy00yy00yy */ | ||
238 | por %%mm5, %%mm2; /* Overlay new v byte 0x0000000000cb00cb */ | ||
239 | |||
240 | /* mm0: 0x000000yy00yy00yy mm1: 0x000000uu00uu0000 mm2: 0x0000000000vv00vv */ | ||
241 | psubw mpeg3_MMX_U_80, %%mm1; /* Subtract 128 from u 0x000000uu00uu0000 */ | ||
242 | pmullw mpeg3_MMX_U_COEF, %%mm1; /* Multiply u coeffs 0x0000uuuuuuuu0000 */ | ||
243 | psllw $6, %%mm0; /* Shift y coeffs 0x0000yyy0yyy0yyy0 */ | ||
244 | psubw mpeg3_MMX_V_80, %%mm2; /* Subtract 128 from v 0x0000000000cb00cb */ | ||
245 | pmullw mpeg3_MMX_V_COEF, %%mm2; /* Multiply v coeffs 0x0000crcrcrcrcrcr */ | ||
246 | |||
247 | /* mm0: 0x000000yy00yy00yy mm1: 0x0000uuuuuuuu0000 mm2: 0x00000000vvvvvvvv */ | ||
248 | paddsw %%mm1, %%mm0; /* Add u to result */ | ||
249 | paddsw %%mm2, %%mm0; /* Add v to result 0x0000rrrrggggbbbb */ | ||
250 | psraw $6, %%mm0; /* Demote precision */ | ||
251 | packuswb %%mm0, %%mm0; /* Pack into ARGB 0x0000000000rrggbb */ | ||
252 | movd %%mm0, (%3); /* Store output */ | ||
253 | " | ||
254 | : | ||
255 | : "r" (&y), "r" (&u), "r" (&v), "r" (output)); | ||
256 | } | ||
257 | |||
258 | inline void mpeg3_601_bgra32_mmx(unsigned long y, | ||
259 | unsigned long u, | ||
260 | unsigned long v, | ||
261 | unsigned long *output) | ||
262 | { | ||
263 | asm(" | ||
264 | /* Output will be 0x00rrggbb with the 00 trailing so this can also be used */ | ||
265 | /* for bgr24. */ | ||
266 | movd (%0), %%mm0; /* Load y 0x00000000000000yy */ | ||
267 | psubsw mpeg3_MMX_601_Y_DIFF, %%mm0; /* Subtract 16 from y */ | ||
268 | movd (%1), %%mm1; /* Load u 0x00000000000000cr */ | ||
269 | movq %%mm0, %%mm3; /* Copy y to temp */ | ||
270 | psllq $16, %%mm1; /* Shift u 0x0000000000cr0000 */ | ||
271 | movd (%2), %%mm2; /* Load v 0x00000000000000cb */ | ||
272 | psllq $16, %%mm3; /* Shift y */ | ||
273 | movq %%mm1, %%mm4; /* Copy u to temp */ | ||
274 | por %%mm3, %%mm0; /* Overlay new y byte 0x0000000000yy00yy */ | ||
275 | psllq $16, %%mm4; /* Shift u */ | ||
276 | movq %%mm2, %%mm5; /* Copy v to temp */ | ||
277 | psllq $16, %%mm3; /* Shift y */ | ||
278 | por %%mm4, %%mm1; /* Overlay new u byte 0x000000cr00cr0000 */ | ||
279 | psllq $16, %%mm5; /* Shift v */ | ||
280 | por %%mm3, %%mm0; /* Overlay new y byte 0x000000yy00yy00yy */ | ||
281 | por %%mm5, %%mm2; /* Overlay new v byte 0x0000000000cb00cb */ | ||
282 | |||
283 | /* mm0: 0x000000yy00yy00yy mm1: 0x000000uu00uu0000 mm2: 0x0000000000vv00vv */ | ||
284 | pmullw mpeg3_MMX_601_Y_COEF, %%mm0; /* Scale and shift y coeffs */ | ||
285 | psubw mpeg3_MMX_U_80, %%mm1; /* Subtract 128 from u 0x000000uu00uu0000 */ | ||
286 | pmullw mpeg3_MMX_U_COEF, %%mm1; /* Multiply u coeffs 0x0000uuuuuuuu0000 */ | ||
287 | psubw mpeg3_MMX_V_80, %%mm2; /* Subtract 128 from v 0x0000000000cb00cb */ | ||
288 | pmullw mpeg3_MMX_V_COEF, %%mm2; /* Multiply v coeffs 0x0000crcrcrcrcrcr */ | ||
289 | |||
290 | /* mm0: 0x000000yy00yy00yy mm1: 0x0000uuuuuuuu0000 mm2: 0x00000000vvvvvvvv */ | ||
291 | paddsw %%mm1, %%mm0; /* Add u to result */ | ||
292 | paddsw %%mm2, %%mm0; /* Add v to result 0x0000rrrrggggbbbb */ | ||
293 | psraw $6, %%mm0; /* Demote precision */ | ||
294 | packuswb %%mm0, %%mm0; /* Pack into ARGB 0x0000000000rrggbb */ | ||
295 | movd %%mm0, (%3); /* Store output */ | ||
296 | " | ||
297 | : | ||
298 | : "r" (&y), "r" (&u), "r" (&v), "r" (output)); | ||
299 | } | ||
300 | |||
301 | static unsigned LONGLONG mpeg3_MMX_U_80_RGB = 0x0000000000800080LL; | ||
302 | static unsigned LONGLONG mpeg3_MMX_V_80_RGB = 0x0000008000800000LL; | ||
303 | static LONGLONG mpeg3_MMX_U_COEF_RGB = 0x00000000ffd30058LL; | ||
304 | static LONGLONG mpeg3_MMX_V_COEF_RGB = 0x0000006fffea0000LL; | ||
305 | |||
306 | inline void mpeg3_rgba32_mmx(unsigned long y, | ||
307 | unsigned long u, | ||
308 | unsigned long v, | ||
309 | unsigned long *output) | ||
310 | { | ||
311 | asm(" | ||
312 | /* Output will be 0x00bbggrr with the 00 trailing so this can also be used */ | ||
313 | /* for rgb24. */ | ||
314 | movd (%0), %%mm0; /* Load y 0x00000000000000yy */ | ||
315 | movd (%1), %%mm1; /* Load v 0x00000000000000vv */ | ||
316 | movq %%mm0, %%mm3; /* Copy y to temp */ | ||
317 | psllq $16, %%mm1; /* Shift v 0x0000000000vv0000 */ | ||
318 | movd (%2), %%mm2; /* Load u 0x00000000000000uu */ | ||
319 | psllq $16, %%mm3; /* Shift y */ | ||
320 | movq %%mm1, %%mm4; /* Copy v to temp */ | ||
321 | por %%mm3, %%mm0; /* Overlay new y byte 0x0000000000yy00yy */ | ||
322 | psllq $16, %%mm4; /* Shift v */ | ||
323 | movq %%mm2, %%mm5; /* Copy u to temp */ | ||
324 | psllq $16, %%mm3; /* Shift y */ | ||
325 | por %%mm4, %%mm1; /* Overlay new v byte 0x000000vv00vv0000 */ | ||
326 | psllq $16, %%mm5; /* Shift u */ | ||
327 | por %%mm3, %%mm0; /* Overlay new y byte 0x000000yy00yy00yy */ | ||
328 | por %%mm5, %%mm2; /* Overlay new u byte 0x0000000000uu00uu */ | ||
329 | |||
330 | /* mm0: 0x000000yy00yy00yy mm1: 0x000000vv00vv0000 mm2: 0x0000000000uu00uu */ | ||
331 | psubw mpeg3_MMX_V_80_RGB, %%mm1; /* Subtract 128 from v 0x000000vv00vv0000 */ | ||
332 | pmullw mpeg3_MMX_V_COEF_RGB, %%mm1; /* Multiply v coeffs 0x0000vvvvvvvv0000 */ | ||
333 | psllw $6, %%mm0; /* Shift y coeffs 0x0000yyy0yyy0yyy0 */ | ||
334 | psubw mpeg3_MMX_U_80_RGB, %%mm2; /* Subtract 128 from u 0x0000000000uu00uu */ | ||
335 | pmullw mpeg3_MMX_U_COEF_RGB, %%mm2; /* Multiply u coeffs 0x0000uuuuuuuuuuuu */ | ||
336 | |||
337 | /* mm0: 0x000000yy00yy00yy mm1: 0x0000vvvvvvvv0000 mm2: 0x00000000uuuuuuuu */ | ||
338 | paddsw %%mm1, %%mm0; /* Add v to result */ | ||
339 | paddsw %%mm2, %%mm0; /* Add u to result 0x0000bbbbggggrrrr */ | ||
340 | psraw $6, %%mm0; /* Demote precision */ | ||
341 | packuswb %%mm0, %%mm0; /* Pack into RGBA 0x0000000000bbggrr */ | ||
342 | movd %%mm0, (%3); /* Store output */ | ||
343 | " | ||
344 | : | ||
345 | : "r" (&y), "r" (&v), "r" (&u), "r" (output)); | ||
346 | } | ||
347 | |||
348 | inline void mpeg3_601_rgba32_mmx(unsigned long y, | ||
349 | unsigned long u, | ||
350 | unsigned long v, | ||
351 | unsigned long *output) | ||
352 | { | ||
353 | asm(" | ||
354 | /* Output will be 0x00bbggrr with the 00 trailing so this can also be used */ | ||
355 | /* for rgb24. */ | ||
356 | movd (%0), %%mm0; /* Load y 0x00000000000000yy */ | ||
357 | psubsw mpeg3_MMX_601_Y_DIFF, %%mm0; /* Subtract 16 from y */ | ||
358 | movd (%1), %%mm1; /* Load v 0x00000000000000vv */ | ||
359 | movq %%mm0, %%mm3; /* Copy y to temp */ | ||
360 | psllq $16, %%mm1; /* Shift v 0x0000000000vv0000 */ | ||
361 | movd (%2), %%mm2; /* Load u 0x00000000000000uu */ | ||
362 | psllq $16, %%mm3; /* Shift y */ | ||
363 | movq %%mm1, %%mm4; /* Copy v to temp */ | ||
364 | por %%mm3, %%mm0; /* Overlay new y byte 0x0000000000yy00yy */ | ||
365 | psllq $16, %%mm4; /* Shift v */ | ||
366 | movq %%mm2, %%mm5; /* Copy u to temp */ | ||
367 | psllq $16, %%mm3; /* Shift y */ | ||
368 | por %%mm4, %%mm1; /* Overlay new v byte 0x000000vv00vv0000 */ | ||
369 | psllq $16, %%mm5; /* Shift u */ | ||
370 | por %%mm3, %%mm0; /* Overlay new y byte 0x000000yy00yy00yy */ | ||
371 | por %%mm5, %%mm2; /* Overlay new u byte 0x0000000000uu00uu */ | ||
372 | |||
373 | /* mm0: 0x000000yy00yy00yy mm1: 0x000000vv00vv0000 mm2: 0x0000000000uu00uu */ | ||
374 | pmullw mpeg3_MMX_601_Y_COEF, %%mm0; /* Scale y coeffs */ | ||
375 | psubw mpeg3_MMX_V_80_RGB, %%mm1; /* Subtract 128 from v 0x000000vv00vv0000 */ | ||
376 | pmullw mpeg3_MMX_V_COEF_RGB, %%mm1; /* Multiply v coeffs 0x0000vvvvvvvv0000 */ | ||
377 | psubw mpeg3_MMX_U_80_RGB, %%mm2; /* Subtract 128 from u 0x0000000000uu00uu */ | ||
378 | pmullw mpeg3_MMX_U_COEF_RGB, %%mm2; /* Multiply u coeffs 0x0000uuuuuuuuuuuu */ | ||
379 | |||
380 | /* mm0: 0x000000yy00yy00yy mm1: 0x0000vvvvvvvv0000 mm2: 0x00000000uuuuuuuu */ | ||
381 | paddsw %%mm1, %%mm0; /* Add v to result */ | ||
382 | paddsw %%mm2, %%mm0; /* Add u to result 0x0000bbbbggggrrrr */ | ||
383 | psraw $6, %%mm0; /* Demote precision */ | ||
384 | packuswb %%mm0, %%mm0; /* Pack into RGBA 0x0000000000bbggrr */ | ||
385 | movd %%mm0, (%3); /* Store output */ | ||
386 | " | ||
387 | : | ||
388 | : "r" (&y), "r" (&v), "r" (&u), "r" (output)); | ||
389 | } | ||
390 | |||
391 | #endif | ||
392 | |||
393 | #define DITHER_ROW_HEAD \ | ||
394 | for(h = 0; h < video->out_h; h++) \ | ||
395 | { \ | ||
396 | y_in = &src[0][(video->y_table[h] + video->in_y) * video->coded_picture_width] + video->in_x; \ | ||
397 | cb_in = &src[1][((video->y_table[h] + video->in_y) >> 1) * video->chrom_width] + (video->in_x >> 2); \ | ||
398 | cr_in = &src[2][((video->y_table[h] + video->in_y) >> 1) * video->chrom_width] + (video->in_x >> 1); \ | ||
399 | data = output_rows[h]; | ||
400 | |||
401 | #define DITHER_ROW_TAIL \ | ||
402 | } | ||
403 | |||
404 | #define DITHER_SCALE_HEAD \ | ||
405 | for(w = 0; w < video->out_w; w++) \ | ||
406 | { \ | ||
407 | uv_subscript = video->x_table[w] / 2; \ | ||
408 | y_l = y_in[video->x_table[w]]; \ | ||
409 | y_l <<= 16; \ | ||
410 | r_l = (y_l + video->cr_to_r[cr_in[uv_subscript]]) >> 16; \ | ||
411 | g_l = (y_l + video->cr_to_g[cr_in[uv_subscript]] + video->cb_to_g[cb_in[uv_subscript]]) >> 16; \ | ||
412 | b_l = (y_l + video->cb_to_b[cb_in[uv_subscript]]) >> 16; | ||
413 | |||
414 | #define DITHER_SCALE_601_HEAD \ | ||
415 | for(w = 0; w < video->out_w; w++) \ | ||
416 | { \ | ||
417 | uv_subscript = video->x_table[w] / 2; \ | ||
418 | y_l = mpeg3_601_to_rgb[y_in[video->x_table[w]]]; \ | ||
419 | y_l <<= 16; \ | ||
420 | r_l = (y_l + video->cr_to_r[cr_in[uv_subscript]]) >> 16; \ | ||
421 | g_l = (y_l + video->cr_to_g[cr_in[uv_subscript]] + video->cb_to_g[cb_in[uv_subscript]]) >> 16; \ | ||
422 | b_l = (y_l + video->cb_to_b[cb_in[uv_subscript]]) >> 16; | ||
423 | |||
424 | #define DITHER_SCALE_TAIL \ | ||
425 | } | ||
426 | |||
427 | #define DITHER_MMX_SCALE_HEAD \ | ||
428 | for(w = 0; w < video->out_w; w++) \ | ||
429 | { \ | ||
430 | uv_subscript = video->x_table[w] / 2; | ||
431 | |||
432 | #define DITHER_MMX_SCALE_TAIL \ | ||
433 | data += step; \ | ||
434 | } | ||
435 | |||
436 | #define DITHER_MMX_HEAD \ | ||
437 | for(w = 0; w < video->out_w; w += 2) \ | ||
438 | { | ||
439 | |||
440 | #define DITHER_MMX_TAIL \ | ||
441 | data += step; \ | ||
442 | cr_in++; \ | ||
443 | cb_in++; \ | ||
444 | } | ||
445 | |||
446 | #define DITHER_HEAD \ | ||
447 | for(w = 0; w < video->horizontal_size; w++) \ | ||
448 | { \ | ||
449 | y_l = *y_in++; \ | ||
450 | y_l <<= 16; \ | ||
451 | r_l = (y_l + video->cr_to_r[*cr_in]) >> 16; \ | ||
452 | g_l = (y_l + video->cr_to_g[*cr_in] + video->cb_to_g[*cb_in]) >> 16; \ | ||
453 | b_l = (y_l + video->cb_to_b[*cb_in]) >> 16; | ||
454 | |||
455 | #define DITHER_601_HEAD \ | ||
456 | for(w = 0; w < video->horizontal_size; w++) \ | ||
457 | { \ | ||
458 | y_l = mpeg3_601_to_rgb[*y_in++]; \ | ||
459 | y_l <<= 16; \ | ||
460 | r_l = (y_l + video->cr_to_r[*cr_in]) >> 16; \ | ||
461 | g_l = (y_l + video->cr_to_g[*cr_in] + video->cb_to_g[*cb_in]) >> 16; \ | ||
462 | b_l = (y_l + video->cb_to_b[*cb_in]) >> 16; | ||
463 | |||
464 | #define DITHER_TAIL \ | ||
465 | if(w & 1) \ | ||
466 | { \ | ||
467 | cr_in++; \ | ||
468 | cb_in++; \ | ||
469 | } \ | ||
470 | } | ||
471 | |||
472 | |||
473 | #define STORE_PIXEL_BGR888 \ | ||
474 | *data++ = CLIP(b_l); \ | ||
475 | *data++ = CLIP(g_l); \ | ||
476 | *data++ = CLIP(r_l); | ||
477 | |||
478 | #define STORE_PIXEL_BGRA8888 \ | ||
479 | *data++ = CLIP(b_l); \ | ||
480 | *data++ = CLIP(g_l); \ | ||
481 | *data++ = CLIP(r_l); \ | ||
482 | *data++ = 0; | ||
483 | |||
484 | #define STORE_PIXEL_RGB565 \ | ||
485 | *((unsigned short*)data)++ = \ | ||
486 | ((CLIP(r_l) & 0xf8) << 8) | \ | ||
487 | ((CLIP(g_l) & 0xfc) << 3) | \ | ||
488 | ((CLIP(b_l) & 0xf8) >> 3); | ||
489 | |||
490 | #define STORE_PIXEL_RGB888 \ | ||
491 | *data++ = CLIP(r_l); \ | ||
492 | *data++ = CLIP(g_l); \ | ||
493 | *data++ = CLIP(b_l); | ||
494 | |||
495 | #define STORE_PIXEL_RGBA8888 \ | ||
496 | *data++ = CLIP(r_l); \ | ||
497 | *data++ = CLIP(g_l); \ | ||
498 | *data++ = CLIP(b_l); \ | ||
499 | *data++ = 0; | ||
500 | |||
501 | #define STORE_PIXEL_RGBA16161616 \ | ||
502 | *data_s++ = CLIP(r_l); \ | ||
503 | *data_s++ = CLIP(g_l); \ | ||
504 | *data_s++ = CLIP(b_l); \ | ||
505 | *data_s++ = 0; | ||
506 | |||
507 | |||
508 | |||
509 | /* Only good for YUV 4:2:0 */ | ||
510 | int mpeg3video_ditherframe(mpeg3video_t *video, unsigned char **src, unsigned char **output_rows) | ||
511 | { | ||
512 | int h = 0; | ||
513 | register unsigned char *y_in, *cb_in, *cr_in; | ||
514 | long y_l, r_l, b_l, g_l; | ||
515 | register unsigned char *data; | ||
516 | register int uv_subscript, step, w = -1; | ||
517 | |||
518 | #ifdef HAVE_MMX | ||
519 | /* =================================== MMX ===================================== */ | ||
520 | if(video->have_mmx && | ||
521 | video->out_w == video->horizontal_size && | ||
522 | video->out_h == video->vertical_size && | ||
523 | video->in_w == video->out_w && | ||
524 | video->in_h == video->out_h && | ||
525 | video->in_x == 0 && | ||
526 | video->in_y == 0 && | ||
527 | (video->color_model == MPEG3_RGB565 || video->color_model == MPEG3_601_RGB565)) | ||
528 | { | ||
529 | /* Unscaled 16 bit */ | ||
530 | mpeg3video_rgb16_mmx(src[0], | ||
531 | src[2], | ||
532 | src[1], | ||
533 | output_rows[0], | ||
534 | video->out_h, | ||
535 | video->out_w, | ||
536 | (output_rows[1] - output_rows[0]) / 2 - video->out_w); | ||
537 | } | ||
538 | else | ||
539 | if(video->have_mmx && | ||
540 | (video->color_model == MPEG3_BGRA8888 || | ||
541 | video->color_model == MPEG3_BGR888 || | ||
542 | /* video->color_model == MPEG3_RGB888 || */ | ||
543 | video->color_model == MPEG3_RGBA8888 || | ||
544 | video->color_model == MPEG3_601_BGR888 || | ||
545 | video->color_model == MPEG3_601_BGRA8888 || | ||
546 | video->color_model == MPEG3_601_RGB888 || | ||
547 | video->color_model == MPEG3_601_RGBA8888)) | ||
548 | { | ||
549 | /* Original MMX */ | ||
550 | if(video->color_model == MPEG3_BGRA8888 || | ||
551 | video->color_model == MPEG3_RGBA8888 || | ||
552 | video->color_model == MPEG3_601_BGRA8888 || | ||
553 | video->color_model == MPEG3_601_RGBA8888) step = 4; | ||
554 | else | ||
555 | if(video->color_model == MPEG3_BGR888 || | ||
556 | video->color_model == MPEG3_RGB888 || | ||
557 | video->color_model == MPEG3_601_BGR888 || | ||
558 | video->color_model == MPEG3_601_RGB888) step = 3; | ||
559 | |||
560 | DITHER_ROW_HEAD | ||
561 | /* Transfer row with scaling */ | ||
562 | if(video->out_w != video->horizontal_size) | ||
563 | { | ||
564 | switch(video->color_model) | ||
565 | { | ||
566 | case MPEG3_BGRA8888: | ||
567 | case MPEG3_BGR888: | ||
568 | DITHER_MMX_SCALE_HEAD | ||
569 | mpeg3_bgra32_mmx(y_in[video->x_table[w]], | ||
570 | cr_in[uv_subscript], | ||
571 | cb_in[uv_subscript], | ||
572 | (unsigned long*)data); | ||
573 | DITHER_MMX_SCALE_TAIL | ||
574 | break; | ||
575 | |||
576 | case MPEG3_601_BGRA8888: | ||
577 | case MPEG3_601_BGR888: | ||
578 | DITHER_MMX_SCALE_HEAD | ||
579 | mpeg3_601_bgra32_mmx(y_in[video->x_table[w]], | ||
580 | cr_in[uv_subscript], | ||
581 | cb_in[uv_subscript], | ||
582 | (unsigned long*)data); | ||
583 | DITHER_MMX_SCALE_TAIL | ||
584 | break; | ||
585 | |||
586 | case MPEG3_RGBA8888: | ||
587 | case MPEG3_RGB888: | ||
588 | DITHER_MMX_SCALE_HEAD | ||
589 | mpeg3_rgba32_mmx(y_in[video->x_table[w]], | ||
590 | cr_in[uv_subscript], | ||
591 | cb_in[uv_subscript], | ||
592 | (unsigned long*)data); | ||
593 | DITHER_MMX_SCALE_TAIL | ||
594 | break; | ||
595 | |||
596 | case MPEG3_601_RGBA8888: | ||
597 | case MPEG3_601_RGB888: | ||
598 | DITHER_MMX_SCALE_HEAD | ||
599 | mpeg3_601_rgba32_mmx(y_in[video->x_table[w]], | ||
600 | cr_in[uv_subscript], | ||
601 | cb_in[uv_subscript], | ||
602 | (unsigned long*)data); | ||
603 | DITHER_MMX_SCALE_TAIL | ||
604 | break; | ||
605 | } | ||
606 | } | ||
607 | else | ||
608 | /* Transfer row unscaled */ | ||
609 | { | ||
610 | switch(video->color_model) | ||
611 | { | ||
612 | /* MMX byte swap 24 and 32 bit */ | ||
613 | case MPEG3_BGRA8888: | ||
614 | case MPEG3_BGR888: | ||
615 | DITHER_MMX_HEAD | ||
616 | mpeg3_bgra32_mmx(*y_in++, | ||
617 | *cr_in, | ||
618 | *cb_in, | ||
619 | (unsigned long*)data); | ||
620 | data += step; | ||
621 | mpeg3_bgra32_mmx(*y_in++, | ||
622 | *cr_in, | ||
623 | *cb_in, | ||
624 | (unsigned long*)data); | ||
625 | DITHER_MMX_TAIL | ||
626 | break; | ||
627 | |||
628 | /* MMX 601 byte swap 24 and 32 bit */ | ||
629 | case MPEG3_601_BGRA8888: | ||
630 | case MPEG3_601_BGR888: | ||
631 | DITHER_MMX_HEAD | ||
632 | mpeg3_601_bgra32_mmx(*y_in++, | ||
633 | *cr_in, | ||
634 | *cb_in, | ||
635 | (unsigned long*)data); | ||
636 | data += step; | ||
637 | mpeg3_601_bgra32_mmx(*y_in++, | ||
638 | *cr_in, | ||
639 | *cb_in, | ||
640 | (unsigned long*)data); | ||
641 | DITHER_MMX_TAIL | ||
642 | break; | ||
643 | |||
644 | /* MMX 24 and 32 bit no byte swap */ | ||
645 | case MPEG3_RGBA8888: | ||
646 | case MPEG3_RGB888: | ||
647 | DITHER_MMX_HEAD | ||
648 | mpeg3_rgba32_mmx(*y_in++, | ||
649 | *cr_in, | ||
650 | *cb_in, | ||
651 | (unsigned long*)data); | ||
652 | data += step; | ||
653 | mpeg3_rgba32_mmx(*y_in++, | ||
654 | *cr_in, | ||
655 | *cb_in, | ||
656 | (unsigned long*)data); | ||
657 | DITHER_MMX_TAIL | ||
658 | break; | ||
659 | |||
660 | /* MMX 601 24 and 32 bit no byte swap */ | ||
661 | case MPEG3_601_RGBA8888: | ||
662 | case MPEG3_601_RGB888: | ||
663 | DITHER_MMX_HEAD | ||
664 | mpeg3_601_rgba32_mmx(*y_in++, | ||
665 | *cr_in, | ||
666 | *cb_in, | ||
667 | (unsigned long*)data); | ||
668 | data += step; | ||
669 | mpeg3_601_rgba32_mmx(*y_in++, | ||
670 | *cr_in, | ||
671 | *cb_in, | ||
672 | (unsigned long*)data); | ||
673 | DITHER_MMX_TAIL | ||
674 | break; | ||
675 | } | ||
676 | } | ||
677 | DITHER_ROW_TAIL | ||
678 | } | ||
679 | else | ||
680 | #endif | ||
681 | /* ================================== NO MMX ==================================== */ | ||
682 | { | ||
683 | DITHER_ROW_HEAD | ||
684 | /* Transfer row with scaling */ | ||
685 | if(video->out_w != video->horizontal_size) | ||
686 | { | ||
687 | switch(video->color_model) | ||
688 | { | ||
689 | case MPEG3_BGR888: | ||
690 | DITHER_SCALE_HEAD | ||
691 | STORE_PIXEL_BGR888 | ||
692 | DITHER_SCALE_TAIL | ||
693 | break; | ||
694 | case MPEG3_BGRA8888: | ||
695 | DITHER_SCALE_HEAD | ||
696 | STORE_PIXEL_BGRA8888 | ||
697 | DITHER_SCALE_TAIL | ||
698 | break; | ||
699 | case MPEG3_RGB565: | ||
700 | DITHER_SCALE_HEAD | ||
701 | STORE_PIXEL_RGB565 | ||
702 | DITHER_SCALE_TAIL | ||
703 | break; | ||
704 | case MPEG3_RGB888: | ||
705 | DITHER_SCALE_HEAD | ||
706 | STORE_PIXEL_RGB888 | ||
707 | DITHER_SCALE_TAIL | ||
708 | break; | ||
709 | case MPEG3_RGBA8888: | ||
710 | DITHER_SCALE_HEAD | ||
711 | STORE_PIXEL_RGBA8888 | ||
712 | DITHER_SCALE_TAIL | ||
713 | break; | ||
714 | case MPEG3_601_BGR888: | ||
715 | DITHER_SCALE_601_HEAD | ||
716 | STORE_PIXEL_BGR888 | ||
717 | DITHER_SCALE_TAIL | ||
718 | break; | ||
719 | case MPEG3_601_BGRA8888: | ||
720 | DITHER_SCALE_601_HEAD | ||
721 | STORE_PIXEL_BGRA8888 | ||
722 | DITHER_SCALE_TAIL | ||
723 | break; | ||
724 | case MPEG3_601_RGB565: | ||
725 | DITHER_SCALE_601_HEAD | ||
726 | STORE_PIXEL_RGB565 | ||
727 | DITHER_SCALE_TAIL | ||
728 | break; | ||
729 | case MPEG3_601_RGB888: | ||
730 | DITHER_SCALE_601_HEAD | ||
731 | STORE_PIXEL_RGB888 | ||
732 | DITHER_SCALE_TAIL | ||
733 | break; | ||
734 | case MPEG3_601_RGBA8888: | ||
735 | DITHER_SCALE_601_HEAD | ||
736 | STORE_PIXEL_RGBA8888 | ||
737 | DITHER_SCALE_TAIL | ||
738 | break; | ||
739 | case MPEG3_RGBA16161616: | ||
740 | { | ||
741 | register unsigned short *data_s = (unsigned short*)data; | ||
742 | DITHER_SCALE_HEAD | ||
743 | STORE_PIXEL_RGBA16161616 | ||
744 | DITHER_SCALE_TAIL | ||
745 | } | ||
746 | break; | ||
747 | } | ||
748 | } | ||
749 | else | ||
750 | { | ||
751 | /* Transfer row unscaled */ | ||
752 | switch(video->color_model) | ||
753 | { | ||
754 | case MPEG3_BGR888: | ||
755 | DITHER_HEAD | ||
756 | STORE_PIXEL_BGR888 | ||
757 | DITHER_TAIL | ||
758 | break; | ||
759 | case MPEG3_BGRA8888: | ||
760 | DITHER_HEAD | ||
761 | STORE_PIXEL_BGRA8888 | ||
762 | DITHER_TAIL | ||
763 | break; | ||
764 | case MPEG3_RGB565: | ||
765 | DITHER_HEAD | ||
766 | STORE_PIXEL_RGB565 | ||
767 | DITHER_TAIL | ||
768 | break; | ||
769 | case MPEG3_RGB888: | ||
770 | DITHER_HEAD | ||
771 | STORE_PIXEL_RGB888 | ||
772 | DITHER_TAIL | ||
773 | break; | ||
774 | case MPEG3_RGBA8888: | ||
775 | DITHER_HEAD | ||
776 | STORE_PIXEL_RGBA8888 | ||
777 | DITHER_TAIL | ||
778 | break; | ||
779 | case MPEG3_601_BGR888: | ||
780 | DITHER_601_HEAD | ||
781 | STORE_PIXEL_BGR888 | ||
782 | DITHER_TAIL | ||
783 | break; | ||
784 | case MPEG3_601_BGRA8888: | ||
785 | DITHER_601_HEAD | ||
786 | STORE_PIXEL_RGB565 | ||
787 | DITHER_TAIL | ||
788 | break; | ||
789 | case MPEG3_601_RGB565: | ||
790 | DITHER_601_HEAD | ||
791 | STORE_PIXEL_RGB565 | ||
792 | DITHER_TAIL | ||
793 | break; | ||
794 | case MPEG3_601_RGB888: | ||
795 | DITHER_601_HEAD | ||
796 | STORE_PIXEL_RGB888 | ||
797 | DITHER_TAIL | ||
798 | break; | ||
799 | case MPEG3_601_RGBA8888: | ||
800 | DITHER_601_HEAD | ||
801 | STORE_PIXEL_RGBA8888 | ||
802 | DITHER_TAIL | ||
803 | break; | ||
804 | case MPEG3_RGBA16161616: | ||
805 | { | ||
806 | register unsigned short *data_s = (unsigned short*)data; | ||
807 | DITHER_HEAD | ||
808 | STORE_PIXEL_RGBA16161616 | ||
809 | DITHER_TAIL | ||
810 | } | ||
811 | break; | ||
812 | } | ||
813 | } | ||
814 | DITHER_ROW_TAIL | ||
815 | } /* End of non-MMX */ | ||
816 | |||
817 | #ifdef HAVE_MMX | ||
818 | if(video->have_mmx) | ||
819 | __asm__ __volatile__ ("emms"); | ||
820 | #endif | ||
821 | return 0; | ||
822 | } | ||
823 | |||
824 | int mpeg3video_ditherframe444(mpeg3video_t *video, unsigned char *src[]) | ||
825 | { | ||
826 | return 0; | ||
827 | } | ||
828 | |||
829 | int mpeg3video_dithertop(mpeg3video_t *video, unsigned char *src[]) | ||
830 | { | ||
831 | return mpeg3video_ditherframe(video, src, video->output_rows); | ||
832 | } | ||
833 | |||
834 | int mpeg3video_dithertop444(mpeg3video_t *video, unsigned char *src[]) | ||
835 | { | ||
836 | return 0; | ||
837 | } | ||
838 | |||
839 | int mpeg3video_ditherbot(mpeg3video_t *video, unsigned char *src[]) | ||
840 | { | ||
841 | return 0; | ||
842 | } | ||
843 | |||
844 | int mpeg3video_ditherbot444(mpeg3video_t *video, unsigned char *src[]) | ||
845 | { | ||
846 | return 0; | ||
847 | } | ||
848 | |||
849 | void memcpy_fast(unsigned char *output, unsigned char *input, long len) | ||
850 | { | ||
851 | int i, len2; | ||
852 | /* 8 byte alignment */ | ||
853 | /* | ||
854 | * if(!((long)input & 0x7)) | ||
855 | * { | ||
856 | * len2 = len >> 4; | ||
857 | * for(i = 0; i < len2; ) | ||
858 | * { | ||
859 | * ((MPEG3_INT64*)output)[i] = ((MPEG3_INT64*)input)[i]; | ||
860 | * i++; | ||
861 | * ((MPEG3_INT64*)output)[i] = ((MPEG3_INT64*)input)[i]; | ||
862 | * i++; | ||
863 | * } | ||
864 | * | ||
865 | * for(i *= 16; i < len; i++) | ||
866 | * { | ||
867 | * output[i] = input[i]; | ||
868 | * } | ||
869 | * } | ||
870 | * else | ||
871 | */ | ||
872 | memcpy(output, input, len); | ||
873 | } | ||
874 | |||
875 | int mpeg3video_init_output() | ||
876 | { | ||
877 | int i, value; | ||
878 | for(i = 0; i < 256; i++) | ||
879 | { | ||
880 | value = (int)(1.1644 * i - 255 * 0.0627 + 0.5); | ||
881 | if(value < 0) value = 0; | ||
882 | else | ||
883 | if(value > 255) value = 255; | ||
884 | mpeg3_601_to_rgb[i] = value; | ||
885 | } | ||
886 | return 0; | ||
887 | } | ||
888 | |||
889 | int mpeg3video_present_frame(mpeg3video_t *video) | ||
890 | { | ||
891 | int i, j, k, l; | ||
892 | unsigned char **src = video->output_src; | ||
893 | |||
894 | /* Copy YUV buffers */ | ||
895 | if(video->want_yvu) | ||
896 | { | ||
897 | long size[2]; | ||
898 | long offset[2]; | ||
899 | |||
900 | /* Drop a frame */ | ||
901 | if(!video->y_output) return 0; | ||
902 | |||
903 | /* Copy a frame */ | ||
904 | if(video->in_x == 0 && | ||
905 | video->in_w >= video->coded_picture_width) | ||
906 | { | ||
907 | size[0] = video->coded_picture_width * video->in_h; | ||
908 | size[1] = video->chrom_width * (int)((float)video->in_h / 2 + 0.5); | ||
909 | offset[0] = video->coded_picture_width * video->in_y; | ||
910 | offset[1] = video->chrom_width * (int)((float)video->in_y / 2 + 0.5); | ||
911 | |||
912 | /* | ||
913 | * if(video->in_y > 0) | ||
914 | * { | ||
915 | * offset[1] += video->chrom_width / 2; | ||
916 | * size[1] += video->chrom_width / 2; | ||
917 | * } | ||
918 | */ | ||
919 | |||
920 | memcpy(video->y_output, src[0] + offset[0], size[0]); | ||
921 | memcpy(video->u_output, src[1] + offset[1], size[1]); | ||
922 | memcpy(video->v_output, src[2] + offset[1], size[1]); | ||
923 | } | ||
924 | else | ||
925 | { | ||
926 | for(i = 0, j = video->in_y; i < video->in_h; i++, j++) | ||
927 | { | ||
928 | memcpy(video->y_output + i * video->in_w, | ||
929 | src[0] + j * video->coded_picture_width + video->in_x, | ||
930 | video->in_w); | ||
931 | memcpy(video->u_output + i * video->in_w / 4, | ||
932 | src[1] + j * video->chrom_width / 2 + video->in_x / 4, | ||
933 | video->in_w / 4); | ||
934 | memcpy(video->v_output + i * video->in_w / 4, | ||
935 | src[2] + j * video->chrom_width / 2 + video->in_x / 4, | ||
936 | video->in_w / 4); | ||
937 | } | ||
938 | } | ||
939 | |||
940 | return 0; | ||
941 | } | ||
942 | |||
943 | /* Want RGB buffer */ | ||
944 | /* Copy the frame to the output with YUV to RGB conversion */ | ||
945 | if(video->prog_seq) | ||
946 | { | ||
947 | if(video->chroma_format != CHROMA444) | ||
948 | { | ||
949 | mpeg3video_ditherframe(video, src, video->output_rows); | ||
950 | } | ||
951 | else | ||
952 | mpeg3video_ditherframe444(video, src); | ||
953 | } | ||
954 | else | ||
955 | { | ||
956 | if((video->pict_struct == FRAME_PICTURE && video->topfirst) || | ||
957 | video->pict_struct == BOTTOM_FIELD) | ||
958 | { | ||
959 | /* top field first */ | ||
960 | if(video->chroma_format != CHROMA444) | ||
961 | { | ||
962 | mpeg3video_dithertop(video, src); | ||
963 | mpeg3video_ditherbot(video, src); | ||
964 | } | ||
965 | else | ||
966 | { | ||
967 | mpeg3video_dithertop444(video, src); | ||
968 | mpeg3video_ditherbot444(video, src); | ||
969 | } | ||
970 | } | ||
971 | else | ||
972 | { | ||
973 | /* bottom field first */ | ||
974 | if(video->chroma_format != CHROMA444) | ||
975 | { | ||
976 | mpeg3video_ditherbot(video, src); | ||
977 | mpeg3video_dithertop(video, src); | ||
978 | } | ||
979 | else | ||
980 | { | ||
981 | mpeg3video_ditherbot444(video, src); | ||
982 | mpeg3video_dithertop444(video, src); | ||
983 | } | ||
984 | } | ||
985 | } | ||
986 | return 0; | ||
987 | } | ||
988 | |||
989 | int mpeg3video_display_second_field(mpeg3video_t *video) | ||
990 | { | ||
991 | /* Not used */ | ||
992 | return 0; | ||
993 | } | ||
diff --git a/core/multimedia/opieplayer/libmpeg3/video/reconmmx.s b/core/multimedia/opieplayer/libmpeg3/video/reconmmx.s new file mode 100644 index 0000000..1bb98ef --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/reconmmx.s | |||
@@ -0,0 +1,301 @@ | |||
1 | ADD_1: dd 01010101h, 01010101h | ||
2 | MASK_AND:dd 7f7f7f7fh, 7f7f7f7fh | ||
3 | PLUS_384:dd 01800180h, 01800180h | ||
4 | PLUS_128:dd 00800080h, 00800080h | ||
5 | |||
6 | %assign LocalFrameSize 0 | ||
7 | %assign RegisterStorageSize 16 | ||
8 | |||
9 | ; Arguments: | ||
10 | %assign source LocalFrameSize + RegisterStorageSize + 4 | ||
11 | %assign dest LocalFrameSize + RegisterStorageSize + 8 | ||
12 | %assign lx2 LocalFrameSize + RegisterStorageSize + 12 | ||
13 | %assign h LocalFrameSize + RegisterStorageSize + 16 | ||
14 | |||
15 | ; Locals (on local stack frame) | ||
16 | |||
17 | |||
18 | ; extern void C rec_mmx ( | ||
19 | ; unsigned char *source, | ||
20 | ; unsigned char *dest, | ||
21 | ; int lx2, | ||
22 | ; int h | ||
23 | ; | ||
24 | ; The local variables are on the stack, | ||
25 | ; | ||
26 | |||
27 | global recva_mmx | ||
28 | global recvac_mmx | ||
29 | global rech_mmx | ||
30 | global rechc_mmx | ||
31 | global add_block_mmx | ||
32 | global set_block_mmx | ||
33 | |||
34 | |||
35 | align 16 | ||
36 | rech_mmx: | ||
37 | push esi | ||
38 | push edi | ||
39 | push ecx | ||
40 | push ebx | ||
41 | mov esi, [esp+source] | ||
42 | mov edi, [esp+dest] | ||
43 | mov ecx, [esp+h] | ||
44 | mov ebx, [esp+lx2] | ||
45 | movq mm5, [MASK_AND] | ||
46 | movq mm6, [ADD_1] | ||
47 | .rech1: | ||
48 | movq mm0,[esi] | ||
49 | movq mm1,[esi+1] | ||
50 | movq mm2,[esi+8] | ||
51 | movq mm3,[esi+9] | ||
52 | psrlw mm0,1 | ||
53 | psrlw mm1,1 | ||
54 | psrlw mm2,1 | ||
55 | psrlw mm3,1 | ||
56 | pand mm0,mm5 | ||
57 | pand mm1,mm5 | ||
58 | pand mm2,mm5 | ||
59 | pand mm3,mm5 | ||
60 | paddusb mm0,mm1 | ||
61 | paddusb mm2,mm3 | ||
62 | paddusb mm0,mm6 | ||
63 | paddusb mm2,mm6 | ||
64 | movq [edi],mm0 | ||
65 | add esi,ebx | ||
66 | movq [edi+8],mm2 | ||
67 | add edi,ebx | ||
68 | dec ecx | ||
69 | jnz .rech1 | ||
70 | emms | ||
71 | pop ebx | ||
72 | pop ecx | ||
73 | pop edi | ||
74 | pop esi | ||
75 | ret | ||
76 | |||
77 | align 16 | ||
78 | rechc_mmx: | ||
79 | push esi | ||
80 | push edi | ||
81 | push ecx | ||
82 | push ebx | ||
83 | ; sub esp, LocalFrameSize | ||
84 | mov esi, [esp+source] | ||
85 | mov edi, [esp+dest] | ||
86 | mov ecx, [esp+h] | ||
87 | mov ebx, [esp+lx2] | ||
88 | movq mm5, [MASK_AND] | ||
89 | movq mm6, [ADD_1] | ||
90 | .rechc1: | ||
91 | movq mm0,[esi] | ||
92 | movq mm1,[esi+1] | ||
93 | psrlw mm0,1 | ||
94 | psrlw mm1,1 | ||
95 | pand mm0,mm5 | ||
96 | pand mm1,mm5 | ||
97 | paddusb mm0,mm1 | ||
98 | paddusb mm0,mm6 | ||
99 | movq [edi],mm0 | ||
100 | add edi,ebx | ||
101 | add esi,ebx | ||
102 | dec ecx | ||
103 | jnz .rechc1 | ||
104 | emms | ||
105 | ; add esp, LocalFrameSize | ||
106 | pop ebx | ||
107 | pop ecx | ||
108 | pop edi | ||
109 | pop esi | ||
110 | ret | ||
111 | |||
112 | |||
113 | |||
114 | %assign RegisterStorageSize 20 | ||
115 | %assign source LocalFrameSize + RegisterStorageSize + 4 | ||
116 | %assign dest LocalFrameSize + RegisterStorageSize + 8 | ||
117 | %assign lx LocalFrameSize + RegisterStorageSize + 12 | ||
118 | %assign lx2 LocalFrameSize + RegisterStorageSize + 16 | ||
119 | %assign h LocalFrameSize + RegisterStorageSize + 20 | ||
120 | |||
121 | align 16 | ||
122 | recva_mmx: | ||
123 | push esi | ||
124 | push edi | ||
125 | push ecx | ||
126 | push ebx | ||
127 | push edx | ||
128 | mov esi, [esp+source] | ||
129 | mov edi, [esp+dest] | ||
130 | mov ecx, [esp+h] | ||
131 | mov ebx, [esp+lx2] | ||
132 | mov edx, [esp+lx] | ||
133 | movq mm7, [MASK_AND] | ||
134 | movq mm6, [ADD_1] | ||
135 | .recva1: | ||
136 | movq mm0,[esi] | ||
137 | movq mm1,[esi+edx] | ||
138 | movq mm2,[esi+8] | ||
139 | movq mm3,[esi+edx+8] | ||
140 | movq mm4,[edi] | ||
141 | movq mm5,[edi+8] | ||
142 | psrlw mm0,1 | ||
143 | psrlw mm1,1 | ||
144 | psrlw mm2,1 | ||
145 | psrlw mm3,1 | ||
146 | psrlw mm4,1 | ||
147 | psrlw mm5,1 | ||
148 | pand mm0,mm7 | ||
149 | pand mm1,mm7 | ||
150 | pand mm2,mm7 | ||
151 | pand mm3,mm7 | ||
152 | pand mm4,mm7 | ||
153 | pand mm5,mm7 | ||
154 | paddusb mm0,mm1 | ||
155 | paddusb mm2,mm3 | ||
156 | paddusb mm0,mm6 | ||
157 | paddusb mm2,mm6 | ||
158 | psrlw mm0,1 | ||
159 | psrlw mm2,1 | ||
160 | pand mm0,mm7 | ||
161 | pand mm2,mm7 | ||
162 | paddusb mm4,mm0 | ||
163 | paddusb mm5,mm2 | ||
164 | paddusb mm4,mm6 | ||
165 | paddusb mm5,mm6 | ||
166 | movq [edi],mm4 | ||
167 | movq [edi+8],mm5 | ||
168 | add edi,ebx | ||
169 | add esi,ebx | ||
170 | dec ecx | ||
171 | jnz near .recva1 | ||
172 | emms | ||
173 | pop edx | ||
174 | pop ebx | ||
175 | pop ecx | ||
176 | pop edi | ||
177 | pop esi | ||
178 | ret | ||
179 | |||
180 | align 16 | ||
181 | recvac_mmx: | ||
182 | push esi | ||
183 | push edi | ||
184 | push ecx | ||
185 | push ebx | ||
186 | push edx | ||
187 | mov esi, [esp+source] | ||
188 | mov edi, [esp+dest] | ||
189 | mov ecx, [esp+h] | ||
190 | mov ebx, [esp+lx2] | ||
191 | mov edx, [esp+lx] | ||
192 | movq mm5, [MASK_AND] | ||
193 | movq mm6, [ADD_1] | ||
194 | .recvac1: | ||
195 | movq mm0,[esi] | ||
196 | movq mm1,[esi+edx] | ||
197 | movq mm4,[edi] | ||
198 | psrlw mm0,1 | ||
199 | psrlw mm1,1 | ||
200 | psrlw mm4,1 | ||
201 | pand mm0,mm5 | ||
202 | pand mm1,mm5 | ||
203 | pand mm4,mm5 | ||
204 | paddusb mm0,mm1 | ||
205 | paddusb mm0,mm6 | ||
206 | psrlw mm0,1 | ||
207 | pand mm0,mm5 | ||
208 | paddusb mm4,mm0 | ||
209 | paddusb mm4,mm6 | ||
210 | movq [edi],mm4 | ||
211 | add edi,ebx | ||
212 | add esi,ebx | ||
213 | dec ecx | ||
214 | jnz .recvac1 | ||
215 | emms | ||
216 | pop edx | ||
217 | pop ebx | ||
218 | pop ecx | ||
219 | pop edi | ||
220 | pop esi | ||
221 | ret | ||
222 | |||
223 | %assign RegisterStorageSize 20 | ||
224 | %assign rfp LocalFrameSize + RegisterStorageSize + 4 | ||
225 | %assign bp LocalFrameSize + RegisterStorageSize + 8 | ||
226 | %assign iincr LocalFrameSize + RegisterStorageSize + 12 | ||
227 | |||
228 | ; FIXME clipping needs to be done | ||
229 | |||
230 | align 16 | ||
231 | add_block_mmx: | ||
232 | push esi | ||
233 | push edi | ||
234 | push ecx | ||
235 | push ebx | ||
236 | push edx | ||
237 | mov esi, [esp+bp] | ||
238 | mov edi, [esp+rfp] | ||
239 | mov ebx, [esp+iincr] | ||
240 | ; movq mm7, [PLUS_384] | ||
241 | mov ecx,8 | ||
242 | pxor mm2,mm2 ; clear | ||
243 | %rep 8 | ||
244 | movq mm0, [edi] ; get dest | ||
245 | movq mm1,mm0 | ||
246 | punpcklbw mm0,mm2 | ||
247 | punpckhbw mm1,mm2 | ||
248 | paddsw mm0, [esi] | ||
249 | paddsw mm1, [esi+8] | ||
250 | ; paddsw mm0, mm7 | ||
251 | ; paddsw mm1, mm7 | ||
252 | packuswb mm0,mm1 | ||
253 | movq [edi], mm0 | ||
254 | add edi,ebx | ||
255 | add esi,16 | ||
256 | %endrep | ||
257 | emms | ||
258 | pop edx | ||
259 | pop ebx | ||
260 | pop ecx | ||
261 | pop edi | ||
262 | pop esi | ||
263 | ret | ||
264 | |||
265 | align 16 | ||
266 | set_block_mmx: | ||
267 | push esi | ||
268 | push edi | ||
269 | push ecx | ||
270 | push ebx | ||
271 | push edx | ||
272 | mov esi, [esp+bp] | ||
273 | mov edi, [esp+rfp] | ||
274 | mov ebx, [esp+iincr] | ||
275 | movq mm7, [PLUS_128] | ||
276 | %rep 4 | ||
277 | movq mm0, [esi] | ||
278 | movq mm1, [esi+8] | ||
279 | paddsw mm0, mm7 | ||
280 | movq mm2, [esi+16] | ||
281 | paddsw mm1, mm7 | ||
282 | movq mm3, [esi+24] | ||
283 | paddsw mm2, mm7 | ||
284 | packuswb mm0, mm1 | ||
285 | paddsw mm3, mm7 | ||
286 | movq [edi], mm0 | ||
287 | packuswb mm2, mm3 | ||
288 | add edi, ebx | ||
289 | add esi, 32 | ||
290 | movq [edi], mm2 | ||
291 | add edi, ebx | ||
292 | %endrep | ||
293 | emms | ||
294 | pop edx | ||
295 | pop ebx | ||
296 | pop ecx | ||
297 | pop edi | ||
298 | pop esi | ||
299 | ret | ||
300 | |||
301 | |||
diff --git a/core/multimedia/opieplayer/libmpeg3/video/reconstruct.c b/core/multimedia/opieplayer/libmpeg3/video/reconstruct.c new file mode 100644 index 0000000..531f9c0 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/reconstruct.c | |||
@@ -0,0 +1,1290 @@ | |||
1 | #include "../libmpeg3.h" | ||
2 | #include "../mpeg3protos.h" | ||
3 | #include "mpeg3video.h" | ||
4 | #include <stdio.h> | ||
5 | |||
6 | #ifdef HAVE_MMX | ||
7 | |||
8 | #ifdef HAVE_3Dnow | ||
9 | static inline void recva_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h) | ||
10 | { | ||
11 | __asm__( | ||
12 | ".align8\n" | ||
13 | "1:" | ||
14 | "movq (%1),%%mm0\n" /* 8 s */ | ||
15 | "movq 8(%1),%%mm1\n" /* 8 s */ | ||
16 | "movq (%4),%%mm2\n" /* 8 s +lx */ | ||
17 | "movq 8(%4),%%mm3\n" /* 8 s +lx **/ | ||
18 | |||
19 | "pavgusb %%mm2, %%mm0\n" | ||
20 | "addl %3, %1\n" | ||
21 | "pavgusb %%mm3, %%mm1\n" | ||
22 | |||
23 | "movq (%2),%%mm2\n" /* 8 d */ | ||
24 | "movq 8(%2),%%mm3\n" /* 8 d */ | ||
25 | "pavgusb %%mm2, %%mm0\n" | ||
26 | "addl %3, %4\n" | ||
27 | "pavgusb %%mm3, %%mm1\n" | ||
28 | |||
29 | "movq %%mm0,(%2)\n" | ||
30 | "movq %%mm1,8(%2)\n" | ||
31 | "addl %3, %2\n" | ||
32 | "loop 1b\n" | ||
33 | : | ||
34 | : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx) | ||
35 | ); | ||
36 | } | ||
37 | |||
38 | static inline void recvac_mmx(unsigned char *s, unsigned char *d, int lx,int lx2, int h) | ||
39 | { | ||
40 | __asm__( | ||
41 | ".align8\n" | ||
42 | "1:" | ||
43 | "movq (%1),%%mm0\n" /* 8 s */ | ||
44 | "movq (%4),%%mm2\n" /* 8 s +lx */ | ||
45 | "addl %3, %1\n" | ||
46 | "pavgusb %%mm2, %%mm0\n" | ||
47 | "movq (%2),%%mm3\n" /* 8 d */ | ||
48 | "addl %3, %4\n" | ||
49 | "pavgusb %%mm3, %%mm0\n" | ||
50 | "movq %%mm0,(%2)\n" | ||
51 | "addl %3, %2\n" | ||
52 | "loop 1b\n" | ||
53 | : | ||
54 | : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx) | ||
55 | ); | ||
56 | } | ||
57 | |||
58 | static inline void rech_mmx(unsigned char *s, unsigned char *d, int lx2, int h) | ||
59 | { | ||
60 | __asm__ ( | ||
61 | ".align8\n" | ||
62 | "1:" | ||
63 | "movq (%1),%%mm0\n" /* 8 s */ | ||
64 | "movq 8(%1),%%mm1\n" /* 8 s */ | ||
65 | "movq 1(%1),%%mm2\n" /* 8 s */ | ||
66 | "movq 9(%1),%%mm3\n" /* 8 s */ | ||
67 | |||
68 | "pavgusb %%mm2, %%mm0\n" | ||
69 | "addl %3, %1\n" | ||
70 | "pavgusb %%mm3, %%mm1\n" | ||
71 | |||
72 | "movq %%mm0,(%2)\n" | ||
73 | "movq %%mm1,8(%2)\n" | ||
74 | "addl %3, %2\n" | ||
75 | "loop 1b\n" | ||
76 | : | ||
77 | : "c" (h), "r" (s), "r" (d), "r" (lx2) | ||
78 | ); | ||
79 | } | ||
80 | |||
81 | static inline void rechc_mmx(unsigned char *s, unsigned char *d, int lx2, int h) | ||
82 | { | ||
83 | __asm__ ( | ||
84 | ".align8\n" | ||
85 | "1:" | ||
86 | "movq (%1),%%mm0\n" /* 8 s */ | ||
87 | "movq 1(%1),%%mm2\n" /* 8 s +1 */ | ||
88 | "addl %3, %1\n" | ||
89 | "pavgusb %%mm2, %%mm0\n" | ||
90 | "movq %%mm0,(%2)\n" | ||
91 | "addl %3, %2\n" | ||
92 | "loop 1b\n" | ||
93 | : | ||
94 | : "c" (h), "r" (s), "r" (d), "r" (lx2) | ||
95 | ); | ||
96 | } | ||
97 | |||
98 | static inline void recha_mmx(unsigned char *s, unsigned char *d,int lx2, int h) | ||
99 | { | ||
100 | __asm__ ( | ||
101 | ".align8\n" | ||
102 | "1:" | ||
103 | "movq (%1),%%mm0\n" /* 8 s */ | ||
104 | "movq 8(%1),%%mm1\n" /* 8 s */ | ||
105 | "movq 1(%1),%%mm2\n" /* 8 s */ | ||
106 | "movq 9(%1),%%mm3\n" /* 8 s */ | ||
107 | |||
108 | "pavgusb %%mm2, %%mm0\n" | ||
109 | "addl %3, %1\n" | ||
110 | "pavgusb %%mm3, %%mm1\n" | ||
111 | |||
112 | "movq (%2),%%mm2\n" /* 8 d */ | ||
113 | "movq 8(%2),%%mm3\n" /* 8 d */ | ||
114 | "pavgusb %%mm2, %%mm0\n" | ||
115 | "pavgusb %%mm3, %%mm1\n" | ||
116 | |||
117 | "movq %%mm0,(%2)\n" | ||
118 | "movq %%mm1,8(%2)\n" | ||
119 | "addl %3, %2\n" | ||
120 | "loop 1b\n" | ||
121 | : | ||
122 | : "c" (h), "r" (s), "r" (d), "r" (lx2) | ||
123 | ); | ||
124 | } | ||
125 | |||
126 | static inline void rechac_mmx(unsigned char *s,unsigned char *d, int lx2, int h) | ||
127 | { | ||
128 | __asm__ ( | ||
129 | ".align8\n" | ||
130 | "1:" | ||
131 | "movq (%1),%%mm0\n" /* 8 s */ | ||
132 | "movq 1(%1),%%mm2\n" /* 8 s */ | ||
133 | |||
134 | "addl %3, %1\n" | ||
135 | "pavgusb %%mm2, %%mm0\n" | ||
136 | |||
137 | "movq (%2),%%mm1\n" /* 8 d */ | ||
138 | "pavgusb %%mm1, %%mm0\n" | ||
139 | |||
140 | "movq %%mm0,(%2)\n" | ||
141 | "addl %3, %2\n" | ||
142 | "loop 1b\n" | ||
143 | : | ||
144 | : "c" (h), "r" (s), "r" (d), "r" (lx2) | ||
145 | ); | ||
146 | } | ||
147 | |||
148 | static inline void rec4_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h) | ||
149 | { | ||
150 | __asm__ __volatile__( | ||
151 | "movq (%1),%%mm0\n" /* 8 s */ | ||
152 | "movq 8(%1),%%mm1\n" /* 8 s */ | ||
153 | "movq 1(%1),%%mm2\n" /* 8 s +1*/ | ||
154 | "movq 9(%1),%%mm3\n" /* 8 s +1*/ | ||
155 | ".align 8\n" | ||
156 | "1:" | ||
157 | "movq (%4),%%mm4\n" /* 8 s+lx */ | ||
158 | "pavgusb %%mm2, %%mm0\n" | ||
159 | "movq 8(%4),%%mm5\n" /* 8 s+lx */ | ||
160 | "pavgusb %%mm3, %%mm1\n" | ||
161 | |||
162 | "movq 1(%4),%%mm6\n" /* 8 s+lx +1*/ | ||
163 | "pavgusb %%mm4, %%mm0\n" | ||
164 | "movq 9(%4),%%mm7\n" /* 8 s+lx +1*/ | ||
165 | "pavgusb %%mm5, %%mm1\n" | ||
166 | |||
167 | "pavgusb %%mm6, %%mm0\n" | ||
168 | "addl %3, %4\n" | ||
169 | "pavgusb %%mm7, %%mm1\n" | ||
170 | "movq %%mm0,(%2)\n" | ||
171 | "movq %%mm6,%%mm2\n" | ||
172 | "movq %%mm7,%%mm3\n" | ||
173 | "movq %%mm1,8(%2)\n" | ||
174 | "movq %%mm4,%%mm0\n" | ||
175 | "movq %%mm5,%%mm1\n" | ||
176 | "addl %3, %2\n" | ||
177 | "loop 1b\n" | ||
178 | : | ||
179 | : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx) | ||
180 | ); | ||
181 | } | ||
182 | |||
183 | static inline void rec4c_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h) | ||
184 | { | ||
185 | __asm__ __volatile__( | ||
186 | "movq (%1),%%mm0\n" /* 8 s */ | ||
187 | "movq 1(%1),%%mm2\n" /* 8 s +1*/ | ||
188 | ".align 8\n" | ||
189 | "1:" | ||
190 | "movq (%4),%%mm4\n" /* 8 s+lx */ | ||
191 | "pavgusb %%mm2, %%mm0\n" | ||
192 | |||
193 | "movq 1(%4),%%mm6\n" /* 8 s+lx +1*/ | ||
194 | "pavgusb %%mm4, %%mm0\n" | ||
195 | |||
196 | "addl %3, %4\n" | ||
197 | "pavgusb %%mm6, %%mm0\n" | ||
198 | "movq %%mm0,(%2)\n" | ||
199 | "movq %%mm6,%%mm2\n" | ||
200 | "movq %%mm4,%%mm0\n" | ||
201 | "addl %3, %2\n" | ||
202 | "loop 1b\n" | ||
203 | : | ||
204 | : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx) | ||
205 | ); | ||
206 | } | ||
207 | |||
208 | static inline void rec4a_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h) | ||
209 | { | ||
210 | __asm__ __volatile__( | ||
211 | "movq (%1),%%mm0\n" /* 8 s */ | ||
212 | "movq 8(%1),%%mm1\n" /* 8 s */ | ||
213 | "movq 1(%1),%%mm2\n" /* 8 s +1*/ | ||
214 | "movq 9(%1),%%mm3\n" /* 8 s +1*/ | ||
215 | ".align 8\n" | ||
216 | "1:" | ||
217 | "movq (%4),%%mm4\n" /* 8 s+lx */ | ||
218 | "pavgusb %%mm2, %%mm0\n" | ||
219 | "movq 8(%4),%%mm5\n" /* 8 s+lx */ | ||
220 | "pavgusb %%mm3, %%mm1\n" | ||
221 | |||
222 | "movq 1(%4),%%mm6\n" /* 8 s+lx +1*/ | ||
223 | "pavgusb %%mm4, %%mm0\n" | ||
224 | "movq 9(%4),%%mm7\n" /* 8 s+lx +1*/ | ||
225 | "pavgusb %%mm5, %%mm1\n" | ||
226 | "movq (%2),%%mm2\n" | ||
227 | "pavgusb %%mm6, %%mm0\n" | ||
228 | "movq 8(%2),%%mm3\n" | ||
229 | |||
230 | "pavgusb %%mm2, %%mm0\n" | ||
231 | "addl %3, %4\n" | ||
232 | "pavgusb %%mm3, %%mm1\n" | ||
233 | "movq %%mm0,(%2)\n" | ||
234 | |||
235 | "pavgusb %%mm7, %%mm1\n" | ||
236 | "movq %%mm6,%%mm2\n" | ||
237 | "movq %%mm7,%%mm3\n" | ||
238 | "movq %%mm1,8(%2)\n" | ||
239 | "movq %%mm4,%%mm0\n" | ||
240 | "movq %%mm5,%%mm1\n" | ||
241 | "addl %3, %2\n" | ||
242 | "loop 1b\n" | ||
243 | : | ||
244 | : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx) | ||
245 | ); | ||
246 | } | ||
247 | |||
248 | static inline void rec4ac_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h) | ||
249 | { | ||
250 | __asm__ __volatile__( | ||
251 | "movq (%1),%%mm0\n" /* 8 s */ | ||
252 | "movq 1(%1),%%mm2\n" /* 8 s +1*/ | ||
253 | ".align 8\n" | ||
254 | "1:" | ||
255 | "movq (%4),%%mm4\n" /* 8 s+lx */ | ||
256 | "pavgusb %%mm2, %%mm0\n" | ||
257 | |||
258 | "movq 1(%4),%%mm6\n" /* 8 s+lx +1*/ | ||
259 | "pavgusb %%mm4, %%mm0\n" | ||
260 | "movq (%2),%%mm1\n" /* 8 d */ | ||
261 | "pavgusb %%mm6, %%mm0\n" | ||
262 | "addl %3, %4\n" | ||
263 | "pavgusb %%mm1, %%mm0\n" | ||
264 | "movq %%mm6,%%mm2\n" | ||
265 | "movq %%mm0,(%2)\n" | ||
266 | "movq %%mm4,%%mm0\n" | ||
267 | "addl %3, %2\n" | ||
268 | "loop 1b\n" | ||
269 | : | ||
270 | : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx) | ||
271 | ); | ||
272 | } | ||
273 | |||
274 | #else // HAVE_3DNOW | ||
275 | static LONGLONG ADD_1 =0x0101010101010101LL; | ||
276 | static LONGLONG MASK_AND = 0x7f7f7f7f7f7f7f7fLL; | ||
277 | #endif | ||
278 | |||
279 | static inline void rec_mmx(unsigned char *s, unsigned char *d, int lx2, int h) | ||
280 | { | ||
281 | __asm__ __volatile__( | ||
282 | ".align 8\n" | ||
283 | "1:\t" | ||
284 | "movq ( %1 ), %%mm0\n" /* 8 s */ | ||
285 | "movq 8( %1 ), %%mm2\n" /* 16 s */ | ||
286 | "movq %%mm0, ( %2 )\n" | ||
287 | "addl %3, %1\n" | ||
288 | "movq %%mm2, 8( %2 )\n" | ||
289 | "decl %0\n" | ||
290 | "leal (%2, %3), %2\n" | ||
291 | "jnz 1b" | ||
292 | : | ||
293 | : "c" (h), "r" (s), "r" (d), "r" (lx2) | ||
294 | ); | ||
295 | } | ||
296 | |||
297 | |||
298 | static inline void recc_mmx(unsigned char *s, unsigned char *d, int lx2, int h) | ||
299 | { | ||
300 | __asm__ __volatile__( | ||
301 | ".align 8\n" | ||
302 | "1:\t" | ||
303 | "movq ( %1 ), %%mm0\n" | ||
304 | "addl %3, %1\n" | ||
305 | "movq %%mm0, ( %2 )\n" | ||
306 | "decl %0\n" | ||
307 | "leal (%2, %3), %2\n" | ||
308 | "jnz 1b" | ||
309 | : | ||
310 | : "c" (h), "r" (s), "r" (d), "r" (lx2) | ||
311 | ); | ||
312 | } | ||
313 | |||
314 | |||
315 | static inline void reca_mmx(unsigned char *s, unsigned char *d, int lx2, int h) | ||
316 | { | ||
317 | #ifdef HAVE_3Dnow | ||
318 | __asm__ ( | ||
319 | ".align8\n" | ||
320 | "1:" | ||
321 | "movq (%1),%%mm0\n" /* 8 s */ | ||
322 | "movq (%2),%%mm2\n" /* 8 d */ | ||
323 | "movq 8(%1),%%mm1\n" /* 8 s */ | ||
324 | "movq 8(%2),%%mm3\n" /* 8 d */ | ||
325 | "pavgusb %%mm2, %%mm0\n" | ||
326 | "addl %3, %1\n" | ||
327 | "pavgusb %%mm3, %%mm1\n" | ||
328 | |||
329 | "movq %%mm0,(%2)\n" | ||
330 | "movq %%mm1,8(%2)\n" | ||
331 | "addl %3, %2\n" | ||
332 | "loop 1b\n" | ||
333 | : | ||
334 | : "c" (h), "r" (s), "r" (d), "r" (lx2) | ||
335 | ); | ||
336 | #else /* No 3dnow */ | ||
337 | __asm__ ( | ||
338 | "movq MASK_AND, %%mm5\n" | ||
339 | "movq ADD_1, %%mm6\n" | ||
340 | "1:\t" | ||
341 | "movq (%1),%%mm0\n" /* Load 16 pixels from each row */ | ||
342 | "movq (%2),%%mm1\n" | ||
343 | "movq 8(%1),%%mm2\n" | ||
344 | "movq 8(%2),%%mm3\n" | ||
345 | "psrlw $1,%%mm0\n" /* Shift pixels down */ | ||
346 | "psrlw $1,%%mm1\n" | ||
347 | "pand %%mm5,%%mm0\n" /* Zero out significant bit */ | ||
348 | "psrlw $1,%%mm2\n" | ||
349 | "pand %%mm5,%%mm1\n" | ||
350 | "psrlw $1,%%mm3\n" | ||
351 | "pand %%mm5,%%mm2\n" | ||
352 | "paddusb %%mm1,%%mm0\n" /* Add pixels */ | ||
353 | "pand %%mm5,%%mm3\n" | ||
354 | "paddusb %%mm3,%%mm2\n" | ||
355 | "paddusb %%mm6,%%mm0\n" /* Add 1 to results */ | ||
356 | "paddusb %%mm6,%%mm2\n" | ||
357 | "movq %%mm0,(%2)\n" | ||
358 | "addl %3,%1\n" | ||
359 | "movq %%mm2, 8(%2)\n" | ||
360 | "decl %0\n" | ||
361 | "leal (%2, %3), %2\n" | ||
362 | "jnz 1b\n" | ||
363 | : | ||
364 | : "c" (h), "r" (s), "r" (d), "r" (lx2) | ||
365 | ); | ||
366 | #endif | ||
367 | } | ||
368 | |||
369 | |||
370 | static inline void recac_mmx(unsigned char *s, unsigned char *d, int lx2, int h) | ||
371 | { | ||
372 | #ifdef HAVE_3Dnow | ||
373 | __asm__ ( | ||
374 | ".align8\n" | ||
375 | "1:" | ||
376 | "movq (%1),%%mm0\n" /* 8 s */ | ||
377 | "movq (%2),%%mm2\n" /* 8 d */ | ||
378 | "pavgusb %%mm2, %%mm0\n" | ||
379 | "addl %3, %1\n" | ||
380 | "movq %%mm0,(%2)\n" | ||
381 | "addl %3, %2\n" | ||
382 | "loop 1b\n" | ||
383 | : | ||
384 | : "c" (h), "r" (s), "r" (d), "r" (lx2) | ||
385 | ); | ||
386 | #else /* No 3dnow */ | ||
387 | __asm__ ( | ||
388 | "movq MASK_AND, %%mm5\n" | ||
389 | "movq ADD_1, %%mm6\n" | ||
390 | "1:\t" | ||
391 | "movq (%1),%%mm0\n" | ||
392 | "movq (%2),%%mm1\n" | ||
393 | "psrlw $1,%%mm0\n" | ||
394 | "psrlw $1,%%mm1\n" | ||
395 | "pand %%mm5,%%mm0\n" | ||
396 | "pand %%mm5,%%mm1\n" | ||
397 | "paddusb %%mm1,%%mm0\n" | ||
398 | "paddusb %%mm6,%%mm0\n" | ||
399 | "addl %3,%1\n" | ||
400 | "movq %%mm0,(%2)\n" | ||
401 | "decl %0\n" | ||
402 | "leal (%2, %3), %2\n" | ||
403 | "jnz 1b\n" | ||
404 | : | ||
405 | : "c" (h), "r" (s), "r" (d), "r" (lx2) | ||
406 | ); | ||
407 | #endif | ||
408 | } | ||
409 | |||
410 | |||
411 | static inline void recv_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h) | ||
412 | { | ||
413 | #ifdef HAVE_3Dnow | ||
414 | __asm__( | ||
415 | ".align8\n" | ||
416 | "1:" | ||
417 | "movq (%1),%%mm0\n" /* 8 s */ | ||
418 | "movq (%4),%%mm2\n" /* 8 s +lx */ | ||
419 | "movq 8(%1),%%mm1\n" /* 8 s */ | ||
420 | "movq 8(%4),%%mm3\n" /* 8 s +lx **/ | ||
421 | |||
422 | "pavgusb %%mm2, %%mm0\n" | ||
423 | "addl %3, %1\n" | ||
424 | "pavgusb %%mm3, %%mm1\n" | ||
425 | |||
426 | "movq %%mm0,(%2)\n" | ||
427 | "addl %3, %4\n" | ||
428 | "movq %%mm1,8(%2)\n" | ||
429 | "addl %3, %2\n" | ||
430 | "loop 1b\n" | ||
431 | : | ||
432 | : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx) | ||
433 | ); | ||
434 | #else | ||
435 | __asm__ ( | ||
436 | "movq MASK_AND, %%mm5\n" | ||
437 | "movq ADD_1, %%mm6\n" | ||
438 | "1:\t" | ||
439 | "movq (%1),%%mm0\n" /* 8 s */ | ||
440 | "movq (%4),%%mm1\n" /* 8 s +lx */ | ||
441 | "movq 8(%1),%%mm2\n" /* 8 s */ | ||
442 | "movq 8(%4),%%mm3\n" /* 8 s +lx **/ | ||
443 | "psrlw $1,%%mm0\n" | ||
444 | "psrlw $1,%%mm1\n" | ||
445 | "pand %%mm5,%%mm0\n" | ||
446 | "psrlw $1,%%mm2\n" | ||
447 | "pand %%mm5,%%mm1\n" | ||
448 | "psrlw $1,%%mm3\n" | ||
449 | "pand %%mm5,%%mm2\n" | ||
450 | "paddusb %%mm1,%%mm0\n" | ||
451 | "pand %%mm5,%%mm3\n" | ||
452 | "paddusb %%mm3,%%mm2\n" | ||
453 | "paddusb %%mm6,%%mm0\n" | ||
454 | "paddusb %%mm6,%%mm2\n" | ||
455 | "movq %%mm0,(%2)\n" | ||
456 | "addl %3,%1\n" | ||
457 | "movq %%mm2, 8(%2)\n" | ||
458 | "addl %3,%4\n" | ||
459 | "decl %0\n" | ||
460 | "leal (%2, %3), %2\n" | ||
461 | "jnz 1b\n" | ||
462 | : | ||
463 | : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx) | ||
464 | ); | ||
465 | #endif | ||
466 | } | ||
467 | |||
468 | |||
469 | static inline void recvc_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h) | ||
470 | { | ||
471 | #ifdef HAVE_3Dnow | ||
472 | __asm__( | ||
473 | ".align8\n" | ||
474 | "1:" | ||
475 | "movq (%1),%%mm0\n" /* 8 s */ | ||
476 | "movq (%4),%%mm2\n" /* 8 s +lx */ | ||
477 | "addl %3, %1\n" | ||
478 | "pavgusb %%mm2, %%mm0\n" | ||
479 | "addl %3, %4\n" | ||
480 | "movq %%mm0,(%2)\n" | ||
481 | "addl %3, %2\n" | ||
482 | "loop 1b\n" | ||
483 | : | ||
484 | : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx) | ||
485 | ); | ||
486 | #else | ||
487 | __asm__ ( | ||
488 | "movq MASK_AND, %%mm5\n" | ||
489 | "movq ADD_1, %%mm6\n" | ||
490 | "1:\t" | ||
491 | "movq (%1),%%mm0\n" /* 8 s */ | ||
492 | "movq (%4),%%mm1\n" /* 8 s +lx */ | ||
493 | "psrlw $1,%%mm0\n" | ||
494 | "psrlw $1,%%mm1\n" | ||
495 | "pand %%mm5,%%mm0\n" | ||
496 | "pand %%mm5,%%mm1\n" | ||
497 | "paddusb %%mm1,%%mm0\n" | ||
498 | "addl %3,%1\n" | ||
499 | "paddusb %%mm6,%%mm0\n" | ||
500 | "addl %3,%4\n" | ||
501 | "movq %%mm0,(%2)\n" | ||
502 | "decl %0\n" | ||
503 | "leal (%2, %3), %2\n" | ||
504 | "jnz 1b\n" | ||
505 | : | ||
506 | : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx) | ||
507 | ); | ||
508 | #endif | ||
509 | } | ||
510 | |||
511 | #endif // HAVE_MMX | ||
512 | |||
513 | static inline void rec(unsigned char *s, unsigned char *d, int lx2, int h) | ||
514 | { | ||
515 | int j; | ||
516 | for(j = 0; j < h; j++, s += lx2, d += lx2) | ||
517 | { | ||
518 | d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; d[3] = s[3]; | ||
519 | d[4] = s[4]; d[5] = s[5]; d[6] = s[6]; d[7] = s[7]; | ||
520 | d[8] = s[8]; d[9] = s[9]; d[10] = s[10]; d[11] = s[11]; | ||
521 | d[12] = s[12]; d[13] = s[13]; d[14] = s[14]; d[15] = s[15]; | ||
522 | } | ||
523 | } | ||
524 | |||
525 | |||
526 | |||
527 | static inline void recc(unsigned char *s, unsigned char *d, int lx2, int h) | ||
528 | { | ||
529 | int j; | ||
530 | for(j = 0; j < h; j++, s += lx2, d += lx2) | ||
531 | { | ||
532 | d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; d[3] = s[3]; | ||
533 | d[4] = s[4]; d[5] = s[5]; d[6] = s[6]; d[7] = s[7]; | ||
534 | } | ||
535 | } | ||
536 | |||
537 | static inline void reca(unsigned char *s, unsigned char *d, int lx2, int h) | ||
538 | { | ||
539 | int j; | ||
540 | for(j = 0; j < h; j++, s +=lx2, d +=lx2) | ||
541 | { | ||
542 | d[0] = (unsigned int)(d[0] + s[0] + 1) >> 1; | ||
543 | d[1] = (unsigned int)(d[1] + s[1] + 1) >> 1; | ||
544 | d[2] = (unsigned int)(d[2] + s[2] + 1) >> 1; | ||
545 | d[3] = (unsigned int)(d[3] + s[3] + 1) >> 1; | ||
546 | d[4] = (unsigned int)(d[4] + s[4] + 1) >> 1; | ||
547 | d[5] = (unsigned int)(d[5] + s[5] + 1) >> 1; | ||
548 | d[6] = (unsigned int)(d[6] + s[6] + 1) >> 1; | ||
549 | d[7] = (unsigned int)(d[7] + s[7] + 1) >> 1; | ||
550 | d[8] = (unsigned int)(d[8] + s[8] + 1) >> 1; | ||
551 | d[9] = (unsigned int)(d[9] + s[9] + 1) >> 1; | ||
552 | d[10] = (unsigned int)(d[10] + s[10] + 1) >> 1; | ||
553 | d[11] = (unsigned int)(d[11] + s[11] + 1) >> 1; | ||
554 | d[12] = (unsigned int)(d[12] + s[12] + 1) >> 1; | ||
555 | d[13] = (unsigned int)(d[13] + s[13] + 1) >> 1; | ||
556 | d[14] = (unsigned int)(d[14] + s[14] + 1) >> 1; | ||
557 | d[15] = (unsigned int)(d[15] + s[15] + 1) >> 1; | ||
558 | } | ||
559 | } | ||
560 | |||
561 | static inline void recac(unsigned char *s, unsigned char *d, int lx2, int h) | ||
562 | { | ||
563 | int j; | ||
564 | for(j = 0; j < h; j++, s += lx2, d += lx2) | ||
565 | { | ||
566 | d[0] = (unsigned int)(d[0] + s[0] + 1)>>1; | ||
567 | d[1] = (unsigned int)(d[1] + s[1] + 1)>>1; | ||
568 | d[2] = (unsigned int)(d[2] + s[2] + 1)>>1; | ||
569 | d[3] = (unsigned int)(d[3] + s[3] + 1)>>1; | ||
570 | d[4] = (unsigned int)(d[4] + s[4] + 1)>>1; | ||
571 | d[5] = (unsigned int)(d[5] + s[5] + 1)>>1; | ||
572 | d[6] = (unsigned int)(d[6] + s[6] + 1)>>1; | ||
573 | d[7] = (unsigned int)(d[7] + s[7] + 1)>>1; | ||
574 | } | ||
575 | } | ||
576 | |||
577 | static inline void recv_(unsigned char *s, unsigned char *d, int lx, int lx2, int h) | ||
578 | { | ||
579 | unsigned char *dp,*sp,*sp2; | ||
580 | int j; | ||
581 | sp = s; | ||
582 | sp2 = s + lx; | ||
583 | dp = d; | ||
584 | for(j = 0; j < h; j++) | ||
585 | { | ||
586 | dp[0] = (unsigned int)(sp[0] + sp2[0] + 1) >> 1; | ||
587 | dp[1] = (unsigned int)(sp[1] + sp2[1] + 1) >> 1; | ||
588 | dp[2] = (unsigned int)(sp[2] + sp2[2] + 1) >> 1; | ||
589 | dp[3] = (unsigned int)(sp[3] + sp2[3] + 1) >> 1; | ||
590 | dp[4] = (unsigned int)(sp[4] + sp2[4] + 1) >> 1; | ||
591 | dp[5] = (unsigned int)(sp[5] + sp2[5] + 1) >> 1; | ||
592 | dp[6] = (unsigned int)(sp[6] + sp2[6] + 1) >> 1; | ||
593 | dp[7] = (unsigned int)(sp[7] + sp2[7] + 1) >> 1; | ||
594 | dp[8] = (unsigned int)(sp[8] + sp2[8] + 1) >> 1; | ||
595 | dp[9] = (unsigned int)(sp[9] + sp2[9] + 1) >> 1; | ||
596 | dp[10] = (unsigned int)(sp[10] + sp2[10] + 1) >> 1; | ||
597 | dp[11] = (unsigned int)(sp[11] + sp2[11] + 1) >> 1; | ||
598 | dp[12] = (unsigned int)(sp[12] + sp2[12] + 1) >> 1; | ||
599 | dp[13] = (unsigned int)(sp[13] + sp2[13] + 1) >> 1; | ||
600 | dp[14] = (unsigned int)(sp[14] + sp2[14] + 1) >> 1; | ||
601 | dp[15] = (unsigned int)(sp[15] + sp2[15] + 1) >> 1; | ||
602 | sp+= lx2; | ||
603 | sp2+= lx2; | ||
604 | dp+= lx2; | ||
605 | } | ||
606 | } | ||
607 | |||
608 | static inline void recvc(unsigned char *s, unsigned char *d, int lx, int lx2, int h) | ||
609 | { | ||
610 | unsigned char *dp,*sp,*sp2; | ||
611 | int j; | ||
612 | |||
613 | sp = s; | ||
614 | sp2 = s+lx; | ||
615 | dp = d; | ||
616 | for(j = 0; j < h; j++) | ||
617 | { | ||
618 | dp[0] = (unsigned int)(sp[0]+sp2[0]+1)>>1; | ||
619 | dp[1] = (unsigned int)(sp[1]+sp2[1]+1)>>1; | ||
620 | dp[2] = (unsigned int)(sp[2]+sp2[2]+1)>>1; | ||
621 | dp[3] = (unsigned int)(sp[3]+sp2[3]+1)>>1; | ||
622 | dp[4] = (unsigned int)(sp[4]+sp2[4]+1)>>1; | ||
623 | dp[5] = (unsigned int)(sp[5]+sp2[5]+1)>>1; | ||
624 | dp[6] = (unsigned int)(sp[6]+sp2[6]+1)>>1; | ||
625 | dp[7] = (unsigned int)(sp[7]+sp2[7]+1)>>1; | ||
626 | sp+= lx2; | ||
627 | sp2+= lx2; | ||
628 | dp+= lx2; | ||
629 | } | ||
630 | } | ||
631 | |||
632 | |||
633 | static inline void recva(unsigned char *s, unsigned char *d, int lx, int lx2, int h) | ||
634 | { | ||
635 | unsigned char *dp,*sp,*sp2; | ||
636 | int j; | ||
637 | |||
638 | sp = s; | ||
639 | sp2 = s+lx; | ||
640 | dp = d; | ||
641 | for (j=0; j<h; j++){ | ||
642 | dp[0] = (dp[0] + ((unsigned int)(sp[0]+sp2[0]+1)>>1) + 1)>>1; | ||
643 | dp[1] = (dp[1] + ((unsigned int)(sp[1]+sp2[1]+1)>>1) + 1)>>1; | ||
644 | dp[2] = (dp[2] + ((unsigned int)(sp[2]+sp2[2]+1)>>1) + 1)>>1; | ||
645 | dp[3] = (dp[3] + ((unsigned int)(sp[3]+sp2[3]+1)>>1) + 1)>>1; | ||
646 | dp[4] = (dp[4] + ((unsigned int)(sp[4]+sp2[4]+1)>>1) + 1)>>1; | ||
647 | dp[5] = (dp[5] + ((unsigned int)(sp[5]+sp2[5]+1)>>1) + 1)>>1; | ||
648 | dp[6] = (dp[6] + ((unsigned int)(sp[6]+sp2[6]+1)>>1) + 1)>>1; | ||
649 | dp[7] = (dp[7] + ((unsigned int)(sp[7]+sp2[7]+1)>>1) + 1)>>1; | ||
650 | dp[8] = (dp[8] + ((unsigned int)(sp[8]+sp2[8]+1)>>1) + 1)>>1; | ||
651 | dp[9] = (dp[9] + ((unsigned int)(sp[9]+sp2[9]+1)>>1) + 1)>>1; | ||
652 | dp[10] = (dp[10] + ((unsigned int)(sp[10]+sp2[10]+1)>>1) + 1)>>1; | ||
653 | dp[11] = (dp[11] + ((unsigned int)(sp[11]+sp2[11]+1)>>1) + 1)>>1; | ||
654 | dp[12] = (dp[12] + ((unsigned int)(sp[12]+sp2[12]+1)>>1) + 1)>>1; | ||
655 | dp[13] = (dp[13] + ((unsigned int)(sp[13]+sp2[13]+1)>>1) + 1)>>1; | ||
656 | dp[14] = (dp[14] + ((unsigned int)(sp[14]+sp2[14]+1)>>1) + 1)>>1; | ||
657 | dp[15] = (dp[15] + ((unsigned int)(sp[15]+sp2[15]+1)>>1) + 1)>>1; | ||
658 | sp+= lx2; | ||
659 | sp2+= lx2; | ||
660 | dp+= lx2; | ||
661 | } | ||
662 | } | ||
663 | |||
664 | |||
665 | static inline void recvac(unsigned char *s, unsigned char *d, int lx,int lx2, int h){ | ||
666 | unsigned char *dp,*sp,*sp2; | ||
667 | int j; | ||
668 | |||
669 | sp = s; | ||
670 | sp2 = s+lx; | ||
671 | dp = d; | ||
672 | for (j=0; j<h; j++){ | ||
673 | dp[0] = (dp[0] + ((unsigned int)(sp[0]+sp2[0]+1)>>1) + 1)>>1; | ||
674 | dp[1] = (dp[1] + ((unsigned int)(sp[1]+sp2[1]+1)>>1) + 1)>>1; | ||
675 | dp[2] = (dp[2] + ((unsigned int)(sp[2]+sp2[2]+1)>>1) + 1)>>1; | ||
676 | dp[3] = (dp[3] + ((unsigned int)(sp[3]+sp2[3]+1)>>1) + 1)>>1; | ||
677 | dp[4] = (dp[4] + ((unsigned int)(sp[4]+sp2[4]+1)>>1) + 1)>>1; | ||
678 | dp[5] = (dp[5] + ((unsigned int)(sp[5]+sp2[5]+1)>>1) + 1)>>1; | ||
679 | dp[6] = (dp[6] + ((unsigned int)(sp[6]+sp2[6]+1)>>1) + 1)>>1; | ||
680 | dp[7] = (dp[7] + ((unsigned int)(sp[7]+sp2[7]+1)>>1) + 1)>>1; | ||
681 | sp+= lx2; | ||
682 | sp2+= lx2; | ||
683 | dp+= lx2; | ||
684 | } | ||
685 | } | ||
686 | |||
687 | |||
688 | static inline void rech(unsigned char *s, unsigned char *d, int lx2, int h){ | ||
689 | unsigned char *dp,*sp; | ||
690 | unsigned int s1,s2; | ||
691 | int j; | ||
692 | |||
693 | sp = s; | ||
694 | dp = d; | ||
695 | for (j=0; j<h; j++){ | ||
696 | s1=sp[0]; | ||
697 | dp[0] = (unsigned int)(s1+(s2=sp[1])+1)>>1; | ||
698 | dp[1] = (unsigned int)(s2+(s1=sp[2])+1)>>1; | ||
699 | dp[2] = (unsigned int)(s1+(s2=sp[3])+1)>>1; | ||
700 | dp[3] = (unsigned int)(s2+(s1=sp[4])+1)>>1; | ||
701 | dp[4] = (unsigned int)(s1+(s2=sp[5])+1)>>1; | ||
702 | dp[5] = (unsigned int)(s2+(s1=sp[6])+1)>>1; | ||
703 | dp[6] = (unsigned int)(s1+(s2=sp[7])+1)>>1; | ||
704 | dp[7] = (unsigned int)(s2+(s1=sp[8])+1)>>1; | ||
705 | dp[8] = (unsigned int)(s1+(s2=sp[9])+1)>>1; | ||
706 | dp[9] = (unsigned int)(s2+(s1=sp[10])+1)>>1; | ||
707 | dp[10] = (unsigned int)(s1+(s2=sp[11])+1)>>1; | ||
708 | dp[11] = (unsigned int)(s2+(s1=sp[12])+1)>>1; | ||
709 | dp[12] = (unsigned int)(s1+(s2=sp[13])+1)>>1; | ||
710 | dp[13] = (unsigned int)(s2+(s1=sp[14])+1)>>1; | ||
711 | dp[14] = (unsigned int)(s1+(s2=sp[15])+1)>>1; | ||
712 | dp[15] = (unsigned int)(s2+sp[16]+1)>>1; | ||
713 | sp+= lx2; | ||
714 | dp+= lx2; | ||
715 | } | ||
716 | } | ||
717 | |||
718 | |||
719 | static inline void rechc(unsigned char *s,unsigned char *d, int lx2, int h){ | ||
720 | unsigned char *dp,*sp; | ||
721 | unsigned int s1,s2; | ||
722 | int j; | ||
723 | |||
724 | sp = s; | ||
725 | dp = d; | ||
726 | for (j=0; j<h; j++){ | ||
727 | s1=sp[0]; | ||
728 | dp[0] = (unsigned int)(s1+(s2=sp[1])+1)>>1; | ||
729 | dp[1] = (unsigned int)(s2+(s1=sp[2])+1)>>1; | ||
730 | dp[2] = (unsigned int)(s1+(s2=sp[3])+1)>>1; | ||
731 | dp[3] = (unsigned int)(s2+(s1=sp[4])+1)>>1; | ||
732 | dp[4] = (unsigned int)(s1+(s2=sp[5])+1)>>1; | ||
733 | dp[5] = (unsigned int)(s2+(s1=sp[6])+1)>>1; | ||
734 | dp[6] = (unsigned int)(s1+(s2=sp[7])+1)>>1; | ||
735 | dp[7] = (unsigned int)(s2+sp[8]+1)>>1; | ||
736 | sp+= lx2; | ||
737 | dp+= lx2; | ||
738 | } | ||
739 | } | ||
740 | |||
741 | static inline void recha(unsigned char *s, unsigned char *d,int lx2, int h) | ||
742 | { | ||
743 | unsigned char *dp,*sp; | ||
744 | unsigned int s1,s2; | ||
745 | int j; | ||
746 | |||
747 | sp = s; | ||
748 | dp = d; | ||
749 | for (j = 0; j < h; j++) | ||
750 | { | ||
751 | s1 = sp[0]; | ||
752 | dp[0] = (dp[0] + ((unsigned int)(s1 + (s2 = sp[1]) + 1) >> 1) + 1) >> 1; | ||
753 | dp[1] = (dp[1] + ((unsigned int)(s2 + (s1 = sp[2]) + 1) >> 1) + 1) >> 1; | ||
754 | dp[2] = (dp[2] + ((unsigned int)(s1 + (s2 = sp[3]) + 1) >> 1) + 1) >> 1; | ||
755 | dp[3] = (dp[3] + ((unsigned int)(s2 + (s1 = sp[4]) + 1) >> 1) + 1) >> 1; | ||
756 | dp[4] = (dp[4] + ((unsigned int)(s1 + (s2 = sp[5]) + 1) >> 1) + 1) >> 1; | ||
757 | dp[5] = (dp[5] + ((unsigned int)(s2 + (s1 = sp[6]) + 1) >> 1) + 1) >> 1; | ||
758 | dp[6] = (dp[6] + ((unsigned int)(s1 + (s2 = sp[7]) + 1) >> 1) + 1) >> 1; | ||
759 | dp[7] = (dp[7] + ((unsigned int)(s2 + (s1 = sp[8]) + 1) >> 1) + 1) >> 1; | ||
760 | dp[8] = (dp[8] + ((unsigned int)(s1 + (s2 = sp[9]) + 1) >> 1) + 1) >> 1; | ||
761 | dp[9] = (dp[9] + ((unsigned int)(s2 + (s1 = sp[10]) + 1) >> 1) + 1) >> 1; | ||
762 | dp[10] = (dp[10] + ((unsigned int)(s1 + (s2 = sp[11]) + 1) >> 1) + 1) >> 1; | ||
763 | dp[11] = (dp[11] + ((unsigned int)(s2 + (s1 = sp[12]) + 1) >> 1) + 1) >> 1; | ||
764 | dp[12] = (dp[12] + ((unsigned int)(s1 + (s2 = sp[13]) + 1) >> 1) + 1) >> 1; | ||
765 | dp[13] = (dp[13] + ((unsigned int)(s2 + (s1 = sp[14]) + 1) >> 1) + 1) >> 1; | ||
766 | dp[14] = (dp[14] + ((unsigned int)(s1 + (s2 = sp[15]) + 1) >> 1) + 1) >> 1; | ||
767 | dp[15] = (dp[15] + ((unsigned int)(s2 + sp[16] + 1) >> 1) + 1) >> 1; | ||
768 | sp += lx2; | ||
769 | dp += lx2; | ||
770 | } | ||
771 | } | ||
772 | |||
773 | |||
774 | static inline void rechac(unsigned char *s,unsigned char *d, int lx2, int h) | ||
775 | { | ||
776 | unsigned char *dp,*sp; | ||
777 | unsigned int s1,s2; | ||
778 | int j; | ||
779 | |||
780 | sp = s; | ||
781 | dp = d; | ||
782 | for(j = 0; j < h; j++) | ||
783 | { | ||
784 | s1 = sp[0]; | ||
785 | dp[0] = (dp[0] + ((unsigned int)(s1 + (s2 = sp[1]) + 1) >> 1) + 1) >> 1; | ||
786 | dp[1] = (dp[1] + ((unsigned int)(s2 + (s1 = sp[2]) + 1) >> 1) + 1) >> 1; | ||
787 | dp[2] = (dp[2] + ((unsigned int)(s1 + (s2 = sp[3]) + 1) >> 1) + 1) >> 1; | ||
788 | dp[3] = (dp[3] + ((unsigned int)(s2 + (s1 = sp[4]) + 1) >> 1) + 1) >> 1; | ||
789 | dp[4] = (dp[4] + ((unsigned int)(s1 + (s2 = sp[5]) + 1) >> 1) + 1) >> 1; | ||
790 | dp[5] = (dp[5] + ((unsigned int)(s2 + (s1 = sp[6]) + 1) >> 1) + 1) >> 1; | ||
791 | dp[6] = (dp[6] + ((unsigned int)(s1 + (s2 = sp[7]) + 1) >> 1) + 1) >> 1; | ||
792 | dp[7] = (dp[7] + ((unsigned int)(s2 + sp[8] + 1) >> 1) + 1) >> 1; | ||
793 | sp += lx2; | ||
794 | dp += lx2; | ||
795 | } | ||
796 | } | ||
797 | |||
798 | |||
799 | static inline void rec4(unsigned char *s, unsigned char *d, int lx, int lx2, int h) | ||
800 | { | ||
801 | unsigned char *dp,*sp,*sp2; | ||
802 | unsigned int s1,s2,s3,s4; | ||
803 | int j; | ||
804 | |||
805 | sp = s; | ||
806 | sp2 = s+lx; | ||
807 | dp = d; | ||
808 | for (j=0; j<h; j++){ | ||
809 | s1=sp[0]; s3=sp2[0]; | ||
810 | dp[0] = (unsigned int)(s1+(s2=sp[1])+s3+(s4=sp2[1])+2)>>2; | ||
811 | dp[1] = (unsigned int)(s2+(s1=sp[2])+s4+(s3=sp2[2])+2)>>2; | ||
812 | dp[2] = (unsigned int)(s1+(s2=sp[3])+s3+(s4=sp2[3])+2)>>2; | ||
813 | dp[3] = (unsigned int)(s2+(s1=sp[4])+s4+(s3=sp2[4])+2)>>2; | ||
814 | dp[4] = (unsigned int)(s1+(s2=sp[5])+s3+(s4=sp2[5])+2)>>2; | ||
815 | dp[5] = (unsigned int)(s2+(s1=sp[6])+s4+(s3=sp2[6])+2)>>2; | ||
816 | dp[6] = (unsigned int)(s1+(s2=sp[7])+s3+(s4=sp2[7])+2)>>2; | ||
817 | dp[7] = (unsigned int)(s2+(s1=sp[8])+s4+(s3=sp2[8])+2)>>2; | ||
818 | dp[8] = (unsigned int)(s1+(s2=sp[9])+s3+(s4=sp2[9])+2)>>2; | ||
819 | dp[9] = (unsigned int)(s2+(s1=sp[10])+s4+(s3=sp2[10])+2)>>2; | ||
820 | dp[10] = (unsigned int)(s1+(s2=sp[11])+s3+(s4=sp2[11])+2)>>2; | ||
821 | dp[11] = (unsigned int)(s2+(s1=sp[12])+s4+(s3=sp2[12])+2)>>2; | ||
822 | dp[12] = (unsigned int)(s1+(s2=sp[13])+s3+(s4=sp2[13])+2)>>2; | ||
823 | dp[13] = (unsigned int)(s2+(s1=sp[14])+s4+(s3=sp2[14])+2)>>2; | ||
824 | dp[14] = (unsigned int)(s1+(s2=sp[15])+s3+(s4=sp2[15])+2)>>2; | ||
825 | dp[15] = (unsigned int)(s2+sp[16]+s4+sp2[16]+2)>>2; | ||
826 | sp+= lx2; | ||
827 | sp2+= lx2; | ||
828 | dp+= lx2; | ||
829 | } | ||
830 | } | ||
831 | |||
832 | |||
833 | static inline void rec4c(unsigned char *s,unsigned char *d, int lx, int lx2, int h) | ||
834 | { | ||
835 | unsigned char *dp,*sp,*sp2; | ||
836 | unsigned int s1,s2,s3,s4; | ||
837 | int j; | ||
838 | |||
839 | sp = s; | ||
840 | sp2 = s+lx; | ||
841 | dp = d; | ||
842 | for (j=0; j<h; j++){ | ||
843 | s1=sp[0]; s3=sp2[0]; | ||
844 | dp[0] = (unsigned int)(s1+(s2=sp[1])+s3+(s4=sp2[1])+2)>>2; | ||
845 | dp[1] = (unsigned int)(s2+(s1=sp[2])+s4+(s3=sp2[2])+2)>>2; | ||
846 | dp[2] = (unsigned int)(s1+(s2=sp[3])+s3+(s4=sp2[3])+2)>>2; | ||
847 | dp[3] = (unsigned int)(s2+(s1=sp[4])+s4+(s3=sp2[4])+2)>>2; | ||
848 | dp[4] = (unsigned int)(s1+(s2=sp[5])+s3+(s4=sp2[5])+2)>>2; | ||
849 | dp[5] = (unsigned int)(s2+(s1=sp[6])+s4+(s3=sp2[6])+2)>>2; | ||
850 | dp[6] = (unsigned int)(s1+(s2=sp[7])+s3+(s4=sp2[7])+2)>>2; | ||
851 | dp[7] = (unsigned int)(s2+sp[8]+s4+sp2[8]+2)>>2; | ||
852 | sp+= lx2; | ||
853 | sp2+= lx2; | ||
854 | dp+= lx2; | ||
855 | } | ||
856 | } | ||
857 | |||
858 | |||
859 | static inline void rec4a(unsigned char *s,unsigned char *d, int lx, int lx2, int h) | ||
860 | { | ||
861 | unsigned char *dp=d, *sp=s, *sp2=s+lx; | ||
862 | unsigned int s1, s2, s3, s4; | ||
863 | int j; | ||
864 | |||
865 | /* | ||
866 | sp = s; | ||
867 | sp2 = s+lx; | ||
868 | dp = d; | ||
869 | */ | ||
870 | for (j=0; j<h; j++){ | ||
871 | s1=sp[0]; s3=sp2[0]; | ||
872 | dp[0] = (dp[0] + ((unsigned int)(s1+(s2=sp[1])+s3+(s4=sp2[1])+2)>>2) + 1)>>1; | ||
873 | dp[1] = (dp[1] + ((unsigned int)(s2+(s1=sp[2])+s4+(s3=sp2[2])+2)>>2) + 1)>>1; | ||
874 | dp[2] = (dp[2] + ((unsigned int)(s1+(s2=sp[3])+s3+(s4=sp2[3])+2)>>2) + 1)>>1; | ||
875 | dp[3] = (dp[3] + ((unsigned int)(s2+(s1=sp[4])+s4+(s3=sp2[4])+2)>>2) + 1)>>1; | ||
876 | dp[4] = (dp[4] + ((unsigned int)(s1+(s2=sp[5])+s3+(s4=sp2[5])+2)>>2) + 1)>>1; | ||
877 | dp[5] = (dp[5] + ((unsigned int)(s2+(s1=sp[6])+s4+(s3=sp2[6])+2)>>2) + 1)>>1; | ||
878 | dp[6] = (dp[6] + ((unsigned int)(s1+(s2=sp[7])+s3+(s4=sp2[7])+2)>>2) + 1)>>1; | ||
879 | dp[7] = (dp[7] + ((unsigned int)(s2+(s1=sp[8])+s4+(s3=sp2[8])+2)>>2) + 1)>>1; | ||
880 | dp[8] = (dp[8] + ((unsigned int)(s1+(s2=sp[9])+s3+(s4=sp2[9])+2)>>2) + 1)>>1; | ||
881 | dp[9] = (dp[9] + ((unsigned int)(s2+(s1=sp[10])+s4+(s3=sp2[10])+2)>>2) + 1)>>1; | ||
882 | dp[10] = (dp[10] + ((unsigned int)(s1+(s2=sp[11])+s3+(s4=sp2[11])+2)>>2) + 1)>>1; | ||
883 | dp[11] = (dp[11] + ((unsigned int)(s2+(s1=sp[12])+s4+(s3=sp2[12])+2)>>2) + 1)>>1; | ||
884 | dp[12] = (dp[12] + ((unsigned int)(s1+(s2=sp[13])+s3+(s4=sp2[13])+2)>>2) + 1)>>1; | ||
885 | dp[13] = (dp[13] + ((unsigned int)(s2+(s1=sp[14])+s4+(s3=sp2[14])+2)>>2) + 1)>>1; | ||
886 | dp[14] = (dp[14] + ((unsigned int)(s1+(s2=sp[15])+s3+(s4=sp2[15])+2)>>2) + 1)>>1; | ||
887 | dp[15] = (dp[15] + ((unsigned int)(s2+sp[16]+s4+sp2[16]+2)>>2) + 1)>>1; | ||
888 | sp+= lx2; | ||
889 | sp2+= lx2; | ||
890 | dp+= lx2; | ||
891 | } | ||
892 | } | ||
893 | |||
894 | |||
895 | static inline void rec4ac(unsigned char *s,unsigned char *d, int lx, int lx2, int h) | ||
896 | { | ||
897 | unsigned char *dp=d, *sp=s, *sp2=s+lx; | ||
898 | unsigned int s1,s2,s3,s4; | ||
899 | int j; | ||
900 | |||
901 | /* | ||
902 | sp = s; | ||
903 | sp2 = s+lx; | ||
904 | dp = d; | ||
905 | */ | ||
906 | for (j=0; j<h; j++) | ||
907 | { | ||
908 | s1=sp[0]; s3=sp2[0]; | ||
909 | dp[0] = (dp[0] + ((unsigned int)(s1+(s2=sp[1])+s3+(s4=sp2[1])+2)>>2) + 1)>>1; | ||
910 | dp[1] = (dp[1] + ((unsigned int)(s2+(s1=sp[2])+s4+(s3=sp2[2])+2)>>2) + 1)>>1; | ||
911 | dp[2] = (dp[2] + ((unsigned int)(s1+(s2=sp[3])+s3+(s4=sp2[3])+2)>>2) + 1)>>1; | ||
912 | dp[3] = (dp[3] + ((unsigned int)(s2+(s1=sp[4])+s4+(s3=sp2[4])+2)>>2) + 1)>>1; | ||
913 | dp[4] = (dp[4] + ((unsigned int)(s1+(s2=sp[5])+s3+(s4=sp2[5])+2)>>2) + 1)>>1; | ||
914 | dp[5] = (dp[5] + ((unsigned int)(s2+(s1=sp[6])+s4+(s3=sp2[6])+2)>>2) + 1)>>1; | ||
915 | dp[6] = (dp[6] + ((unsigned int)(s1+(s2=sp[7])+s3+(s4=sp2[7])+2)>>2) + 1)>>1; | ||
916 | dp[7] = (dp[7] + ((unsigned int)(s2+sp[8]+s4+sp2[8]+2)>>2) + 1)>>1; | ||
917 | sp+= lx2; | ||
918 | sp2+= lx2; | ||
919 | dp+= lx2; | ||
920 | } | ||
921 | } | ||
922 | |||
923 | static inline | ||
924 | void recon_comp(mpeg3video_t *video, | ||
925 | unsigned char *src, | ||
926 | unsigned char *dst, | ||
927 | int lx, | ||
928 | int lx2, | ||
929 | int w, | ||
930 | int h, | ||
931 | int x, | ||
932 | int y, | ||
933 | int dx, | ||
934 | int dy, | ||
935 | int addflag) | ||
936 | { | ||
937 | int switcher; | ||
938 | unsigned char *s, *d; | ||
939 | |||
940 | /* half pel scaling */ | ||
941 | switcher = (dx & 1) << 3 | (dy & 1) << 2 | w; | ||
942 | if(addflag) switcher |= 2; | ||
943 | /* origins */ | ||
944 | s = src + lx * (y + (dy >> 1)) + x + (dx >> 1); | ||
945 | d = dst + lx * y + x; | ||
946 | |||
947 | // Accelerated functions | ||
948 | #ifdef HAVE_3Dnow | ||
949 | if(video->have_mmx) | ||
950 | { | ||
951 | switch(switcher) | ||
952 | { | ||
953 | case 0x3: reca_mmx(s, d, lx2, h); break; | ||
954 | case 0x2:recac_mmx(s, d, lx2, h); break; | ||
955 | case 0x1:rec_mmx(s, d, lx2, h); break; | ||
956 | case 0x0:recc_mmx(s, d, lx2, h); break; | ||
957 | case 0x7: recva_mmx(s, d, lx, lx2, h); break; | ||
958 | case 0x6: recvac_mmx(s, d, lx, lx2, h); break; | ||
959 | case 0x5:recv_mmx(s, d, lx, lx2, h); break; | ||
960 | case 0x4:recvc_mmx(s, d, lx, lx2, h); break; | ||
961 | case 0x9:rech_mmx(s, d, lx2, h); break; | ||
962 | case 0x8: rechc_mmx(s, d, lx2, h); break; | ||
963 | } | ||
964 | } | ||
965 | else | ||
966 | #endif | ||
967 | { | ||
968 | switch(switcher) | ||
969 | { | ||
970 | case 0x3: reca(s, d, lx2, h); break; | ||
971 | case 0x2:recac(s, d, lx2, h); break; | ||
972 | case 0x1:rec(s, d, lx2, h); break; | ||
973 | case 0x0:recc(s, d, lx2, h); break; | ||
974 | case 0x7: recva(s, d, lx, lx2, h); break; | ||
975 | case 0x6: recvac(s, d, lx, lx2, h); break; | ||
976 | case 0x5:recv_(s, d, lx, lx2, h); break; | ||
977 | case 0x4:recvc(s, d, lx, lx2, h); break; | ||
978 | case 0x9:rech(s, d, lx2, h); break; | ||
979 | case 0x8: rechc(s, d, lx2, h); break; | ||
980 | } | ||
981 | } | ||
982 | |||
983 | // Unaccelerated functions | ||
984 | switch(switcher) | ||
985 | { | ||
986 | case 0xb: recha(s, d, lx2, h); break; | ||
987 | case 0xa:rechac(s, d, lx2, h); break; | ||
988 | case 0xf: rec4a(s, d, lx, lx2, h); break; | ||
989 | case 0xe:rec4ac(s, d, lx, lx2, h); break; | ||
990 | case 0xd:rec4(s, d, lx, lx2, h); break; | ||
991 | case 0xc:rec4c(s, d, lx, lx2, h); break; | ||
992 | } | ||
993 | } | ||
994 | |||
995 | /* | ||
996 | unsigned char *src[]; * prediction source buffer * | ||
997 | int sfield; * prediction source field number (0 or 1) * | ||
998 | unsigned char *dst[]; * prediction destination buffer * | ||
999 | int dfield; * prediction destination field number (0 or 1)* | ||
1000 | int lx,lx2; * horizontal offsets * | ||
1001 | int w,h; * prediction block/sub-block width, height * | ||
1002 | int x,y; * pixel co-ordinates of top-left sample in current MB * | ||
1003 | int dx,dy; * horizontal, vertical motion vector * | ||
1004 | int addflag; * add prediction error to prediction ? * | ||
1005 | */ | ||
1006 | static void recon(mpeg3video_t *video, | ||
1007 | unsigned char *src[], | ||
1008 | int sfield, | ||
1009 | unsigned char *dst[], | ||
1010 | int dfield, | ||
1011 | int lx, | ||
1012 | int lx2, | ||
1013 | int w, | ||
1014 | int h, | ||
1015 | int x, | ||
1016 | int y, | ||
1017 | int dx, | ||
1018 | int dy, | ||
1019 | int addflag) | ||
1020 | { | ||
1021 | |||
1022 | /* Y */ | ||
1023 | recon_comp(video, (src[0] + (sfield ? (lx2 >> 1) : 0)), | ||
1024 | dst[0] + (dfield ? (lx2 >> 1) : 0), | ||
1025 | lx, lx2, w, h, x, y, dx, dy, addflag); | ||
1026 | |||
1027 | if(video->chroma_format != CHROMA444) | ||
1028 | { | ||
1029 | lx >>= 1; | ||
1030 | dx /= 2; | ||
1031 | lx2 >>= 1; | ||
1032 | w = 0; | ||
1033 | x >>= 1; | ||
1034 | } | ||
1035 | |||
1036 | if(video->chroma_format == CHROMA420) | ||
1037 | { | ||
1038 | h >>= 1; | ||
1039 | dy /= 2; | ||
1040 | y >>= 1; | ||
1041 | } | ||
1042 | |||
1043 | /* Cb */ | ||
1044 | recon_comp(video, (src[1] + (sfield ? (lx2 >> 1) : 0)), | ||
1045 | dst[1] + (dfield ? (lx2 >> 1) : 0), | ||
1046 | lx, lx2, w, h, x, y, dx, dy, addflag); | ||
1047 | |||
1048 | /* Cr */ | ||
1049 | recon_comp(video, (src[2] + (sfield ? (lx2 >> 1) : 0)), | ||
1050 | dst[2] + (dfield ? (lx2 >> 1) : 0), | ||
1051 | lx, lx2, w, h, x, y, dx, dy, addflag); | ||
1052 | } | ||
1053 | |||
1054 | #define WIDTH 1 | ||
1055 | |||
1056 | int mpeg3video_reconstruct(mpeg3video_t *video, | ||
1057 | int bx, | ||
1058 | int by, | ||
1059 | int mb_type, | ||
1060 | int motion_type, | ||
1061 | int PMV[2][2][2], | ||
1062 | int mv_field_sel[2][2], | ||
1063 | int dmvector[2], | ||
1064 | int stwtype) | ||
1065 | { | ||
1066 | int currentfield; | ||
1067 | unsigned char **predframe; | ||
1068 | int DMV[2][2]; | ||
1069 | int stwtop, stwbot; | ||
1070 | |||
1071 | stwtop = stwtype % 3; /* 0:temporal, 1 : (spat+temp) / 2, 2 : spatial */ | ||
1072 | stwbot = stwtype / 3; | ||
1073 | |||
1074 | if((mb_type & MB_FORWARD) || (video->pict_type == P_TYPE)) | ||
1075 | { | ||
1076 | if(video->pict_struct == FRAME_PICTURE) | ||
1077 | { | ||
1078 | if((motion_type == MC_FRAME) || !(mb_type & MB_FORWARD)) | ||
1079 | { | ||
1080 | /* frame-based prediction */ | ||
1081 | { | ||
1082 | if(stwtop < 2) | ||
1083 | recon(video, video->oldrefframe, 0, video->newframe, 0, | ||
1084 | video->coded_picture_width, video->coded_picture_width << 1, WIDTH, 8, bx, by, | ||
1085 | PMV[0][0][0], PMV[0][0][1], stwtop); | ||
1086 | |||
1087 | if(stwbot < 2) | ||
1088 | recon(video, video->oldrefframe, 1, video->newframe, 1, | ||
1089 | video->coded_picture_width, video->coded_picture_width << 1, WIDTH, 8, bx, by, | ||
1090 | PMV[0][0][0], PMV[0][0][1], stwbot); | ||
1091 | } | ||
1092 | } | ||
1093 | else if(motion_type == MC_FIELD) /* field-based prediction */ | ||
1094 | { | ||
1095 | /* top field prediction */ | ||
1096 | if(stwtop < 2) | ||
1097 | recon(video, video->oldrefframe, mv_field_sel[0][0], video->newframe, 0, | ||
1098 | video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by >> 1, | ||
1099 | PMV[0][0][0], PMV[0][0][1] >> 1, stwtop); | ||
1100 | |||
1101 | /* bottom field prediction */ | ||
1102 | if(stwbot < 2) | ||
1103 | recon(video, video->oldrefframe, mv_field_sel[1][0], video->newframe, 1, | ||
1104 | video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by >> 1, | ||
1105 | PMV[1][0][0], PMV[1][0][1] >> 1, stwbot); | ||
1106 | } | ||
1107 | else if(motion_type == MC_DMV) | ||
1108 | { | ||
1109 | /* dual prime prediction */ | ||
1110 | /* calculate derived motion vectors */ | ||
1111 | mpeg3video_calc_dmv(video, | ||
1112 | DMV, | ||
1113 | dmvector, | ||
1114 | PMV[0][0][0], | ||
1115 | PMV[0][0][1] >> 1); | ||
1116 | |||
1117 | if(stwtop < 2) | ||
1118 | { | ||
1119 | /* predict top field from top field */ | ||
1120 | recon(video, video->oldrefframe, 0, video->newframe, 0, | ||
1121 | video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by>>1, | ||
1122 | PMV[0][0][0], PMV[0][0][1] >> 1, 0); | ||
1123 | |||
1124 | /* predict and add to top field from bottom field */ | ||
1125 | recon(video, video->oldrefframe, 1, video->newframe, 0, | ||
1126 | video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by>>1, | ||
1127 | DMV[0][0], DMV[0][1], 1); | ||
1128 | } | ||
1129 | |||
1130 | if(stwbot < 2) | ||
1131 | { | ||
1132 | /* predict bottom field from bottom field */ | ||
1133 | recon(video, video->oldrefframe, 1, video->newframe, 1, | ||
1134 | video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by>>1, | ||
1135 | PMV[0][0][0], PMV[0][0][1]>>1, 0); | ||
1136 | |||
1137 | /* predict and add to bottom field from top field */ | ||
1138 | recon(video, video->oldrefframe, 0, video->newframe, 1, | ||
1139 | video->coded_picture_width << 1, video->coded_picture_width<<1, WIDTH, 8, bx, by>>1, | ||
1140 | DMV[1][0], DMV[1][1], 1); | ||
1141 | } | ||
1142 | } | ||
1143 | else | ||
1144 | /* invalid motion_type */ | ||
1145 | /* fprintf(stderr, "reconstruct: invalid motion_type\n"); */ | ||
1146 | ; | ||
1147 | } | ||
1148 | else | ||
1149 | { | ||
1150 | /* TOP_FIELD or BOTTOM_FIELD */ | ||
1151 | /* field picture */ | ||
1152 | currentfield = (video->pict_struct == BOTTOM_FIELD); | ||
1153 | |||
1154 | /* determine which frame to use for prediction */ | ||
1155 | if((video->pict_type == P_TYPE) && video->secondfield | ||
1156 | && (currentfield != mv_field_sel[0][0])) | ||
1157 | predframe = video->refframe; /* same frame */ | ||
1158 | else | ||
1159 | predframe = video->oldrefframe; /* previous frame */ | ||
1160 | |||
1161 | if((motion_type == MC_FIELD) || !(mb_type & MB_FORWARD)) | ||
1162 | { | ||
1163 | /* field-based prediction */ | ||
1164 | if(stwtop < 2) | ||
1165 | recon(video, predframe,mv_field_sel[0][0],video->newframe,0, | ||
1166 | video->coded_picture_width << 1,video->coded_picture_width << 1,WIDTH,16,bx,by, | ||
1167 | PMV[0][0][0],PMV[0][0][1],stwtop); | ||
1168 | } | ||
1169 | else | ||
1170 | if(motion_type == MC_16X8) | ||
1171 | { | ||
1172 | if(stwtop < 2) | ||
1173 | { | ||
1174 | recon(video, predframe, mv_field_sel[0][0], video->newframe, 0, | ||
1175 | video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by, | ||
1176 | PMV[0][0][0], PMV[0][0][1], stwtop); | ||
1177 | |||
1178 | /* determine which frame to use for lower half prediction */ | ||
1179 | if((video->pict_type==P_TYPE) && video->secondfield | ||
1180 | && (currentfield!=mv_field_sel[1][0])) | ||
1181 | predframe = video->refframe; /* same frame */ | ||
1182 | else | ||
1183 | predframe = video->oldrefframe; /* previous frame */ | ||
1184 | |||
1185 | recon(video, predframe, mv_field_sel[1][0], video->newframe, 0, | ||
1186 | video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by+8, | ||
1187 | PMV[1][0][0], PMV[1][0][1], stwtop); | ||
1188 | } | ||
1189 | } | ||
1190 | else | ||
1191 | if(motion_type == MC_DMV) /* dual prime prediction */ | ||
1192 | { | ||
1193 | if(video->secondfield) | ||
1194 | predframe = video->refframe; /* same frame */ | ||
1195 | else | ||
1196 | predframe = video->oldrefframe; /* previous frame */ | ||
1197 | |||
1198 | /* calculate derived motion vectors */ | ||
1199 | mpeg3video_calc_dmv(video, | ||
1200 | DMV, | ||
1201 | dmvector, | ||
1202 | PMV[0][0][0], | ||
1203 | PMV[0][0][1]); | ||
1204 | |||
1205 | /* predict from field of same parity */ | ||
1206 | recon(video, video->oldrefframe, currentfield, video->newframe, 0, | ||
1207 | video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 16, bx, by, | ||
1208 | PMV[0][0][0], PMV[0][0][1], 0); | ||
1209 | |||
1210 | /* predict from field of opposite parity */ | ||
1211 | recon(video, predframe, !currentfield, video->newframe, 0, | ||
1212 | video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 16, bx, by, | ||
1213 | DMV[0][0], DMV[0][1], 1); | ||
1214 | } | ||
1215 | else | ||
1216 | /* invalid motion_type */ | ||
1217 | /* fprintf(stderr, "reconstruct: invalid motion_type\n"); */ | ||
1218 | ; | ||
1219 | } | ||
1220 | stwtop = stwbot = 1; | ||
1221 | } | ||
1222 | |||
1223 | if(mb_type & MB_BACKWARD) | ||
1224 | { | ||
1225 | if(video->pict_struct == FRAME_PICTURE) | ||
1226 | { | ||
1227 | if(motion_type == MC_FRAME) | ||
1228 | { | ||
1229 | /* frame-based prediction */ | ||
1230 | if(stwtop < 2) | ||
1231 | recon(video, video->refframe, 0, video->newframe, 0, | ||
1232 | video->coded_picture_width, video->coded_picture_width << 1, WIDTH, 8, bx, by, | ||
1233 | PMV[0][1][0], PMV[0][1][1], stwtop); | ||
1234 | |||
1235 | if(stwbot < 2) | ||
1236 | recon(video, video->refframe, 1, video->newframe, 1, | ||
1237 | video->coded_picture_width, video->coded_picture_width << 1, WIDTH, 8, bx, by, | ||
1238 | PMV[0][1][0], PMV[0][1][1], stwbot); | ||
1239 | } | ||
1240 | else | ||
1241 | { | ||
1242 | /* field-based prediction */ | ||
1243 | /* top field prediction */ | ||
1244 | if(stwtop < 2) | ||
1245 | { | ||
1246 | recon(video, video->refframe, mv_field_sel[0][1], video->newframe, 0, | ||
1247 | (video->coded_picture_width << 1), (video->coded_picture_width<<1), WIDTH, 8, bx, (by >> 1), | ||
1248 | PMV[0][1][0], (PMV[0][1][1] >> 1), stwtop); | ||
1249 | } | ||
1250 | |||
1251 | /* bottom field prediction */ | ||
1252 | if(stwbot < 2) | ||
1253 | { | ||
1254 | recon(video, video->refframe, mv_field_sel[1][1], video->newframe, 1, (video->coded_picture_width << 1), | ||
1255 | (video->coded_picture_width << 1), WIDTH, 8, bx, (by>>1), | ||
1256 | PMV[1][1][0], (PMV[1][1][1]>>1), stwbot); | ||
1257 | } | ||
1258 | } | ||
1259 | } | ||
1260 | else | ||
1261 | { | ||
1262 | /* TOP_FIELD or BOTTOM_FIELD */ | ||
1263 | /* field picture */ | ||
1264 | if(motion_type == MC_FIELD) | ||
1265 | { | ||
1266 | /* field-based prediction */ | ||
1267 | recon(video, video->refframe, mv_field_sel[0][1], video->newframe, 0, | ||
1268 | video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 16, bx, by, | ||
1269 | PMV[0][1][0], PMV[0][1][1], stwtop); | ||
1270 | } | ||
1271 | else if(motion_type==MC_16X8) | ||
1272 | { | ||
1273 | recon(video, video->refframe, mv_field_sel[0][1], video->newframe, 0, | ||
1274 | video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by, | ||
1275 | PMV[0][1][0], PMV[0][1][1], stwtop); | ||
1276 | |||
1277 | recon(video, video->refframe, mv_field_sel[1][1], video->newframe, 0, | ||
1278 | video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by+8, | ||
1279 | PMV[1][1][0], PMV[1][1][1], stwtop); | ||
1280 | } | ||
1281 | else | ||
1282 | /* invalid motion_type */ | ||
1283 | /* fprintf(stderr, "reconstruct: invalid motion_type\n"); */ | ||
1284 | ; | ||
1285 | } | ||
1286 | } /* mb_type & MB_BACKWARD */ | ||
1287 | return 0; | ||
1288 | } | ||
1289 | |||
1290 | |||
diff --git a/core/multimedia/opieplayer/libmpeg3/video/seek.c b/core/multimedia/opieplayer/libmpeg3/video/seek.c new file mode 100644 index 0000000..04faba4 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/seek.c | |||
@@ -0,0 +1,233 @@ | |||
1 | #include "../mpeg3private.h" | ||
2 | #include "../mpeg3protos.h" | ||
3 | #include "mpeg3video.h" | ||
4 | #include <stdlib.h> | ||
5 | #include <string.h> | ||
6 | |||
7 | unsigned int mpeg3bits_next_startcode(mpeg3_bits_t* stream) | ||
8 | { | ||
9 | /* Perform forwards search */ | ||
10 | mpeg3bits_byte_align(stream); | ||
11 | |||
12 | /* Perform search */ | ||
13 | while((mpeg3bits_showbits32_noptr(stream) >> 8) != MPEG3_PACKET_START_CODE_PREFIX && | ||
14 | !mpeg3bits_eof(stream)) | ||
15 | { | ||
16 | mpeg3bits_getbyte_noptr(stream); | ||
17 | } | ||
18 | return mpeg3bits_showbits32_noptr(stream); | ||
19 | } | ||
20 | |||
21 | /* Line up on the beginning of the next code. */ | ||
22 | int mpeg3video_next_code(mpeg3_bits_t* stream, unsigned int code) | ||
23 | { | ||
24 | while(!mpeg3bits_eof(stream) && | ||
25 | mpeg3bits_showbits32_noptr(stream) != code) | ||
26 | { | ||
27 | mpeg3bits_getbyte_noptr(stream); | ||
28 | } | ||
29 | return mpeg3bits_eof(stream); | ||
30 | } | ||
31 | |||
32 | /* Line up on the beginning of the previous code. */ | ||
33 | int mpeg3video_prev_code(mpeg3_bits_t* stream, unsigned int code) | ||
34 | { | ||
35 | while(!mpeg3bits_bof(stream) && | ||
36 | mpeg3bits_showbits_reverse(stream, 32) != code) | ||
37 | { | ||
38 | mpeg3bits_getbits_reverse(stream, 8); | ||
39 | } | ||
40 | return mpeg3bits_bof(stream); | ||
41 | } | ||
42 | |||
43 | long mpeg3video_goptimecode_to_frame(mpeg3video_t *video) | ||
44 | { | ||
45 | /* printf("mpeg3video_goptimecode_to_frame %d %d %d %d %f\n", */ | ||
46 | /* video->gop_timecode.hour, video->gop_timecode.minute, video->gop_timecode.second, video->gop_timecode.frame, video->frame_rate); */ | ||
47 | return (long)(video->gop_timecode.hour * 3600 * video->frame_rate + | ||
48 | video->gop_timecode.minute * 60 * video->frame_rate + | ||
49 | video->gop_timecode.second * video->frame_rate + | ||
50 | video->gop_timecode.frame) - 1 - video->first_frame; | ||
51 | } | ||
52 | |||
53 | int mpeg3video_match_refframes(mpeg3video_t *video) | ||
54 | { | ||
55 | unsigned char *dst, *src; | ||
56 | int i, j, size; | ||
57 | |||
58 | for(i = 0; i < 3; i++) | ||
59 | { | ||
60 | if(video->newframe[i]) | ||
61 | { | ||
62 | if(video->newframe[i] == video->refframe[i]) | ||
63 | { | ||
64 | src = video->refframe[i]; | ||
65 | dst = video->oldrefframe[i]; | ||
66 | } | ||
67 | else | ||
68 | { | ||
69 | src = video->oldrefframe[i]; | ||
70 | dst = video->refframe[i]; | ||
71 | } | ||
72 | |||
73 | if(i == 0) | ||
74 | size = video->coded_picture_width * video->coded_picture_height + 32 * video->coded_picture_width; | ||
75 | else | ||
76 | size = video->chrom_width * video->chrom_height + 32 * video->chrom_width; | ||
77 | |||
78 | memcpy(dst, src, size); | ||
79 | } | ||
80 | } | ||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | int mpeg3video_seek(mpeg3video_t *video) | ||
85 | { | ||
86 | long this_gop_start; | ||
87 | int result = 0; | ||
88 | int back_step; | ||
89 | int attempts; | ||
90 | mpeg3_t *file = video->file; | ||
91 | mpeg3_bits_t *vstream = video->vstream; | ||
92 | double percentage; | ||
93 | long frame_number; | ||
94 | int match_refframes = 1; | ||
95 | |||
96 | /* Seek to a percentage */ | ||
97 | if(video->percentage_seek >= 0) | ||
98 | { | ||
99 | percentage = video->percentage_seek; | ||
100 | video->percentage_seek = -1; | ||
101 | mpeg3bits_seek_percentage(vstream, percentage); | ||
102 | // Go to previous I-frame | ||
103 | mpeg3bits_start_reverse(vstream); | ||
104 | result = mpeg3video_prev_code(vstream, MPEG3_GOP_START_CODE); | ||
105 | if(!result) mpeg3bits_getbits_reverse(vstream, 32); | ||
106 | mpeg3bits_start_forward(vstream); | ||
107 | |||
108 | if(mpeg3bits_tell_percentage(vstream) < 0) mpeg3bits_seek_percentage(vstream, 0); | ||
109 | |||
110 | // Read up to the correct percentage | ||
111 | result = 0; | ||
112 | while(!result && mpeg3bits_tell_percentage(vstream) < percentage) | ||
113 | { | ||
114 | result = mpeg3video_read_frame_backend(video, 0); | ||
115 | if(match_refframes) | ||
116 | mpeg3video_match_refframes(video); | ||
117 | match_refframes = 0; | ||
118 | } | ||
119 | } | ||
120 | else | ||
121 | /* Seek to a frame */ | ||
122 | if(video->frame_seek >= 0) | ||
123 | { | ||
124 | frame_number = video->frame_seek; | ||
125 | video->frame_seek = -1; | ||
126 | if(frame_number < 0) frame_number = 0; | ||
127 | if(frame_number > video->maxframe) frame_number = video->maxframe; | ||
128 | |||
129 | /* Seek to start of file */ | ||
130 | if(frame_number < 16) | ||
131 | { | ||
132 | video->repeat_count = video->current_repeat = 0; | ||
133 | mpeg3bits_seek_start(vstream); | ||
134 | video->framenum = 0; | ||
135 | result = mpeg3video_drop_frames(video, frame_number - video->framenum); | ||
136 | } | ||
137 | else | ||
138 | { | ||
139 | /* Seek to an I frame. */ | ||
140 | if((frame_number < video->framenum || frame_number - video->framenum > MPEG3_SEEK_THRESHOLD)) | ||
141 | { | ||
142 | /* Elementary stream */ | ||
143 | if(file->is_video_stream) | ||
144 | { | ||
145 | mpeg3_t *file = video->file; | ||
146 | mpeg3_vtrack_t *track = video->track; | ||
147 | long byte = (long)((float)(mpeg3demuxer_total_bytes(vstream->demuxer) / | ||
148 | track->total_frames) * | ||
149 | frame_number); | ||
150 | long minimum = 65535; | ||
151 | int done = 0; | ||
152 | |||
153 | //printf("seek elementary %d\n", frame_number); | ||
154 | /* Get GOP just before frame */ | ||
155 | do | ||
156 | { | ||
157 | result = mpeg3bits_seek_byte(vstream, byte); | ||
158 | mpeg3bits_start_reverse(vstream); | ||
159 | if(!result) result = mpeg3video_prev_code(vstream, MPEG3_GOP_START_CODE); | ||
160 | mpeg3bits_start_forward(vstream); | ||
161 | mpeg3bits_getbits(vstream, 8); | ||
162 | if(!result) result = mpeg3video_getgophdr(video); | ||
163 | this_gop_start = mpeg3video_goptimecode_to_frame(video); | ||
164 | |||
165 | //printf("wanted %ld guessed %ld byte %ld result %d\n", frame_number, this_gop_start, byte, result); | ||
166 | if(labs(this_gop_start - frame_number) >= labs(minimum)) | ||
167 | done = 1; | ||
168 | else | ||
169 | { | ||
170 | minimum = this_gop_start - frame_number; | ||
171 | byte += (long)((float)(frame_number - this_gop_start) * | ||
172 | (float)(mpeg3demuxer_total_bytes(vstream->demuxer) / | ||
173 | track->total_frames)); | ||
174 | if(byte < 0) byte = 0; | ||
175 | } | ||
176 | }while(!result && !done); | ||
177 | |||
178 | //printf("wanted %d guessed %d\n", frame_number, this_gop_start); | ||
179 | if(!result) | ||
180 | { | ||
181 | video->framenum = this_gop_start; | ||
182 | result = mpeg3video_drop_frames(video, frame_number - video->framenum); | ||
183 | } | ||
184 | } | ||
185 | else | ||
186 | /* System stream */ | ||
187 | { | ||
188 | mpeg3bits_seek_time(vstream, (double)frame_number / video->frame_rate); | ||
189 | percentage = mpeg3bits_tell_percentage(vstream); | ||
190 | //printf("seek frame %ld percentage %f byte %ld\n", frame_number, percentage, mpeg3bits_tell(vstream)); | ||
191 | mpeg3bits_start_reverse(vstream); | ||
192 | mpeg3video_prev_code(vstream, MPEG3_GOP_START_CODE); | ||
193 | mpeg3bits_getbits_reverse(vstream, 32); | ||
194 | mpeg3bits_start_forward(vstream); | ||
195 | //printf("seek system 1 %f\n", (double)frame_number / video->frame_rate); | ||
196 | |||
197 | while(!result && mpeg3bits_tell_percentage(vstream) < percentage) | ||
198 | { | ||
199 | result = mpeg3video_read_frame_backend(video, 0); | ||
200 | if(match_refframes) | ||
201 | mpeg3video_match_refframes(video); | ||
202 | |||
203 | //printf("seek system 2 %f %f\n", mpeg3bits_tell_percentage(vstream) / percentage); | ||
204 | match_refframes = 0; | ||
205 | } | ||
206 | //printf("seek system 3 %f\n", (double)frame_number / video->frame_rate); | ||
207 | } | ||
208 | |||
209 | video->framenum = frame_number; | ||
210 | } | ||
211 | else | ||
212 | // Drop frames | ||
213 | { | ||
214 | mpeg3video_drop_frames(video, frame_number - video->framenum); | ||
215 | } | ||
216 | } | ||
217 | } | ||
218 | |||
219 | return result; | ||
220 | } | ||
221 | |||
222 | int mpeg3video_drop_frames(mpeg3video_t *video, long frames) | ||
223 | { | ||
224 | int result = 0; | ||
225 | long frame_number = video->framenum + frames; | ||
226 | |||
227 | /* Read the selected number of frames and skip b-frames */ | ||
228 | while(!result && frame_number > video->framenum) | ||
229 | { | ||
230 | result = mpeg3video_read_frame_backend(video, frame_number - video->framenum); | ||
231 | } | ||
232 | return result; | ||
233 | } | ||
diff --git a/core/multimedia/opieplayer/libmpeg3/video/slice.c b/core/multimedia/opieplayer/libmpeg3/video/slice.c new file mode 100644 index 0000000..90891b0 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/slice.c | |||
@@ -0,0 +1,702 @@ | |||
1 | #include "../libmpeg3.h" | ||
2 | #include "../mpeg3protos.h" | ||
3 | #include "mpeg3video.h" | ||
4 | #include "mpeg3videoprotos.h" | ||
5 | #include "slice.h" | ||
6 | |||
7 | #include <stdlib.h> | ||
8 | |||
9 | static ULONGLONG MMX_128 = 0x80008000800080LL; | ||
10 | |||
11 | int mpeg3_new_slice_buffer(mpeg3_slice_buffer_t *slice_buffer) | ||
12 | { | ||
13 | pthread_mutexattr_t mutex_attr; | ||
14 | slice_buffer->data = (unsigned char*)malloc(1024); | ||
15 | slice_buffer->buffer_size = 0; | ||
16 | slice_buffer->buffer_allocation = 1024; | ||
17 | slice_buffer->current_position = 0; | ||
18 | slice_buffer->bits_size = 0; | ||
19 | slice_buffer->bits = 0; | ||
20 | slice_buffer->done = 0; | ||
21 | pthread_mutexattr_init(&mutex_attr); | ||
22 | pthread_mutex_init(&(slice_buffer->completion_lock), &mutex_attr); | ||
23 | return 0; | ||
24 | } | ||
25 | |||
26 | int mpeg3_delete_slice_buffer(mpeg3_slice_buffer_t *slice_buffer) | ||
27 | { | ||
28 | free(slice_buffer->data); | ||
29 | pthread_mutex_destroy(&(slice_buffer->completion_lock)); | ||
30 | return 0; | ||
31 | } | ||
32 | |||
33 | int mpeg3_expand_slice_buffer(mpeg3_slice_buffer_t *slice_buffer) | ||
34 | { | ||
35 | int i; | ||
36 | unsigned char *new_buffer = | ||
37 | (unsigned char*)malloc(slice_buffer->buffer_allocation * 2); | ||
38 | for(i = 0; i < slice_buffer->buffer_size; i++) | ||
39 | new_buffer[i] = slice_buffer->data[i]; | ||
40 | free(slice_buffer->data); | ||
41 | slice_buffer->data = new_buffer; | ||
42 | slice_buffer->buffer_allocation *= 2; | ||
43 | return 0; | ||
44 | } | ||
45 | |||
46 | /* limit coefficients to -2048..2047 */ | ||
47 | |||
48 | /* move/add 8x8-Block from block[comp] to refframe */ | ||
49 | |||
50 | static inline int mpeg3video_addblock(mpeg3_slice_t *slice, | ||
51 | mpeg3video_t *video, | ||
52 | int comp, | ||
53 | int bx, | ||
54 | int by, | ||
55 | int dct_type, | ||
56 | int addflag) | ||
57 | { | ||
58 | int cc, i, iincr; | ||
59 | unsigned char *rfp; | ||
60 | short *bp; | ||
61 | int spar = slice->sparse[comp]; | ||
62 | /* color component index */ | ||
63 | cc = (comp < 4) ? 0 : (comp & 1) + 1; | ||
64 | |||
65 | if(cc == 0) | ||
66 | { | ||
67 | /* luminance */ | ||
68 | if(video->pict_struct == FRAME_PICTURE) | ||
69 | { | ||
70 | if(dct_type) | ||
71 | { | ||
72 | /* field DCT coding */ | ||
73 | rfp = video->newframe[0] + | ||
74 | video->coded_picture_width * (by + ((comp & 2) >> 1)) + bx + ((comp & 1) << 3); | ||
75 | iincr = (video->coded_picture_width << 1); | ||
76 | } | ||
77 | else | ||
78 | { | ||
79 | /* frame DCT coding */ | ||
80 | rfp = video->newframe[0] + | ||
81 | video->coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3); | ||
82 | iincr = video->coded_picture_width; | ||
83 | } | ||
84 | } | ||
85 | else | ||
86 | { | ||
87 | /* field picture */ | ||
88 | rfp = video->newframe[0] + | ||
89 | (video->coded_picture_width << 1) * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3); | ||
90 | iincr = (video->coded_picture_width << 1); | ||
91 | } | ||
92 | } | ||
93 | else | ||
94 | { | ||
95 | /* chrominance */ | ||
96 | |||
97 | /* scale coordinates */ | ||
98 | if(video->chroma_format != CHROMA444) bx >>= 1; | ||
99 | if(video->chroma_format == CHROMA420) by >>= 1; | ||
100 | if(video->pict_struct == FRAME_PICTURE) | ||
101 | { | ||
102 | if(dct_type && (video->chroma_format != CHROMA420)) | ||
103 | { | ||
104 | /* field DCT coding */ | ||
105 | rfp = video->newframe[cc] | ||
106 | + video->chrom_width * (by + ((comp & 2) >> 1)) + bx + (comp & 8); | ||
107 | iincr = (video->chrom_width << 1); | ||
108 | } | ||
109 | else | ||
110 | { | ||
111 | /* frame DCT coding */ | ||
112 | rfp = video->newframe[cc] | ||
113 | + video->chrom_width * (by + ((comp & 2) << 2)) + bx + (comp & 8); | ||
114 | iincr = video->chrom_width; | ||
115 | } | ||
116 | } | ||
117 | else | ||
118 | { | ||
119 | /* field picture */ | ||
120 | rfp = video->newframe[cc] | ||
121 | + (video->chrom_width << 1) * (by + ((comp & 2) << 2)) + bx + (comp & 8); | ||
122 | iincr = (video->chrom_width << 1); | ||
123 | } | ||
124 | } | ||
125 | |||
126 | bp = slice->block[comp]; | ||
127 | |||
128 | if(addflag) | ||
129 | { | ||
130 | #ifdef HAVE_MMX | ||
131 | if(video->have_mmx) | ||
132 | { | ||
133 | if(spar) | ||
134 | { | ||
135 | __asm__ __volatile__( | ||
136 | "movq (%2), %%mm6\n" /* 4 blockvals */ | ||
137 | "pxor %%mm4, %%mm4\n" | ||
138 | "punpcklwd %%mm6, %%mm6\n" | ||
139 | "punpcklwd %%mm6, %%mm6\n" | ||
140 | ".align 8\n" | ||
141 | "1:" | ||
142 | "movq (%1), %%mm0\n" /* 8 rindex1 */ | ||
143 | "movq %%mm0, %%mm2\n" | ||
144 | "punpcklbw %%mm4, %%mm0\n" | ||
145 | "punpckhbw %%mm4, %%mm2\n" | ||
146 | "paddw %%mm6, %%mm0\n" | ||
147 | "paddw %%mm6, %%mm2\n" | ||
148 | |||
149 | "packuswb %%mm2, %%mm0\n" | ||
150 | "movq %%mm0, (%1)\n" | ||
151 | |||
152 | "leal (%1, %3), %1\n" | ||
153 | "loop 1b\n" | ||
154 | : /* scr dest */ | ||
155 | : "c" (8),"r" (rfp), "r" (bp), "r" (iincr) | ||
156 | ); | ||
157 | } | ||
158 | else | ||
159 | { | ||
160 | __asm__ __volatile__( | ||
161 | "pxor %%mm4, %%mm4\n" | ||
162 | |||
163 | ".align 8\n" | ||
164 | "1:" | ||
165 | "movq (%2), %%mm0\n" /* 8 rfp 0 1 2 3 4 5 6 7*/ | ||
166 | "movq (%1), %%mm6\n" /* 4 blockvals 0 1 2 3 */ | ||
167 | |||
168 | "movq %%mm0, %%mm2\n" | ||
169 | "movq 8(%1), %%mm5\n" /* 4 blockvals 0 1 2 3 */ | ||
170 | "punpcklbw %%mm4, %%mm0\n" /* 0 2 4 6 */ | ||
171 | "punpckhbw %%mm4, %%mm2\n" /* 1 3 5 7 */ | ||
172 | |||
173 | "paddw %%mm6, %%mm0\n" | ||
174 | "paddw %%mm5, %%mm2\n" | ||
175 | "packuswb %%mm2, %%mm0\n" | ||
176 | |||
177 | "addl $16, %1\n" | ||
178 | "movq %%mm0, (%2)\n" | ||
179 | |||
180 | "leal (%2,%3), %2\n" | ||
181 | "loop 1b\n" | ||
182 | : /* scr dest */ | ||
183 | : "c" (8),"r" (bp), "r" (rfp), "r" (iincr) | ||
184 | ); | ||
185 | } | ||
186 | } | ||
187 | else | ||
188 | #endif | ||
189 | for(i = 0; i < 8; i++) | ||
190 | { | ||
191 | rfp[0] = CLIP(bp[0] + rfp[0]); | ||
192 | rfp[1] = CLIP(bp[1] + rfp[1]); | ||
193 | rfp[2] = CLIP(bp[2] + rfp[2]); | ||
194 | rfp[3] = CLIP(bp[3] + rfp[3]); | ||
195 | rfp[4] = CLIP(bp[4] + rfp[4]); | ||
196 | rfp[5] = CLIP(bp[5] + rfp[5]); | ||
197 | rfp[6] = CLIP(bp[6] + rfp[6]); | ||
198 | rfp[7] = CLIP(bp[7] + rfp[7]); | ||
199 | rfp += iincr; | ||
200 | bp += 8; | ||
201 | } | ||
202 | } | ||
203 | else | ||
204 | { | ||
205 | #ifdef HAVE_MMX | ||
206 | if(video->have_mmx) | ||
207 | { | ||
208 | if(spar) | ||
209 | { | ||
210 | __asm__ __volatile__( | ||
211 | "movd (%2), %%mm0\n" /* " 0 0 0 v1" */ | ||
212 | "punpcklwd %%mm0, %%mm0\n" /* " 0 0 v1 v1" */ | ||
213 | "punpcklwd %%mm0, %%mm0\n" | ||
214 | "paddw MMX_128, %%mm0\n" | ||
215 | "packuswb %%mm0, %%mm0\n" | ||
216 | "leal (%0,%1,2), %%eax\n" | ||
217 | |||
218 | "movq %%mm0, (%0, %1)\n" | ||
219 | "movq %%mm0, (%%eax)\n" | ||
220 | "leal (%%eax,%1,2), %0\n" | ||
221 | "movq %%mm0, (%%eax, %1)\n" | ||
222 | |||
223 | "movq %%mm0, (%0)\n" | ||
224 | "leal (%0,%1,2), %%eax\n" | ||
225 | "movq %%mm0, (%0, %1)\n" | ||
226 | |||
227 | "movq %%mm0, (%%eax)\n" | ||
228 | "movq %%mm0, (%%eax, %1)\n" | ||
229 | : | ||
230 | : "D" (rfp), "c" (iincr), "b" (bp) | ||
231 | : "eax"); | ||
232 | } | ||
233 | else | ||
234 | { | ||
235 | __asm__ __volatile__( | ||
236 | "movq MMX_128,%%mm4\n" | ||
237 | ".align 8\n" | ||
238 | "1:" | ||
239 | "movq (%1), %%mm0\n" | ||
240 | "movq 8(%1), %%mm1\n" | ||
241 | "paddw %%mm4, %%mm0\n" | ||
242 | |||
243 | "movq 16(%1), %%mm2\n" | ||
244 | "paddw %%mm4, %%mm1\n" | ||
245 | |||
246 | "movq 24(%1), %%mm3\n" | ||
247 | "paddw %%mm4, %%mm2\n" | ||
248 | |||
249 | "packuswb %%mm1, %%mm0\n" | ||
250 | "paddw %%mm4, %%mm3\n" | ||
251 | |||
252 | "addl $32, %1\n" | ||
253 | "packuswb %%mm3, %%mm2\n" | ||
254 | |||
255 | "movq %%mm0, (%2)\n" | ||
256 | |||
257 | "movq %%mm2, (%2,%3)\n" | ||
258 | |||
259 | "leal (%2,%3,2), %2\n" | ||
260 | "loop 1b\n" | ||
261 | : | ||
262 | : "c" (4), "r" (bp), "r" (rfp), "r" (iincr) | ||
263 | ); | ||
264 | } | ||
265 | } | ||
266 | else | ||
267 | #endif | ||
268 | for(i = 0; i < 8; i++) | ||
269 | { | ||
270 | rfp[0] = CLIP(bp[0] + 128); | ||
271 | rfp[1] = CLIP(bp[1] + 128); | ||
272 | rfp[2] = CLIP(bp[2] + 128); | ||
273 | rfp[3] = CLIP(bp[3] + 128); | ||
274 | rfp[4] = CLIP(bp[4] + 128); | ||
275 | rfp[5] = CLIP(bp[5] + 128); | ||
276 | rfp[6] = CLIP(bp[6] + 128); | ||
277 | rfp[7] = CLIP(bp[7] + 128); | ||
278 | rfp+= iincr; | ||
279 | bp += 8; | ||
280 | } | ||
281 | } | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | int mpeg3_decode_slice(mpeg3_slice_t *slice) | ||
286 | { | ||
287 | mpeg3video_t *video = slice->video; | ||
288 | int comp; | ||
289 | int mb_type, cbp, motion_type = 0, dct_type; | ||
290 | int macroblock_address, mba_inc, mba_max; | ||
291 | int slice_vert_pos_ext; | ||
292 | unsigned int code; | ||
293 | int bx, by; | ||
294 | int dc_dct_pred[3]; | ||
295 | int mv_count, mv_format, mvscale; | ||
296 | int pmv[2][2][2], mv_field_sel[2][2]; | ||
297 | int dmv, dmvector[2]; | ||
298 | int qs; | ||
299 | int stwtype, stwclass; | ||
300 | int snr_cbp; | ||
301 | int i; | ||
302 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
303 | |||
304 | /* number of macroblocks per picture */ | ||
305 | mba_max = video->mb_width * video->mb_height; | ||
306 | |||
307 | /* field picture has half as many macroblocks as frame */ | ||
308 | if(video->pict_struct != FRAME_PICTURE) | ||
309 | mba_max >>= 1; | ||
310 | |||
311 | /* macroblock address */ | ||
312 | macroblock_address = 0; | ||
313 | /* first macroblock in slice is not skipped */ | ||
314 | mba_inc = 0; | ||
315 | slice->fault = 0; | ||
316 | |||
317 | code = mpeg3slice_getbits(slice_buffer, 32); | ||
318 | /* decode slice header (may change quant_scale) */ | ||
319 | slice_vert_pos_ext = mpeg3video_getslicehdr(slice, video); | ||
320 | |||
321 | /* reset all DC coefficient and motion vector predictors */ | ||
322 | dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0; | ||
323 | pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0; | ||
324 | pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0; | ||
325 | |||
326 | for(i = 0; | ||
327 | slice_buffer->current_position < slice_buffer->buffer_size; | ||
328 | i++) | ||
329 | { | ||
330 | if(mba_inc == 0) | ||
331 | { | ||
332 | /* Done */ | ||
333 | if(!mpeg3slice_showbits(slice_buffer, 23)) return 0; | ||
334 | /* decode macroblock address increment */ | ||
335 | mba_inc = mpeg3video_get_macroblock_address(slice); | ||
336 | |||
337 | if(slice->fault) return 1; | ||
338 | |||
339 | if(i == 0) | ||
340 | { | ||
341 | /* Get the macroblock_address */ | ||
342 | macroblock_address = ((slice_vert_pos_ext << 7) + (code & 255) - 1) * video->mb_width + mba_inc - 1; | ||
343 | /* first macroblock in slice: not skipped */ | ||
344 | mba_inc = 1; | ||
345 | } | ||
346 | } | ||
347 | |||
348 | if(slice->fault) return 1; | ||
349 | |||
350 | if(macroblock_address >= mba_max) | ||
351 | { | ||
352 | /* mba_inc points beyond picture dimensions */ | ||
353 | /*fprintf(stderr, "mpeg3_decode_slice: too many macroblocks in picture\n"); */ | ||
354 | return 1; | ||
355 | } | ||
356 | |||
357 | /* not skipped */ | ||
358 | if(mba_inc == 1) | ||
359 | { | ||
360 | mpeg3video_macroblock_modes(slice, | ||
361 | video, | ||
362 | &mb_type, | ||
363 | &stwtype, | ||
364 | &stwclass, | ||
365 | &motion_type, | ||
366 | &mv_count, | ||
367 | &mv_format, | ||
368 | &dmv, | ||
369 | &mvscale, | ||
370 | &dct_type); | ||
371 | |||
372 | if(slice->fault) return 1; | ||
373 | |||
374 | if(mb_type & MB_QUANT) | ||
375 | { | ||
376 | qs = mpeg3slice_getbits(slice_buffer, 5); | ||
377 | |||
378 | if(video->mpeg2) | ||
379 | slice->quant_scale = video->qscale_type ? mpeg3_non_linear_mquant_table[qs] : (qs << 1); | ||
380 | else | ||
381 | slice->quant_scale = qs; | ||
382 | |||
383 | if(video->scalable_mode == SC_DP) | ||
384 | /* make sure quant_scale is valid */ | ||
385 | slice->quant_scale = slice->quant_scale; | ||
386 | } | ||
387 | |||
388 | /* motion vectors */ | ||
389 | |||
390 | |||
391 | /* decode forward motion vectors */ | ||
392 | if((mb_type & MB_FORWARD) || ((mb_type & MB_INTRA) && video->conceal_mv)) | ||
393 | { | ||
394 | if(video->mpeg2) | ||
395 | mpeg3video_motion_vectors(slice, | ||
396 | video, | ||
397 | pmv, | ||
398 | dmvector, | ||
399 | mv_field_sel, | ||
400 | 0, | ||
401 | mv_count, | ||
402 | mv_format, | ||
403 | video->h_forw_r_size, | ||
404 | video->v_forw_r_size, | ||
405 | dmv, | ||
406 | mvscale); | ||
407 | else | ||
408 | mpeg3video_motion_vector(slice, | ||
409 | video, | ||
410 | pmv[0][0], | ||
411 | dmvector, | ||
412 | video->forw_r_size, | ||
413 | video->forw_r_size, | ||
414 | 0, | ||
415 | 0, | ||
416 | video->full_forw); | ||
417 | } | ||
418 | if(slice->fault) return 1; | ||
419 | |||
420 | /* decode backward motion vectors */ | ||
421 | if(mb_type & MB_BACKWARD) | ||
422 | { | ||
423 | if(video->mpeg2) | ||
424 | mpeg3video_motion_vectors(slice, | ||
425 | video, | ||
426 | pmv, | ||
427 | dmvector, | ||
428 | mv_field_sel, | ||
429 | 1, | ||
430 | mv_count, | ||
431 | mv_format, | ||
432 | video->h_back_r_size, | ||
433 | video->v_back_r_size, | ||
434 | 0, | ||
435 | mvscale); | ||
436 | else | ||
437 | mpeg3video_motion_vector(slice, | ||
438 | video, | ||
439 | pmv[0][1], | ||
440 | dmvector, | ||
441 | video->back_r_size, | ||
442 | video->back_r_size, | ||
443 | 0, | ||
444 | 0, | ||
445 | video->full_back); | ||
446 | } | ||
447 | |||
448 | if(slice->fault) return 1; | ||
449 | |||
450 | /* remove marker_bit */ | ||
451 | if((mb_type & MB_INTRA) && video->conceal_mv) | ||
452 | mpeg3slice_flushbit(slice_buffer); | ||
453 | |||
454 | /* macroblock_pattern */ | ||
455 | if(mb_type & MB_PATTERN) | ||
456 | { | ||
457 | cbp = mpeg3video_get_cbp(slice); | ||
458 | if(video->chroma_format == CHROMA422) | ||
459 | { | ||
460 | /* coded_block_pattern_1 */ | ||
461 | cbp = (cbp << 2) | mpeg3slice_getbits2(slice_buffer); | ||
462 | } | ||
463 | else | ||
464 | if(video->chroma_format == CHROMA444) | ||
465 | { | ||
466 | /* coded_block_pattern_2 */ | ||
467 | cbp = (cbp << 6) | mpeg3slice_getbits(slice_buffer, 6); | ||
468 | } | ||
469 | } | ||
470 | else | ||
471 | cbp = (mb_type & MB_INTRA) ? ((1 << video->blk_cnt) - 1) : 0; | ||
472 | |||
473 | if(slice->fault) return 1; | ||
474 | /* decode blocks */ | ||
475 | mpeg3video_clearblock(slice, 0, video->blk_cnt); | ||
476 | for(comp = 0; comp < video->blk_cnt; comp++) | ||
477 | { | ||
478 | if(cbp & (1 << (video->blk_cnt - comp - 1))) | ||
479 | { | ||
480 | if(mb_type & MB_INTRA) | ||
481 | { | ||
482 | if(video->mpeg2) | ||
483 | mpeg3video_getmpg2intrablock(slice, video, comp, dc_dct_pred); | ||
484 | else | ||
485 | mpeg3video_getintrablock(slice, video, comp, dc_dct_pred); | ||
486 | } | ||
487 | else | ||
488 | { | ||
489 | if(video->mpeg2) | ||
490 | mpeg3video_getmpg2interblock(slice, video, comp); | ||
491 | else | ||
492 | mpeg3video_getinterblock(slice, video, comp); | ||
493 | } | ||
494 | if(slice->fault) return 1; | ||
495 | } | ||
496 | } | ||
497 | |||
498 | /* reset intra_dc predictors */ | ||
499 | if(!(mb_type & MB_INTRA)) | ||
500 | dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0; | ||
501 | |||
502 | /* reset motion vector predictors */ | ||
503 | if((mb_type & MB_INTRA) && !video->conceal_mv) | ||
504 | { | ||
505 | /* intra mb without concealment motion vectors */ | ||
506 | pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0; | ||
507 | pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0; | ||
508 | } | ||
509 | |||
510 | if((video->pict_type == P_TYPE) && !(mb_type & (MB_FORWARD | MB_INTRA))) | ||
511 | { | ||
512 | /* non-intra mb without forward mv in a P picture */ | ||
513 | pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0; | ||
514 | |||
515 | /* derive motion_type */ | ||
516 | if(video->pict_struct == FRAME_PICTURE) | ||
517 | motion_type = MC_FRAME; | ||
518 | else | ||
519 | { | ||
520 | motion_type = MC_FIELD; | ||
521 | /* predict from field of same parity */ | ||
522 | mv_field_sel[0][0] = (video->pict_struct == BOTTOM_FIELD); | ||
523 | } | ||
524 | } | ||
525 | |||
526 | if(stwclass == 4) | ||
527 | { | ||
528 | /* purely spatially predicted macroblock */ | ||
529 | pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0; | ||
530 | pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0; | ||
531 | } | ||
532 | } | ||
533 | else | ||
534 | { | ||
535 | /* mba_inc!=1: skipped macroblock */ | ||
536 | mpeg3video_clearblock(slice, 0, video->blk_cnt); | ||
537 | |||
538 | /* reset intra_dc predictors */ | ||
539 | dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0; | ||
540 | |||
541 | /* reset motion vector predictors */ | ||
542 | if(video->pict_type == P_TYPE) | ||
543 | pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0; | ||
544 | |||
545 | /* derive motion_type */ | ||
546 | if(video->pict_struct == FRAME_PICTURE) | ||
547 | motion_type = MC_FRAME; | ||
548 | else | ||
549 | { | ||
550 | motion_type = MC_FIELD; | ||
551 | /* predict from field of same parity */ | ||
552 | mv_field_sel[0][0] = mv_field_sel[0][1] = (video->pict_struct == BOTTOM_FIELD); | ||
553 | } | ||
554 | |||
555 | /* skipped I are spatial-only predicted, */ | ||
556 | /* skipped P and B are temporal-only predicted */ | ||
557 | stwtype = (video->pict_type == I_TYPE) ? 8 : 0; | ||
558 | |||
559 | /* clear MB_INTRA */ | ||
560 | mb_type &= ~MB_INTRA; | ||
561 | |||
562 | /* no block data */ | ||
563 | cbp = 0; | ||
564 | } | ||
565 | |||
566 | snr_cbp = 0; | ||
567 | |||
568 | /* pixel coordinates of top left corner of current macroblock */ | ||
569 | bx = 16 * (macroblock_address % video->mb_width); | ||
570 | by = 16 * (macroblock_address / video->mb_width); | ||
571 | |||
572 | /* motion compensation */ | ||
573 | if(!(mb_type & MB_INTRA)) | ||
574 | mpeg3video_reconstruct(video, | ||
575 | bx, | ||
576 | by, | ||
577 | mb_type, | ||
578 | motion_type, | ||
579 | pmv, | ||
580 | mv_field_sel, | ||
581 | dmvector, | ||
582 | stwtype); | ||
583 | |||
584 | /* copy or add block data into picture */ | ||
585 | for(comp = 0; comp < video->blk_cnt; comp++) | ||
586 | { | ||
587 | if((cbp | snr_cbp) & (1 << (video->blk_cnt - 1 - comp))) | ||
588 | { | ||
589 | #ifdef HAVE_MMX | ||
590 | if(video->have_mmx) | ||
591 | IDCT_mmx(slice->block[comp]); | ||
592 | else | ||
593 | #endif | ||
594 | mpeg3video_idct_conversion(slice->block[comp]); | ||
595 | |||
596 | mpeg3video_addblock(slice, | ||
597 | video, | ||
598 | comp, | ||
599 | bx, | ||
600 | by, | ||
601 | dct_type, | ||
602 | (mb_type & MB_INTRA) == 0); | ||
603 | } | ||
604 | } | ||
605 | |||
606 | /* advance to next macroblock */ | ||
607 | macroblock_address++; | ||
608 | mba_inc--; | ||
609 | } | ||
610 | |||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | void mpeg3_slice_loop(mpeg3_slice_t *slice) | ||
615 | { | ||
616 | mpeg3video_t *video = slice->video; | ||
617 | int result = 1; | ||
618 | |||
619 | while(!slice->done) | ||
620 | { | ||
621 | pthread_mutex_lock(&(slice->input_lock)); | ||
622 | |||
623 | if(!slice->done) | ||
624 | { | ||
625 | /* Get a buffer to decode */ | ||
626 | result = 1; | ||
627 | pthread_mutex_lock(&(video->slice_lock)); | ||
628 | if(slice->buffer_step > 0) | ||
629 | { | ||
630 | while(slice->current_buffer <= slice->last_buffer) | ||
631 | { | ||
632 | if(!video->slice_buffers[slice->current_buffer].done && | ||
633 | slice->current_buffer <= slice->last_buffer) | ||
634 | { | ||
635 | result = 0; | ||
636 | break; | ||
637 | } | ||
638 | slice->current_buffer += slice->buffer_step; | ||
639 | } | ||
640 | } | ||
641 | else | ||
642 | { | ||
643 | while(slice->current_buffer >= slice->last_buffer) | ||
644 | { | ||
645 | if(!video->slice_buffers[slice->current_buffer].done && | ||
646 | slice->current_buffer >= slice->last_buffer) | ||
647 | { | ||
648 | result = 0; | ||
649 | break; | ||
650 | } | ||
651 | slice->current_buffer += slice->buffer_step; | ||
652 | } | ||
653 | } | ||
654 | |||
655 | /* Got one */ | ||
656 | if(!result && slice->current_buffer >= 0 && slice->current_buffer < video->total_slice_buffers) | ||
657 | { | ||
658 | slice->slice_buffer = &(video->slice_buffers[slice->current_buffer]); | ||
659 | slice->slice_buffer->done = 1; | ||
660 | pthread_mutex_unlock(&(video->slice_lock)); | ||
661 | pthread_mutex_unlock(&(slice->input_lock)); | ||
662 | mpeg3_decode_slice(slice); | ||
663 | pthread_mutex_unlock(&(slice->slice_buffer->completion_lock)); | ||
664 | } | ||
665 | else | ||
666 | pthread_mutex_unlock(&(video->slice_lock)); | ||
667 | } | ||
668 | |||
669 | pthread_mutex_unlock(&(slice->output_lock)); | ||
670 | } | ||
671 | } | ||
672 | |||
673 | int mpeg3_new_slice_decoder(mpeg3video_t *video, mpeg3_slice_t *slice) | ||
674 | { | ||
675 | pthread_attr_t attr; | ||
676 | //struct sched_param param; | ||
677 | pthread_mutexattr_t mutex_attr; | ||
678 | |||
679 | slice->video = video; | ||
680 | slice->done = 0; | ||
681 | pthread_mutexattr_init(&mutex_attr); | ||
682 | pthread_mutex_init(&(slice->input_lock), &mutex_attr); | ||
683 | pthread_mutex_lock(&(slice->input_lock)); | ||
684 | pthread_mutex_init(&(slice->output_lock), &mutex_attr); | ||
685 | pthread_mutex_lock(&(slice->output_lock)); | ||
686 | |||
687 | pthread_attr_init(&attr); | ||
688 | pthread_create(&(slice->tid), &attr, | ||
689 | (void * (*)(void *))mpeg3_slice_loop, slice); | ||
690 | |||
691 | return 0; | ||
692 | } | ||
693 | |||
694 | int mpeg3_delete_slice_decoder(mpeg3_slice_t *slice) | ||
695 | { | ||
696 | slice->done = 1; | ||
697 | pthread_mutex_unlock(&(slice->input_lock)); | ||
698 | pthread_join(slice->tid, 0); | ||
699 | pthread_mutex_destroy(&(slice->input_lock)); | ||
700 | pthread_mutex_destroy(&(slice->output_lock)); | ||
701 | return 0; | ||
702 | } | ||
diff --git a/core/multimedia/opieplayer/libmpeg3/video/slice.h b/core/multimedia/opieplayer/libmpeg3/video/slice.h new file mode 100644 index 0000000..e36ffef --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/slice.h | |||
@@ -0,0 +1,194 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | #ifndef SLICE_H | ||
21 | #define SLICE_H | ||
22 | |||
23 | #ifndef _WIN32 | ||
24 | #include <pthread.h> | ||
25 | #endif | ||
26 | |||
27 | /* Array of these feeds the slice decoders */ | ||
28 | typedef struct | ||
29 | { | ||
30 | unsigned char *data; /* Buffer for holding the slice data */ | ||
31 | int buffer_size; /* Size of buffer */ | ||
32 | int buffer_allocation; /* Space allocated for buffer */ | ||
33 | int current_position; /* Position in buffer */ | ||
34 | unsigned MPEG3_INT32 bits; | ||
35 | int bits_size; | ||
36 | pthread_mutex_t completion_lock; /* Lock slice until completion */ | ||
37 | int done; /* Signal for slice decoder to skip */ | ||
38 | } mpeg3_slice_buffer_t; | ||
39 | |||
40 | /* Each slice decoder */ | ||
41 | typedef struct | ||
42 | { | ||
43 | struct mpeg3video_rec *video; | ||
44 | mpeg3_slice_buffer_t *slice_buffer; | ||
45 | |||
46 | int thread_number; /* Number of this thread */ | ||
47 | int current_buffer; /* Buffer this slice decoder is on */ | ||
48 | int buffer_step; /* Number of buffers to skip */ | ||
49 | int last_buffer; /* Last buffer this decoder should process */ | ||
50 | int fault; | ||
51 | int done; | ||
52 | int quant_scale; | ||
53 | int pri_brk; /* slice/macroblock */ | ||
54 | short block[12][64]; | ||
55 | int sparse[12]; | ||
56 | pthread_t tid; /* ID of thread */ | ||
57 | pthread_mutex_t input_lock, output_lock; | ||
58 | } mpeg3_slice_t; | ||
59 | |||
60 | #define mpeg3slice_fillbits(buffer, nbits) \ | ||
61 | while(((mpeg3_slice_buffer_t*)(buffer))->bits_size < (nbits)) \ | ||
62 | { \ | ||
63 | if(((mpeg3_slice_buffer_t*)(buffer))->current_position < ((mpeg3_slice_buffer_t*)(buffer))->buffer_size) \ | ||
64 | { \ | ||
65 | ((mpeg3_slice_buffer_t*)(buffer))->bits <<= 8; \ | ||
66 | ((mpeg3_slice_buffer_t*)(buffer))->bits |= ((mpeg3_slice_buffer_t*)(buffer))->data[((mpeg3_slice_buffer_t*)(buffer))->current_position++]; \ | ||
67 | } \ | ||
68 | ((mpeg3_slice_buffer_t*)(buffer))->bits_size += 8; \ | ||
69 | } | ||
70 | |||
71 | #define mpeg3slice_flushbits(buffer, nbits) \ | ||
72 | { \ | ||
73 | mpeg3slice_fillbits((buffer), (nbits)); \ | ||
74 | ((mpeg3_slice_buffer_t*)(buffer))->bits_size -= (nbits); \ | ||
75 | } | ||
76 | |||
77 | #define mpeg3slice_flushbit(buffer) \ | ||
78 | { \ | ||
79 | if(((mpeg3_slice_buffer_t*)(buffer))->bits_size) \ | ||
80 | ((mpeg3_slice_buffer_t*)(buffer))->bits_size--; \ | ||
81 | else \ | ||
82 | if(((mpeg3_slice_buffer_t*)(buffer))->current_position < ((mpeg3_slice_buffer_t*)(buffer))->buffer_size) \ | ||
83 | { \ | ||
84 | ((mpeg3_slice_buffer_t*)(buffer))->bits = \ | ||
85 | ((mpeg3_slice_buffer_t*)(buffer))->data[((mpeg3_slice_buffer_t*)(buffer))->current_position++]; \ | ||
86 | ((mpeg3_slice_buffer_t*)(buffer))->bits_size = 7; \ | ||
87 | } \ | ||
88 | } | ||
89 | |||
90 | extern inline unsigned int mpeg3slice_getbit(mpeg3_slice_buffer_t *buffer) | ||
91 | { | ||
92 | if(buffer->bits_size) | ||
93 | return (buffer->bits >> (--buffer->bits_size)) & 0x1; | ||
94 | else | ||
95 | if(buffer->current_position < buffer->buffer_size) | ||
96 | { | ||
97 | buffer->bits = buffer->data[buffer->current_position++]; | ||
98 | buffer->bits_size = 7; | ||
99 | return (buffer->bits >> 7) & 0x1; | ||
100 | } | ||
101 | return 0; // WWA - stop warn | ||
102 | } | ||
103 | |||
104 | extern inline unsigned int mpeg3slice_getbits2(mpeg3_slice_buffer_t *buffer) | ||
105 | { | ||
106 | if(buffer->bits_size >= 2) | ||
107 | return (buffer->bits >> (buffer->bits_size -= 2)) & 0x3; | ||
108 | else | ||
109 | if(buffer->current_position < buffer->buffer_size) | ||
110 | { | ||
111 | buffer->bits <<= 8; | ||
112 | buffer->bits |= buffer->data[buffer->current_position++]; | ||
113 | buffer->bits_size += 6; | ||
114 | return (buffer->bits >> buffer->bits_size) & 0x3; | ||
115 | } | ||
116 | return 0; // WWA - stop warn | ||
117 | } | ||
118 | |||
119 | extern inline unsigned int mpeg3slice_getbyte(mpeg3_slice_buffer_t *buffer) | ||
120 | { | ||
121 | if(buffer->bits_size >= 8) | ||
122 | return (buffer->bits >> (buffer->bits_size -= 8)) & 0xff; | ||
123 | else | ||
124 | if(buffer->current_position < buffer->buffer_size) | ||
125 | { | ||
126 | buffer->bits <<= 8; | ||
127 | buffer->bits |= buffer->data[buffer->current_position++]; | ||
128 | return (buffer->bits >> buffer->bits_size) & 0xff; | ||
129 | } | ||
130 | return 0; // WWA - stop warn | ||
131 | } | ||
132 | |||
133 | |||
134 | extern inline unsigned int mpeg3slice_getbits(mpeg3_slice_buffer_t *slice_buffer, int bits) | ||
135 | { | ||
136 | if(bits == 1) return mpeg3slice_getbit(slice_buffer); | ||
137 | mpeg3slice_fillbits(slice_buffer, bits); | ||
138 | return (slice_buffer->bits >> (slice_buffer->bits_size -= bits)) & (0xffffffff >> (32 - bits)); | ||
139 | } | ||
140 | |||
141 | extern inline unsigned int mpeg3slice_showbits16(mpeg3_slice_buffer_t *buffer) | ||
142 | { | ||
143 | if(buffer->bits_size >= 16) | ||
144 | return (buffer->bits >> (buffer->bits_size - 16)) & 0xffff; | ||
145 | else | ||
146 | if(buffer->current_position < buffer->buffer_size) | ||
147 | { | ||
148 | buffer->bits <<= 16; | ||
149 | buffer->bits_size += 16; | ||
150 | buffer->bits |= (unsigned int)buffer->data[buffer->current_position++] << 8; | ||
151 | buffer->bits |= buffer->data[buffer->current_position++]; | ||
152 | return (buffer->bits >> (buffer->bits_size - 16)) & 0xffff; | ||
153 | } | ||
154 | return 0; // WWA - stop warn | ||
155 | } | ||
156 | |||
157 | extern inline unsigned int mpeg3slice_showbits9(mpeg3_slice_buffer_t *buffer) | ||
158 | { | ||
159 | if(buffer->bits_size >= 9) | ||
160 | return (buffer->bits >> (buffer->bits_size - 9)) & 0x1ff; | ||
161 | else | ||
162 | if(buffer->current_position < buffer->buffer_size) | ||
163 | { | ||
164 | buffer->bits <<= 16; | ||
165 | buffer->bits_size += 16; | ||
166 | buffer->bits |= (unsigned int)buffer->data[buffer->current_position++] << 8; | ||
167 | buffer->bits |= buffer->data[buffer->current_position++]; | ||
168 | return (buffer->bits >> (buffer->bits_size - 9)) & 0x1ff; | ||
169 | } | ||
170 | return 0; // WWA - stop warn | ||
171 | } | ||
172 | |||
173 | extern inline unsigned int mpeg3slice_showbits5(mpeg3_slice_buffer_t *buffer) | ||
174 | { | ||
175 | if(buffer->bits_size >= 5) | ||
176 | return (buffer->bits >> (buffer->bits_size - 5)) & 0x1f; | ||
177 | else | ||
178 | if(buffer->current_position < buffer->buffer_size) | ||
179 | { | ||
180 | buffer->bits <<= 8; | ||
181 | buffer->bits_size += 8; | ||
182 | buffer->bits |= buffer->data[buffer->current_position++]; | ||
183 | return (buffer->bits >> (buffer->bits_size - 5)) & 0x1f; | ||
184 | } | ||
185 | return 0; // WWA - stop warn | ||
186 | } | ||
187 | |||
188 | extern inline unsigned int mpeg3slice_showbits(mpeg3_slice_buffer_t *slice_buffer, int bits) | ||
189 | { | ||
190 | mpeg3slice_fillbits(slice_buffer, bits); | ||
191 | return (slice_buffer->bits >> (slice_buffer->bits_size - bits)) & (0xffffffff >> (32 - bits)); | ||
192 | } | ||
193 | |||
194 | #endif | ||
diff --git a/core/multimedia/opieplayer/libmpeg3/video/vlc.c b/core/multimedia/opieplayer/libmpeg3/video/vlc.c new file mode 100644 index 0000000..4328d8a --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/vlc.c | |||
@@ -0,0 +1,421 @@ | |||
1 | #include "mpeg3video.h" | ||
2 | #include "vlc.h" | ||
3 | |||
4 | /* variable length code tables */ | ||
5 | |||
6 | /* Table B-3, mb_type in P-pictures, codes 001..1xx */ | ||
7 | mpeg3_VLCtab_t mpeg3_PMBtab0[8] = { | ||
8 | {ERROR,0}, | ||
9 | {MB_FORWARD,3}, | ||
10 | {MB_PATTERN,2}, {MB_PATTERN,2}, | ||
11 | {MB_FORWARD|MB_PATTERN,1}, {MB_FORWARD|MB_PATTERN,1}, | ||
12 | {MB_FORWARD|MB_PATTERN,1}, {MB_FORWARD|MB_PATTERN,1} | ||
13 | }; | ||
14 | |||
15 | /* Table B-3, mb_type in P-pictures, codes 000001..00011x */ | ||
16 | mpeg3_VLCtab_t mpeg3_PMBtab1[8] = { | ||
17 | {ERROR,0}, | ||
18 | {MB_QUANT|MB_INTRA,6}, | ||
19 | {MB_QUANT|MB_PATTERN,5}, {MB_QUANT|MB_PATTERN,5}, | ||
20 | {MB_QUANT|MB_FORWARD|MB_PATTERN,5}, {MB_QUANT|MB_FORWARD|MB_PATTERN,5}, | ||
21 | {MB_INTRA,5}, {MB_INTRA,5} | ||
22 | }; | ||
23 | |||
24 | /* Table B-4, mb_type in B-pictures, codes 0010..11xx */ | ||
25 | mpeg3_VLCtab_t mpeg3_BMBtab0[16] = { | ||
26 | {ERROR,0}, {ERROR,0}, | ||
27 | {MB_FORWARD,4}, | ||
28 | {MB_FORWARD|MB_PATTERN,4}, | ||
29 | {MB_BACKWARD,3}, {MB_BACKWARD,3}, | ||
30 | {MB_BACKWARD|MB_PATTERN,3}, {MB_BACKWARD|MB_PATTERN,3}, | ||
31 | {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2}, | ||
32 | {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2}, | ||
33 | {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}, | ||
34 | {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}, | ||
35 | {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}, | ||
36 | {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2} | ||
37 | }; | ||
38 | |||
39 | /* Table B-4, mb_type in B-pictures, codes 000001..00011x */ | ||
40 | mpeg3_VLCtab_t mpeg3_BMBtab1[8] = { | ||
41 | {ERROR,0}, | ||
42 | {MB_QUANT|MB_INTRA,6}, | ||
43 | {MB_QUANT|MB_BACKWARD|MB_PATTERN,6}, | ||
44 | {MB_QUANT|MB_FORWARD|MB_PATTERN,6}, | ||
45 | {MB_QUANT|MB_FORWARD|MB_BACKWARD|MB_PATTERN,5}, | ||
46 | {MB_QUANT|MB_FORWARD|MB_BACKWARD|MB_PATTERN,5}, | ||
47 | {MB_INTRA,5}, {MB_INTRA,5} | ||
48 | }; | ||
49 | |||
50 | /* Table B-5, mb_type in spat. scal. I-pictures, codes 0001..1xxx */ | ||
51 | mpeg3_VLCtab_t mpeg3_spIMBtab[16] = { | ||
52 | {ERROR,0}, | ||
53 | {MB_CLASS4,4}, | ||
54 | {MB_QUANT|MB_INTRA,4}, | ||
55 | {MB_INTRA,4}, | ||
56 | {MB_CLASS4|MB_QUANT|MB_PATTERN,2}, {MB_CLASS4|MB_QUANT|MB_PATTERN,2}, | ||
57 | {MB_CLASS4|MB_QUANT|MB_PATTERN,2}, {MB_CLASS4|MB_QUANT|MB_PATTERN,2}, | ||
58 | {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1}, | ||
59 | {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1}, | ||
60 | {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1}, | ||
61 | {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1} | ||
62 | }; | ||
63 | |||
64 | /* Table B-6, mb_type in spat. scal. P-pictures, codes 0010..11xx */ | ||
65 | mpeg3_VLCtab_t mpeg3_spPMBtab0[16] = | ||
66 | { | ||
67 | {ERROR,0},{ERROR,0}, | ||
68 | {MB_FORWARD,4}, | ||
69 | {MB_WEIGHT|MB_FORWARD,4}, | ||
70 | {MB_QUANT|MB_FORWARD|MB_PATTERN,3}, {MB_QUANT|MB_FORWARD|MB_PATTERN,3}, | ||
71 | {MB_WEIGHT|MB_FORWARD|MB_PATTERN,3}, {MB_WEIGHT|MB_FORWARD|MB_PATTERN,3}, | ||
72 | {MB_FORWARD|MB_PATTERN,2}, {MB_FORWARD|MB_PATTERN,2}, | ||
73 | {MB_FORWARD|MB_PATTERN,2}, {MB_FORWARD|MB_PATTERN,2}, | ||
74 | {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2}, | ||
75 | {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2}, | ||
76 | {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2}, | ||
77 | {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2} | ||
78 | }; | ||
79 | |||
80 | /* Table B-6, mb_type in spat. scal. P-pictures, codes 0000010..000111x */ | ||
81 | mpeg3_VLCtab_t mpeg3_spPMBtab1[16] = { | ||
82 | {ERROR,0},{ERROR,0}, | ||
83 | {MB_CLASS4|MB_QUANT|MB_PATTERN,7}, | ||
84 | {MB_CLASS4,7}, | ||
85 | {MB_PATTERN,7}, | ||
86 | {MB_CLASS4|MB_PATTERN,7}, | ||
87 | {MB_QUANT|MB_INTRA,7}, | ||
88 | {MB_INTRA,7}, | ||
89 | {MB_QUANT|MB_PATTERN,6}, {MB_QUANT|MB_PATTERN,6}, | ||
90 | {MB_WEIGHT|MB_QUANT|MB_PATTERN,6}, {MB_WEIGHT|MB_QUANT|MB_PATTERN,6}, | ||
91 | {MB_WEIGHT,6}, {MB_WEIGHT,6}, | ||
92 | {MB_WEIGHT|MB_PATTERN,6}, {MB_WEIGHT|MB_PATTERN,6} | ||
93 | }; | ||
94 | |||
95 | /* Table B-7, mb_type in spat. scal. B-pictures, codes 0010..11xx */ | ||
96 | mpeg3_VLCtab_t mpeg3_spBMBtab0[14] = { | ||
97 | {MB_FORWARD,4}, | ||
98 | {MB_FORWARD|MB_PATTERN,4}, | ||
99 | {MB_BACKWARD,3}, {MB_BACKWARD,3}, | ||
100 | {MB_BACKWARD|MB_PATTERN,3}, {MB_BACKWARD|MB_PATTERN,3}, | ||
101 | {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2}, | ||
102 | {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2}, | ||
103 | {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}, | ||
104 | {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}, | ||
105 | {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}, | ||
106 | {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2} | ||
107 | }; | ||
108 | |||
109 | /* Table B-7, mb_type in spat. scal. B-pictures, codes 0000100..000111x */ | ||
110 | mpeg3_VLCtab_t mpeg3_spBMBtab1[12] = { | ||
111 | {MB_QUANT|MB_FORWARD|MB_PATTERN,7}, | ||
112 | {MB_QUANT|MB_BACKWARD|MB_PATTERN,7}, | ||
113 | {MB_INTRA,7}, | ||
114 | {MB_QUANT|MB_FORWARD|MB_BACKWARD|MB_PATTERN,7}, | ||
115 | {MB_WEIGHT|MB_FORWARD,6}, {MB_WEIGHT|MB_FORWARD,6}, | ||
116 | {MB_WEIGHT|MB_FORWARD|MB_PATTERN,6}, {MB_WEIGHT|MB_FORWARD|MB_PATTERN,6}, | ||
117 | {MB_WEIGHT|MB_BACKWARD,6}, {MB_WEIGHT|MB_BACKWARD,6}, | ||
118 | {MB_WEIGHT|MB_BACKWARD|MB_PATTERN,6}, {MB_WEIGHT|MB_BACKWARD|MB_PATTERN,6} | ||
119 | }; | ||
120 | |||
121 | /* Table B-7, mb_type in spat. scal. B-pictures, codes 00000100x..000001111 */ | ||
122 | mpeg3_VLCtab_t mpeg3_spBMBtab2[8] = { | ||
123 | {MB_QUANT|MB_INTRA,8}, {MB_QUANT|MB_INTRA,8}, | ||
124 | {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,8}, | ||
125 | {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,8}, | ||
126 | {MB_WEIGHT|MB_QUANT|MB_BACKWARD|MB_PATTERN,9}, | ||
127 | {MB_CLASS4|MB_QUANT|MB_PATTERN,9}, | ||
128 | {MB_CLASS4,9}, | ||
129 | {MB_CLASS4|MB_PATTERN,9} | ||
130 | }; | ||
131 | |||
132 | /* Table B-8, mb_type in spat. scal. B-pictures, codes 001..1xx */ | ||
133 | mpeg3_VLCtab_t mpeg3_SNRMBtab[8] = { | ||
134 | {ERROR,0}, | ||
135 | {0,3}, | ||
136 | {MB_QUANT|MB_PATTERN,2}, {MB_QUANT|MB_PATTERN,2}, | ||
137 | {MB_PATTERN,1}, {MB_PATTERN,1}, {MB_PATTERN,1}, {MB_PATTERN,1} | ||
138 | }; | ||
139 | |||
140 | /* Table B-10, motion_code, codes 0001 ... 01xx */ | ||
141 | mpeg3_VLCtab_t mpeg3_MVtab0[8] = | ||
142 | { {ERROR,0}, {3,3}, {2,2}, {2,2}, {1,1}, {1,1}, {1,1}, {1,1} | ||
143 | }; | ||
144 | |||
145 | /* Table B-10, motion_code, codes 0000011 ... 000011x */ | ||
146 | mpeg3_VLCtab_t mpeg3_MVtab1[8] = | ||
147 | { {ERROR,0}, {ERROR,0}, {ERROR,0}, {7,6}, {6,6}, {5,6}, {4,5}, {4,5} | ||
148 | }; | ||
149 | |||
150 | /* Table B-10, motion_code, codes 0000001100 ... 000001011x */ | ||
151 | mpeg3_VLCtab_t mpeg3_MVtab2[12] = | ||
152 | { {16,9}, {15,9}, {14,9}, {13,9}, | ||
153 | {12,9}, {11,9}, {10,8}, {10,8}, | ||
154 | {9,8}, {9,8}, {8,8}, {8,8} | ||
155 | }; | ||
156 | |||
157 | /* Table B-9, coded_block_pattern, codes 01000 ... 111xx */ | ||
158 | mpeg3_VLCtab_t mpeg3_CBPtab0[32] = | ||
159 | { {ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0}, | ||
160 | {ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0}, | ||
161 | {62,5}, {2,5}, {61,5}, {1,5}, {56,5}, {52,5}, {44,5}, {28,5}, | ||
162 | {40,5}, {20,5}, {48,5}, {12,5}, {32,4}, {32,4}, {16,4}, {16,4}, | ||
163 | {8,4}, {8,4}, {4,4}, {4,4}, {60,3}, {60,3}, {60,3}, {60,3} | ||
164 | }; | ||
165 | |||
166 | /* Table B-9, coded_block_pattern, codes 00000100 ... 001111xx */ | ||
167 | mpeg3_VLCtab_t mpeg3_CBPtab1[64] = | ||
168 | { {ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0}, | ||
169 | {58,8}, {54,8}, {46,8}, {30,8}, | ||
170 | {57,8}, {53,8}, {45,8}, {29,8}, {38,8}, {26,8}, {37,8}, {25,8}, | ||
171 | {43,8}, {23,8}, {51,8}, {15,8}, {42,8}, {22,8}, {50,8}, {14,8}, | ||
172 | {41,8}, {21,8}, {49,8}, {13,8}, {35,8}, {19,8}, {11,8}, {7,8}, | ||
173 | {34,7}, {34,7}, {18,7}, {18,7}, {10,7}, {10,7}, {6,7}, {6,7}, | ||
174 | {33,7}, {33,7}, {17,7}, {17,7}, {9,7}, {9,7}, {5,7}, {5,7}, | ||
175 | {63,6}, {63,6}, {63,6}, {63,6}, {3,6}, {3,6}, {3,6}, {3,6}, | ||
176 | {36,6}, {36,6}, {36,6}, {36,6}, {24,6}, {24,6}, {24,6}, {24,6} | ||
177 | }; | ||
178 | |||
179 | /* Table B-9, coded_block_pattern, codes 000000001 ... 000000111 */ | ||
180 | mpeg3_VLCtab_t mpeg3_CBPtab2[8] = | ||
181 | { {ERROR,0}, {0,9}, {39,9}, {27,9}, {59,9}, {55,9}, {47,9}, {31,9} | ||
182 | }; | ||
183 | |||
184 | /* Table B-1, macroblock_address_increment, codes 00010 ... 011xx */ | ||
185 | mpeg3_VLCtab_t mpeg3_MBAtab1[16] = | ||
186 | { {ERROR,0}, {ERROR,0}, {7,5}, {6,5}, {5,4}, {5,4}, {4,4}, {4,4}, | ||
187 | {3,3}, {3,3}, {3,3}, {3,3}, {2,3}, {2,3}, {2,3}, {2,3} | ||
188 | }; | ||
189 | |||
190 | /* Table B-1, macroblock_address_increment, codes 00000011000 ... 0000111xxxx */ | ||
191 | mpeg3_VLCtab_t mpeg3_MBAtab2[104] = | ||
192 | { | ||
193 | {33,11}, {32,11}, {31,11}, {30,11}, {29,11}, {28,11}, {27,11}, {26,11}, | ||
194 | {25,11}, {24,11}, {23,11}, {22,11}, {21,10}, {21,10}, {20,10}, {20,10}, | ||
195 | {19,10}, {19,10}, {18,10}, {18,10}, {17,10}, {17,10}, {16,10}, {16,10}, | ||
196 | {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, | ||
197 | {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, | ||
198 | {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, | ||
199 | {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, | ||
200 | {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, | ||
201 | {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, | ||
202 | {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, | ||
203 | {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, | ||
204 | {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, | ||
205 | {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7} | ||
206 | }; | ||
207 | |||
208 | /* Table B-12, dct_dc_size_luminance, codes 00xxx ... 11110 */ | ||
209 | mpeg3_VLCtab_t mpeg3_DClumtab0[32] = | ||
210 | { {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, | ||
211 | {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, | ||
212 | {0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3}, | ||
213 | {4, 3}, {4, 3}, {4, 3}, {4, 3}, {5, 4}, {5, 4}, {6, 5}, {ERROR, 0} | ||
214 | }; | ||
215 | |||
216 | /* Table B-12, dct_dc_size_luminance, codes 111110xxx ... 111111111 */ | ||
217 | mpeg3_VLCtab_t mpeg3_DClumtab1[16] = | ||
218 | { {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, | ||
219 | {8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10,9}, {11,9} | ||
220 | }; | ||
221 | |||
222 | /* Table B-13, dct_dc_size_chrominance, codes 00xxx ... 11110 */ | ||
223 | mpeg3_VLCtab_t mpeg3_DCchromtab0[32] = | ||
224 | { {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, | ||
225 | {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, | ||
226 | {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, | ||
227 | {3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 4}, {4, 4}, {5, 5}, {ERROR, 0} | ||
228 | }; | ||
229 | |||
230 | /* Table B-13, dct_dc_size_chrominance, codes 111110xxxx ... 1111111111 */ | ||
231 | mpeg3_VLCtab_t mpeg3_DCchromtab1[32] = | ||
232 | { {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, | ||
233 | {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, | ||
234 | {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, | ||
235 | {8, 8}, {8, 8}, {8, 8}, {8, 8}, {9, 9}, {9, 9}, {10,10}, {11,10} | ||
236 | }; | ||
237 | |||
238 | /* Table B-14, DCT coefficients table zero, | ||
239 | * codes 0100 ... 1xxx (used for first (DC) coefficient) | ||
240 | */ | ||
241 | mpeg3_DCTtab_t mpeg3_DCTtabfirst[12] = | ||
242 | { | ||
243 | {0,2,4}, {2,1,4}, {1,1,3}, {1,1,3}, | ||
244 | {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1}, | ||
245 | {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1} | ||
246 | }; | ||
247 | |||
248 | /* Table B-14, DCT coefficients table zero, | ||
249 | * codes 0100 ... 1xxx (used for all other coefficients) | ||
250 | */ | ||
251 | mpeg3_DCTtab_t mpeg3_DCTtabnext[12] = | ||
252 | { | ||
253 | {0,2,4}, {2,1,4}, {1,1,3}, {1,1,3}, | ||
254 | {64,0,2}, {64,0,2}, {64,0,2}, {64,0,2}, /* EOB */ | ||
255 | {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2} | ||
256 | }; | ||
257 | |||
258 | /* Table B-14, DCT coefficients table zero, | ||
259 | * codes 000001xx ... 00111xxx | ||
260 | */ | ||
261 | mpeg3_DCTtab_t mpeg3_DCTtab0[60] = | ||
262 | { | ||
263 | {65,0,6}, {65,0,6}, {65,0,6}, {65,0,6}, /* Escape */ | ||
264 | {2,2,7}, {2,2,7}, {9,1,7}, {9,1,7}, | ||
265 | {0,4,7}, {0,4,7}, {8,1,7}, {8,1,7}, | ||
266 | {7,1,6}, {7,1,6}, {7,1,6}, {7,1,6}, | ||
267 | {6,1,6}, {6,1,6}, {6,1,6}, {6,1,6}, | ||
268 | {1,2,6}, {1,2,6}, {1,2,6}, {1,2,6}, | ||
269 | {5,1,6}, {5,1,6}, {5,1,6}, {5,1,6}, | ||
270 | {13,1,8}, {0,6,8}, {12,1,8}, {11,1,8}, | ||
271 | {3,2,8}, {1,3,8}, {0,5,8}, {10,1,8}, | ||
272 | {0,3,5}, {0,3,5}, {0,3,5}, {0,3,5}, | ||
273 | {0,3,5}, {0,3,5}, {0,3,5}, {0,3,5}, | ||
274 | {4,1,5}, {4,1,5}, {4,1,5}, {4,1,5}, | ||
275 | {4,1,5}, {4,1,5}, {4,1,5}, {4,1,5}, | ||
276 | {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, | ||
277 | {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5} | ||
278 | }; | ||
279 | |||
280 | /* Table B-15, DCT coefficients table one, | ||
281 | * codes 000001xx ... 11111111 | ||
282 | */ | ||
283 | mpeg3_DCTtab_t mpeg3_DCTtab0a[252] = | ||
284 | { | ||
285 | {65,0,6}, {65,0,6}, {65,0,6}, {65,0,6}, /* Escape */ | ||
286 | {7,1,7}, {7,1,7}, {8,1,7}, {8,1,7}, | ||
287 | {6,1,7}, {6,1,7}, {2,2,7}, {2,2,7}, | ||
288 | {0,7,6}, {0,7,6}, {0,7,6}, {0,7,6}, | ||
289 | {0,6,6}, {0,6,6}, {0,6,6}, {0,6,6}, | ||
290 | {4,1,6}, {4,1,6}, {4,1,6}, {4,1,6}, | ||
291 | {5,1,6}, {5,1,6}, {5,1,6}, {5,1,6}, | ||
292 | {1,5,8}, {11,1,8}, {0,11,8}, {0,10,8}, | ||
293 | {13,1,8}, {12,1,8}, {3,2,8}, {1,4,8}, | ||
294 | {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5}, | ||
295 | {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5}, | ||
296 | {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5}, | ||
297 | {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5}, | ||
298 | {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, | ||
299 | {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, | ||
300 | {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, | ||
301 | {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, | ||
302 | {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, | ||
303 | {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, | ||
304 | {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, | ||
305 | {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, | ||
306 | {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, | ||
307 | {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, | ||
308 | {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, /* EOB */ | ||
309 | {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, | ||
310 | {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, | ||
311 | {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, | ||
312 | {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, | ||
313 | {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, | ||
314 | {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, | ||
315 | {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, | ||
316 | {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, | ||
317 | {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, | ||
318 | {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, | ||
319 | {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, | ||
320 | {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, | ||
321 | {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, | ||
322 | {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, | ||
323 | {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, | ||
324 | {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, | ||
325 | {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, | ||
326 | {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, | ||
327 | {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, | ||
328 | {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, | ||
329 | {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, | ||
330 | {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, | ||
331 | {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, | ||
332 | {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, | ||
333 | {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, | ||
334 | {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, | ||
335 | {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, | ||
336 | {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, | ||
337 | {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, | ||
338 | {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, | ||
339 | {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, | ||
340 | {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5}, | ||
341 | {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5}, | ||
342 | {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5}, | ||
343 | {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5}, | ||
344 | {9,1,7}, {9,1,7}, {1,3,7}, {1,3,7}, | ||
345 | {10,1,7}, {10,1,7}, {0,8,7}, {0,8,7}, | ||
346 | {0,9,7}, {0,9,7}, {0,12,8}, {0,13,8}, | ||
347 | {2,3,8}, {4,2,8}, {0,14,8}, {0,15,8} | ||
348 | }; | ||
349 | |||
350 | /* Table B-14, DCT coefficients table zero, | ||
351 | * codes 0000001000 ... 0000001111 | ||
352 | */ | ||
353 | mpeg3_DCTtab_t mpeg3_DCTtab1[8] = | ||
354 | { | ||
355 | {16,1,10}, {5,2,10}, {0,7,10}, {2,3,10}, | ||
356 | {1,4,10}, {15,1,10}, {14,1,10}, {4,2,10} | ||
357 | }; | ||
358 | |||
359 | /* Table B-15, DCT coefficients table one, | ||
360 | * codes 000000100x ... 000000111x | ||
361 | */ | ||
362 | mpeg3_DCTtab_t mpeg3_DCTtab1a[8] = | ||
363 | { | ||
364 | {5,2,9}, {5,2,9}, {14,1,9}, {14,1,9}, | ||
365 | {2,4,10}, {16,1,10}, {15,1,9}, {15,1,9} | ||
366 | }; | ||
367 | |||
368 | /* Table B-14/15, DCT coefficients table zero / one, | ||
369 | * codes 000000010000 ... 000000011111 | ||
370 | */ | ||
371 | mpeg3_DCTtab_t mpeg3_DCTtab2[16] = | ||
372 | { | ||
373 | {0,11,12}, {8,2,12}, {4,3,12}, {0,10,12}, | ||
374 | {2,4,12}, {7,2,12}, {21,1,12}, {20,1,12}, | ||
375 | {0,9,12}, {19,1,12}, {18,1,12}, {1,5,12}, | ||
376 | {3,3,12}, {0,8,12}, {6,2,12}, {17,1,12} | ||
377 | }; | ||
378 | |||
379 | /* Table B-14/15, DCT coefficients table zero / one, | ||
380 | * codes 0000000010000 ... 0000000011111 | ||
381 | */ | ||
382 | mpeg3_DCTtab_t mpeg3_DCTtab3[16] = | ||
383 | { | ||
384 | {10,2,13}, {9,2,13}, {5,3,13}, {3,4,13}, | ||
385 | {2,5,13}, {1,7,13}, {1,6,13}, {0,15,13}, | ||
386 | {0,14,13}, {0,13,13}, {0,12,13}, {26,1,13}, | ||
387 | {25,1,13}, {24,1,13}, {23,1,13}, {22,1,13} | ||
388 | }; | ||
389 | |||
390 | /* Table B-14/15, DCT coefficients table zero / one, | ||
391 | * codes 00000000010000 ... 00000000011111 | ||
392 | */ | ||
393 | mpeg3_DCTtab_t mpeg3_DCTtab4[16] = | ||
394 | { | ||
395 | {0,31,14}, {0,30,14}, {0,29,14}, {0,28,14}, | ||
396 | {0,27,14}, {0,26,14}, {0,25,14}, {0,24,14}, | ||
397 | {0,23,14}, {0,22,14}, {0,21,14}, {0,20,14}, | ||
398 | {0,19,14}, {0,18,14}, {0,17,14}, {0,16,14} | ||
399 | }; | ||
400 | |||
401 | /* Table B-14/15, DCT coefficients table zero / one, | ||
402 | * codes 000000000010000 ... 000000000011111 | ||
403 | */ | ||
404 | mpeg3_DCTtab_t mpeg3_DCTtab5[16] = | ||
405 | { | ||
406 | {0,40,15}, {0,39,15}, {0,38,15}, {0,37,15}, | ||
407 | {0,36,15}, {0,35,15}, {0,34,15}, {0,33,15}, | ||
408 | {0,32,15}, {1,14,15}, {1,13,15}, {1,12,15}, | ||
409 | {1,11,15}, {1,10,15}, {1,9,15}, {1,8,15} | ||
410 | }; | ||
411 | |||
412 | /* Table B-14/15, DCT coefficients table zero / one, | ||
413 | * codes 0000000000010000 ... 0000000000011111 | ||
414 | */ | ||
415 | mpeg3_DCTtab_t mpeg3_DCTtab6[16] = | ||
416 | { | ||
417 | {1,18,16}, {1,17,16}, {1,16,16}, {1,15,16}, | ||
418 | {6,3,16}, {16,2,16}, {15,2,16}, {14,2,16}, | ||
419 | {13,2,16}, {12,2,16}, {11,2,16}, {31,1,16}, | ||
420 | {30,1,16}, {29,1,16}, {28,1,16}, {27,1,16} | ||
421 | }; | ||
diff --git a/core/multimedia/opieplayer/libmpeg3/video/vlc.h b/core/multimedia/opieplayer/libmpeg3/video/vlc.h new file mode 100644 index 0000000..727040b --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/vlc.h | |||
@@ -0,0 +1,164 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | #ifndef VLC_H | ||
21 | #define VLC_H | ||
22 | |||
23 | /* variable length code tables */ | ||
24 | |||
25 | typedef struct { | ||
26 | char val, len; | ||
27 | } mpeg3_VLCtab_t; | ||
28 | |||
29 | typedef struct { | ||
30 | char run, level, len; | ||
31 | } mpeg3_DCTtab_t; | ||
32 | |||
33 | /* Added 03/38/96 by Alex de Jong : avoid IRIX GNU warning */ | ||
34 | #ifdef ERROR | ||
35 | #undef ERROR | ||
36 | #define ERROR 99 | ||
37 | #endif | ||
38 | |||
39 | /* Table B-3, mb_type in P-pictures, codes 001..1xx */ | ||
40 | extern mpeg3_VLCtab_t mpeg3_PMBtab0[8]; | ||
41 | |||
42 | /* Table B-3, mb_type in P-pictures, codes 000001..00011x */ | ||
43 | extern mpeg3_VLCtab_t mpeg3_PMBtab1[8]; | ||
44 | |||
45 | /* Table B-4, mb_type in B-pictures, codes 0010..11xx */ | ||
46 | extern mpeg3_VLCtab_t mpeg3_BMBtab0[16]; | ||
47 | |||
48 | /* Table B-4, mb_type in B-pictures, codes 000001..00011x */ | ||
49 | extern mpeg3_VLCtab_t mpeg3_BMBtab1[8]; | ||
50 | |||
51 | /* Table B-5, mb_type in spat. scal. I-pictures, codes 0001..1xxx */ | ||
52 | extern mpeg3_VLCtab_t mpeg3_spIMBtab[16]; | ||
53 | |||
54 | /* Table B-6, mb_type in spat. scal. P-pictures, codes 0010..11xx */ | ||
55 | extern mpeg3_VLCtab_t mpeg3_spPMBtab0[16]; | ||
56 | |||
57 | /* Table B-6, mb_type in spat. scal. P-pictures, codes 0000010..000111x */ | ||
58 | extern mpeg3_VLCtab_t mpeg3_spPMBtab1[16]; | ||
59 | |||
60 | /* Table B-7, mb_type in spat. scal. B-pictures, codes 0010..11xx */ | ||
61 | extern mpeg3_VLCtab_t mpeg3_spBMBtab0[14]; | ||
62 | |||
63 | /* Table B-7, mb_type in spat. scal. B-pictures, codes 0000100..000111x */ | ||
64 | extern mpeg3_VLCtab_t mpeg3_spBMBtab1[12]; | ||
65 | |||
66 | /* Table B-7, mb_type in spat. scal. B-pictures, codes 00000100x..000001111 */ | ||
67 | extern mpeg3_VLCtab_t mpeg3_spBMBtab2[8]; | ||
68 | |||
69 | /* Table B-8, mb_type in spat. scal. B-pictures, codes 001..1xx */ | ||
70 | extern mpeg3_VLCtab_t mpeg3_SNRMBtab[8]; | ||
71 | |||
72 | /* Table B-10, motion_code, codes 0001 ... 01xx */ | ||
73 | extern mpeg3_VLCtab_t mpeg3_MVtab0[8]; | ||
74 | |||
75 | /* Table B-10, motion_code, codes 0000011 ... 000011x */ | ||
76 | extern mpeg3_VLCtab_t mpeg3_MVtab1[8]; | ||
77 | |||
78 | /* Table B-10, motion_code, codes 0000001100 ... 000001011x */ | ||
79 | extern mpeg3_VLCtab_t mpeg3_MVtab2[12]; | ||
80 | |||
81 | /* Table B-9, coded_block_pattern, codes 01000 ... 111xx */ | ||
82 | extern mpeg3_VLCtab_t mpeg3_CBPtab0[32]; | ||
83 | |||
84 | /* Table B-9, coded_block_pattern, codes 00000100 ... 001111xx */ | ||
85 | extern mpeg3_VLCtab_t mpeg3_CBPtab1[64]; | ||
86 | |||
87 | /* Table B-9, coded_block_pattern, codes 000000001 ... 000000111 */ | ||
88 | extern mpeg3_VLCtab_t mpeg3_CBPtab2[8]; | ||
89 | |||
90 | /* Table B-1, macroblock_address_increment, codes 00010 ... 011xx */ | ||
91 | extern mpeg3_VLCtab_t mpeg3_MBAtab1[16]; | ||
92 | |||
93 | /* Table B-1, macroblock_address_increment, codes 00000011000 ... 0000111xxxx */ | ||
94 | extern mpeg3_VLCtab_t mpeg3_MBAtab2[104]; | ||
95 | |||
96 | /* Table B-12, dct_dc_size_luminance, codes 00xxx ... 11110 */ | ||
97 | extern mpeg3_VLCtab_t mpeg3_DClumtab0[32]; | ||
98 | |||
99 | /* Table B-12, dct_dc_size_luminance, codes 111110xxx ... 111111111 */ | ||
100 | extern mpeg3_VLCtab_t mpeg3_DClumtab1[16]; | ||
101 | |||
102 | /* Table B-13, dct_dc_size_chrominance, codes 00xxx ... 11110 */ | ||
103 | extern mpeg3_VLCtab_t mpeg3_DCchromtab0[32]; | ||
104 | |||
105 | /* Table B-13, dct_dc_size_chrominance, codes 111110xxxx ... 1111111111 */ | ||
106 | extern mpeg3_VLCtab_t mpeg3_DCchromtab1[32]; | ||
107 | |||
108 | /* Table B-14, DCT coefficients table zero, | ||
109 | * codes 0100 ... 1xxx (used for first (DC) coefficient) | ||
110 | */ | ||
111 | extern mpeg3_DCTtab_t mpeg3_DCTtabfirst[12]; | ||
112 | |||
113 | /* Table B-14, DCT coefficients table zero, | ||
114 | * codes 0100 ... 1xxx (used for all other coefficients) | ||
115 | */ | ||
116 | extern mpeg3_DCTtab_t mpeg3_DCTtabnext[12]; | ||
117 | |||
118 | /* Table B-14, DCT coefficients table zero, | ||
119 | * codes 000001xx ... 00111xxx | ||
120 | */ | ||
121 | extern mpeg3_DCTtab_t mpeg3_DCTtab0[60]; | ||
122 | |||
123 | /* Table B-15, DCT coefficients table one, | ||
124 | * codes 000001xx ... 11111111 | ||
125 | */ | ||
126 | extern mpeg3_DCTtab_t mpeg3_DCTtab0a[252]; | ||
127 | |||
128 | /* Table B-14, DCT coefficients table zero, | ||
129 | * codes 0000001000 ... 0000001111 | ||
130 | */ | ||
131 | extern mpeg3_DCTtab_t mpeg3_DCTtab1[8]; | ||
132 | |||
133 | /* Table B-15, DCT coefficients table one, | ||
134 | * codes 000000100x ... 000000111x | ||
135 | */ | ||
136 | extern mpeg3_DCTtab_t mpeg3_DCTtab1a[8]; | ||
137 | |||
138 | /* Table B-14/15, DCT coefficients table zero / one, | ||
139 | * codes 000000010000 ... 000000011111 | ||
140 | */ | ||
141 | extern mpeg3_DCTtab_t mpeg3_DCTtab2[16]; | ||
142 | |||
143 | /* Table B-14/15, DCT coefficients table zero / one, | ||
144 | * codes 0000000010000 ... 0000000011111 | ||
145 | */ | ||
146 | extern mpeg3_DCTtab_t mpeg3_DCTtab3[16]; | ||
147 | |||
148 | /* Table B-14/15, DCT coefficients table zero / one, | ||
149 | * codes 00000000010000 ... 00000000011111 | ||
150 | */ | ||
151 | extern mpeg3_DCTtab_t mpeg3_DCTtab4[16]; | ||
152 | |||
153 | /* Table B-14/15, DCT coefficients table zero / one, | ||
154 | * codes 000000000010000 ... 000000000011111 | ||
155 | */ | ||
156 | extern mpeg3_DCTtab_t mpeg3_DCTtab5[16]; | ||
157 | |||
158 | /* Table B-14/15, DCT coefficients table zero / one, | ||
159 | * codes 0000000000010000 ... 0000000000011111 | ||
160 | */ | ||
161 | extern mpeg3_DCTtab_t mpeg3_DCTtab6[16]; | ||
162 | |||
163 | |||
164 | #endif | ||
diff --git a/core/multimedia/opieplayer/libmpeg3/video/worksheet.c b/core/multimedia/opieplayer/libmpeg3/video/worksheet.c new file mode 100644 index 0000000..c5a0553 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/worksheet.c | |||
@@ -0,0 +1,30 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <time.h> | ||
4 | |||
5 | |||
6 | static LONGLONG mpeg3_MMX_601_Y_COEF = 0x0000004000400040; | ||
7 | |||
8 | inline void mpeg3_601_mmx(unsigned long y, | ||
9 | unsigned long *output) | ||
10 | { | ||
11 | asm(" | ||
12 | /* Output will be 0x00rrggbb */ | ||
13 | movd (%0), %%mm0; /* Load y 0x00000000000000yy */ | ||
14 | /*pmullw mpeg3_MMX_601_Y_COEF, %%mm0; // Scale y 0x00000000000000yy */ | ||
15 | psllw $6, %%mm0; /* Shift y coeffs 0x0000yyy0yyy0yyy0 */ | ||
16 | movd %%mm0, (%1); /* Store output */ | ||
17 | " | ||
18 | : | ||
19 | : "r" (&y), "r" (output)); | ||
20 | } | ||
21 | |||
22 | |||
23 | int main(int argc, char *argv[]) | ||
24 | { | ||
25 | unsigned char output[1024]; | ||
26 | |||
27 | memset(output, 0, 1024); | ||
28 | mpeg3_601_mmx(1, (unsigned long*)output); | ||
29 | printf("%02x%02x\n", *(unsigned char*)&output[1], *(unsigned char*)&output[0]); | ||
30 | } | ||