summaryrefslogtreecommitdiff
path: root/core/multimedia/opieplayer/libmpeg3/video
Unidiff
Diffstat (limited to 'core/multimedia/opieplayer/libmpeg3/video') (more/less context) (show whitespace changes)
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/Makefile32
-rwxr-xr-xcore/multimedia/opieplayer/libmpeg3/video/c_flags1
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/getpicture.c767
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/headers.c492
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/idct.c160
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/idct.h24
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/layerdata.h35
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/macroblocks.c338
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/mmxidct.S675
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/mmxtest.c35
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/motion.c230
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/mpeg3video.c597
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/mpeg3video.h180
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/mpeg3videoprotos.h26
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/output.c993
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/reconmmx.s301
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/reconstruct.c1290
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/seek.c233
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/slice.c702
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/slice.h194
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/vlc.c421
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/vlc.h164
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/worksheet.c30
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 @@
1include ../global_config
2export CFLAGS
3export CFLAGS_lessopt
4
5OBJS = \
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
20all: $(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
31clean:
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
10int 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 */
42int 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 {
60printf("mpeg3video_clearblock size = %d\n", size);
61 memset(slice->block[comp], 0, sizeof(short) * 64 * size);
62 }
63 return 0;
64}
65
66static 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
95int 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
127int 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
244int 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 */
342int 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
471int 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 */
569int 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
660int 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
685int 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
9int 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
65int 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
93int 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
116int 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
160int 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
185int 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
208int 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
270int 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
293int 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
301int 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
352int 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
374int 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
403int 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
462int 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 */
469int 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
35int 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
99int 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 */
155void 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
23typedef 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
9int 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
56static 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
75static 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
98static 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
123static 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
140static 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
163static 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
187static 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
199static 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
215int 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
239int 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
16preSC: .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
28x0005000200010001:
29 .long0x00010001, 0x00050002
30 .align 8
31 .typex0040000000000000, @object
32 .sizex0040000000000000, 8
33x0040000000000000:
34 .long0, 0x00400000
35 .align 8
36 .typex5a825a825a825a82, @object
37 .sizex5a825a825a825a82, 8
38x5a825a825a825a82:
39 .long0x5a825a82, 0x5a825a82
40 .align 8
41 .typex539f539f539f539f, @object
42 .sizex539f539f539f539f, 8
43x539f539f539f539f:
44 .long0x539f539f, 0x539f539f
45 .align 8
46 .typex4546454645464546, @object
47 .sizex4546454645464546, 8
48x4546454645464546:
49 .long0x45464546, 0x45464546
50 .align 8
51 .typex61f861f861f861f8, @object
52 .sizex61f861f861f861f8, 8
53x61f861f861f861f8:
54 .long0x61f861f8, 0x61f861f8
55/* Static variables */
56 .align 8
57 .type x0, @object
58 .size x0, 8
59x0:
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
69IDCT_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
7int 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
11static 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/*
32int *dmvector, * differential motion vector *
33int mvx, int mvy * decoded mv components (always in field format) *
34*/
35void 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
78static 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
115static 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
132void 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
166int 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
7unsigned 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 */
20unsigned 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 */
35unsigned 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 */
44unsigned 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 */
53unsigned 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
65unsigned 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
73double 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
94int 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
198int 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
219void 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
235mpeg3video_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
262int 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
285int 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
315int* 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. */
328int 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
348mpeg3video_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
442int 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
452int mpeg3video_set_cpus(mpeg3video_t *video, int cpus)
453{
454 return 0;
455}
456
457int 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
464int mpeg3video_seek_percentage(mpeg3video_t *video, double percentage)
465{
466 video->percentage_seek = percentage;
467 return 0;
468}
469
470int 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
483int 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 */
490int 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
509int 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
565int 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 */
30extern unsigned char mpeg3_zig_zag_scan_nommx[64];
31extern unsigned char mpeg3_zig_zag_scan_mmx[64];
32
33/* alternate scan */
34extern unsigned char mpeg3_alternate_scan_nommx[64];
35extern unsigned char mpeg3_alternate_scan_mmx[64];
36
37/* default intra quantization matrix */
38extern unsigned char mpeg3_default_intra_quantizer_matrix[64];
39
40/* Frame rate table must agree with the one in the encoder */
41extern double mpeg3_frame_rate_table[16];
42
43/* non-linear quantization coefficient table */
44extern 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
97struct 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
178typedef 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
23void mpeg3video_idct_conversion(short* block);
24unsigned 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
6static LONGLONG mpeg3_MMX_0 = 0L;
7static unsigned long mpeg3_MMX_10w[] = {0x00100010, 0x00100010}; /*dd 00010 0010h, 000100010h */
8static unsigned long mpeg3_MMX_80w[] = {0x00800080, 0x00800080}; /*dd 00080 0080h, 000800080h */
9
10static unsigned long mpeg3_MMX_00FFw[] = {0x00ff00ff, 0x00ff00ff}; /*dd 000FF 00FFh, 000FF00FFh */
11
12static unsigned short mpeg3_MMX_Ublucoeff[] = {0x81, 0x81, 0x81, 0x81}; /*dd 00081 0081h, 000810081h */
13static unsigned short mpeg3_MMX_Vredcoeff[] = {0x66, 0x66, 0x66, 0x66}; /*dd 00066 0066h, 000660066h */
14
15static unsigned short mpeg3_MMX_Ugrncoeff[] = {0xffe8, 0xffe8, 0xffe8, 0xffe8}; /*dd 0FFE7 FFE7h, 0FFE7FFE7h */
16static unsigned short mpeg3_MMX_Vgrncoeff[] = {0xffcd, 0xffcd, 0xffcd, 0xffcd}; /*dd 0FFCC FFCCh, 0FFCCFFCCh */
17
18static unsigned short mpeg3_MMX_Ycoeff[] = {0x4a, 0x4a, 0x4a, 0x4a}; /*dd 0004A 004Ah, 0004A004Ah */
19
20static unsigned short mpeg3_MMX_redmask[] = {0xf800, 0xf800, 0xf800, 0xf800}; /*dd 07c00 7c00h, 07c007c00h */
21
22static unsigned short mpeg3_MMX_grnmask[] = {0x7e0, 0x7e0, 0x7e0, 0x7e0}; /*dd 003e0 03e0h, 003e003e0h */
23
24static 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
32inline 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
209static unsigned LONGLONG mpeg3_MMX_U_80 = 0x0000008000800000LL;
210static unsigned LONGLONG mpeg3_MMX_V_80 = 0x0000000000800080LL;
211static LONGLONG mpeg3_MMX_U_COEF = 0x00000058ffd30000LL;
212static LONGLONG mpeg3_MMX_V_COEF = 0x00000000ffea006fLL;
213static LONGLONG mpeg3_MMX_601_Y_COEF = 0x0000004800480048LL;
214static LONGLONG mpeg3_MMX_601_Y_DIFF = 0x0000000000000010LL;
215
216inline void mpeg3_bgra32_mmx(unsigned long y,
217 unsigned long u,
218 unsigned long v,
219 unsigned long *output)
220{
221asm("
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
258inline void mpeg3_601_bgra32_mmx(unsigned long y,
259 unsigned long u,
260 unsigned long v,
261 unsigned long *output)
262{
263asm("
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
301static unsigned LONGLONG mpeg3_MMX_U_80_RGB = 0x0000000000800080LL;
302static unsigned LONGLONG mpeg3_MMX_V_80_RGB = 0x0000008000800000LL;
303static LONGLONG mpeg3_MMX_U_COEF_RGB = 0x00000000ffd30058LL;
304static LONGLONG mpeg3_MMX_V_COEF_RGB = 0x0000006fffea0000LL;
305
306inline void mpeg3_rgba32_mmx(unsigned long y,
307 unsigned long u,
308 unsigned long v,
309 unsigned long *output)
310{
311asm("
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
348inline void mpeg3_601_rgba32_mmx(unsigned long y,
349 unsigned long u,
350 unsigned long v,
351 unsigned long *output)
352{
353asm("
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 */
510int 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
824int mpeg3video_ditherframe444(mpeg3video_t *video, unsigned char *src[])
825{
826 return 0;
827}
828
829int mpeg3video_dithertop(mpeg3video_t *video, unsigned char *src[])
830{
831 return mpeg3video_ditherframe(video, src, video->output_rows);
832}
833
834int mpeg3video_dithertop444(mpeg3video_t *video, unsigned char *src[])
835{
836 return 0;
837}
838
839int mpeg3video_ditherbot(mpeg3video_t *video, unsigned char *src[])
840{
841 return 0;
842}
843
844int mpeg3video_ditherbot444(mpeg3video_t *video, unsigned char *src[])
845{
846 return 0;
847}
848
849void 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
875int 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
889int 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
989int 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
27global recva_mmx
28global recvac_mmx
29global rech_mmx
30global rechc_mmx
31global add_block_mmx
32global set_block_mmx
33
34
35 align 16
36rech_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
78rechc_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
122recva_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
181recvac_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
231add_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
266set_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
9static 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
38static 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
58static 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
81static 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
98static 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
126static 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
148static 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
183static 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
208static 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
248static 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
279static 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
298static 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
315static 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
370static 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
411static 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
469static 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
513static 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
527static 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
537static 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
561static 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
577static 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
608static 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
633static 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
665static 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
688static 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
719static 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
741static 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
774static 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
799static 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
833static 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
859static 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
895static 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
923static inline
924void 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*/
1006static 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
1056int 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
7unsigned 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. */
22int 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. */
33int 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
43long 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
53int 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
84int 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
222int 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
9static ULONGLONG MMX_128 = 0x80008000800080LL;
10
11int 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
26int 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
33int 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
50static 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
285int 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
614void 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
673int 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
694int 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 */
28typedef 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 */
41typedef 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
90extern 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
104extern 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
119extern 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
134extern 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
141extern 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
157extern 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
173extern 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
188extern 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 */
7mpeg3_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 */
16mpeg3_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 */
25mpeg3_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 */
40mpeg3_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 */
51mpeg3_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 */
65mpeg3_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 */
81mpeg3_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 */
96mpeg3_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 */
110mpeg3_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 */
122mpeg3_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 */
133mpeg3_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 */
141mpeg3_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 */
146mpeg3_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 */
151mpeg3_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 */
158mpeg3_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 */
167mpeg3_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 */
180mpeg3_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 */
185mpeg3_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 */
191mpeg3_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 */
209mpeg3_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 */
217mpeg3_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 */
223mpeg3_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 */
231mpeg3_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 */
241mpeg3_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 */
251mpeg3_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 */
261mpeg3_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*/
283mpeg3_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 */
353mpeg3_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 */
362mpeg3_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 */
371mpeg3_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 */
382mpeg3_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 */
393mpeg3_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 */
404mpeg3_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 */
415mpeg3_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
25typedef struct {
26 char val, len;
27} mpeg3_VLCtab_t;
28
29typedef 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 */
40extern mpeg3_VLCtab_t mpeg3_PMBtab0[8];
41
42/* Table B-3, mb_type in P-pictures, codes 000001..00011x */
43extern mpeg3_VLCtab_t mpeg3_PMBtab1[8];
44
45/* Table B-4, mb_type in B-pictures, codes 0010..11xx */
46extern mpeg3_VLCtab_t mpeg3_BMBtab0[16];
47
48/* Table B-4, mb_type in B-pictures, codes 000001..00011x */
49extern mpeg3_VLCtab_t mpeg3_BMBtab1[8];
50
51/* Table B-5, mb_type in spat. scal. I-pictures, codes 0001..1xxx */
52extern mpeg3_VLCtab_t mpeg3_spIMBtab[16];
53
54/* Table B-6, mb_type in spat. scal. P-pictures, codes 0010..11xx */
55extern mpeg3_VLCtab_t mpeg3_spPMBtab0[16];
56
57/* Table B-6, mb_type in spat. scal. P-pictures, codes 0000010..000111x */
58extern mpeg3_VLCtab_t mpeg3_spPMBtab1[16];
59
60/* Table B-7, mb_type in spat. scal. B-pictures, codes 0010..11xx */
61extern mpeg3_VLCtab_t mpeg3_spBMBtab0[14];
62
63/* Table B-7, mb_type in spat. scal. B-pictures, codes 0000100..000111x */
64extern mpeg3_VLCtab_t mpeg3_spBMBtab1[12];
65
66/* Table B-7, mb_type in spat. scal. B-pictures, codes 00000100x..000001111 */
67extern mpeg3_VLCtab_t mpeg3_spBMBtab2[8];
68
69/* Table B-8, mb_type in spat. scal. B-pictures, codes 001..1xx */
70extern mpeg3_VLCtab_t mpeg3_SNRMBtab[8];
71
72/* Table B-10, motion_code, codes 0001 ... 01xx */
73extern mpeg3_VLCtab_t mpeg3_MVtab0[8];
74
75/* Table B-10, motion_code, codes 0000011 ... 000011x */
76extern mpeg3_VLCtab_t mpeg3_MVtab1[8];
77
78/* Table B-10, motion_code, codes 0000001100 ... 000001011x */
79extern mpeg3_VLCtab_t mpeg3_MVtab2[12];
80
81/* Table B-9, coded_block_pattern, codes 01000 ... 111xx */
82extern mpeg3_VLCtab_t mpeg3_CBPtab0[32];
83
84/* Table B-9, coded_block_pattern, codes 00000100 ... 001111xx */
85extern mpeg3_VLCtab_t mpeg3_CBPtab1[64];
86
87/* Table B-9, coded_block_pattern, codes 000000001 ... 000000111 */
88extern mpeg3_VLCtab_t mpeg3_CBPtab2[8];
89
90/* Table B-1, macroblock_address_increment, codes 00010 ... 011xx */
91extern mpeg3_VLCtab_t mpeg3_MBAtab1[16];
92
93/* Table B-1, macroblock_address_increment, codes 00000011000 ... 0000111xxxx */
94extern mpeg3_VLCtab_t mpeg3_MBAtab2[104];
95
96/* Table B-12, dct_dc_size_luminance, codes 00xxx ... 11110 */
97extern mpeg3_VLCtab_t mpeg3_DClumtab0[32];
98
99/* Table B-12, dct_dc_size_luminance, codes 111110xxx ... 111111111 */
100extern mpeg3_VLCtab_t mpeg3_DClumtab1[16];
101
102/* Table B-13, dct_dc_size_chrominance, codes 00xxx ... 11110 */
103extern mpeg3_VLCtab_t mpeg3_DCchromtab0[32];
104
105/* Table B-13, dct_dc_size_chrominance, codes 111110xxxx ... 1111111111 */
106extern 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 */
111extern 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 */
116extern mpeg3_DCTtab_t mpeg3_DCTtabnext[12];
117
118/* Table B-14, DCT coefficients table zero,
119 * codes 000001xx ... 00111xxx
120 */
121extern mpeg3_DCTtab_t mpeg3_DCTtab0[60];
122
123/* Table B-15, DCT coefficients table one,
124 * codes 000001xx ... 11111111
125*/
126extern mpeg3_DCTtab_t mpeg3_DCTtab0a[252];
127
128/* Table B-14, DCT coefficients table zero,
129 * codes 0000001000 ... 0000001111
130 */
131extern mpeg3_DCTtab_t mpeg3_DCTtab1[8];
132
133/* Table B-15, DCT coefficients table one,
134 * codes 000000100x ... 000000111x
135 */
136extern mpeg3_DCTtab_t mpeg3_DCTtab1a[8];
137
138/* Table B-14/15, DCT coefficients table zero / one,
139 * codes 000000010000 ... 000000011111
140 */
141extern mpeg3_DCTtab_t mpeg3_DCTtab2[16];
142
143/* Table B-14/15, DCT coefficients table zero / one,
144 * codes 0000000010000 ... 0000000011111
145 */
146extern mpeg3_DCTtab_t mpeg3_DCTtab3[16];
147
148/* Table B-14/15, DCT coefficients table zero / one,
149 * codes 00000000010000 ... 00000000011111
150 */
151extern mpeg3_DCTtab_t mpeg3_DCTtab4[16];
152
153/* Table B-14/15, DCT coefficients table zero / one,
154 * codes 000000000010000 ... 000000000011111
155 */
156extern mpeg3_DCTtab_t mpeg3_DCTtab5[16];
157
158/* Table B-14/15, DCT coefficients table zero / one,
159 * codes 0000000000010000 ... 0000000000011111
160 */
161extern 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
6static LONGLONG mpeg3_MMX_601_Y_COEF = 0x0000004000400040;
7
8inline void mpeg3_601_mmx(unsigned long y,
9 unsigned long *output)
10{
11asm("
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
23int 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}