summaryrefslogtreecommitdiff
path: root/core/multimedia/opieplayer/libmpeg3/video
authorkergoth <kergoth>2002-01-25 22:14:26 (UTC)
committer kergoth <kergoth>2002-01-25 22:14:26 (UTC)
commit15318cad33835e4e2dc620d033e43cd930676cdd (patch) (side-by-side diff)
treec2fa0399a2c47fda8e2cd0092c73a809d17f68eb /core/multimedia/opieplayer/libmpeg3/video
downloadopie-15318cad33835e4e2dc620d033e43cd930676cdd.zip
opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.gz
opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.bz2
Initial revision
Diffstat (limited to 'core/multimedia/opieplayer/libmpeg3/video') (more/less context) (ignore whitespace changes)
-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 @@
+include ../global_config
+export CFLAGS
+export CFLAGS_lessopt
+
+OBJS = \
+ getpicture.o \
+ headers.o \
+ idct.o \
+ macroblocks.o \
+ mmxtest.o \
+ motion.o \
+ mpeg3video.o \
+ output.o \
+ reconstruct.o \
+ seek.o \
+ slice.o \
+ vlc.o
+
+
+all: $(OBJS) $(MMXOBJS2)
+
+.c.o:
+ $(CC) -c `./c_flags` -o $@ $<
+
+.s.o:
+ $(NASM) -f elf $*.s
+
+.S.o:
+ $(CC) -S `./c_flags` $*.S
+
+clean:
+ 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 @@
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include "mpeg3video.h"
+#include "vlc.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int mpeg3video_get_cbp(mpeg3_slice_t *slice)
+{
+ int code;
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+
+ if((code = mpeg3slice_showbits9(slice_buffer)) >= 128)
+ {
+ code >>= 4;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_CBPtab0[code].len);
+ return mpeg3_CBPtab0[code].val;
+ }
+
+ if(code >= 8)
+ {
+ code >>= 1;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_CBPtab1[code].len);
+ return mpeg3_CBPtab1[code].val;
+ }
+
+ if(code < 1)
+ {
+/* fprintf(stderr,"mpeg3video_get_cbp: invalid coded_block_pattern code\n"); */
+ slice->fault = 1;
+ return 0;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, mpeg3_CBPtab2[code].len);
+ return mpeg3_CBPtab2[code].val;
+}
+
+
+/* set block to zero */
+int mpeg3video_clearblock(mpeg3_slice_t *slice, int comp, int size)
+{
+ slice->sparse[comp] = 1;
+
+/* Compiler error */
+/*
+ * for(i = 0; i < size; i++)
+ * {
+ * bzero(slice->block[comp] + sizeof(short) * 64 * i, sizeof(short) * 64);
+ * }
+ */
+
+ if(size == 6)
+ {
+ bzero(slice->block[comp], sizeof(short) * 64 * 6);
+ }
+ else
+ {
+printf("mpeg3video_clearblock size = %d\n", size);
+ memset(slice->block[comp], 0, sizeof(short) * 64 * size);
+ }
+ return 0;
+}
+
+static inline int mpeg3video_getdclum(mpeg3_slice_buffer_t *slice_buffer)
+{
+ int code, size, val;
+/* decode length */
+ code = mpeg3slice_showbits5(slice_buffer);
+
+ if(code < 31)
+ {
+ size = mpeg3_DClumtab0[code].val;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_DClumtab0[code].len);
+ }
+ else
+ {
+ code = mpeg3slice_showbits9(slice_buffer) - 0x1f0;
+ size = mpeg3_DClumtab1[code].val;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_DClumtab1[code].len);
+ }
+
+ if(size == 0) val = 0;
+ else
+ {
+ val = mpeg3slice_getbits(slice_buffer, size);
+ if((val & (1 << (size - 1))) == 0) val -= (1 << size) - 1;
+ }
+
+ return val;
+}
+
+
+int mpeg3video_getdcchrom(mpeg3_slice_buffer_t *slice_buffer)
+{
+ int code, size, val;
+
+/* decode length */
+ code = mpeg3slice_showbits5(slice_buffer);
+
+ if(code < 31)
+ {
+ size = mpeg3_DCchromtab0[code].val;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_DCchromtab0[code].len);
+ }
+ else
+ {
+ code = mpeg3slice_showbits(slice_buffer, 10) - 0x3e0;
+ size = mpeg3_DCchromtab1[code].val;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_DCchromtab1[code].len);
+ }
+
+ if(size == 0) val = 0;
+ else
+ {
+ val = mpeg3slice_getbits(slice_buffer, size);
+ if((val & (1 << (size - 1))) == 0) val -= (1 << size) - 1;
+ }
+
+ return val;
+}
+
+
+/* decode one intra coded MPEG-1 block */
+
+int mpeg3video_getintrablock(mpeg3_slice_t *slice,
+ mpeg3video_t *video,
+ int comp,
+ int dc_dct_pred[])
+{
+ int val, i, j, sign;
+ unsigned int code;
+ mpeg3_DCTtab_t *tab = 0;
+ short *bp = slice->block[comp];
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+
+/* decode DC coefficients */
+ if(comp < 4)
+ bp[0] = (dc_dct_pred[0] += mpeg3video_getdclum(slice_buffer)) << 3;
+ else
+ if(comp == 4)
+ bp[0] = (dc_dct_pred[1] += mpeg3video_getdcchrom(slice_buffer)) << 3;
+ else
+ bp[0] = (dc_dct_pred[2] += mpeg3video_getdcchrom(slice_buffer)) << 3;
+
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ bp[0] <<= 4;
+#endif
+
+ if(slice->fault) return 1;
+
+/* decode AC coefficients */
+ for(i = 1; ; i++)
+ {
+ code = mpeg3slice_showbits16(slice_buffer);
+ if(code >= 16384)
+ tab = &mpeg3_DCTtabnext[(code >> 12) - 4];
+ else
+ if(code >= 1024) tab = &mpeg3_DCTtab0[(code >> 8) - 4];
+ else
+ if(code >= 512) tab = &mpeg3_DCTtab1[(code >> 6) - 8];
+ else
+ if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16];
+ else
+ if(code >= 128) tab = &mpeg3_DCTtab3[(code >> 3) - 16];
+ else
+ if(code >= 64) tab = &mpeg3_DCTtab4[(code >> 2) - 16];
+ else
+ if(code >= 32) tab = &mpeg3_DCTtab5[(code >> 1) - 16];
+ else
+ if(code >= 16) tab = &mpeg3_DCTtab6[code - 16];
+ else
+ {
+/* fprintf(stderr, "mpeg3video_getintrablock: invalid Huffman code\n"); */
+ slice->fault = 1;
+ return 1;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, tab->len);
+
+ if(tab->run == 64) break; /* end_of_block */
+
+ if(tab->run == 65)
+ {
+/* escape */
+ i += mpeg3slice_getbits(slice_buffer, 6);
+
+ if((val = mpeg3slice_getbits(slice_buffer, 8)) == 0)
+ val = mpeg3slice_getbits(slice_buffer, 8);
+ else
+ if(val == 128)
+ val = mpeg3slice_getbits(slice_buffer, 8) - 256;
+ else
+ if(val > 128)
+ val -= 256;
+
+ if((sign = (val < 0)) != 0) val= -val;
+ }
+ else
+ {
+ i += tab->run;
+ val = tab->level;
+ sign = mpeg3slice_getbit(slice_buffer);
+ }
+
+ if(i < 64)
+ j = video->mpeg3_zigzag_scan_table[i];
+ else
+ {
+ slice->fault = 1;
+ return 1;
+ }
+
+
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ {
+ val = (val * slice->quant_scale * video->intra_quantizer_matrix[j]) << 1;
+ val = (val - 16) | 16;
+ }
+ else
+#endif
+ {
+ val = (val * slice->quant_scale * video->intra_quantizer_matrix[j]) >> 3;
+ val = (val - 1) | 1;
+ }
+
+ bp[j] = sign ? -val : val;
+ }
+
+ if(j != 0)
+ {
+/* not a sparse matrix ! */
+ slice->sparse[comp] = 0;
+ }
+ return 0;
+}
+
+
+/* decode one non-intra coded MPEG-1 block */
+
+int mpeg3video_getinterblock(mpeg3_slice_t *slice,
+ mpeg3video_t *video,
+ int comp)
+{
+ int val, i, j, sign;
+ unsigned int code;
+ mpeg3_DCTtab_t *tab;
+ short *bp = slice->block[comp];
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+
+/* decode AC coefficients */
+ for(i = 0; ; i++)
+ {
+ code = mpeg3slice_showbits16(slice_buffer);
+ if(code >= 16384)
+ {
+ if(i == 0)
+ tab = &mpeg3_DCTtabfirst[(code >> 12) - 4];
+ else
+ tab = &mpeg3_DCTtabnext[(code >> 12) - 4];
+ }
+ else
+ if(code >= 1024) tab = &mpeg3_DCTtab0[(code >> 8) - 4];
+ else
+ if(code >= 512) tab = &mpeg3_DCTtab1[(code >> 6) - 8];
+ else
+ if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16];
+ else
+ if(code >= 128) tab = &mpeg3_DCTtab3[(code >> 3) - 16];
+ else
+ if(code >= 64) tab = &mpeg3_DCTtab4[(code >> 2) - 16];
+ else
+ if(code >= 32) tab = &mpeg3_DCTtab5[(code >> 1) - 16];
+ else
+ if(code >= 16) tab = &mpeg3_DCTtab6[code - 16];
+ else
+ {
+// invalid Huffman code
+ slice->fault = 1;
+ return 1;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, tab->len);
+
+/* end of block */
+ if(tab->run == 64)
+ break;
+
+ if(tab->run == 65)
+ {
+/* escape */
+ i += mpeg3slice_getbits(slice_buffer, 6);
+ if((val = mpeg3slice_getbits(slice_buffer, 8)) == 0)
+ val = mpeg3slice_getbits(slice_buffer, 8);
+ else
+ if(val == 128)
+ val = mpeg3slice_getbits(slice_buffer, 8) - 256;
+ else
+ if(val > 128)
+ val -= 256;
+
+ if((sign = (val < 0)) != 0) val = -val;
+ }
+ else
+ {
+ i += tab->run;
+ val = tab->level;
+ sign = mpeg3slice_getbit(slice_buffer);
+ }
+
+ j = video->mpeg3_zigzag_scan_table[i];
+
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ {
+ val = (((val << 1)+1) * slice->quant_scale * video->non_intra_quantizer_matrix[j]);
+ val = (val - 16) | 16;
+ }
+ else
+#endif
+ {
+ val = (((val << 1)+1) * slice->quant_scale * video->non_intra_quantizer_matrix[j]) >> 4;
+ val = (val - 1) | 1;
+ }
+
+ bp[j] = sign ? -val : val;
+ }
+
+ if(j != 0)
+ {
+/* not a sparse matrix ! */
+ slice->sparse[comp] = 0;
+ }
+ return 0;
+}
+
+
+/* decode one intra coded MPEG-2 block */
+int mpeg3video_getmpg2intrablock(mpeg3_slice_t *slice,
+ mpeg3video_t *video,
+ int comp,
+ int dc_dct_pred[])
+{
+ int val, i, j, sign, nc;
+ unsigned int code;
+ mpeg3_DCTtab_t *tab;
+ short *bp;
+ int *qmat;
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+
+/* with data partitioning, data always goes to base layer */
+ bp = slice->block[comp];
+
+ qmat = (comp < 4 || video->chroma_format == CHROMA420)
+ ? video->intra_quantizer_matrix
+ : video->chroma_intra_quantizer_matrix;
+
+/* decode DC coefficients */
+ if(comp < 4)
+ val = (dc_dct_pred[0] += mpeg3video_getdclum(slice_buffer));
+ else
+ if((comp & 1) == 0)
+ val = (dc_dct_pred[1] += mpeg3video_getdcchrom(slice_buffer));
+ else
+ val = (dc_dct_pred[2] += mpeg3video_getdcchrom(slice_buffer));
+
+ if(slice->fault) return 1;
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ bp[0] = val << (7 - video->dc_prec);
+ else
+#endif
+ bp[0] = val << (3 - video->dc_prec);
+
+ nc = 0;
+
+/* decode AC coefficients */
+ for(i = 1; ; i++)
+ {
+ code = mpeg3slice_showbits16(slice_buffer);
+
+ if(code >= 16384 && !video->intravlc)
+ tab = &mpeg3_DCTtabnext[(code >> 12) - 4];
+ else
+ if(code >= 1024)
+ {
+ if(video->intravlc)
+ tab = &mpeg3_DCTtab0a[(code >> 8) - 4];
+ else
+ tab = &mpeg3_DCTtab0[(code >> 8) - 4];
+ }
+ else
+ if(code >= 512)
+ {
+ if(video->intravlc)
+ tab = &mpeg3_DCTtab1a[(code >> 6) - 8];
+ else
+ tab = &mpeg3_DCTtab1[(code >> 6) - 8];
+ }
+ else
+ if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16];
+ else
+ if(code >= 128) tab = &mpeg3_DCTtab3[(code >> 3) - 16];
+ else
+ if(code >= 64) tab = &mpeg3_DCTtab4[(code >> 2) - 16];
+ else
+ if(code >= 32) tab = &mpeg3_DCTtab5[(code >> 1) - 16];
+ else
+ if(code >= 16) tab = &mpeg3_DCTtab6[code - 16];
+ else
+ {
+/* fprintf(stderr,"mpeg3video_getmpg2intrablock: invalid Huffman code\n"); */
+ slice->fault = 1;
+ return 1;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, tab->len);
+
+/* end_of_block */
+ if(tab->run == 64)
+ break;
+
+ if(tab->run == 65)
+ {
+/* escape */
+ i += mpeg3slice_getbits(slice_buffer, 6);
+
+ val = mpeg3slice_getbits(slice_buffer, 12);
+ if((val & 2047) == 0)
+ {
+// invalid signed_level (escape)
+ slice->fault = 1;
+ return 1;
+ }
+ if((sign = (val >= 2048)) != 0) val = 4096 - val;
+ }
+ else
+ {
+ i += tab->run;
+ val = tab->level;
+ sign = mpeg3slice_getbit(slice_buffer);
+ }
+
+ j = (video->altscan ? video->mpeg3_alternate_scan_table : video->mpeg3_zigzag_scan_table)[i];
+
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ val = (val * slice->quant_scale * qmat[j]);
+ else
+#endif
+ val = (val * slice->quant_scale * qmat[j]) >> 4;
+
+ bp[j] = sign ? -val : val;
+ nc++;
+ }
+
+ if(j != 0)
+ {
+/* not a sparse matrix ! */
+ slice->sparse[comp] = 0;
+ }
+ return 1;
+}
+
+
+/* decode one non-intra coded MPEG-2 block */
+
+int mpeg3video_getmpg2interblock(mpeg3_slice_t *slice,
+ mpeg3video_t *video,
+ int comp)
+{
+ int val, i, j, sign, nc;
+ unsigned int code;
+ mpeg3_DCTtab_t *tab;
+ short *bp;
+ int *qmat;
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+
+/* with data partitioning, data always goes to base layer */
+ bp = slice->block[comp];
+
+ qmat = (comp < 4 || video->chroma_format == CHROMA420)
+ ? video->non_intra_quantizer_matrix
+ : video->chroma_non_intra_quantizer_matrix;
+
+ nc = 0;
+
+/* decode AC coefficients */
+ for(i = 0; ; i++)
+ {
+ code = mpeg3slice_showbits16(slice_buffer);
+ if(code >= 16384)
+ {
+ if(i == 0) tab = &mpeg3_DCTtabfirst[(code >> 12) - 4];
+ else tab = &mpeg3_DCTtabnext[(code >> 12) - 4];
+ }
+ else
+ if(code >= 1024) tab = &mpeg3_DCTtab0[(code >> 8) - 4];
+ else
+ if(code >= 512) tab = &mpeg3_DCTtab1[(code >> 6) - 8];
+ else
+ if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16];
+ else
+ if(code >= 128) tab = &mpeg3_DCTtab3[(code >> 3) - 16];
+ else
+ if(code >= 64) tab = &mpeg3_DCTtab4[(code >> 2) - 16];
+ else
+ if(code >= 32) tab = &mpeg3_DCTtab5[(code >> 1) - 16];
+ else
+ if(code >= 16) tab = &mpeg3_DCTtab6[code - 16];
+ else
+ {
+// invalid Huffman code
+ slice->fault = 1;
+ return 1;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, tab->len);
+
+/* end_of_block */
+ if(tab->run == 64)
+ break;
+
+ if(tab->run == 65)
+ {
+/* escape */
+ i += mpeg3slice_getbits(slice_buffer, 6);
+ val = mpeg3slice_getbits(slice_buffer, 12);
+ if((val & 2047) == 0)
+ {
+/* fprintf(stderr, "mpeg3video_getmpg2interblock: invalid signed_level (escape)\n"); */
+ slice->fault = 1;
+ return 1;
+ }
+ if((sign = (val >= 2048)) != 0) val = 4096 - val;
+ }
+ else
+ {
+ i += tab->run;
+ val = tab->level;
+ sign = mpeg3slice_getbit(slice_buffer);
+ }
+
+ j = (video->altscan ? video->mpeg3_alternate_scan_table : video->mpeg3_zigzag_scan_table)[i];
+
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ val = (((val << 1)+1) * slice->quant_scale * qmat[j]) >> 1;
+ else
+#endif
+ val = (((val << 1)+1) * slice->quant_scale * qmat[j]) >> 5;
+
+ bp[j] = sign ? (-val) : val ;
+ nc++;
+ }
+
+ if(j != 0)
+ {
+ slice->sparse[comp] = 0;
+ }
+ return 0;
+}
+
+
+/* decode all macroblocks of the current picture */
+int mpeg3video_get_macroblocks(mpeg3video_t *video, int framenum)
+{
+ unsigned int code;
+ mpeg3_slice_buffer_t *slice_buffer; /* Buffer being loaded */
+ int i;
+ int current_buffer;
+ mpeg3_bits_t *vstream = video->vstream;
+
+/* Load every slice into a buffer array */
+ video->total_slice_buffers = 0;
+ current_buffer = 0;
+ while(!mpeg3bits_eof(vstream) &&
+ mpeg3bits_showbits32_noptr(vstream) >= MPEG3_SLICE_MIN_START &&
+ mpeg3bits_showbits32_noptr(vstream) <= MPEG3_SLICE_MAX_START)
+ {
+/* Initialize the buffer */
+ if(current_buffer >= video->slice_buffers_initialized)
+ mpeg3_new_slice_buffer(&(video->slice_buffers[video->slice_buffers_initialized++]));
+ slice_buffer = &(video->slice_buffers[current_buffer]);
+ slice_buffer->buffer_size = 0;
+ slice_buffer->current_position = 0;
+ slice_buffer->bits_size = 0;
+ slice_buffer->done = 0;
+
+/* Read the slice into the buffer including the slice start code */
+ do
+ {
+/* Expand buffer */
+ if(slice_buffer->buffer_allocation <= slice_buffer->buffer_size)
+ mpeg3_expand_slice_buffer(slice_buffer);
+
+/* Load 1 char into buffer */
+ slice_buffer->data[slice_buffer->buffer_size++] = mpeg3bits_getbyte_noptr(vstream);
+ }while(!mpeg3bits_eof(vstream) &&
+ mpeg3bits_showbits24_noptr(vstream) != MPEG3_PACKET_START_CODE_PREFIX);
+
+/* Pad the buffer to get the last macroblock */
+ if(slice_buffer->buffer_allocation <= slice_buffer->buffer_size + 4)
+ mpeg3_expand_slice_buffer(slice_buffer);
+
+ slice_buffer->data[slice_buffer->buffer_size++] = 0;
+ slice_buffer->data[slice_buffer->buffer_size++] = 0;
+ slice_buffer->data[slice_buffer->buffer_size++] = 1;
+ slice_buffer->data[slice_buffer->buffer_size++] = 0;
+ slice_buffer->bits_size = 0;
+
+ pthread_mutex_lock(&(slice_buffer->completion_lock)); fflush(stdout);
+ current_buffer++;
+ video->total_slice_buffers++;
+ }
+
+/* Run the slice decoders */
+ if(video->total_slice_buffers > 0)
+ {
+ for(i = 0; i < video->total_slice_decoders; i++)
+ {
+ if(i == 0 && video->total_slice_decoders > 1)
+ {
+ video->slice_decoders[i].current_buffer = 0;
+ video->slice_decoders[i].buffer_step = 1;
+ video->slice_decoders[i].last_buffer = (video->total_slice_buffers - 1);
+ }
+ else
+ if(i == 1)
+ {
+ video->slice_decoders[i].current_buffer = video->total_slice_buffers - 1;
+ video->slice_decoders[i].buffer_step = -1;
+ video->slice_decoders[i].last_buffer = 0;
+ }
+ else
+ {
+ video->slice_decoders[i].current_buffer = i;
+ video->slice_decoders[i].buffer_step = 1;
+ video->slice_decoders[i].last_buffer = video->total_slice_buffers - 1;
+ }
+ pthread_mutex_unlock(&(video->slice_decoders[i].input_lock));
+ }
+ }
+
+/* Wait for the slice decoders to finish */
+ if(video->total_slice_buffers > 0)
+ {
+ for(i = 0; i < video->total_slice_buffers; i++)
+ {
+ pthread_mutex_lock(&(video->slice_buffers[i].completion_lock));
+ pthread_mutex_unlock(&(video->slice_buffers[i].completion_lock));
+ }
+ }
+ return 0;
+}
+
+int mpeg3video_allocate_decoders(mpeg3video_t *video, int decoder_count)
+{
+ int i;
+ mpeg3_t *file = video->file;
+/* Get the slice decoders */
+ if(video->total_slice_decoders != file->cpus)
+ {
+ for(i = 0; i < video->total_slice_decoders; i++)
+ {
+ mpeg3_delete_slice_decoder(&video->slice_decoders[i]);
+ }
+
+ for(i = 0; i < file->cpus && i < MPEG3_MAX_CPUS; i++)
+ {
+ mpeg3_new_slice_decoder(video, &(video->slice_decoders[i]));
+ video->slice_decoders[i].thread_number = i;
+ }
+
+ video->total_slice_decoders = file->cpus;
+ }
+ return 0;
+}
+
+/* decode one frame or field picture */
+
+int mpeg3video_getpicture(mpeg3video_t *video, int framenum)
+{
+ int i, result = 0;
+ mpeg3_t *file = video->file;
+
+ if(video->pict_struct == FRAME_PICTURE && video->secondfield)
+ {
+/* recover from illegal number of field pictures */
+ video->secondfield = 0;
+ }
+
+ if(!video->mpeg2)
+ {
+ video->current_repeat = video->repeat_count = 0;
+ }
+
+ mpeg3video_allocate_decoders(video, file->cpus);
+
+ for(i = 0; i < 3; i++)
+ {
+ if(video->pict_type == B_TYPE)
+ {
+ video->newframe[i] = video->auxframe[i];
+ }
+ else
+ {
+ if(!video->secondfield && !video->current_repeat)
+ {
+/* Swap refframes for I frames */
+ unsigned char* tmp = video->oldrefframe[i];
+ video->oldrefframe[i] = video->refframe[i];
+ video->refframe[i] = tmp;
+ }
+
+ video->newframe[i] = video->refframe[i];
+ }
+
+ if(video->pict_struct == BOTTOM_FIELD)
+ {
+/* Only used if fields are in different pictures */
+ video->newframe[i] += (i == 0) ? video->coded_picture_width : video->chrom_width;
+ }
+ }
+
+/* The problem is when a B frame lands on the first repeat and is skipped, */
+/* the second repeat goes for the same bitmap as the skipped repeat, */
+/* so it picks up a frame from 3 frames back. */
+/* The first repeat must consititutively read a B frame if its B frame is going to be */
+/* used in a later repeat. */
+ if(!video->current_repeat)
+ if(!(video->skip_bframes && video->pict_type == B_TYPE) ||
+ (video->repeat_count >= 100 + 100 * video->skip_bframes))
+ result = mpeg3video_get_macroblocks(video, framenum);
+
+/* Set the frame to display */
+ video->output_src = 0;
+ if(framenum > -1 && !result)
+ {
+ if(video->pict_struct == FRAME_PICTURE || video->secondfield)
+ {
+ if(video->pict_type == B_TYPE)
+ {
+ video->output_src = video->auxframe;
+ }
+ else
+ {
+ video->output_src = video->oldrefframe;
+ }
+ }
+ else
+ {
+ mpeg3video_display_second_field(video);
+ }
+ }
+
+ if(video->mpeg2)
+ {
+ video->current_repeat += 100;
+ }
+
+ if(video->pict_struct != FRAME_PICTURE) video->secondfield = !video->secondfield;
+ return result;
+}
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 @@
+#include "../mpeg3demux.h"
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include "mpeg3video.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int mpeg3video_getseqhdr(mpeg3video_t *video)
+{
+ int i;
+ mpeg3_t *file = video->file;
+
+ int aspect_ratio, picture_rate, vbv_buffer_size;
+ int constrained_parameters_flag;
+ int load_intra_quantizer_matrix, load_non_intra_quantizer_matrix;
+
+ video->horizontal_size = mpeg3bits_getbits(video->vstream, 12);
+ video->vertical_size = mpeg3bits_getbits(video->vstream, 12);
+ aspect_ratio = mpeg3bits_getbits(video->vstream, 4);
+ video->framerate_code = mpeg3bits_getbits(video->vstream, 4);
+ video->bitrate = mpeg3bits_getbits(video->vstream, 18);
+ mpeg3bits_getbit_noptr(video->vstream); /* marker bit (=1) */
+ vbv_buffer_size = mpeg3bits_getbits(video->vstream, 10);
+ constrained_parameters_flag = mpeg3bits_getbit_noptr(video->vstream);
+ video->frame_rate = mpeg3_frame_rate_table[video->framerate_code];
+
+ load_intra_quantizer_matrix = mpeg3bits_getbit_noptr(video->vstream);
+ if(load_intra_quantizer_matrix)
+ {
+ for(i = 0; i < 64; i++)
+ video->intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream);
+ }
+ else
+ {
+ for(i = 0; i < 64; i++)
+ video->intra_quantizer_matrix[i] = mpeg3_default_intra_quantizer_matrix[i];
+ }
+
+ load_non_intra_quantizer_matrix = mpeg3bits_getbit_noptr(video->vstream);
+ if(load_non_intra_quantizer_matrix)
+ {
+ for(i = 0; i < 64; i++)
+ video->non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream);
+ }
+ else
+ {
+ for(i = 0; i < 64; i++)
+ video->non_intra_quantizer_matrix[i] = 16;
+ }
+
+/* copy luminance to chrominance matrices */
+ for(i = 0; i < 64; i++)
+ {
+ video->chroma_intra_quantizer_matrix[i] = video->intra_quantizer_matrix[i];
+ video->chroma_non_intra_quantizer_matrix[i] = video->non_intra_quantizer_matrix[i];
+ }
+
+ return 0;
+}
+
+
+/* decode sequence extension */
+
+int mpeg3video_sequence_extension(mpeg3video_t *video)
+{
+ int prof_lev;
+ int horizontal_size_extension, vertical_size_extension;
+ int bit_rate_extension, vbv_buffer_size_extension, low_delay;
+ int frame_rate_extension_n, frame_rate_extension_d;
+ int pos = 0;
+
+ video->mpeg2 = 1;
+ video->scalable_mode = SC_NONE; /* unless overwritten by seq. scal. ext. */
+ prof_lev = mpeg3bits_getbyte_noptr(video->vstream);
+ video->prog_seq = mpeg3bits_getbit_noptr(video->vstream);
+ video->chroma_format = mpeg3bits_getbits(video->vstream, 2);
+ horizontal_size_extension = mpeg3bits_getbits(video->vstream, 2);
+ vertical_size_extension = mpeg3bits_getbits(video->vstream, 2);
+ bit_rate_extension = mpeg3bits_getbits(video->vstream, 12);
+ mpeg3bits_getbit_noptr(video->vstream);
+ vbv_buffer_size_extension = mpeg3bits_getbyte_noptr(video->vstream);
+ low_delay = mpeg3bits_getbit_noptr(video->vstream);
+ frame_rate_extension_n = mpeg3bits_getbits(video->vstream, 2);
+ frame_rate_extension_d = mpeg3bits_getbits(video->vstream, 5);
+ video->horizontal_size = (horizontal_size_extension << 12) | (video->horizontal_size & 0x0fff);
+ video->vertical_size = (vertical_size_extension << 12) | (video->vertical_size & 0x0fff);
+}
+
+
+/* decode sequence display extension */
+
+int mpeg3video_sequence_display_extension(mpeg3video_t *video)
+{
+ int colour_primaries = 0, transfer_characteristics = 0;
+ int display_horizontal_size, display_vertical_size;
+ int pos = 0;
+ int video_format = mpeg3bits_getbits(video->vstream, 3);
+ int colour_description = mpeg3bits_getbit_noptr(video->vstream);
+
+ if(colour_description)
+ {
+ colour_primaries = mpeg3bits_getbyte_noptr(video->vstream);
+ transfer_characteristics = mpeg3bits_getbyte_noptr(video->vstream);
+ video->matrix_coefficients = mpeg3bits_getbyte_noptr(video->vstream);
+ }
+
+ display_horizontal_size = mpeg3bits_getbits(video->vstream, 14);
+ mpeg3bits_getbit_noptr(video->vstream);
+ display_vertical_size = mpeg3bits_getbits(video->vstream, 14);
+}
+
+
+/* decode quant matrix entension */
+
+int mpeg3video_quant_matrix_extension(mpeg3video_t *video)
+{
+ int i;
+ int load_intra_quantiser_matrix, load_non_intra_quantiser_matrix;
+ int load_chroma_intra_quantiser_matrix;
+ int load_chroma_non_intra_quantiser_matrix;
+ int pos = 0;
+
+ if((load_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0)
+ {
+ for(i = 0; i < 64; i++)
+ {
+ video->chroma_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]]
+ = video->intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]]
+ = mpeg3bits_getbyte_noptr(video->vstream);
+ }
+ }
+
+ if((load_non_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0)
+ {
+ for (i = 0; i < 64; i++)
+ {
+ video->chroma_non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]]
+ = video->non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]]
+ = mpeg3bits_getbyte_noptr(video->vstream);
+ }
+ }
+
+ if((load_chroma_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0)
+ {
+ for(i = 0; i < 64; i++)
+ video->chroma_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream);
+ }
+
+ if((load_chroma_non_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0)
+ {
+ for(i = 0; i < 64; i++)
+ video->chroma_non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream);
+ }
+}
+
+
+/* decode sequence scalable extension */
+
+int mpeg3video_sequence_scalable_extension(mpeg3video_t *video)
+{
+ int layer_id;
+
+ video->scalable_mode = mpeg3bits_getbits(video->vstream, 2) + 1; /* add 1 to make SC_DP != SC_NONE */
+ layer_id = mpeg3bits_getbits(video->vstream, 4);
+
+ if(video->scalable_mode == SC_SPAT)
+ {
+ video->llw = mpeg3bits_getbits(video->vstream, 14); /* lower_layer_prediction_horizontal_size */
+ mpeg3bits_getbit_noptr(video->vstream);
+ video->llh = mpeg3bits_getbits(video->vstream, 14); /* lower_layer_prediction_vertical_size */
+ video->hm = mpeg3bits_getbits(video->vstream, 5);
+ video->hn = mpeg3bits_getbits(video->vstream, 5);
+ video->vm = mpeg3bits_getbits(video->vstream, 5);
+ video->vn = mpeg3bits_getbits(video->vstream, 5);
+ }
+
+ if(video->scalable_mode == SC_TEMP)
+ fprintf(stderr, "mpeg3video_sequence_scalable_extension: temporal scalability not implemented\n");
+}
+
+
+/* decode picture display extension */
+
+int mpeg3video_picture_display_extension(mpeg3video_t *video)
+{
+ int n, i;
+ short frame_centre_horizontal_offset[3];
+ short frame_centre_vertical_offset[3];
+
+ if(video->prog_seq || video->pict_struct != FRAME_PICTURE)
+ n = 1;
+ else
+ n = video->repeatfirst ? 3 : 2;
+
+ for(i = 0; i < n; i++)
+ {
+ frame_centre_horizontal_offset[i] = (short)mpeg3bits_getbits(video->vstream, 16);
+ mpeg3bits_getbit_noptr(video->vstream);
+ frame_centre_vertical_offset[i] = (short)mpeg3bits_getbits(video->vstream, 16);
+ mpeg3bits_getbit_noptr(video->vstream);
+ }
+}
+
+
+/* decode picture coding extension */
+
+int mpeg3video_picture_coding_extension(mpeg3video_t *video)
+{
+ int chroma_420_type, composite_display_flag;
+ int v_axis = 0, field_sequence = 0, sub_carrier = 0, burst_amplitude = 0, sub_carrier_phase = 0;
+
+ video->h_forw_r_size = mpeg3bits_getbits(video->vstream, 4) - 1;
+ video->v_forw_r_size = mpeg3bits_getbits(video->vstream, 4) - 1;
+ video->h_back_r_size = mpeg3bits_getbits(video->vstream, 4) - 1;
+ video->v_back_r_size = mpeg3bits_getbits(video->vstream, 4) - 1;
+ video->dc_prec = mpeg3bits_getbits(video->vstream, 2);
+ video->pict_struct = mpeg3bits_getbits(video->vstream, 2);
+ video->topfirst = mpeg3bits_getbit_noptr(video->vstream);
+ video->frame_pred_dct = mpeg3bits_getbit_noptr(video->vstream);
+ video->conceal_mv = mpeg3bits_getbit_noptr(video->vstream);
+ video->qscale_type = mpeg3bits_getbit_noptr(video->vstream);
+ video->intravlc = mpeg3bits_getbit_noptr(video->vstream);
+ video->altscan = mpeg3bits_getbit_noptr(video->vstream);
+ video->repeatfirst = mpeg3bits_getbit_noptr(video->vstream);
+ chroma_420_type = mpeg3bits_getbit_noptr(video->vstream);
+ video->prog_frame = mpeg3bits_getbit_noptr(video->vstream);
+
+ if(video->repeat_count > 100)
+ video->repeat_count = 0;
+ video->repeat_count += 100;
+
+ video->current_repeat = 0;
+
+ if(video->prog_seq)
+ {
+ if(video->repeatfirst)
+ {
+ if(video->topfirst)
+ video->repeat_count += 200;
+ else
+ video->repeat_count += 100;
+ }
+ }
+ else
+ if(video->prog_frame)
+ {
+ if(video->repeatfirst)
+ {
+ video->repeat_count += 50;
+ }
+ }
+
+/*printf("mpeg3video_picture_coding_extension %d\n", video->repeat_count); */
+ composite_display_flag = mpeg3bits_getbit_noptr(video->vstream);
+
+ if(composite_display_flag)
+ {
+ v_axis = mpeg3bits_getbit_noptr(video->vstream);
+ field_sequence = mpeg3bits_getbits(video->vstream, 3);
+ sub_carrier = mpeg3bits_getbit_noptr(video->vstream);
+ burst_amplitude = mpeg3bits_getbits(video->vstream, 7);
+ sub_carrier_phase = mpeg3bits_getbyte_noptr(video->vstream);
+ }
+}
+
+
+/* decode picture spatial scalable extension */
+
+int mpeg3video_picture_spatial_scalable_extension(mpeg3video_t *video)
+{
+ video->pict_scal = 1; /* use spatial scalability in this picture */
+
+ video->lltempref = mpeg3bits_getbits(video->vstream, 10);
+ mpeg3bits_getbit_noptr(video->vstream);
+ video->llx0 = mpeg3bits_getbits(video->vstream, 15);
+ if(video->llx0 >= 16384) video->llx0 -= 32768;
+ mpeg3bits_getbit_noptr(video->vstream);
+ video->lly0 = mpeg3bits_getbits(video->vstream, 15);
+ if(video->lly0 >= 16384) video->lly0 -= 32768;
+ video->stwc_table_index = mpeg3bits_getbits(video->vstream, 2);
+ video->llprog_frame = mpeg3bits_getbit_noptr(video->vstream);
+ video->llfieldsel = mpeg3bits_getbit_noptr(video->vstream);
+}
+
+
+/* decode picture temporal scalable extension
+ *
+ * not implemented
+ *
+ */
+
+int mpeg3video_picture_temporal_scalable_extension(mpeg3video_t *video)
+{
+ fprintf(stderr, "mpeg3video_picture_temporal_scalable_extension: temporal scalability not supported\n");
+}
+
+
+/* decode extension and user data */
+
+int mpeg3video_ext_user_data(mpeg3video_t *video)
+{
+ int code = mpeg3bits_next_startcode(video->vstream);
+
+
+ while(code == MPEG3_EXT_START_CODE || code == MPEG3_USER_START_CODE &&
+ !mpeg3bits_eof(video->vstream))
+ {
+ mpeg3bits_refill(video->vstream);
+
+ if(code == MPEG3_EXT_START_CODE)
+ {
+ int ext_id = mpeg3bits_getbits(video->vstream, 4);
+ switch(ext_id)
+ {
+ case SEQ_ID:
+ mpeg3video_sequence_extension(video);
+ break;
+ case DISP_ID:
+ mpeg3video_sequence_display_extension(video);
+ break;
+ case QUANT_ID:
+ mpeg3video_quant_matrix_extension(video);
+ break;
+ case SEQSCAL_ID:
+ mpeg3video_sequence_scalable_extension(video);
+ break;
+ case PANSCAN_ID:
+ mpeg3video_picture_display_extension(video);
+ break;
+ case CODING_ID:
+ mpeg3video_picture_coding_extension(video);
+ break;
+ case SPATSCAL_ID:
+ mpeg3video_picture_spatial_scalable_extension(video);
+ break;
+ case TEMPSCAL_ID:
+ mpeg3video_picture_temporal_scalable_extension(video);
+ break;
+ default:
+ fprintf(stderr,"mpeg3video_ext_user_data: reserved extension start code ID %d\n", ext_id);
+ break;
+ }
+ }
+ code = mpeg3bits_next_startcode(video->vstream);
+ }
+}
+
+
+/* decode group of pictures header */
+
+int mpeg3video_getgophdr(mpeg3video_t *video)
+{
+ int drop_flag, closed_gop, broken_link;
+
+ drop_flag = mpeg3bits_getbit_noptr(video->vstream);
+ video->gop_timecode.hour = mpeg3bits_getbits(video->vstream, 5);
+ video->gop_timecode.minute = mpeg3bits_getbits(video->vstream, 6);
+ mpeg3bits_getbit_noptr(video->vstream);
+ video->gop_timecode.second = mpeg3bits_getbits(video->vstream, 6);
+ video->gop_timecode.frame = mpeg3bits_getbits(video->vstream, 6);
+ closed_gop = mpeg3bits_getbit_noptr(video->vstream);
+ broken_link = mpeg3bits_getbit_noptr(video->vstream);
+
+/*
+ * 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,
+ * drop_flag, closed_gop, broken_link);
+ */
+ return mpeg3bits_error(video->vstream);
+}
+
+/* decode picture header */
+
+int mpeg3video_getpicturehdr(mpeg3video_t *video)
+{
+ int temp_ref, vbv_delay;
+
+ video->pict_scal = 0; /* unless overwritten by pict. spat. scal. ext. */
+
+ temp_ref = mpeg3bits_getbits(video->vstream, 10);
+ video->pict_type = mpeg3bits_getbits(video->vstream, 3);
+ vbv_delay = mpeg3bits_getbits(video->vstream, 16);
+
+ if(video->pict_type == P_TYPE || video->pict_type == B_TYPE)
+ {
+ video->full_forw = mpeg3bits_getbit_noptr(video->vstream);
+ video->forw_r_size = mpeg3bits_getbits(video->vstream, 3) - 1;
+ }
+
+ if(video->pict_type == B_TYPE)
+ {
+ video->full_back = mpeg3bits_getbit_noptr(video->vstream);
+ video->back_r_size = mpeg3bits_getbits(video->vstream, 3) - 1;
+ }
+
+/* get extra bit picture */
+ while(mpeg3bits_getbit_noptr(video->vstream) &&
+ !mpeg3bits_eof(video->vstream)) mpeg3bits_getbyte_noptr(video->vstream);
+ return 0;
+}
+
+
+int mpeg3video_get_header(mpeg3video_t *video, int dont_repeat)
+{
+ unsigned int code;
+
+/* a sequence header should be found before returning from `getheader' the */
+/* first time (this is to set horizontal/vertical size properly) */
+
+/* Repeat the frame until it's less than 1 count from repeat_count */
+ if(video->repeat_count - video->current_repeat >= 100 && !dont_repeat)
+ {
+ return 0;
+ }
+
+ if(dont_repeat)
+ {
+ video->repeat_count = 0;
+ video->current_repeat = 0;
+ }
+ else
+ video->repeat_count -= video->current_repeat;
+
+ while(1)
+ {
+/* look for startcode */
+ code = mpeg3bits_next_startcode(video->vstream);
+ if(mpeg3bits_eof(video->vstream)) return 1;
+ if(code != MPEG3_SEQUENCE_END_CODE) mpeg3bits_refill(video->vstream);
+
+ switch(code)
+ {
+ case MPEG3_SEQUENCE_START_CODE:
+ video->found_seqhdr = 1;
+ mpeg3video_getseqhdr(video);
+ mpeg3video_ext_user_data(video);
+ break;
+
+ case MPEG3_GOP_START_CODE:
+ mpeg3video_getgophdr(video);
+ mpeg3video_ext_user_data(video);
+ break;
+
+ case MPEG3_PICTURE_START_CODE:
+ mpeg3video_getpicturehdr(video);
+ mpeg3video_ext_user_data(video);
+ if(video->found_seqhdr) return 0; /* Exit here */
+ break;
+
+ case MPEG3_SEQUENCE_END_CODE:
+// Continue until the end
+ mpeg3bits_refill(video->vstream);
+ break;
+
+ default:
+ break;
+ }
+ }
+ return 1; /* Shouldn't be reached. */
+}
+
+int mpeg3video_ext_bit_info(mpeg3_slice_buffer_t *slice_buffer)
+{
+ while(mpeg3slice_getbit(slice_buffer)) mpeg3slice_getbyte(slice_buffer);
+ return 0;
+}
+
+/* decode slice header */
+int mpeg3video_getslicehdr(mpeg3_slice_t *slice, mpeg3video_t *video)
+{
+ int slice_vertical_position_extension, intra_slice;
+ int qs;
+
+ slice_vertical_position_extension = (video->mpeg2 && video->vertical_size > 2800) ?
+ mpeg3slice_getbits(slice->slice_buffer, 3) : 0;
+
+ if(video->scalable_mode == SC_DP) slice->pri_brk = mpeg3slice_getbits(slice->slice_buffer, 7);
+
+ qs = mpeg3slice_getbits(slice->slice_buffer, 5);
+ slice->quant_scale = video->mpeg2 ? (video->qscale_type ? mpeg3_non_linear_mquant_table[qs] : (qs << 1)) : qs;
+
+ if(mpeg3slice_getbit(slice->slice_buffer))
+ {
+ intra_slice = mpeg3slice_getbit(slice->slice_buffer);
+ mpeg3slice_getbits(slice->slice_buffer, 7);
+ mpeg3video_ext_bit_info(slice->slice_buffer);
+ }
+ else
+ intra_slice = 0;
+
+ return slice_vertical_position_extension;
+}
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 @@
+#include "idct.h"
+#include <stdlib.h>
+
+/**********************************************************/
+/* inverse two dimensional DCT, Chen-Wang algorithm */
+/* (cf. IEEE ASSP-32, pp. 803-816, Aug. 1984) */
+/* 32-bit integer arithmetic (8 bit coefficients) */
+/* 11 mults, 29 adds per DCT */
+/* sE, 18.8.91 */
+/**********************************************************/
+/* coefficients extended to 12 bit for IEEE1180-1990 */
+/* compliance sE, 2.1.94 */
+/**********************************************************/
+
+/* this code assumes >> to be a two's-complement arithmetic */
+/* right shift: (-2)>>1 == -1 , (-3)>>1 == -2 */
+
+#define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */
+#define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */
+#define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */
+#define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */
+#define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */
+#define W7 565 /* 2048*sqrt(2)*cos(7*pi/16) */
+
+/* row (horizontal) IDCT
+ *
+ * 7 pi 1
+ * dst[k] = sum c[l] * src[l] * cos( -- * ( k + - ) * l )
+ * l=0 8 2
+ *
+ * where: c[0] = 128
+ * c[1..7] = 128*sqrt(2)
+ */
+
+int mpeg3video_idctrow(short *blk)
+{
+ int x0, x1, x2, x3, x4, x5, x6, x7, x8;
+
+ /* shortcut */
+ if (!((x1 = blk[4]<<11) | (x2 = blk[6]) | (x3 = blk[2]) |
+ (x4 = blk[1]) | (x5 = blk[7]) | (x6 = blk[5]) | (x7 = blk[3])))
+ {
+ blk[0]=blk[1]=blk[2]=blk[3]=blk[4]=blk[5]=blk[6]=blk[7]=blk[0]<<3;
+ return 0;
+ }
+
+ x0 = (blk[0]<<11) + 128; /* for proper rounding in the fourth stage */
+
+ /* first stage */
+ x8 = W7*(x4+x5);
+ x4 = x8 + (W1-W7)*x4;
+ x5 = x8 - (W1+W7)*x5;
+ x8 = W3*(x6+x7);
+ x6 = x8 - (W3-W5)*x6;
+ x7 = x8 - (W3+W5)*x7;
+
+ /* second stage */
+ x8 = x0 + x1;
+ x0 -= x1;
+ x1 = W6*(x3+x2);
+ x2 = x1 - (W2+W6)*x2;
+ x3 = x1 + (W2-W6)*x3;
+ x1 = x4 + x6;
+ x4 -= x6;
+ x6 = x5 + x7;
+ x5 -= x7;
+
+ /* third stage */
+ x7 = x8 + x3;
+ x8 -= x3;
+ x3 = x0 + x2;
+ x0 -= x2;
+ x2 = (181*(x4+x5)+128)>>8;
+ x4 = (181*(x4-x5)+128)>>8;
+
+ /* fourth stage */
+ blk[0] = (x7+x1)>>8;
+ blk[1] = (x3+x2)>>8;
+ blk[2] = (x0+x4)>>8;
+ blk[3] = (x8+x6)>>8;
+ blk[4] = (x8-x6)>>8;
+ blk[5] = (x0-x4)>>8;
+ blk[6] = (x3-x2)>>8;
+ blk[7] = (x7-x1)>>8;
+
+ return 1;
+}
+
+/* column (vertical) IDCT
+ *
+ * 7 pi 1
+ * dst[8*k] = sum c[l] * src[8*l] * cos( -- * ( k + - ) * l )
+ * l=0 8 2
+ *
+ * where: c[0] = 1/1024
+ * c[1..7] = (1/1024)*sqrt(2)
+ */
+
+int mpeg3video_idctcol(short *blk)
+{
+ int x0, x1, x2, x3, x4, x5, x6, x7, x8;
+
+ /* shortcut */
+ if (!((x1 = (blk[8 * 4]<<8)) | (x2 = blk[8 * 6]) | (x3 = blk[8 * 2]) |
+ (x4 = blk[8*1]) | (x5 = blk[8 * 7]) | (x6 = blk[8 * 5]) | (x7 = blk[8 * 3]))){
+ blk[8*0]=blk[8*1]=blk[8 * 2]=blk[8 * 3]=blk[8 * 4]=blk[8 * 5]=blk[8 * 6]=blk[8 * 7]=
+ (blk[8*0]+32)>>6;
+ return 0;
+ }
+
+ x0 = (blk[8*0]<<8) + 8192;
+
+ /* first stage */
+ x8 = W7*(x4+x5) + 4;
+ x4 = (x8+(W1-W7)*x4)>>3;
+ x5 = (x8-(W1+W7)*x5)>>3;
+ x8 = W3*(x6+x7) + 4;
+ x6 = (x8-(W3-W5)*x6)>>3;
+ x7 = (x8-(W3+W5)*x7)>>3;
+
+ /* second stage */
+ x8 = x0 + x1;
+ x0 -= x1;
+ x1 = W6*(x3+x2) + 4;
+ x2 = (x1-(W2+W6)*x2)>>3;
+ x3 = (x1+(W2-W6)*x3)>>3;
+ x1 = x4 + x6;
+ x4 -= x6;
+ x6 = x5 + x7;
+ x5 -= x7;
+
+ /* third stage */
+ x7 = x8 + x3;
+ x8 -= x3;
+ x3 = x0 + x2;
+ x0 -= x2;
+ x2 = (181 * (x4 + x5) + 128) >> 8;
+ x4 = (181 * (x4 - x5) + 128) >> 8;
+
+ /* fourth stage */
+ blk[8 * 0] = (x7 + x1) >> 14;
+ blk[8 * 1] = (x3 + x2) >> 14;
+ blk[8 * 2] = (x0 + x4) >> 14;
+ blk[8 * 3] = (x8 + x6) >> 14;
+ blk[8 * 4] = (x8 - x6) >> 14;
+ blk[8 * 5] = (x0 - x4) >> 14;
+ blk[8 * 6] = (x3 - x2) >> 14;
+ blk[8 * 7] = (x7 - x1) >> 14;
+
+ return 1;
+}
+
+
+/* two dimensional inverse discrete cosine transform */
+void mpeg3video_idct_conversion(short* block)
+{
+ int i;
+ for(i = 0; i < 8; i++) mpeg3video_idctrow(block + 8 * i);
+ for(i = 0; i < 8; i++) mpeg3video_idctcol(block + i);
+}
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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef IDCT_H
+#define IDCT_H
+
+
+#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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef LAYERDATA_H
+#define LAYERDATA_H
+
+typedef struct
+{
+/* sequence header */
+ int intra_quantizer_matrix[64], non_intra_quantizer_matrix[64];
+ int chroma_intra_quantizer_matrix[64], chroma_non_intra_quantizer_matrix[64];
+ int mpeg2;
+ int qscale_type, altscan; /* picture coding extension */
+ int pict_scal; /* picture spatial scalable extension */
+ int scalable_mode; /* sequence scalable extension */
+} mpeg3_layerdata_t;
+
+
+#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 @@
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include "mpeg3video.h"
+#include "slice.h"
+#include "vlc.h"
+
+#include <stdio.h>
+
+int mpeg3video_get_macroblock_address(mpeg3_slice_t *slice)
+{
+ int code, val = 0;
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+
+ while((code = mpeg3slice_showbits(slice_buffer, 11)) < 24)
+ {
+/* Is not macroblock_stuffing */
+ if(code != 15)
+ {
+/* Is macroblock_escape */
+ if(code == 8)
+ {
+ val += 33;
+ }
+ else
+ {
+/* fprintf(stderr, "mpeg3video_get_macroblock_address: invalid macroblock_address_increment code\n"); */
+ slice->fault = 1;
+ return 1;
+ }
+ }
+
+ mpeg3slice_flushbits(slice_buffer, 11);
+ }
+
+ if(code >= 1024)
+ {
+ mpeg3slice_flushbit(slice_buffer);
+ return val + 1;
+ }
+
+ if(code >= 128)
+ {
+ code >>= 6;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_MBAtab1[code].len);
+ return val + mpeg3_MBAtab1[code].val;
+ }
+
+ code -= 24;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_MBAtab2[code].len);
+
+ return val + mpeg3_MBAtab2[code].val;
+}
+
+/* macroblock_type for pictures with spatial scalability */
+
+static inline int mpeg3video_getsp_imb_type(mpeg3_slice_t *slice)
+{
+// ### This looks wrong.
+// slice_buffer is used without being initialised and slice is not used
+// mpeg3_slice_buffer_t *slice_buffer = slice_buffer;
+// I think this would make more sense and might be what is intended
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+ unsigned int code = mpeg3slice_showbits(slice_buffer, 4);
+ if(!code)
+ {
+/* fprintf(stderr,"mpeg3video_getsp_imb_type: invalid macroblock_type code\n"); */
+ slice->fault = 1;
+ return 0;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, mpeg3_spIMBtab[code].len);
+ return mpeg3_spIMBtab[code].val;
+}
+
+static inline int mpeg3video_getsp_pmb_type(mpeg3_slice_t *slice)
+{
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+ int code = mpeg3slice_showbits(slice_buffer, 7);
+ if(code < 2)
+ {
+/* fprintf(stderr,"mpeg3video_getsp_pmb_type: invalid macroblock_type code\n"); */
+ slice->fault = 1;
+ return 0;
+ }
+
+ if(code >= 16)
+ {
+ code >>= 3;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_spPMBtab0[code].len);
+
+ return mpeg3_spPMBtab0[code].val;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, mpeg3_spPMBtab1[code].len);
+ return mpeg3_spPMBtab1[code].val;
+}
+
+static inline int mpeg3video_getsp_bmb_type(mpeg3_slice_t *slice)
+{
+ mpeg3_VLCtab_t *p;
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+ int code = mpeg3slice_showbits9(slice_buffer);
+
+ if(code >= 64)
+ p = &mpeg3_spBMBtab0[(code >> 5) - 2];
+ else
+ if(code >= 16)
+ p = &mpeg3_spBMBtab1[(code >> 2) - 4];
+ else
+ if(code >= 8)
+ p = &mpeg3_spBMBtab2[code - 8];
+ else
+ {
+/* fprintf(stderr,"mpeg3video_getsp_bmb_type: invalid macroblock_type code\n"); */
+ slice->fault = 1;
+ return 0;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, p->len);
+ return p->val;
+}
+
+static inline int mpeg3video_get_imb_type(mpeg3_slice_t *slice)
+{
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+ if(mpeg3slice_getbit(slice_buffer))
+ {
+ return 1;
+ }
+
+ if(!mpeg3slice_getbit(slice_buffer))
+ {
+/* fprintf(stderr,"mpeg3video_get_imb_type: invalid macroblock_type code\n"); */
+ slice->fault = 1;
+ }
+
+ return 17;
+}
+
+static inline int mpeg3video_get_pmb_type(mpeg3_slice_t *slice)
+{
+ int code;
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+
+ if((code = mpeg3slice_showbits(slice_buffer, 6)) >= 8)
+ {
+ code >>= 3;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_PMBtab0[code].len);
+ return mpeg3_PMBtab0[code].val;
+ }
+
+ if(code == 0)
+ {
+/* fprintf(stderr,"mpeg3video_get_pmb_type: invalid macroblock_type code\n"); */
+ slice->fault = 1;
+ return 0;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, mpeg3_PMBtab1[code].len);
+ return mpeg3_PMBtab1[code].val;
+}
+
+static inline int mpeg3video_get_bmb_type(mpeg3_slice_t *slice)
+{
+ int code;
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+
+ if((code = mpeg3slice_showbits(slice_buffer, 6)) >= 8)
+ {
+ code >>= 2;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_BMBtab0[code].len);
+ return mpeg3_BMBtab0[code].val;
+ }
+
+ if(code == 0)
+ {
+/* fprintf(stderr,"mpeg3video_get_bmb_type: invalid macroblock_type code\n"); */
+ slice->fault = 1;
+ return 0;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, mpeg3_BMBtab1[code].len);
+
+ return mpeg3_BMBtab1[code].val;
+}
+
+static inline int mpeg3video_get_dmb_type(mpeg3_slice_t *slice)
+{
+ if(!mpeg3slice_getbit(slice->slice_buffer))
+ {
+/* fprintf(stderr,"mpeg3video_get_dmb_type: invalid macroblock_type code\n"); */
+ slice->fault=1;
+ }
+
+ return 1;
+}
+
+
+static inline int mpeg3video_get_snrmb_type(mpeg3_slice_t *slice)
+{
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+ int code = mpeg3slice_showbits(slice_buffer, 3);
+
+ if(code == 0)
+ {
+/* fprintf(stderr,"mpeg3video_get_snrmb_type: invalid macroblock_type code\n"); */
+ slice->fault = 1;
+ return 0;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, mpeg3_SNRMBtab[code].len);
+ return mpeg3_SNRMBtab[code].val;
+}
+
+int mpeg3video_get_mb_type(mpeg3_slice_t *slice, mpeg3video_t *video)
+{
+ if(video->scalable_mode == SC_SNR)
+ {
+ return mpeg3video_get_snrmb_type(slice);
+ }
+ else
+ {
+ switch(video->pict_type)
+ {
+ case I_TYPE: return video->pict_scal ? mpeg3video_getsp_imb_type(slice) : mpeg3video_get_imb_type(slice);
+ case P_TYPE: return video->pict_scal ? mpeg3video_getsp_pmb_type(slice) : mpeg3video_get_pmb_type(slice);
+ case B_TYPE: return video->pict_scal ? mpeg3video_getsp_bmb_type(slice) : mpeg3video_get_bmb_type(slice);
+ case D_TYPE: return mpeg3video_get_dmb_type(slice);
+ default:
+ /*fprintf(stderr, "mpeg3video_getmbtype: unknown coding type\n"); */
+ break;
+/* MPEG-1 only, not implemented */
+ }
+ }
+
+ return 0;
+}
+
+int mpeg3video_macroblock_modes(mpeg3_slice_t *slice,
+ mpeg3video_t *video,
+ int *pmb_type,
+ int *pstwtype,
+ int *pstwclass,
+ int *pmotion_type,
+ int *pmv_count,
+ int *pmv_format,
+ int *pdmv,
+ int *pmvscale,
+ int *pdct_type)
+{
+ int mb_type;
+ int stwtype, stwcode, stwclass;
+ int motion_type = 0, mv_count, mv_format, dmv, mvscale;
+ int dct_type;
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+ static unsigned char stwc_table[3][4]
+ = { {6,3,7,4}, {2,1,5,4}, {2,5,7,4} };
+ static unsigned char stwclass_table[9]
+ = {0, 1, 2, 1, 1, 2, 3, 3, 4};
+
+/* get macroblock_type */
+ mb_type = mpeg3video_get_mb_type(slice, video);
+
+ if(slice->fault) return 1;
+
+/* get spatial_temporal_weight_code */
+ if(mb_type & MB_WEIGHT)
+ {
+ if(video->stwc_table_index == 0)
+ stwtype = 4;
+ else
+ {
+ stwcode = mpeg3slice_getbits2(slice_buffer);
+ stwtype = stwc_table[video->stwc_table_index - 1][stwcode];
+ }
+ }
+ else
+ stwtype = (mb_type & MB_CLASS4) ? 8 : 0;
+
+/* derive spatial_temporal_weight_class (Table 7-18) */
+ stwclass = stwclass_table[stwtype];
+
+/* get frame/field motion type */
+ if(mb_type & (MB_FORWARD | MB_BACKWARD))
+ {
+ if(video->pict_struct == FRAME_PICTURE)
+ {
+/* frame_motion_type */
+ motion_type = video->frame_pred_dct ? MC_FRAME : mpeg3slice_getbits2(slice_buffer);
+ }
+ else
+ {
+/* field_motion_type */
+ motion_type = mpeg3slice_getbits2(slice_buffer);
+ }
+ }
+ else
+ if((mb_type & MB_INTRA) && video->conceal_mv)
+ {
+/* concealment motion vectors */
+ motion_type = (video->pict_struct == FRAME_PICTURE) ? MC_FRAME : MC_FIELD;
+ }
+
+/* derive mv_count, mv_format and dmv, (table 6-17, 6-18) */
+ if(video->pict_struct == FRAME_PICTURE)
+ {
+ mv_count = (motion_type == MC_FIELD && stwclass < 2) ? 2 : 1;
+ mv_format = (motion_type == MC_FRAME) ? MV_FRAME : MV_FIELD;
+ }
+ else
+ {
+ mv_count = (motion_type == MC_16X8) ? 2 : 1;
+ mv_format = MV_FIELD;
+ }
+
+ dmv = (motion_type == MC_DMV); /* dual prime */
+
+/* field mv predictions in frame pictures have to be scaled */
+ mvscale = ((mv_format == MV_FIELD) && (video->pict_struct == FRAME_PICTURE));
+
+/* get dct_type (frame DCT / field DCT) */
+ dct_type = (video->pict_struct == FRAME_PICTURE) &&
+ (!video->frame_pred_dct) &&
+ (mb_type & (MB_PATTERN | MB_INTRA)) ?
+ mpeg3slice_getbit(slice_buffer) : 0;
+
+/* return values */
+ *pmb_type = mb_type;
+ *pstwtype = stwtype;
+ *pstwclass = stwclass;
+ *pmotion_type = motion_type;
+ *pmv_count = mv_count;
+ *pmv_format = mv_format;
+ *pdmv = dmv;
+ *pmvscale = mvscale;
+ *pdct_type = dct_type;
+ return 0;
+}
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 @@
+/*
+ * the input data is tranposed and each 16 bit element in the 8x8 matrix
+ * is left aligned:
+ * for example in 11...1110000 format
+ * If the iDCT is of I macroblock then 0.5 needs to be added to the;DC Component
+ * (element[0][0] of the matrix)
+ */
+
+/* extrn re_matrix */
+
+/* constants */
+
+.data
+ .align 16
+ .type preSC, @object
+preSC: .short 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520
+ .short 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270
+ .short 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906
+ .short 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315
+ .short 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520
+ .short 12873, 17855, 16819, 15137, 25746, 20228, 13933, 7103
+ .short 17734, 24598, 23170, 20853, 17734, 13933, 9597, 4892
+ .short 18081, 25080, 23624, 21261, 18081, 14206, 9785, 4988
+ .size preSC, 128
+ .align 8
+ .type x0005000200010001, @object
+ .size x0005000200010001, 8
+x0005000200010001:
+ .long 0x00010001, 0x00050002
+ .align 8
+ .type x0040000000000000, @object
+ .size x0040000000000000, 8
+x0040000000000000:
+ .long 0, 0x00400000
+ .align 8
+ .type x5a825a825a825a82, @object
+ .size x5a825a825a825a82, 8
+x5a825a825a825a82:
+ .long 0x5a825a82, 0x5a825a82
+ .align 8
+ .type x539f539f539f539f, @object
+ .size x539f539f539f539f, 8
+x539f539f539f539f:
+ .long 0x539f539f, 0x539f539f
+ .align 8
+ .type x4546454645464546, @object
+ .size x4546454645464546, 8
+x4546454645464546:
+ .long 0x45464546, 0x45464546
+ .align 8
+ .type x61f861f861f861f8, @object
+ .size x61f861f861f861f8, 8
+x61f861f861f861f8:
+ .long 0x61f861f8, 0x61f861f8
+/* Static variables */
+ .align 8
+ .type x0, @object
+ .size x0, 8
+x0:
+ .long 0, 0
+/* Procedure */
+
+
+ .align 8
+.text
+ .align 4
+.globl IDCT_mmx
+ .type IDCT_mmx, @function
+IDCT_mmx:
+ pushl %ebp
+ movl %esp, %ebp
+ pushl %ebx
+ pushl %ecx
+ pushl %edx
+ pushl %esi
+ pushl %edi
+
+ pushl $0 /* allocate the temp variables */
+ pushl $0
+ pushl $0
+ pushl $0
+ pushl $0
+ pushl $0
+ pushl $0
+ pushl $0
+
+ movl 8(%ebp), %esi /* source matrix */
+ leal preSC, %ecx
+/* column 0: even part
+ * use V4, V12, V0, V8 to produce V22..V25
+ */
+ movq 8*12(%ecx), %mm0 /* maybe the first mul can be done together */
+ /* with the dequantization in iHuff module */
+ pmulhw 8*12(%esi), %mm0 /* V12 */
+ movq 8*4(%ecx), %mm1
+ pmulhw 8*4(%esi), %mm1 /* V4 */
+ movq (%ecx), %mm3
+ psraw $1, %mm0 /* t64=t66 */
+ pmulhw (%esi), %mm3 /* V0 */
+ movq 8*8(%ecx), %mm5 /* duplicate V4 */
+ movq %mm1, %mm2 /* added 11/1/96 */
+ pmulhw 8*8(%esi),%mm5 /* V8 */
+ psubsw %mm0, %mm1 /* V16 */
+ pmulhw x5a825a825a825a82, %mm1 /* 23170 ->V18 */
+ paddsw %mm0, %mm2 /* V17 */
+ movq %mm2, %mm0 /* duplicate V17 */
+ psraw $1, %mm2 /* t75=t82 */
+ psraw $2, %mm0 /* t72 */
+ movq %mm3, %mm4 /* duplicate V0 */
+ paddsw %mm5, %mm3 /* V19 */
+ psubsw %mm5, %mm4 /* V20 ;mm5 free */
+/* moved from the block below */
+ movq 8*10(%ecx), %mm7
+ psraw $1, %mm3 /* t74=t81 */
+ movq %mm3, %mm6 /* duplicate t74=t81 */
+ psraw $2, %mm4 /* t77=t79 */
+ psubsw %mm0, %mm1 /* V21 ; mm0 free */
+ paddsw %mm2, %mm3 /* V22 */
+ movq %mm1, %mm5 /* duplicate V21 */
+ paddsw %mm4, %mm1 /* V23 */
+ movq %mm3, 8*4(%esi) /* V22 */
+ psubsw %mm5, %mm4 /* V24; mm5 free */
+ movq %mm1, 8*12(%esi) /* V23 */
+ psubsw %mm2, %mm6 /* V25; mm2 free */
+ movq %mm4, (%esi) /* V24 */
+/* keep mm6 alive all along the next block */
+ /* movq %mm6, 8*8(%esi) V25 */
+/* column 0: odd part
+ * use V2, V6, V10, V14 to produce V31, V39, V40, V41
+ */
+/* moved above: movq 8*10(%ecx), %mm7 */
+
+ pmulhw 8*10(%esi), %mm7 /* V10 */
+ movq 8*6(%ecx), %mm0
+ pmulhw 8*6(%esi), %mm0 /* V6 */
+ movq 8*2(%ecx), %mm5
+ movq %mm7, %mm3 /* duplicate V10 */
+ pmulhw 8*2(%esi), %mm5 /* V2 */
+ movq 8*14(%ecx), %mm4
+ psubsw %mm0, %mm7 /* V26 */
+ pmulhw 8*14(%esi), %mm4 /* V14 */
+ paddsw %mm0, %mm3 /* V29 ; free mm0 */
+ movq %mm7, %mm1 /* duplicate V26 */
+ psraw $1, %mm3 /* t91=t94 */
+ pmulhw x539f539f539f539f,%mm7 /* V33 */
+ psraw $1, %mm1 /* t96 */
+ movq %mm5, %mm0 /* duplicate V2 */
+ psraw $2, %mm4 /* t85=t87 */
+ paddsw %mm4,%mm5 /* V27 */
+ psubsw %mm4, %mm0 /* V28 ; free mm4 */
+ movq %mm0, %mm2 /* duplicate V28 */
+ psraw $1, %mm5 /* t90=t93 */
+ pmulhw x4546454645464546,%mm0 /* V35 */
+ psraw $1, %mm2 /* t97 */
+ movq %mm5, %mm4 /* duplicate t90=t93 */
+ psubsw %mm2, %mm1 /* V32 ; free mm2 */
+ pmulhw x61f861f861f861f8,%mm1 /* V36 */
+ psllw $1, %mm7 /* t107 */
+ paddsw %mm3, %mm5 /* V31 */
+ psubsw %mm3, %mm4 /* V30 ; free mm3 */
+ pmulhw x5a825a825a825a82,%mm4 /* V34 */
+ nop
+ psubsw %mm1, %mm0 /* V38 */
+ psubsw %mm7, %mm1 /* V37 ; free mm7 */
+ psllw $1, %mm1 /* t114 */
+/* move from the next block */
+ movq %mm6, %mm3 /* duplicate V25 */
+/* move from the next block */
+ movq 8*4(%esi), %mm7 /* V22 */
+ psllw $1, %mm0 /* t110 */
+ psubsw %mm5, %mm0 /* V39 (mm5 needed for next block) */
+ psllw $2, %mm4 /* t112 */
+/* moved from the next block */
+ movq 8*12(%esi), %mm2 /* V23 */
+ psubsw %mm0, %mm4 /* V40 */
+ paddsw %mm4, %mm1 /* V41; free mm0 */
+/* moved from the next block */
+ psllw $1, %mm2 /* t117=t125 */
+/* column 0: output butterfly */
+/* moved above:
+ * movq %mm6, %mm3 duplicate V25
+ * movq 8*4(%esi), %mm7 V22
+ * movq 8*12(%esi), %mm2 V23
+ * psllw $1, %mm2 t117=t125
+ */
+ psubsw %mm1, %mm6 /* tm6 */
+ paddsw %mm1, %mm3 /* tm8; free mm1 */
+ movq %mm7, %mm1 /* duplicate V22 */
+ paddsw %mm5, %mm7 /* tm0 */
+ movq %mm3, 8*8(%esi) /* tm8; free mm3 */
+ psubsw %mm5, %mm1 /* tm14; free mm5 */
+ movq %mm6, 8*6(%esi) /* tm6; free mm6 */
+ movq %mm2, %mm3 /* duplicate t117=t125 */
+ movq (%esi), %mm6 /* V24 */
+ paddsw %mm0, %mm2 /* tm2 */
+ movq %mm7, (%esi) /* tm0; free mm7 */
+ psubsw %mm0, %mm3 /* tm12; free mm0 */
+ movq %mm1, 8*14(%esi) /* tm14; free mm1 */
+ psllw $1, %mm6 /* t119=t123 */
+ movq %mm2, 8*2(%esi) /* tm2; free mm2 */
+ movq %mm6, %mm0 /* duplicate t119=t123 */
+ movq %mm3, 8*12(%esi) /* tm12; free mm3 */
+ paddsw %mm4, %mm6 /* tm4 */
+/* moved from next block */
+ movq 8*5(%ecx), %mm1
+ psubsw %mm4, %mm0 /* tm10; free mm4 */
+/* moved from next block */
+ pmulhw 8*5(%esi), %mm1 /* V5 */
+ movq %mm6, 8*4(%esi) /* tm4; free mm6 */
+ movq %mm0, 8*10(%esi) /* tm10; free mm0 */
+/* column 1: even part
+ * use V5, V13, V1, V9 to produce V56..V59
+ */
+/* moved to prev block:
+ * movq 8*5(%ecx), %mm1
+ * pmulhw 8*5(%esi), %mm1 V5
+ */
+ movq 8*13(%ecx), %mm7
+ psllw $1, %mm1 /* t128=t130 */
+ pmulhw 8*13(%esi), %mm7 /* V13 */
+ movq %mm1, %mm2 /* duplicate t128=t130 */
+ movq 8(%ecx), %mm3
+ pmulhw 8(%esi), %mm3 /* V1 */
+ movq 8*9(%ecx), %mm5
+ psubsw %mm7, %mm1 /* V50 */
+ pmulhw 8*9(%esi), %mm5 /* V9 */
+ paddsw %mm7, %mm2 /* V51 */
+ pmulhw x5a825a825a825a82, %mm1 /* 23170 ->V52 */
+ movq %mm2, %mm6 /* duplicate V51 */
+ psraw $1, %mm2 /* t138=t144 */
+ movq %mm3, %mm4 /* duplicate V1 */
+ psraw $2, %mm6 /* t136 */
+ paddsw %mm5, %mm3 /* V53 */
+ psubsw %mm5, %mm4 /* V54 ;mm5 free */
+ movq %mm3, %mm7 /* duplicate V53 */
+/* moved from next block */
+ movq 8*11(%ecx), %mm0
+ psraw $1, %mm4 /* t140=t142 */
+ psubsw %mm6, %mm1 /* V55 ; mm6 free */
+ paddsw %mm2, %mm3 /* V56 */
+ movq %mm4, %mm5 /* duplicate t140=t142 */
+ paddsw %mm1, %mm4 /* V57 */
+ movq %mm3, 8*5(%esi) /* V56 */
+ psubsw %mm1, %mm5 /* V58; mm1 free */
+ movq %mm4, 8*13(%esi) /* V57 */
+ psubsw %mm2, %mm7 /* V59; mm2 free */
+ movq %mm5, 8*9(%esi) /* V58 */
+/* keep mm7 alive all along the next block
+ * movq %mm7, 8(%esi) V59
+ * moved above
+ * movq 8*11(%ecx), %mm0
+ */
+ pmulhw 8*11(%esi), %mm0 /* V11 */
+ movq 8*7(%ecx), %mm6
+ pmulhw 8*7(%esi), %mm6 /* V7 */
+ movq 8*15(%ecx), %mm4
+ movq %mm0, %mm3 /* duplicate V11 */
+ pmulhw 8*15(%esi), %mm4 /* V15 */
+ movq 8*3(%ecx), %mm5
+ psllw $1, %mm6 /* t146=t152 */
+ pmulhw 8*3(%esi), %mm5 /* V3 */
+ paddsw %mm6, %mm0 /* V63 */
+/* note that V15 computation has a correction step:
+ * this is a 'magic' constant that rebiases the results to be closer to the
+ * expected result. this magic constant can be refined to reduce the error
+ * even more by doing the correction step in a later stage when the number
+ * is actually multiplied by 16
+ */
+ paddw x0005000200010001, %mm4
+ psubsw %mm6, %mm3 /* V60 ; free mm6 */
+ psraw $1, %mm0 /* t154=t156 */
+ movq %mm3, %mm1 /* duplicate V60 */
+ pmulhw x539f539f539f539f, %mm1 /* V67 */
+ movq %mm5, %mm6 /* duplicate V3 */
+ psraw $2, %mm4 /* t148=t150 */
+ paddsw %mm4, %mm5 /* V61 */
+ psubsw %mm4, %mm6 /* V62 ; free mm4 */
+ movq %mm5, %mm4 /* duplicate V61 */
+ psllw $1, %mm1 /* t169 */
+ paddsw %mm0, %mm5 /* V65 -> result */
+ psubsw %mm0, %mm4 /* V64 ; free mm0 */
+ pmulhw x5a825a825a825a82, %mm4 /* V68 */
+ psraw $1, %mm3 /* t158 */
+ psubsw %mm6, %mm3 /* V66 */
+ movq %mm5, %mm2 /* duplicate V65 */
+ pmulhw x61f861f861f861f8, %mm3 /* V70 */
+ psllw $1, %mm6 /* t165 */
+ pmulhw x4546454645464546, %mm6 /* V69 */
+ psraw $1, %mm2 /* t172 */
+/* moved from next block */
+ movq 8*5(%esi), %mm0 /* V56 */
+ psllw $1, %mm4 /* t174 */
+/* moved from next block */
+ psraw $1, %mm0 /* t177=t188 */
+ nop
+ psubsw %mm3, %mm6 /* V72 */
+ psubsw %mm1, %mm3 /* V71 ; free mm1 */
+ psubsw %mm2, %mm6 /* V73 ; free mm2 */
+/* moved from next block */
+ psraw $1, %mm5 /* t178=t189 */
+ psubsw %mm6, %mm4 /* V74 */
+/* moved from next block */
+ movq %mm0, %mm1 /* duplicate t177=t188 */
+ paddsw %mm4, %mm3 /* V75 */
+/* moved from next block */
+ paddsw %mm5, %mm0 /* tm1 */
+/* location
+ * 5 - V56
+ * 13 - V57
+ * 9 - V58
+ * X - V59, mm7
+ * X - V65, mm5
+ * X - V73, mm6
+ * X - V74, mm4
+ * X - V75, mm3
+ * free mm0, mm1 & mm2
+ * moved above
+ * movq 8*5(%esi), %mm0 V56
+ * psllw $1, %mm0 t177=t188 ! new !!
+ * psllw $1, %mm5 t178=t189 ! new !!
+ * movq %mm0, %mm1 duplicate t177=t188
+ * paddsw %mm5, %mm0 tm1
+ */
+ movq 8*13(%esi), %mm2 /* V57 */
+ psubsw %mm5, %mm1 /* tm15; free mm5 */
+ movq %mm0, 8(%esi) /* tm1; free mm0 */
+ psraw $1, %mm7 /* t182=t184 ! new !! */
+/* save the store as used directly in the transpose
+ * movq %mm1, 120(%esi) tm15; free mm1
+ */
+ movq %mm7, %mm5 /* duplicate t182=t184 */
+ psubsw %mm3, %mm7 /* tm7 */
+ paddsw %mm3, %mm5 /* tm9; free mm3 */
+ movq 8*9(%esi), %mm0 /* V58 */
+ movq %mm2, %mm3 /* duplicate V57 */
+ movq %mm7, 8*7(%esi) /* tm7; free mm7 */
+ psubsw %mm6, %mm3 /* tm13 */
+ paddsw %mm6, %mm2 /* tm3 ; free mm6 */
+/* moved up from the transpose */
+ movq %mm3, %mm7
+/* moved up from the transpose */
+ punpcklwd %mm1, %mm3
+ movq %mm0, %mm6 /* duplicate V58 */
+ movq %mm2, 8*3(%esi) /* tm3; free mm2 */
+ paddsw %mm4, %mm0 /* tm5 */
+ psubsw %mm4, %mm6 /* tm11; free mm4 */
+/* moved up from the transpose */
+ punpckhwd %mm1, %mm7
+ movq %mm0, 8*5(%esi) /* tm5; free mm0 */
+/* moved up from the transpose */
+ movq %mm5, %mm2
+/* transpose - M4 part
+ * --------- ---------
+ * | M1 | M2 | | M1'| M3'|
+ * --------- --> ---------
+ * | M3 | M4 | | M2'| M4'|
+ * --------- ---------
+ * Two alternatives: use full mmword approach so the following code can be
+ * scheduled before the transpose is done without stores, or use the faster
+ * half mmword stores (when possible)
+ */
+ movd %mm3, 8*9+4(%esi) /* MS part of tmt9 */
+ punpcklwd %mm6, %mm5
+ movd %mm7, 8*13+4(%esi) /* MS part of tmt13 */
+ punpckhwd %mm6, %mm2
+ movd %mm5, 8*9(%esi) /* LS part of tmt9 */
+ punpckhdq %mm3, %mm5 /* free mm3 */
+ movd %mm2, 8*13(%esi) /* LS part of tmt13 */
+ punpckhdq %mm7, %mm2 /* free mm7 */
+/* moved up from the M3 transpose */
+ movq 8*8(%esi), %mm0
+/* moved up from the M3 transpose */
+ movq 8*10(%esi), %mm1
+/* moved up from the M3 transpose */
+ movq %mm0, %mm3
+/* shuffle the rest of the data, and write it with 2 mmword writes */
+ movq %mm5, 8*11(%esi) /* tmt11 */
+/* moved up from the M3 transpose */
+ punpcklwd %mm1, %mm0
+ movq %mm2, 8*15(%esi) /* tmt15 */
+/* moved up from the M3 transpose */
+ punpckhwd %mm1, %mm3
+/* transpose - M3 part
+ * moved up to previous code section
+ * movq 8*8(%esi), %mm0
+ * movq 8*10(%esi), %mm1
+ * movq %mm0, %mm3
+ * punpcklwd %mm1, %mm0
+ * punpckhwd %mm1, %mm3
+ */
+ movq 8*12(%esi), %mm6
+ movq 8*14(%esi), %mm4
+ movq %mm6, %mm2
+/* shuffle the data and write the lower parts of the transposed in 4 dwords */
+ punpcklwd %mm4, %mm6
+ movq %mm0, %mm1
+ punpckhdq %mm6, %mm1
+ movq %mm3, %mm7
+ punpckhwd %mm4, %mm2 /* free mm4 */
+ punpckldq %mm6, %mm0 /* free mm6 */
+/* moved from next block */
+ movq 8*13(%esi), %mm4 /* tmt13 */
+ punpckldq %mm2, %mm3
+ punpckhdq %mm2, %mm7 /* free mm2 */
+/* moved from next block */
+ movq %mm3, %mm5 /* duplicate tmt5 */
+/* column 1: even part (after transpose)
+* moved above
+* movq %mm3, %mm5 duplicate tmt5
+* movq 8*13(%esi), %mm4 tmt13
+*/
+ psubsw %mm4, %mm3 /* V134 */
+ pmulhw x5a825a825a825a82, %mm3 /* 23170 ->V136 */
+ movq 8*9(%esi), %mm6 /* tmt9 */
+ paddsw %mm4, %mm5 /* V135 ; mm4 free */
+ movq %mm0, %mm4 /* duplicate tmt1 */
+ paddsw %mm6, %mm0 /* V137 */
+ psubsw %mm6, %mm4 /* V138 ; mm6 free */
+ psllw $2, %mm3 /* t290 */
+ psubsw %mm5, %mm3 /* V139 */
+ movq %mm0, %mm6 /* duplicate V137 */
+ paddsw %mm5, %mm0 /* V140 */
+ movq %mm4, %mm2 /* duplicate V138 */
+ paddsw %mm3, %mm2 /* V141 */
+ psubsw %mm3, %mm4 /* V142 ; mm3 free */
+ movq %mm0, 8*9(%esi) /* V140 */
+ psubsw %mm5, %mm6 /* V143 ; mm5 free */
+/* moved from next block */
+ movq 8*11(%esi), %mm0 /* tmt11 */
+ movq %mm2, 8*13(%esi) /* V141 */
+/* moved from next block */
+ movq %mm0, %mm2 /* duplicate tmt11 */
+/* column 1: odd part (after transpose) */
+/* moved up to the prev block
+ * movq 8*11(%esi), %mm0 tmt11
+ * movq %mm0, %mm2 duplicate tmt11
+ */
+ movq 8*15(%esi), %mm5 /* tmt15 */
+ psubsw %mm7, %mm0 /* V144 */
+ movq %mm0, %mm3 /* duplicate V144 */
+ paddsw %mm7, %mm2 /* V147 ; free mm7 */
+ pmulhw x539f539f539f539f, %mm0 /* 21407-> V151 */
+ movq %mm1, %mm7 /* duplicate tmt3 */
+ paddsw %mm5, %mm7 /* V145 */
+ psubsw %mm5, %mm1 /* V146 ; free mm5 */
+ psubsw %mm1, %mm3 /* V150 */
+ movq %mm7, %mm5 /* duplicate V145 */
+ pmulhw x4546454645464546, %mm1 /* 17734-> V153 */
+ psubsw %mm2, %mm5 /* V148 */
+ pmulhw x61f861f861f861f8, %mm3 /* 25080-> V154 */
+ psllw $2, %mm0 /* t311 */
+ pmulhw x5a825a825a825a82, %mm5 /* 23170-> V152 */
+ paddsw %mm2, %mm7 /* V149 ; free mm2 */
+ psllw $1, %mm1 /* t313 */
+ nop /* without the nop - freeze here for one clock */
+ movq %mm3, %mm2 /* duplicate V154 */
+ psubsw %mm0, %mm3 /* V155 ; free mm0 */
+ psubsw %mm2, %mm1 /* V156 ; free mm2 */
+/* moved from the next block */
+ movq %mm6, %mm2 /* duplicate V143 */
+/* moved from the next block */
+ movq 8*13(%esi), %mm0 /* V141 */
+ psllw $1, %mm1 /* t315 */
+ psubsw %mm7, %mm1 /* V157 (keep V149) */
+ psllw $2, %mm5 /* t317 */
+ psubsw %mm1, %mm5 /* V158 */
+ psllw $1, %mm3 /* t319 */
+ paddsw %mm5, %mm3 /* V159 */
+/* column 1: output butterfly (after transform)
+ * moved to the prev block
+ * movq %mm6, %mm2 duplicate V143
+ * movq 8*13(%esi), %mm0 V141
+ */
+ psubsw %mm3, %mm2 /* V163 */
+ paddsw %mm3, %mm6 /* V164 ; free mm3 */
+ movq %mm4, %mm3 /* duplicate V142 */
+ psubsw %mm5, %mm4 /* V165 ; free mm5 */
+ movq %mm2, (%esp) /* out7 */
+ psraw $4, %mm6
+ psraw $4, %mm4
+ paddsw %mm5, %mm3 /* V162 */
+ movq 8*9(%esi), %mm2 /* V140 */
+ movq %mm0, %mm5 /* duplicate V141 */
+/* in order not to perculate this line up,
+ * we read 72(%esi) very near to this location
+ */
+ movq %mm6, 8*9(%esi) /* out9 */
+ paddsw %mm1, %mm0 /* V161 */
+ movq %mm3, 8(%esp) /* out5 */
+ psubsw %mm1, %mm5 /* V166 ; free mm1 */
+ movq %mm4, 8*11(%esi) /* out11 */
+ psraw $4, %mm5
+ movq %mm0, 16(%esp) /* out3 */
+ movq %mm2, %mm4 /* duplicate V140 */
+ movq %mm5, 8*13(%esi) /* out13 */
+ paddsw %mm7, %mm2 /* V160 */
+/* moved from the next block */
+ movq 8(%esi), %mm0
+ psubsw %mm7, %mm4 /* V167 ; free mm7 */
+/* moved from the next block */
+ movq 8*3(%esi), %mm7
+ psraw $4, %mm4
+ movq %mm2, 24(%esp) /* out1 */
+/* moved from the next block */
+ movq %mm0, %mm1
+ movq %mm4, 8*15(%esi) /* out15 */
+/* moved from the next block */
+ punpcklwd %mm7, %mm0
+/* transpose - M2 parts
+ * moved up to the prev block
+ * movq 8(%esi), %mm0
+ * movq 8*3(%esi), %mm7
+ * movq %mm0, %mm1
+ * punpcklwd %mm7, %mm0
+ */
+ movq 8*5(%esi), %mm5
+ punpckhwd %mm7, %mm1
+ movq 8*7(%esi), %mm4
+ movq %mm5, %mm3
+/* shuffle the data and write the lower parts of the trasposed in 4 dwords */
+ movd %mm0, 8*8(%esi) /* LS part of tmt8 */
+ punpcklwd %mm4, %mm5
+ movd %mm1, 8*12(%esi) /* LS part of tmt12 */
+ punpckhwd %mm4, %mm3
+ movd %mm5, 8*8+4(%esi) /* MS part of tmt8 */
+ punpckhdq %mm5, %mm0 /* tmt10 */
+ movd %mm3, 8*12+4(%esi) /* MS part of tmt12 */
+ punpckhdq %mm3, %mm1 /* tmt14 */
+/* transpose - M1 parts */
+ movq (%esi), %mm7
+ movq 8*2(%esi), %mm2
+ movq %mm7, %mm6
+ movq 8*4(%esi), %mm5
+ punpcklwd %mm2, %mm7
+ movq 8*6(%esi), %mm4
+ punpckhwd %mm2, %mm6 /* free mm2 */
+ movq %mm5, %mm3
+ punpcklwd %mm4, %mm5
+ punpckhwd %mm4, %mm3 /* free mm4 */
+ movq %mm7, %mm2
+ movq %mm6, %mm4
+ punpckldq %mm5, %mm7 /* tmt0 */
+ punpckhdq %mm5, %mm2 /* tmt2 ; free mm5 */
+/* shuffle the rest of the data, and write it with 2 mmword writes */
+ punpckldq %mm3, %mm6 /* tmt4 */
+/* moved from next block */
+ movq %mm2, %mm5 /* duplicate tmt2 */
+ punpckhdq %mm3, %mm4 /* tmt6 ; free mm3 */
+/* moved from next block */
+ movq %mm0, %mm3 /* duplicate tmt10 */
+/* column 0: odd part (after transpose)
+ *moved up to prev block
+ * movq %mm0, %mm3 duplicate tmt10
+ * movq %mm2, %mm5 duplicate tmt2
+ */
+ psubsw %mm4, %mm0 /* V110 */
+ paddsw %mm4, %mm3 /* V113 ; free mm4 */
+ movq %mm0, %mm4 /* duplicate V110 */
+ paddsw %mm1, %mm2 /* V111 */
+ pmulhw x539f539f539f539f, %mm0 /* 21407-> V117 */
+ psubsw %mm1, %mm5 /* V112 ; free mm1 */
+ psubsw %mm5, %mm4 /* V116 */
+ movq %mm2, %mm1 /* duplicate V111 */
+ pmulhw x4546454645464546, %mm5 /* 17734-> V119 */
+ psubsw %mm3, %mm2 /* V114 */
+ pmulhw x61f861f861f861f8, %mm4 /* 25080-> V120 */
+ paddsw %mm3, %mm1 /* V115 ; free mm3 */
+ pmulhw x5a825a825a825a82, %mm2 /* 23170-> V118 */
+ psllw $2, %mm0 /* t266 */
+ movq %mm1, (%esi) /* save V115 */
+ psllw $1, %mm5 /* t268 */
+ psubsw %mm4, %mm5 /* V122 */
+ psubsw %mm0, %mm4 /* V121 ; free mm0 */
+ psllw $1, %mm5 /* t270 */
+ psubsw %mm1, %mm5 /* V123 ; free mm1 */
+ psllw $2, %mm2 /* t272 */
+ psubsw %mm5, %mm2 /* V124 (keep V123) */
+ psllw $1, %mm4 /* t274 */
+ movq %mm5, 8*2(%esi) /* save V123 ; free mm5 */
+ paddsw %mm2, %mm4 /* V125 (keep V124) */
+/* column 0: even part (after transpose) */
+ movq 8*12(%esi), %mm0 /* tmt12 */
+ movq %mm6, %mm3 /* duplicate tmt4 */
+ psubsw %mm0, %mm6 /* V100 */
+ paddsw %mm0, %mm3 /* V101 ; free mm0 */
+ pmulhw x5a825a825a825a82, %mm6 /* 23170 ->V102 */
+ movq %mm7, %mm5 /* duplicate tmt0 */
+ movq 8*8(%esi), %mm1 /* tmt8 */
+ paddsw %mm1, %mm7 /* V103 */
+ psubsw %mm1, %mm5 /* V104 ; free mm1 */
+ movq %mm7, %mm0 /* duplicate V103 */
+ psllw $2, %mm6 /* t245 */
+ paddsw %mm3, %mm7 /* V106 */
+ movq %mm5, %mm1 /* duplicate V104 */
+ psubsw %mm3, %mm6 /* V105 */
+ psubsw %mm3, %mm0 /* V109; free mm3 */
+ paddsw %mm6, %mm5 /* V107 */
+ psubsw %mm6, %mm1 /* V108 ; free mm6 */
+/* column 0: output butterfly (after transform) */
+ movq %mm1, %mm3 /* duplicate V108 */
+ paddsw %mm2, %mm1 /* out4 */
+ psraw $4, %mm1
+ psubsw %mm2, %mm3 /* out10 ; free mm2 */
+ psraw $4, %mm3
+ movq %mm0, %mm6 /* duplicate V109 */
+ movq %mm1, 8*4(%esi) /* out4 ; free mm1 */
+ psubsw %mm4, %mm0 /* out6 */
+ movq %mm3, 8*10(%esi) /* out10 ; free mm3 */
+ psraw $4, %mm0
+ paddsw %mm4, %mm6 /* out8 ; free mm4 */
+ movq %mm7, %mm1 /* duplicate V106 */
+ movq %mm0, 8*6(%esi) /* out6 ; free mm0 */
+ psraw $4, %mm6
+ movq (%esi), %mm4 /* V115 */
+ movq %mm6, 8*8(%esi) /* out8 ; free mm6 */
+ movq %mm5, %mm2 /* duplicate V107 */
+ movq 8*2(%esi), %mm3 /* V123 */
+ paddsw %mm4, %mm7 /* out0 */
+/* moved up from next block */
+ movq 16(%esp), %mm0
+ psraw $4, %mm7
+/* moved up from next block */
+ movq 8(%esp), %mm6
+ psubsw %mm4, %mm1 /* out14 ; free mm4 */
+ paddsw %mm3, %mm5 /* out2 */
+ psraw $4, %mm1
+ movq %mm7, (%esi) /* out0 ; free mm7 */
+ psraw $4, %mm5
+ movq %mm1, 8*14(%esi) /* out14 ; free mm1 */
+ psubsw %mm3, %mm2 /* out12 ; free mm3 */
+ movq %mm5, 8*2(%esi) /* out2 ; free mm5 */
+ psraw $4, %mm2
+/* moved up to the prev block */
+ movq (%esp), %mm4
+/* moved up to the prev block */
+ psraw $4, %mm0
+ movq %mm2, 8*12(%esi) /* out12 ; free mm2 */
+/* moved up to the prev block */
+ psraw $4, %mm6
+/* move back the data to its correct place
+* moved up to the prev block
+ * movq 16(%esp), %mm0
+ * movq 8(%esp), %mm6
+ * movq (%esp), %mm4
+ * psraw $4, %mm0
+ * psraw $4, %mm6
+*/
+ movq 24(%esp), %mm1
+ psraw $4, %mm4
+ movq %mm0, 8*3(%esi) /* out3 */
+ psraw $4, %mm1
+ movq %mm6, 8*5(%esi) /* out5 */
+ movq %mm4, 8*7(%esi) /* out7 */
+ movq %mm1, 8(%esi) /* out1 */
+
+ popl %edi /* Pop off the temp variables */
+ popl %edi
+ popl %edi
+ popl %edi
+ popl %edi
+ popl %edi
+ popl %edi
+ popl %edi
+
+ popl %edi /* Pop off the old variables */
+ popl %esi
+ popl %edx
+ popl %ecx
+ popl %ebx
+ movl %ebp, %esp
+ popl %ebp
+
+ ret
+.Lfe1:
+ .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 @@
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+
+#include <stdio.h>
+#include <string.h>
+
+int mpeg3_mmx_test()
+{
+ int result = 0;
+ FILE *proc;
+ char string[MPEG3_STRLEN];
+
+
+#ifdef HAVE_MMX
+ if(!(proc = fopen(MPEG3_PROC_CPUINFO, "r")))
+ {
+ return 0;
+ }
+
+ while(!feof(proc))
+ {
+ fgets(string, MPEG3_STRLEN, proc);
+/* Got the flags line */
+ if(!strncmp(string, "flags", 5))
+ {
+ char *needle;
+ needle = strstr(string, "mmx");
+ if(!needle) return 0;
+ if(!strncmp(needle, "mmx", 3)) return 1;
+ }
+ }
+#endif
+
+ return 0;
+}
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 @@
+#include "mpeg3video.h"
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include "vlc.h"
+
+#include <stdio.h>
+
+
+/* calculate motion vector component */
+
+static inline void mpeg3video_calc_mv(int *pred, int r_size, int motion_code, int motion_r, int full_pel_vector)
+{
+ int lim = 16 << r_size;
+ int vec = full_pel_vector ? (*pred >> 1) : (*pred);
+
+ if(motion_code > 0)
+ {
+ vec += ((motion_code - 1) << r_size) + motion_r + 1;
+ if(vec >= lim) vec -= lim + lim;
+ }
+ else
+ if(motion_code < 0)
+ {
+ vec -= ((-motion_code - 1) << r_size) + motion_r + 1;
+ if(vec < -lim) vec += lim + lim;
+ }
+ *pred = full_pel_vector ? (vec << 1) : vec;
+}
+
+
+/*
+int *dmvector, * differential motion vector *
+int mvx, int mvy * decoded mv components (always in field format) *
+*/
+void mpeg3video_calc_dmv(mpeg3video_t *video,
+ int DMV[][2],
+ int *dmvector,
+ int mvx,
+ int mvy)
+{
+ if(video->pict_struct == FRAME_PICTURE)
+ {
+ if(video->topfirst)
+ {
+/* vector for prediction of top field from bottom field */
+ DMV[0][0] = ((mvx + (mvx>0)) >> 1) + dmvector[0];
+ DMV[0][1] = ((mvy + (mvy>0)) >> 1) + dmvector[1] - 1;
+
+/* vector for prediction of bottom field from top field */
+ DMV[1][0] = ((3 * mvx + (mvx > 0)) >> 1) + dmvector[0];
+ DMV[1][1] = ((3 * mvy + (mvy > 0)) >> 1) + dmvector[1] + 1;
+ }
+ else
+ {
+/* vector for prediction of top field from bottom field */
+ DMV[0][0] = ((3 * mvx + (mvx>0)) >> 1) + dmvector[0];
+ DMV[0][1] = ((3 * mvy + (mvy>0)) >> 1) + dmvector[1] - 1;
+
+/* vector for prediction of bottom field from top field */
+ DMV[1][0] = ((mvx + (mvx>0)) >> 1) + dmvector[0];
+ DMV[1][1] = ((mvy + (mvy>0)) >> 1) + dmvector[1] + 1;
+ }
+ }
+ else
+ {
+/* vector for prediction from field of opposite 'parity' */
+ DMV[0][0] = ((mvx + (mvx > 0)) >> 1) + dmvector[0];
+ DMV[0][1] = ((mvy + (mvy > 0)) >> 1) + dmvector[1];
+
+/* correct for vertical field shift */
+ if(video->pict_struct == TOP_FIELD)
+ DMV[0][1]--;
+ else
+ DMV[0][1]++;
+ }
+}
+
+static inline int mpeg3video_get_mv(mpeg3_slice_t *slice)
+{
+ int code;
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+
+ if(mpeg3slice_getbit(slice_buffer))
+ {
+ return 0;
+ }
+
+ if((code = mpeg3slice_showbits9(slice_buffer)) >= 64)
+ {
+ code >>= 6;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_MVtab0[code].len);
+ return mpeg3slice_getbit(slice_buffer) ? -mpeg3_MVtab0[code].val : mpeg3_MVtab0[code].val;
+ }
+
+ if(code >= 24)
+ {
+ code >>= 3;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_MVtab1[code].len);
+ return mpeg3slice_getbit(slice_buffer) ? -mpeg3_MVtab1[code].val : mpeg3_MVtab1[code].val;
+ }
+
+ if((code -= 12) < 0)
+ {
+/* fprintf(stdout,"mpeg3video_get_mv: invalid motion_vector code\n"); */
+ slice->fault = 1;
+ return 1;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, mpeg3_MVtab2[code].len);
+ return mpeg3slice_getbit(slice_buffer) ? -mpeg3_MVtab2[code].val : mpeg3_MVtab2[code].val;
+}
+
+/* get differential motion vector (for dual prime prediction) */
+
+static inline int mpeg3video_get_dmv(mpeg3_slice_t *slice)
+{
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+ if(mpeg3slice_getbit(slice_buffer))
+ {
+ return mpeg3slice_getbit(slice_buffer) ? -1 : 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+
+
+/* get and decode motion vector and differential motion vector */
+
+void mpeg3video_motion_vector(mpeg3_slice_t *slice,
+ mpeg3video_t *video,
+ int *PMV,
+ int *dmvector,
+ int h_r_size,
+ int v_r_size,
+ int dmv,
+ int mvscale,
+ int full_pel_vector)
+{
+ int motion_r;
+ int motion_code = mpeg3video_get_mv(slice);
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+
+ if(slice->fault) return;
+ motion_r = (h_r_size != 0 && motion_code != 0) ? mpeg3slice_getbits(slice_buffer, h_r_size) : 0;
+
+ mpeg3video_calc_mv(&PMV[0], h_r_size, motion_code, motion_r, full_pel_vector);
+
+ if(dmv) dmvector[0] = mpeg3video_get_dmv(slice);
+
+ motion_code = mpeg3video_get_mv(slice);
+ if(slice->fault) return;
+ motion_r = (v_r_size != 0 && motion_code != 0) ? mpeg3slice_getbits(slice_buffer, v_r_size) : 0;
+
+/* DIV 2 */
+ if(mvscale) PMV[1] >>= 1;
+
+ mpeg3video_calc_mv(&PMV[1], v_r_size, motion_code, motion_r, full_pel_vector);
+
+ if(mvscale) PMV[1] <<= 1;
+ if(dmv) dmvector[1] = mpeg3video_get_dmv(slice);
+}
+
+int mpeg3video_motion_vectors(mpeg3_slice_t *slice,
+ mpeg3video_t *video,
+ int PMV[2][2][2],
+ int dmvector[2],
+ int mv_field_sel[2][2],
+ int s,
+ int mv_count,
+ int mv_format,
+ int h_r_size,
+ int v_r_size,
+ int dmv,
+ int mvscale)
+{
+ int result = 0;
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+ if(mv_count == 1)
+ {
+ if(mv_format == MV_FIELD && !dmv)
+ {
+ mv_field_sel[1][s] = mv_field_sel[0][s] = mpeg3slice_getbit(slice_buffer);
+ }
+
+ mpeg3video_motion_vector(slice,
+ video,
+ PMV[0][s],
+ dmvector,
+ h_r_size,
+ v_r_size,
+ dmv,
+ mvscale,
+ 0);
+ if(slice->fault) return 1;
+
+/* update other motion vector predictors */
+ PMV[1][s][0] = PMV[0][s][0];
+ PMV[1][s][1] = PMV[0][s][1];
+ }
+ else
+ {
+ mv_field_sel[0][s] = mpeg3slice_getbit(slice_buffer);
+ mpeg3video_motion_vector(slice,
+ video,
+ PMV[0][s],
+ dmvector,
+ h_r_size,
+ v_r_size,
+ dmv,
+ mvscale,
+ 0);
+ if(slice->fault) return 1;
+
+ mv_field_sel[1][s] = mpeg3slice_getbit(slice_buffer);
+ mpeg3video_motion_vector(slice,
+ video,
+ PMV[1][s],
+ dmvector,
+ h_r_size,
+ v_r_size,
+ dmv,
+ mvscale,
+ 0);
+ if(slice->fault) return 1;
+ }
+ return 0;
+}
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 @@
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include "mpeg3video.h"
+#include "mpeg3videoprotos.h"
+#include <stdlib.h>
+
+unsigned char mpeg3_zig_zag_scan_mmx[64] =
+{
+ 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*/,
+ 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*/,
+ 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*/,
+ 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*/,
+ 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*/,
+ 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*/,
+ 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*/,
+ 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*/
+};
+
+/* alternate scan */
+unsigned char mpeg3_alternate_scan_mmx[64] =
+{
+ 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*/,
+ 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*/,
+ 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*/,
+ 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*/,
+ 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*/,
+ 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*/,
+ 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*/,
+ 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*/
+};
+
+
+
+/* zig-zag scan */
+unsigned char mpeg3_zig_zag_scan_nommx[64] =
+{
+ 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
+ 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
+ 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
+ 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
+};
+
+/* alternate scan */
+unsigned char mpeg3_alternate_scan_nommx[64] =
+{
+ 0, 8, 16, 24, 1, 9, 2, 10, 17, 25, 32, 40, 48, 56, 57, 49,
+ 41, 33, 26, 18, 3, 11, 4, 12, 19, 27, 34, 42, 50, 58, 35, 43,
+ 51, 59, 20, 28, 5, 13, 6, 14, 21, 29, 36, 44, 52, 60, 37, 45,
+ 53, 61, 22, 30, 7, 15, 23, 31, 38, 46, 54, 62, 39, 47, 55, 63
+};
+
+/* default intra quantization matrix */
+unsigned char mpeg3_default_intra_quantizer_matrix[64] =
+{
+ 8, 16, 19, 22, 26, 27, 29, 34,
+ 16, 16, 22, 24, 27, 29, 34, 37,
+ 19, 22, 26, 27, 29, 34, 34, 38,
+ 22, 22, 26, 27, 29, 34, 37, 40,
+ 22, 26, 27, 29, 32, 35, 40, 48,
+ 26, 27, 29, 32, 35, 40, 48, 58,
+ 26, 27, 29, 34, 38, 46, 56, 69,
+ 27, 29, 35, 38, 46, 56, 69, 83
+};
+
+unsigned char mpeg3_non_linear_mquant_table[32] =
+{
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 10, 12, 14, 16, 18, 20, 22,
+ 24, 28, 32, 36, 40, 44, 48, 52,
+ 56, 64, 72, 80, 88, 96, 104, 112
+};
+
+double mpeg3_frame_rate_table[16] =
+{
+ 0.0, /* Pad */
+ 24000.0/1001.0, /* Official frame rates */
+ 24.0,
+ 25.0,
+ 30000.0/1001.0,
+ 30.0,
+ 50.0,
+ ((60.0*1000.0)/1001.0),
+ 60.0,
+
+ 1, /* Unofficial economy rates */
+ 5,
+ 10,
+ 12,
+ 15,
+ 0,
+ 0,
+};
+
+int mpeg3video_initdecoder(mpeg3video_t *video)
+{
+ int blk_cnt_tab[3] = {6, 8, 12};
+ int cc;
+ int i;
+ long size[4], padding[2]; /* Size of Y, U, and V buffers */
+
+ if(!video->mpeg2)
+ {
+/* force MPEG-1 parameters */
+ video->prog_seq = 1;
+ video->prog_frame = 1;
+ video->pict_struct = FRAME_PICTURE;
+ video->frame_pred_dct = 1;
+ video->chroma_format = CHROMA420;
+ video->matrix_coefficients = 5;
+ }
+
+/* Get dimensions rounded to nearest multiple of coded macroblocks */
+ video->mb_width = (video->horizontal_size + 15) / 16;
+ video->mb_height = (video->mpeg2 && !video->prog_seq) ?
+ (2 * ((video->vertical_size + 31) / 32)) :
+ ((video->vertical_size + 15) / 16);
+ video->coded_picture_width = 16 * video->mb_width;
+ video->coded_picture_height = 16 * video->mb_height;
+ video->chrom_width = (video->chroma_format == CHROMA444) ?
+ video->coded_picture_width :
+ (video->coded_picture_width >> 1);
+ video->chrom_height = (video->chroma_format != CHROMA420) ?
+ video->coded_picture_height :
+ (video->coded_picture_height >> 1);
+ video->blk_cnt = blk_cnt_tab[video->chroma_format - 1];
+
+/* Get sizes of YUV buffers */
+ padding[0] = 16 * video->coded_picture_width;
+ size[0] = video->coded_picture_width * video->coded_picture_height + padding[0] * 2;
+
+ padding[1] = 16 * video->chrom_width;
+ size[1] = video->chrom_width * video->chrom_height + 2 * padding[1];
+
+ size[2] = (video->llw * video->llh);
+ size[3] = (video->llw * video->llh) / 4;
+
+/* Allocate contiguous fragments for YUV buffers for hardware YUV decoding */
+ video->yuv_buffer[0] = (unsigned char*)calloc(1, (size[0] + padding[0]) + 2 * (size[1] + padding[1]));
+ video->yuv_buffer[1] = (unsigned char*)calloc(1, (size[0] + padding[0]) + 2 * (size[1] + padding[1]));
+ video->yuv_buffer[2] = (unsigned char*)calloc(1, (size[0] + padding[0]) + 2 * (size[1] + padding[1]));
+
+ if(video->scalable_mode == SC_SPAT)
+ {
+ video->yuv_buffer[3] = (unsigned char*)calloc(1, size[2] + 2 * size[3]);
+ video->yuv_buffer[4] = (unsigned char*)calloc(1, size[2] + 2 * size[3]);
+ }
+
+/* Direct pointers to areas of contiguous fragments in YVU order per Microsoft */
+ for(cc = 0; cc < 3; cc++)
+ {
+ video->llframe0[cc] = 0;
+ video->llframe1[cc] = 0;
+ video->newframe[cc] = 0;
+ }
+
+ video->refframe[0] = video->yuv_buffer[0];
+ video->oldrefframe[0] = video->yuv_buffer[1];
+ video->auxframe[0] = video->yuv_buffer[2];
+ video->refframe[2] = video->yuv_buffer[0] + size[0] + padding[0];
+ video->oldrefframe[2] = video->yuv_buffer[1] + size[0] + padding[0];
+ video->auxframe[2] = video->yuv_buffer[2] + size[0] + padding[0];
+ video->refframe[1] = video->yuv_buffer[0] + size[0] + padding[0] + size[1] + padding[1];
+ video->oldrefframe[1] = video->yuv_buffer[1] + size[0] + padding[0] + size[1] + padding[1];
+ video->auxframe[1] = video->yuv_buffer[2] + size[0] + padding[0] + size[1] + padding[1];
+
+ if(video->scalable_mode == SC_SPAT)
+ {
+/* this assumes lower layer is 4:2:0 */
+ video->llframe0[0] = video->yuv_buffer[3] + padding[0] ;
+ video->llframe1[0] = video->yuv_buffer[4] + padding[0] ;
+ video->llframe0[2] = video->yuv_buffer[3] + padding[1] + size[2] ;
+ video->llframe1[2] = video->yuv_buffer[4] + padding[1] + size[2] ;
+ video->llframe0[1] = video->yuv_buffer[3] + padding[1] + size[2] + size[3];
+ video->llframe1[1] = video->yuv_buffer[4] + padding[1] + size[2] + size[3];
+ }
+
+/* Initialize the YUV tables for software YUV decoding */
+ video->cr_to_r = (long*)malloc(sizeof(long) * 256);
+ video->cr_to_g = (long*)malloc(sizeof(long) * 256);
+ video->cb_to_g = (long*)malloc(sizeof(long) * 256);
+ video->cb_to_b = (long*)malloc(sizeof(long) * 256);
+ video->cr_to_r_ptr = video->cr_to_r + 128;
+ video->cr_to_g_ptr = video->cr_to_g + 128;
+ video->cb_to_g_ptr = video->cb_to_g + 128;
+ video->cb_to_b_ptr = video->cb_to_b + 128;
+
+ for(i = -128; i < 128; i++)
+ {
+ video->cr_to_r_ptr[i] = (long)( 1.371 * 65536 * i);
+ video->cr_to_g_ptr[i] = (long)(-0.698 * 65536 * i);
+ video->cb_to_g_ptr[i] = (long)(-0.336 * 65536 * i);
+ video->cb_to_b_ptr[i] = (long)( 1.732 * 65536 * i);
+ }
+
+ return 0;
+}
+
+int mpeg3video_deletedecoder(mpeg3video_t *video)
+{
+ int i, padding;
+
+ free(video->yuv_buffer[0]);
+ free(video->yuv_buffer[1]);
+ free(video->yuv_buffer[2]);
+
+ if(video->llframe0[0])
+ {
+ free(video->yuv_buffer[3]);
+ free(video->yuv_buffer[4]);
+ }
+
+ free(video->cr_to_r);
+ free(video->cr_to_g);
+ free(video->cb_to_g);
+ free(video->cb_to_b);
+ return 0;
+}
+
+void mpeg3video_init_scantables(mpeg3video_t *video)
+{
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ {
+ video->mpeg3_zigzag_scan_table = mpeg3_zig_zag_scan_mmx;
+ video->mpeg3_alternate_scan_table = mpeg3_alternate_scan_mmx;
+ }
+ else
+#endif
+ {
+ video->mpeg3_zigzag_scan_table = mpeg3_zig_zag_scan_nommx;
+ video->mpeg3_alternate_scan_table = mpeg3_alternate_scan_nommx;
+ }
+}
+
+mpeg3video_t* mpeg3video_allocate_struct(mpeg3_t *file, mpeg3_vtrack_t *track)
+{
+ int i;
+ mpeg3video_t *video = (mpeg3video_t*)calloc(1, sizeof(mpeg3video_t));
+ pthread_mutexattr_t mutex_attr;
+
+ video->file = file;
+ video->track = track;
+ video->vstream = mpeg3bits_new_stream(file, track->demuxer);
+ video->last_number = -1;
+
+/* First frame is all green */
+ video->framenum = -1;
+ video->have_mmx = file->have_mmx;
+
+ video->percentage_seek = -1;
+ video->frame_seek = -1;
+
+ mpeg3video_init_scantables(video);
+ mpeg3video_init_output();
+
+ pthread_mutexattr_init(&mutex_attr);
+ pthread_mutex_init(&(video->test_lock), &mutex_attr);
+ pthread_mutex_init(&(video->slice_lock), &mutex_attr);
+ return video;
+}
+
+int mpeg3video_delete_struct(mpeg3video_t *video)
+{
+ int i;
+ mpeg3bits_delete_stream(video->vstream);
+ pthread_mutex_destroy(&(video->test_lock));
+ pthread_mutex_destroy(&(video->slice_lock));
+ if(video->x_table)
+ {
+ free(video->x_table);
+ free(video->y_table);
+ }
+ if(video->total_slice_decoders)
+ {
+ for(i = 0; i < video->total_slice_decoders; i++)
+ mpeg3_delete_slice_decoder(&video->slice_decoders[i]);
+ }
+ for(i = 0; i < video->slice_buffers_initialized; i++)
+ mpeg3_delete_slice_buffer(&(video->slice_buffers[i]));
+
+ free(video);
+}
+
+
+int mpeg3video_read_frame_backend(mpeg3video_t *video, int skip_bframes)
+{
+ int result = 0;
+
+ if(mpeg3bits_eof(video->vstream)) result = 1;
+
+ if(!result) result = mpeg3video_get_header(video, 0);
+
+//printf("frame type %d\n", video->pict_type);
+/* skip_bframes is the number of bframes we can skip successfully. */
+/* This is in case a skipped B-frame is repeated and the second repeat happens */
+/* to be a B frame we need. */
+ video->skip_bframes = skip_bframes;
+
+ if(!result)
+ result = mpeg3video_getpicture(video, video->framenum);
+
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ __asm__ __volatile__ ("emms");
+#endif
+
+ if(!result)
+ {
+ video->last_number = video->framenum;
+ video->framenum++;
+ }
+ return result;
+}
+
+int* mpeg3video_get_scaletable(int input_w, int output_w)
+{
+ int *result = (int*)malloc(sizeof(int) * output_w);
+ float i;
+ float scale = (float)input_w / output_w;
+ for(i = 0; i < output_w; i++)
+ {
+ result[(int)i] = (int)(scale * i);
+ }
+ return result;
+}
+
+/* Get the first frame read. */
+int mpeg3video_get_firstframe(mpeg3video_t *video)
+{
+ int result = 0;
+ if(video->framenum < 0)
+ {
+ video->repeat_count = video->current_repeat = 0;
+ result = mpeg3video_read_frame_backend(video, 0);
+ mpeg3bits_seek_byte(video->vstream, 0);
+ mpeg3video_match_refframes(video);
+ }
+ return result;
+}
+
+
+/* ======================================================================= */
+/* ENTRY POINTS */
+/* ======================================================================= */
+
+
+
+mpeg3video_t* mpeg3video_new(mpeg3_t *file, mpeg3_vtrack_t *track)
+{
+ mpeg3video_t *video;
+ int result = 0;
+
+ video = mpeg3video_allocate_struct(file, track);
+ result = mpeg3video_get_header(video, 1);
+
+ if(!result)
+ {
+ int hour, minute, second, frame;
+ int gop_found;
+
+ mpeg3video_initdecoder(video);
+ video->decoder_initted = 1;
+ track->width = video->horizontal_size;
+ track->height = video->vertical_size;
+ track->frame_rate = video->frame_rate;
+
+/* Get the length of the file from an elementary stream */
+ if(file->is_video_stream)
+ {
+/* Load the first GOP */
+ mpeg3bits_seek_start(video->vstream);
+ result = mpeg3video_next_code(video->vstream, MPEG3_GOP_START_CODE);
+ if(!result) mpeg3bits_getbits(video->vstream, 32);
+ if(!result) result = mpeg3video_getgophdr(video);
+
+ hour = video->gop_timecode.hour;
+ minute = video->gop_timecode.minute;
+ second = video->gop_timecode.second;
+ frame = video->gop_timecode.frame;
+ video->first_frame = (long)(hour * 3600 * video->frame_rate +
+ minute * 60 * video->frame_rate +
+ second * video->frame_rate +
+ frame);
+
+/* GOPs always have 16 frames */
+ video->frames_per_gop = 16;
+
+/* Read the last GOP in the file by seeking backward. */
+ mpeg3bits_seek_end(video->vstream);
+ mpeg3bits_start_reverse(video->vstream);
+ result = mpeg3video_prev_code(video->vstream, MPEG3_GOP_START_CODE);
+ mpeg3bits_start_forward(video->vstream);
+ mpeg3bits_getbits(video->vstream, 8);
+ if(!result) result = mpeg3video_getgophdr(video);
+
+ hour = video->gop_timecode.hour;
+ minute = video->gop_timecode.minute;
+ second = video->gop_timecode.second;
+ frame = video->gop_timecode.frame;
+
+ video->last_frame = (long)(hour * 3600 * video->frame_rate +
+ minute * 60 * video->frame_rate +
+ second * video->frame_rate +
+ frame);
+
+/* Count number of frames to end */
+ while(!result)
+ {
+ result = mpeg3video_next_code(video->vstream, MPEG3_PICTURE_START_CODE);
+ if(!result)
+ {
+ mpeg3bits_getbyte_noptr(video->vstream);
+ video->last_frame++;
+ }
+ }
+
+ track->total_frames = video->last_frame - video->first_frame + 1;
+ mpeg3bits_seek_start(video->vstream);
+ }
+ else
+ {
+/* Gross approximation from a multiplexed file. */
+ video->first_frame = 0;
+ track->total_frames = video->last_frame =
+ (long)(mpeg3demux_length(video->vstream->demuxer) *
+ video->frame_rate);
+ video->first_frame = 0;
+ }
+
+ video->maxframe = track->total_frames;
+ mpeg3bits_seek_start(video->vstream);
+ }
+ else
+ {
+ mpeg3video_delete(video);
+ video = 0;
+ }
+
+ return video;
+}
+
+int mpeg3video_delete(mpeg3video_t *video)
+{
+ if(video->decoder_initted)
+ {
+ mpeg3video_deletedecoder(video);
+ }
+ mpeg3video_delete_struct(video);
+ return 0;
+}
+
+int mpeg3video_set_cpus(mpeg3video_t *video, int cpus)
+{
+ return 0;
+}
+
+int mpeg3video_set_mmx(mpeg3video_t *video, int use_mmx)
+{
+ video->have_mmx = use_mmx;
+ mpeg3video_init_scantables(video);
+ return 0;
+}
+
+int mpeg3video_seek_percentage(mpeg3video_t *video, double percentage)
+{
+ video->percentage_seek = percentage;
+ return 0;
+}
+
+int mpeg3video_previous_frame(mpeg3video_t *video)
+{
+ if(mpeg3bits_tell_percentage(video->vstream) <= 0) return 1;
+ mpeg3bits_start_reverse(video->vstream);
+ mpeg3video_prev_code(video->vstream, MPEG3_PICTURE_START_CODE);
+ mpeg3bits_getbits_reverse(video->vstream, 32);
+
+ if(mpeg3bits_bof(video->vstream)) mpeg3bits_seek_percentage(video->vstream, 0);
+ mpeg3bits_start_forward(video->vstream);
+ video->repeat_count = 0;
+ return 0;
+}
+
+int mpeg3video_seek_frame(mpeg3video_t *video, long frame)
+{
+ video->frame_seek = frame;
+ return 0;
+}
+
+/* Read all the way up to and including the next picture start code */
+int mpeg3video_read_raw(mpeg3video_t *video, unsigned char *output, long *size, long max_size)
+{
+ unsigned MPEG3_INT32 code = 0;
+ mpeg3_bits_t *vstream = video->vstream;
+
+ *size = 0;
+ while(code != MPEG3_PICTURE_START_CODE &&
+ code != MPEG3_SEQUENCE_END_CODE &&
+ *size < max_size &&
+ !mpeg3bits_eof(vstream))
+ {
+ code <<= 8;
+ *output = mpeg3bits_getbyte_noptr(vstream);
+ code |= *output++;
+ (*size)++;
+ }
+ return mpeg3bits_eof(vstream);
+}
+
+int mpeg3video_read_frame(mpeg3video_t *video,
+ long frame_number,
+ unsigned char **output_rows,
+ int in_x,
+ int in_y,
+ int in_w,
+ int in_h,
+ int out_w,
+ int out_h,
+ int color_model)
+{
+ int result = 0;
+
+ video->want_yvu = 0;
+ video->output_rows = output_rows;
+ video->color_model = color_model;
+
+/* Get scaling tables */
+ if(video->out_w != out_w || video->out_h != out_h ||
+ video->in_w != in_w || video->in_h != in_h ||
+ video->in_x != in_x || video->in_y != in_y)
+ {
+ if(video->x_table)
+ {
+ free(video->x_table);
+ free(video->y_table);
+ video->x_table = 0;
+ video->y_table = 0;
+ }
+ }
+
+ video->out_w = out_w;
+ video->out_h = out_h;
+ video->in_w = in_w;
+ video->in_h = in_h;
+ video->in_x = in_x;
+ video->in_y = in_y;
+
+ if(!video->x_table)
+ {
+ video->x_table = mpeg3video_get_scaletable(video->in_w, video->out_w);
+ video->y_table = mpeg3video_get_scaletable(video->in_h, video->out_h);
+ }
+
+ mpeg3video_get_firstframe(video);
+
+ if(!result) result = mpeg3video_seek(video);
+
+ if(!result) result = mpeg3video_read_frame_backend(video, 0);
+
+ if(video->output_src) mpeg3video_present_frame(video);
+
+ video->percentage_seek = -1;
+ return result;
+}
+
+int mpeg3video_read_yuvframe(mpeg3video_t *video,
+ long frame_number,
+ char *y_output,
+ char *u_output,
+ char *v_output,
+ int in_x,
+ int in_y,
+ int in_w,
+ int in_h)
+{
+ int result = 0;
+
+ video->want_yvu = 1;
+ video->y_output = y_output;
+ video->u_output = u_output;
+ video->v_output = v_output;
+ video->in_x = in_x;
+ video->in_y = in_y;
+ video->in_w = in_w;
+ video->in_h = in_h;
+
+ mpeg3video_get_firstframe(video);
+
+ if(!result) result = mpeg3video_seek(video);
+
+ if(!result) result = mpeg3video_read_frame_backend(video, 0);
+
+ if(video->output_src) mpeg3video_present_frame(video);
+
+ video->want_yvu = 0;
+ video->percentage_seek = -1;
+ return result;
+}
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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef MPEGVIDEO_H
+#define MPEGVIDEO_H
+
+#include "../bitstream.h"
+#include "../mpeg3private.inc"
+#include "idct.h"
+#include "slice.h"
+#include "../timecode.h"
+
+/* zig-zag scan */
+extern unsigned char mpeg3_zig_zag_scan_nommx[64];
+extern unsigned char mpeg3_zig_zag_scan_mmx[64];
+
+/* alternate scan */
+extern unsigned char mpeg3_alternate_scan_nommx[64];
+extern unsigned char mpeg3_alternate_scan_mmx[64];
+
+/* default intra quantization matrix */
+extern unsigned char mpeg3_default_intra_quantizer_matrix[64];
+
+/* Frame rate table must agree with the one in the encoder */
+extern double mpeg3_frame_rate_table[16];
+
+/* non-linear quantization coefficient table */
+extern unsigned char mpeg3_non_linear_mquant_table[32];
+
+#define CHROMA420 1 /* chroma_format */
+#define CHROMA422 2
+#define CHROMA444 3
+
+#define TOP_FIELD 1 /* picture structure */
+#define BOTTOM_FIELD 2
+#define FRAME_PICTURE 3
+
+#define SEQ_ID 1 /* extension start code IDs */
+#define DISP_ID 2
+#define QUANT_ID 3
+#define SEQSCAL_ID 5
+#define PANSCAN_ID 7
+#define CODING_ID 8
+#define SPATSCAL_ID 9
+#define TEMPSCAL_ID 10
+
+#define ERROR (-1)
+
+#define SC_NONE 0 /* scalable_mode */
+#define SC_DP 1
+#define SC_SPAT 2
+#define SC_SNR 3
+#define SC_TEMP 4
+
+#define I_TYPE 1 /* picture coding type */
+#define P_TYPE 2
+#define B_TYPE 3
+#define D_TYPE 4
+
+#define MB_INTRA 1 /* macroblock type */
+#define MB_PATTERN 2
+#define MB_BACKWARD 4
+#define MB_FORWARD 8
+#define MB_QUANT 16
+#define MB_WEIGHT 32
+#define MB_CLASS4 64
+
+#define MC_FIELD 1 /* motion_type */
+#define MC_FRAME 2
+#define MC_16X8 2
+#define MC_DMV 3
+
+#define MV_FIELD 0 /* mv_format */
+#define MV_FRAME 1
+
+#define CLIP(x) ((x) >= 0 ? ((x) < 255 ? (x) : 255) : 0)
+
+/* Statically allocate as little as possible so a fake video struct */
+/* can be used for reading the GOP headers. */
+
+struct mpeg3video_rec
+{
+ struct mpeg3_rec* file;
+ struct mpeg3_vtrack_rec* track;
+
+/* ================================= Seeking variables ========================= */
+ mpeg3_bits_t *vstream;
+ int decoder_initted;
+ unsigned char **output_rows; /* Output frame buffer supplied by user */
+ int in_x, in_y, in_w, in_h, out_w, out_h; /* Output dimensions */
+ int *x_table, *y_table; /* Location of every output pixel in the input */
+ int color_model;
+ int want_yvu; /* Want to return a YUV frame */
+ char *y_output, *u_output, *v_output; /* Output pointers for a YUV frame */
+
+ mpeg3_slice_t slice_decoders[MPEG3_MAX_CPUS]; /* One slice decoder for every CPU */
+ int total_slice_decoders; /* Total slice decoders in use */
+ mpeg3_slice_buffer_t slice_buffers[MPEG3_MAX_CPUS]; /* Buffers for holding the slice data */
+ int total_slice_buffers; /* Total buffers in the array to be decompressed */
+ int slice_buffers_initialized; /* Total buffers initialized in the array */
+ pthread_mutex_t slice_lock; /* Lock slice array while getting the next buffer */
+ pthread_mutex_t test_lock;
+
+ int blockreadsize;
+ long maxframe; /* Max value of frame num to read */
+ double percentage_seek; /* Perform a percentage seek before the next frame is read */
+ int frame_seek; /* Perform a frame seek before the next frame is read */
+ long framenum; /* Number of the next frame to be decoded */
+ long last_number; /* Last framenum rendered */
+ int found_seqhdr;
+ long bitrate;
+ mpeg3_timecode_t gop_timecode; /* Timecode for the last GOP header read. */
+
+/* These are only available from elementary streams. */
+ long frames_per_gop; /* Frames per GOP after the first GOP. */
+ long first_gop_frames; /* Frames in the first GOP. */
+ long first_frame; /* Number of first frame stored in timecode */
+ long last_frame; /* Last frame in file */
+
+/* ================================= Compression variables ===================== */
+/* Malloced frame buffers. 2 refframes are swapped in and out. */
+/* while only 1 auxframe is used. */
+ unsigned char *yuv_buffer[5]; /* Make YVU buffers contiguous for all frames */
+ unsigned char *oldrefframe[3], *refframe[3], *auxframe[3];
+ unsigned char *llframe0[3], *llframe1[3];
+ unsigned char *mpeg3_zigzag_scan_table;
+ unsigned char *mpeg3_alternate_scan_table;
+// Source for the next frame presentation
+ unsigned char **output_src;
+/* Pointers to frame buffers. */
+ unsigned char *newframe[3];
+ int horizontal_size, vertical_size, mb_width, mb_height;
+ int coded_picture_width, coded_picture_height;
+ int chroma_format, chrom_width, chrom_height, blk_cnt;
+ int pict_type;
+ int forw_r_size, back_r_size, full_forw, full_back;
+ int prog_seq, prog_frame;
+ int h_forw_r_size, v_forw_r_size, h_back_r_size, v_back_r_size;
+ int dc_prec, pict_struct, topfirst, frame_pred_dct, conceal_mv;
+ int intravlc;
+ int repeatfirst;
+ int repeat_count; /* Number of times to repeat the current frame * 100 since floating point is impossible in MMX */
+ int current_repeat; /* Number of times the current frame has been repeated * 100 */
+ int secondfield;
+ int skip_bframes;
+ int stwc_table_index, llw, llh, hm, hn, vm, vn;
+ int lltempref, llx0, lly0, llprog_frame, llfieldsel;
+ int matrix_coefficients;
+ int framerate_code;
+ float frame_rate;
+ long *cr_to_r, *cr_to_g, *cb_to_g, *cb_to_b;
+ long *cr_to_r_ptr, *cr_to_g_ptr, *cb_to_g_ptr, *cb_to_b_ptr;
+ int have_mmx;
+ int intra_quantizer_matrix[64], non_intra_quantizer_matrix[64];
+ int chroma_intra_quantizer_matrix[64], chroma_non_intra_quantizer_matrix[64];
+ int mpeg2;
+ int qscale_type, altscan; /* picture coding extension */
+ int pict_scal; /* picture spatial scalable extension */
+ int scalable_mode; /* sequence scalable extension */
+};
+
+typedef struct mpeg3video_rec mpeg3video_t;
+
+#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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef MPEG3VIDEOPROTOS_H
+#define MPEG3VIDEOPROTOS_H
+
+void mpeg3video_idct_conversion(short* block);
+unsigned int mpeg3slice_showbits(mpeg3_slice_buffer_t *slice_buffer, int bits);
+
+#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 @@
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include "mpeg3video.h"
+#include <string.h>
+
+static LONGLONG mpeg3_MMX_0 = 0L;
+static unsigned long mpeg3_MMX_10w[] = {0x00100010, 0x00100010}; /*dd 00010 0010h, 000100010h */
+static unsigned long mpeg3_MMX_80w[] = {0x00800080, 0x00800080}; /*dd 00080 0080h, 000800080h */
+
+static unsigned long mpeg3_MMX_00FFw[] = {0x00ff00ff, 0x00ff00ff}; /*dd 000FF 00FFh, 000FF00FFh */
+
+static unsigned short mpeg3_MMX_Ublucoeff[] = {0x81, 0x81, 0x81, 0x81}; /*dd 00081 0081h, 000810081h */
+static unsigned short mpeg3_MMX_Vredcoeff[] = {0x66, 0x66, 0x66, 0x66}; /*dd 00066 0066h, 000660066h */
+
+static unsigned short mpeg3_MMX_Ugrncoeff[] = {0xffe8, 0xffe8, 0xffe8, 0xffe8}; /*dd 0FFE7 FFE7h, 0FFE7FFE7h */
+static unsigned short mpeg3_MMX_Vgrncoeff[] = {0xffcd, 0xffcd, 0xffcd, 0xffcd}; /*dd 0FFCC FFCCh, 0FFCCFFCCh */
+
+static unsigned short mpeg3_MMX_Ycoeff[] = {0x4a, 0x4a, 0x4a, 0x4a}; /*dd 0004A 004Ah, 0004A004Ah */
+
+static unsigned short mpeg3_MMX_redmask[] = {0xf800, 0xf800, 0xf800, 0xf800}; /*dd 07c00 7c00h, 07c007c00h */
+
+static unsigned short mpeg3_MMX_grnmask[] = {0x7e0, 0x7e0, 0x7e0, 0x7e0}; /*dd 003e0 03e0h, 003e003e0h */
+
+static unsigned char mpeg3_601_to_rgb[256];
+
+/* Algorithm */
+/* r = (int)(*y + 1.371 * (*cr - 128)); */
+/* g = (int)(*y - 0.698 * (*cr - 128) - 0.336 * (*cb - 128)); */
+/* b = (int)(*y + 1.732 * (*cb - 128)); */
+
+#ifdef HAVE_MMX
+inline void mpeg3video_rgb16_mmx(unsigned char *lum,
+ unsigned char *cr,
+ unsigned char *cb,
+ unsigned char *out,
+ int rows,
+ int cols,
+ int mod)
+{
+ unsigned short *row1;
+ int x;
+ unsigned char *y;
+ int col1;
+
+ row1 = (unsigned short *)out;
+ col1 = cols + mod;
+ mod += cols + mod;
+ mod *= 2;
+ y = lum + cols * rows;
+ x = 0;
+
+ __asm__ __volatile__(
+ ".align 8\n"
+ "1:\n"
+ "movd (%1), %%mm0\n" /* 4 Cb 0 0 0 0 u3 u2 u1 u0 */
+ "pxor %%mm7, %%mm7\n"
+ "movd (%0), %%mm1\n" /* 4 Cr 0 0 0 0 v3 v2 v1 v0 */
+ "punpcklbw %%mm7, %%mm0\n" /* 4 W cb 0 u3 0 u2 0 u1 0 u0 */
+ "punpcklbw %%mm7, %%mm1\n" /* 4 W cr 0 v3 0 v2 0 v1 0 v0 */
+
+ "psubw mpeg3_MMX_80w, %%mm0\n"
+ "psubw mpeg3_MMX_80w, %%mm1\n"
+ "movq %%mm0, %%mm2\n" /* Cb 0 u3 0 u2 0 u1 0 u0 */
+ "movq %%mm1, %%mm3\n" /* Cr */
+ "pmullw mpeg3_MMX_Ugrncoeff, %%mm2\n" /* Cb2green 0 R3 0 R2 0 R1 0 R0 */
+ "movq (%2), %%mm6\n" /* L1 l7 L6 L5 L4 L3 L2 L1 L0 */
+ "pmullw mpeg3_MMX_Ublucoeff, %%mm0\n" /* Cb2blue */
+ "pand mpeg3_MMX_00FFw, %%mm6\n" /* L1 00 L6 00 L4 00 L2 00 L0 */
+ "pmullw mpeg3_MMX_Vgrncoeff, %%mm3\n" /* Cr2green */
+ "movq (%2), %%mm7\n" /* L2 */
+ "pmullw mpeg3_MMX_Vredcoeff, %%mm1\n" /* Cr2red */
+ "psrlw $8, %%mm7\n" /* L2 00 L7 00 L5 00 L3 00 L1 */
+ "pmullw mpeg3_MMX_Ycoeff, %%mm6\n" /* lum1 */
+ "paddw %%mm3, %%mm2\n" /* Cb2green + Cr2green == green */
+ "pmullw mpeg3_MMX_Ycoeff, %%mm7\n" /* lum2 */
+
+ "movq %%mm6, %%mm4\n" /* lum1 */
+ "paddw %%mm0, %%mm6\n" /* lum1 +blue 00 B6 00 B4 00 B2 00 B0 */
+ "movq %%mm4, %%mm5\n" /* lum1 */
+ "paddw %%mm1, %%mm4\n" /* lum1 +red 00 R6 00 R4 00 R2 00 R0 */
+ "paddw %%mm2, %%mm5\n" /* lum1 +green 00 G6 00 G4 00 G2 00 G0 */
+ "psraw $6, %%mm4\n" /* R1 0 .. 64 */
+ "movq %%mm7, %%mm3\n" /* lum2 00 L7 00 L5 00 L3 00 L1 */
+ "psraw $6, %%mm5\n" /* G1 - .. + */
+ "paddw %%mm0, %%mm7\n" /* Lum2 +blue 00 B7 00 B5 00 B3 00 B1 */
+ "psraw $6, %%mm6\n" /* B1 0 .. 64 */
+ "packuswb %%mm4, %%mm4\n" /* R1 R1 */
+ "packuswb %%mm5, %%mm5\n" /* G1 G1 */
+ "packuswb %%mm6, %%mm6\n" /* B1 B1 */
+ "punpcklbw %%mm4, %%mm4\n"
+ "punpcklbw %%mm5, %%mm5\n"
+
+ "pand mpeg3_MMX_redmask, %%mm4\n"
+ "psllw $3, %%mm5\n" /* GREEN 1 */
+ "punpcklbw %%mm6, %%mm6\n"
+ "pand mpeg3_MMX_grnmask, %%mm5\n"
+ "pand mpeg3_MMX_redmask, %%mm6\n"
+ "por %%mm5, %%mm4\n" /* */
+ "psrlw $11, %%mm6\n" /* BLUE 1 */
+ "movq %%mm3, %%mm5\n" /* lum2 */
+ "paddw %%mm1, %%mm3\n" /* lum2 +red 00 R7 00 R5 00 R3 00 R1 */
+ "paddw %%mm2, %%mm5\n" /* lum2 +green 00 G7 00 G5 00 G3 00 G1 */
+ "psraw $6, %%mm3\n" /* R2 */
+ "por %%mm6, %%mm4\n" /* MM4 */
+ "psraw $6, %%mm5\n" /* G2 */
+ "movq (%2, %3), %%mm6\n" /* L3 */
+ "psraw $6, %%mm7\n"
+ "packuswb %%mm3, %%mm3\n"
+ "packuswb %%mm5, %%mm5\n"
+ "packuswb %%mm7, %%mm7\n"
+ "pand mpeg3_MMX_00FFw, %%mm6\n" /* L3 */
+ "punpcklbw %%mm3, %%mm3\n"
+ "punpcklbw %%mm5, %%mm5\n"
+ "pmullw mpeg3_MMX_Ycoeff, %%mm6\n" /* lum3 */
+ "punpcklbw %%mm7, %%mm7\n"
+ "psllw $3, %%mm5\n" /* GREEN 2 */
+ "pand mpeg3_MMX_redmask, %%mm7\n"
+ "pand mpeg3_MMX_redmask, %%mm3\n"
+ "psrlw $11, %%mm7\n" /* BLUE 2 */
+ "pand mpeg3_MMX_grnmask, %%mm5\n"
+ "por %%mm7, %%mm3\n"
+ "movq (%2,%3), %%mm7\n" /* L4 */
+ "por %%mm5, %%mm3\n" /* */
+ "psrlw $8, %%mm7\n" /* L4 */
+ "movq %%mm4, %%mm5\n"
+ "punpcklwd %%mm3, %%mm4\n"
+ "pmullw mpeg3_MMX_Ycoeff, %%mm7\n" /* lum4 */
+ "punpckhwd %%mm3, %%mm5\n"
+
+ "movq %%mm4, (%4)\n"
+ "movq %%mm5, 8(%4)\n"
+
+ "movq %%mm6, %%mm4\n" /* Lum3 */
+ "paddw %%mm0, %%mm6\n" /* Lum3 +blue */
+
+ "movq %%mm4, %%mm5\n" /* Lum3 */
+ "paddw %%mm1, %%mm4\n" /* Lum3 +red */
+ "paddw %%mm2, %%mm5\n" /* Lum3 +green */
+ "psraw $6, %%mm4\n"
+ "movq %%mm7, %%mm3\n" /* Lum4 */
+ "psraw $6, %%mm5\n"
+ "paddw %%mm0, %%mm7\n" /* Lum4 +blue */
+ "psraw $6, %%mm6\n" /* Lum3 +blue */
+ "movq %%mm3, %%mm0\n" /* Lum4 */
+ "packuswb %%mm4, %%mm4\n"
+ "paddw %%mm1, %%mm3\n" /* Lum4 +red */
+ "packuswb %%mm5, %%mm5\n"
+ "paddw %%mm2, %%mm0\n" /* Lum4 +green */
+ "packuswb %%mm6, %%mm6\n"
+ "punpcklbw %%mm4, %%mm4\n"
+ "punpcklbw %%mm5, %%mm5\n"
+ "punpcklbw %%mm6, %%mm6\n"
+ "psllw $3, %%mm5\n" /* GREEN 3 */
+ "pand mpeg3_MMX_redmask, %%mm4\n"
+ "psraw $6, %%mm3\n" /* psr 6 */
+ "psraw $6, %%mm0\n"
+ "pand mpeg3_MMX_redmask, %%mm6\n" /* BLUE */
+ "pand mpeg3_MMX_grnmask, %%mm5\n"
+ "psrlw $11, %%mm6\n" /* BLUE 3 */
+ "por %%mm5, %%mm4\n"
+ "psraw $6, %%mm7\n"
+ "por %%mm6, %%mm4\n"
+ "packuswb %%mm3, %%mm3\n"
+ "packuswb %%mm0, %%mm0\n"
+ "packuswb %%mm7, %%mm7\n"
+ "punpcklbw %%mm3, %%mm3\n"
+ "punpcklbw %%mm0, %%mm0\n"
+ "punpcklbw %%mm7, %%mm7\n"
+ "pand mpeg3_MMX_redmask, %%mm3\n"
+ "pand mpeg3_MMX_redmask, %%mm7\n" /* BLUE */
+ "psllw $3, %%mm0\n" /* GREEN 4 */
+ "psrlw $11, %%mm7\n"
+ "pand mpeg3_MMX_grnmask, %%mm0\n"
+ "por %%mm7, %%mm3\n"
+ "addl $8, %6\n"
+ "por %%mm0, %%mm3\n"
+
+ "movq %%mm4, %%mm5\n"
+
+ "punpcklwd %%mm3, %%mm4\n"
+ "punpckhwd %%mm3, %%mm5\n"
+
+ "movq %%mm4, (%4,%5,2)\n"
+ "movq %%mm5, 8(%4,%5,2)\n"
+
+ "addl $8, %2\n"
+ "addl $4, %0\n"
+ "addl $4, %1\n"
+ "cmpl %3, %6\n"
+ "leal 16(%4), %4\n"
+ "jl 1b\n"
+ "addl %3, %2\n" /* lum += cols */
+ "addl %7, %4\n" /* row1 += mod */
+ "movl $0, %6\n"
+ "cmpl %8, %2\n"
+ "jl 1b\n"
+ : : "r" (cr),
+ "r" (cb),
+ "r" (lum),
+ "r" (cols),
+ "r" (row1) ,
+ "r" (col1),
+ "m" (x),
+ "m" (mod),
+ "m" (y)
+ );
+}
+
+static unsigned LONGLONG mpeg3_MMX_U_80 = 0x0000008000800000LL;
+static unsigned LONGLONG mpeg3_MMX_V_80 = 0x0000000000800080LL;
+static LONGLONG mpeg3_MMX_U_COEF = 0x00000058ffd30000LL;
+static LONGLONG mpeg3_MMX_V_COEF = 0x00000000ffea006fLL;
+static LONGLONG mpeg3_MMX_601_Y_COEF = 0x0000004800480048LL;
+static LONGLONG mpeg3_MMX_601_Y_DIFF = 0x0000000000000010LL;
+
+inline void mpeg3_bgra32_mmx(unsigned long y,
+ unsigned long u,
+ unsigned long v,
+ unsigned long *output)
+{
+asm("
+/* Output will be 0x00rrggbb with the 00 trailing so this can also be used */
+/* for bgr24. */
+ movd (%0), %%mm0; /* Load y 0x00000000000000yy */
+ movd (%1), %%mm1; /* Load u 0x00000000000000cr */
+ movq %%mm0, %%mm3; /* Copy y to temp */
+ psllq $16, %%mm1; /* Shift u 0x0000000000cr0000 */
+ movd (%2), %%mm2; /* Load v 0x00000000000000cb */
+ psllq $16, %%mm3; /* Shift y */
+ movq %%mm1, %%mm4; /* Copy u to temp */
+ por %%mm3, %%mm0; /* Overlay new y byte 0x0000000000yy00yy */
+ psllq $16, %%mm4; /* Shift u */
+ movq %%mm2, %%mm5; /* Copy v to temp */
+ psllq $16, %%mm3; /* Shift y */
+ por %%mm4, %%mm1; /* Overlay new u byte 0x000000cr00cr0000 */
+ psllq $16, %%mm5; /* Shift v */
+ por %%mm3, %%mm0; /* Overlay new y byte 0x000000yy00yy00yy */
+ por %%mm5, %%mm2; /* Overlay new v byte 0x0000000000cb00cb */
+
+/* mm0: 0x000000yy00yy00yy mm1: 0x000000uu00uu0000 mm2: 0x0000000000vv00vv */
+ psubw mpeg3_MMX_U_80, %%mm1; /* Subtract 128 from u 0x000000uu00uu0000 */
+ pmullw mpeg3_MMX_U_COEF, %%mm1; /* Multiply u coeffs 0x0000uuuuuuuu0000 */
+ psllw $6, %%mm0; /* Shift y coeffs 0x0000yyy0yyy0yyy0 */
+ psubw mpeg3_MMX_V_80, %%mm2; /* Subtract 128 from v 0x0000000000cb00cb */
+ pmullw mpeg3_MMX_V_COEF, %%mm2; /* Multiply v coeffs 0x0000crcrcrcrcrcr */
+
+/* mm0: 0x000000yy00yy00yy mm1: 0x0000uuuuuuuu0000 mm2: 0x00000000vvvvvvvv */
+ paddsw %%mm1, %%mm0; /* Add u to result */
+ paddsw %%mm2, %%mm0; /* Add v to result 0x0000rrrrggggbbbb */
+ psraw $6, %%mm0; /* Demote precision */
+ packuswb %%mm0, %%mm0; /* Pack into ARGB 0x0000000000rrggbb */
+ movd %%mm0, (%3); /* Store output */
+ "
+:
+: "r" (&y), "r" (&u), "r" (&v), "r" (output));
+}
+
+inline void mpeg3_601_bgra32_mmx(unsigned long y,
+ unsigned long u,
+ unsigned long v,
+ unsigned long *output)
+{
+asm("
+/* Output will be 0x00rrggbb with the 00 trailing so this can also be used */
+/* for bgr24. */
+ movd (%0), %%mm0; /* Load y 0x00000000000000yy */
+ psubsw mpeg3_MMX_601_Y_DIFF, %%mm0; /* Subtract 16 from y */
+ movd (%1), %%mm1; /* Load u 0x00000000000000cr */
+ movq %%mm0, %%mm3; /* Copy y to temp */
+ psllq $16, %%mm1; /* Shift u 0x0000000000cr0000 */
+ movd (%2), %%mm2; /* Load v 0x00000000000000cb */
+ psllq $16, %%mm3; /* Shift y */
+ movq %%mm1, %%mm4; /* Copy u to temp */
+ por %%mm3, %%mm0; /* Overlay new y byte 0x0000000000yy00yy */
+ psllq $16, %%mm4; /* Shift u */
+ movq %%mm2, %%mm5; /* Copy v to temp */
+ psllq $16, %%mm3; /* Shift y */
+ por %%mm4, %%mm1; /* Overlay new u byte 0x000000cr00cr0000 */
+ psllq $16, %%mm5; /* Shift v */
+ por %%mm3, %%mm0; /* Overlay new y byte 0x000000yy00yy00yy */
+ por %%mm5, %%mm2; /* Overlay new v byte 0x0000000000cb00cb */
+
+/* mm0: 0x000000yy00yy00yy mm1: 0x000000uu00uu0000 mm2: 0x0000000000vv00vv */
+ pmullw mpeg3_MMX_601_Y_COEF, %%mm0; /* Scale and shift y coeffs */
+ psubw mpeg3_MMX_U_80, %%mm1; /* Subtract 128 from u 0x000000uu00uu0000 */
+ pmullw mpeg3_MMX_U_COEF, %%mm1; /* Multiply u coeffs 0x0000uuuuuuuu0000 */
+ psubw mpeg3_MMX_V_80, %%mm2; /* Subtract 128 from v 0x0000000000cb00cb */
+ pmullw mpeg3_MMX_V_COEF, %%mm2; /* Multiply v coeffs 0x0000crcrcrcrcrcr */
+
+/* mm0: 0x000000yy00yy00yy mm1: 0x0000uuuuuuuu0000 mm2: 0x00000000vvvvvvvv */
+ paddsw %%mm1, %%mm0; /* Add u to result */
+ paddsw %%mm2, %%mm0; /* Add v to result 0x0000rrrrggggbbbb */
+ psraw $6, %%mm0; /* Demote precision */
+ packuswb %%mm0, %%mm0; /* Pack into ARGB 0x0000000000rrggbb */
+ movd %%mm0, (%3); /* Store output */
+ "
+:
+: "r" (&y), "r" (&u), "r" (&v), "r" (output));
+}
+
+static unsigned LONGLONG mpeg3_MMX_U_80_RGB = 0x0000000000800080LL;
+static unsigned LONGLONG mpeg3_MMX_V_80_RGB = 0x0000008000800000LL;
+static LONGLONG mpeg3_MMX_U_COEF_RGB = 0x00000000ffd30058LL;
+static LONGLONG mpeg3_MMX_V_COEF_RGB = 0x0000006fffea0000LL;
+
+inline void mpeg3_rgba32_mmx(unsigned long y,
+ unsigned long u,
+ unsigned long v,
+ unsigned long *output)
+{
+asm("
+/* Output will be 0x00bbggrr with the 00 trailing so this can also be used */
+/* for rgb24. */
+ movd (%0), %%mm0; /* Load y 0x00000000000000yy */
+ movd (%1), %%mm1; /* Load v 0x00000000000000vv */
+ movq %%mm0, %%mm3; /* Copy y to temp */
+ psllq $16, %%mm1; /* Shift v 0x0000000000vv0000 */
+ movd (%2), %%mm2; /* Load u 0x00000000000000uu */
+ psllq $16, %%mm3; /* Shift y */
+ movq %%mm1, %%mm4; /* Copy v to temp */
+ por %%mm3, %%mm0; /* Overlay new y byte 0x0000000000yy00yy */
+ psllq $16, %%mm4; /* Shift v */
+ movq %%mm2, %%mm5; /* Copy u to temp */
+ psllq $16, %%mm3; /* Shift y */
+ por %%mm4, %%mm1; /* Overlay new v byte 0x000000vv00vv0000 */
+ psllq $16, %%mm5; /* Shift u */
+ por %%mm3, %%mm0; /* Overlay new y byte 0x000000yy00yy00yy */
+ por %%mm5, %%mm2; /* Overlay new u byte 0x0000000000uu00uu */
+
+/* mm0: 0x000000yy00yy00yy mm1: 0x000000vv00vv0000 mm2: 0x0000000000uu00uu */
+ psubw mpeg3_MMX_V_80_RGB, %%mm1; /* Subtract 128 from v 0x000000vv00vv0000 */
+ pmullw mpeg3_MMX_V_COEF_RGB, %%mm1; /* Multiply v coeffs 0x0000vvvvvvvv0000 */
+ psllw $6, %%mm0; /* Shift y coeffs 0x0000yyy0yyy0yyy0 */
+ psubw mpeg3_MMX_U_80_RGB, %%mm2; /* Subtract 128 from u 0x0000000000uu00uu */
+ pmullw mpeg3_MMX_U_COEF_RGB, %%mm2; /* Multiply u coeffs 0x0000uuuuuuuuuuuu */
+
+/* mm0: 0x000000yy00yy00yy mm1: 0x0000vvvvvvvv0000 mm2: 0x00000000uuuuuuuu */
+ paddsw %%mm1, %%mm0; /* Add v to result */
+ paddsw %%mm2, %%mm0; /* Add u to result 0x0000bbbbggggrrrr */
+ psraw $6, %%mm0; /* Demote precision */
+ packuswb %%mm0, %%mm0; /* Pack into RGBA 0x0000000000bbggrr */
+ movd %%mm0, (%3); /* Store output */
+ "
+:
+: "r" (&y), "r" (&v), "r" (&u), "r" (output));
+}
+
+inline void mpeg3_601_rgba32_mmx(unsigned long y,
+ unsigned long u,
+ unsigned long v,
+ unsigned long *output)
+{
+asm("
+/* Output will be 0x00bbggrr with the 00 trailing so this can also be used */
+/* for rgb24. */
+ movd (%0), %%mm0; /* Load y 0x00000000000000yy */
+ psubsw mpeg3_MMX_601_Y_DIFF, %%mm0; /* Subtract 16 from y */
+ movd (%1), %%mm1; /* Load v 0x00000000000000vv */
+ movq %%mm0, %%mm3; /* Copy y to temp */
+ psllq $16, %%mm1; /* Shift v 0x0000000000vv0000 */
+ movd (%2), %%mm2; /* Load u 0x00000000000000uu */
+ psllq $16, %%mm3; /* Shift y */
+ movq %%mm1, %%mm4; /* Copy v to temp */
+ por %%mm3, %%mm0; /* Overlay new y byte 0x0000000000yy00yy */
+ psllq $16, %%mm4; /* Shift v */
+ movq %%mm2, %%mm5; /* Copy u to temp */
+ psllq $16, %%mm3; /* Shift y */
+ por %%mm4, %%mm1; /* Overlay new v byte 0x000000vv00vv0000 */
+ psllq $16, %%mm5; /* Shift u */
+ por %%mm3, %%mm0; /* Overlay new y byte 0x000000yy00yy00yy */
+ por %%mm5, %%mm2; /* Overlay new u byte 0x0000000000uu00uu */
+
+/* mm0: 0x000000yy00yy00yy mm1: 0x000000vv00vv0000 mm2: 0x0000000000uu00uu */
+ pmullw mpeg3_MMX_601_Y_COEF, %%mm0; /* Scale y coeffs */
+ psubw mpeg3_MMX_V_80_RGB, %%mm1; /* Subtract 128 from v 0x000000vv00vv0000 */
+ pmullw mpeg3_MMX_V_COEF_RGB, %%mm1; /* Multiply v coeffs 0x0000vvvvvvvv0000 */
+ psubw mpeg3_MMX_U_80_RGB, %%mm2; /* Subtract 128 from u 0x0000000000uu00uu */
+ pmullw mpeg3_MMX_U_COEF_RGB, %%mm2; /* Multiply u coeffs 0x0000uuuuuuuuuuuu */
+
+/* mm0: 0x000000yy00yy00yy mm1: 0x0000vvvvvvvv0000 mm2: 0x00000000uuuuuuuu */
+ paddsw %%mm1, %%mm0; /* Add v to result */
+ paddsw %%mm2, %%mm0; /* Add u to result 0x0000bbbbggggrrrr */
+ psraw $6, %%mm0; /* Demote precision */
+ packuswb %%mm0, %%mm0; /* Pack into RGBA 0x0000000000bbggrr */
+ movd %%mm0, (%3); /* Store output */
+ "
+:
+: "r" (&y), "r" (&v), "r" (&u), "r" (output));
+}
+
+#endif
+
+#define DITHER_ROW_HEAD \
+ for(h = 0; h < video->out_h; h++) \
+ { \
+ y_in = &src[0][(video->y_table[h] + video->in_y) * video->coded_picture_width] + video->in_x; \
+ cb_in = &src[1][((video->y_table[h] + video->in_y) >> 1) * video->chrom_width] + (video->in_x >> 2); \
+ cr_in = &src[2][((video->y_table[h] + video->in_y) >> 1) * video->chrom_width] + (video->in_x >> 1); \
+ data = output_rows[h];
+
+#define DITHER_ROW_TAIL \
+ }
+
+#define DITHER_SCALE_HEAD \
+ for(w = 0; w < video->out_w; w++) \
+ { \
+ uv_subscript = video->x_table[w] / 2; \
+ y_l = y_in[video->x_table[w]]; \
+ y_l <<= 16; \
+ r_l = (y_l + video->cr_to_r[cr_in[uv_subscript]]) >> 16; \
+ g_l = (y_l + video->cr_to_g[cr_in[uv_subscript]] + video->cb_to_g[cb_in[uv_subscript]]) >> 16; \
+ b_l = (y_l + video->cb_to_b[cb_in[uv_subscript]]) >> 16;
+
+#define DITHER_SCALE_601_HEAD \
+ for(w = 0; w < video->out_w; w++) \
+ { \
+ uv_subscript = video->x_table[w] / 2; \
+ y_l = mpeg3_601_to_rgb[y_in[video->x_table[w]]]; \
+ y_l <<= 16; \
+ r_l = (y_l + video->cr_to_r[cr_in[uv_subscript]]) >> 16; \
+ g_l = (y_l + video->cr_to_g[cr_in[uv_subscript]] + video->cb_to_g[cb_in[uv_subscript]]) >> 16; \
+ b_l = (y_l + video->cb_to_b[cb_in[uv_subscript]]) >> 16;
+
+#define DITHER_SCALE_TAIL \
+ }
+
+#define DITHER_MMX_SCALE_HEAD \
+ for(w = 0; w < video->out_w; w++) \
+ { \
+ uv_subscript = video->x_table[w] / 2;
+
+#define DITHER_MMX_SCALE_TAIL \
+ data += step; \
+ }
+
+#define DITHER_MMX_HEAD \
+ for(w = 0; w < video->out_w; w += 2) \
+ {
+
+#define DITHER_MMX_TAIL \
+ data += step; \
+ cr_in++; \
+ cb_in++; \
+ }
+
+#define DITHER_HEAD \
+ for(w = 0; w < video->horizontal_size; w++) \
+ { \
+ y_l = *y_in++; \
+ y_l <<= 16; \
+ r_l = (y_l + video->cr_to_r[*cr_in]) >> 16; \
+ g_l = (y_l + video->cr_to_g[*cr_in] + video->cb_to_g[*cb_in]) >> 16; \
+ b_l = (y_l + video->cb_to_b[*cb_in]) >> 16;
+
+#define DITHER_601_HEAD \
+ for(w = 0; w < video->horizontal_size; w++) \
+ { \
+ y_l = mpeg3_601_to_rgb[*y_in++]; \
+ y_l <<= 16; \
+ r_l = (y_l + video->cr_to_r[*cr_in]) >> 16; \
+ g_l = (y_l + video->cr_to_g[*cr_in] + video->cb_to_g[*cb_in]) >> 16; \
+ b_l = (y_l + video->cb_to_b[*cb_in]) >> 16;
+
+#define DITHER_TAIL \
+ if(w & 1) \
+ { \
+ cr_in++; \
+ cb_in++; \
+ } \
+ }
+
+
+#define STORE_PIXEL_BGR888 \
+ *data++ = CLIP(b_l); \
+ *data++ = CLIP(g_l); \
+ *data++ = CLIP(r_l);
+
+#define STORE_PIXEL_BGRA8888 \
+ *data++ = CLIP(b_l); \
+ *data++ = CLIP(g_l); \
+ *data++ = CLIP(r_l); \
+ *data++ = 0;
+
+#define STORE_PIXEL_RGB565 \
+ *((unsigned short*)data)++ = \
+ ((CLIP(r_l) & 0xf8) << 8) | \
+ ((CLIP(g_l) & 0xfc) << 3) | \
+ ((CLIP(b_l) & 0xf8) >> 3);
+
+#define STORE_PIXEL_RGB888 \
+ *data++ = CLIP(r_l); \
+ *data++ = CLIP(g_l); \
+ *data++ = CLIP(b_l);
+
+#define STORE_PIXEL_RGBA8888 \
+ *data++ = CLIP(r_l); \
+ *data++ = CLIP(g_l); \
+ *data++ = CLIP(b_l); \
+ *data++ = 0;
+
+#define STORE_PIXEL_RGBA16161616 \
+ *data_s++ = CLIP(r_l); \
+ *data_s++ = CLIP(g_l); \
+ *data_s++ = CLIP(b_l); \
+ *data_s++ = 0;
+
+
+
+/* Only good for YUV 4:2:0 */
+int mpeg3video_ditherframe(mpeg3video_t *video, unsigned char **src, unsigned char **output_rows)
+{
+ int h = 0;
+ register unsigned char *y_in, *cb_in, *cr_in;
+ long y_l, r_l, b_l, g_l;
+ register unsigned char *data;
+ register int uv_subscript, step, w = -1;
+
+#ifdef HAVE_MMX
+/* =================================== MMX ===================================== */
+ if(video->have_mmx &&
+ video->out_w == video->horizontal_size &&
+ video->out_h == video->vertical_size &&
+ video->in_w == video->out_w &&
+ video->in_h == video->out_h &&
+ video->in_x == 0 &&
+ video->in_y == 0 &&
+ (video->color_model == MPEG3_RGB565 || video->color_model == MPEG3_601_RGB565))
+ {
+/* Unscaled 16 bit */
+ mpeg3video_rgb16_mmx(src[0],
+ src[2],
+ src[1],
+ output_rows[0],
+ video->out_h,
+ video->out_w,
+ (output_rows[1] - output_rows[0]) / 2 - video->out_w);
+ }
+ else
+ if(video->have_mmx &&
+ (video->color_model == MPEG3_BGRA8888 ||
+ video->color_model == MPEG3_BGR888 ||
+/* video->color_model == MPEG3_RGB888 || */
+ video->color_model == MPEG3_RGBA8888 ||
+ video->color_model == MPEG3_601_BGR888 ||
+ video->color_model == MPEG3_601_BGRA8888 ||
+ video->color_model == MPEG3_601_RGB888 ||
+ video->color_model == MPEG3_601_RGBA8888))
+ {
+/* Original MMX */
+ if(video->color_model == MPEG3_BGRA8888 ||
+ video->color_model == MPEG3_RGBA8888 ||
+ video->color_model == MPEG3_601_BGRA8888 ||
+ video->color_model == MPEG3_601_RGBA8888) step = 4;
+ else
+ if(video->color_model == MPEG3_BGR888 ||
+ video->color_model == MPEG3_RGB888 ||
+ video->color_model == MPEG3_601_BGR888 ||
+ video->color_model == MPEG3_601_RGB888) step = 3;
+
+ DITHER_ROW_HEAD
+/* Transfer row with scaling */
+ if(video->out_w != video->horizontal_size)
+ {
+ switch(video->color_model)
+ {
+ case MPEG3_BGRA8888:
+ case MPEG3_BGR888:
+ DITHER_MMX_SCALE_HEAD
+ mpeg3_bgra32_mmx(y_in[video->x_table[w]],
+ cr_in[uv_subscript],
+ cb_in[uv_subscript],
+ (unsigned long*)data);
+ DITHER_MMX_SCALE_TAIL
+ break;
+
+ case MPEG3_601_BGRA8888:
+ case MPEG3_601_BGR888:
+ DITHER_MMX_SCALE_HEAD
+ mpeg3_601_bgra32_mmx(y_in[video->x_table[w]],
+ cr_in[uv_subscript],
+ cb_in[uv_subscript],
+ (unsigned long*)data);
+ DITHER_MMX_SCALE_TAIL
+ break;
+
+ case MPEG3_RGBA8888:
+ case MPEG3_RGB888:
+ DITHER_MMX_SCALE_HEAD
+ mpeg3_rgba32_mmx(y_in[video->x_table[w]],
+ cr_in[uv_subscript],
+ cb_in[uv_subscript],
+ (unsigned long*)data);
+ DITHER_MMX_SCALE_TAIL
+ break;
+
+ case MPEG3_601_RGBA8888:
+ case MPEG3_601_RGB888:
+ DITHER_MMX_SCALE_HEAD
+ mpeg3_601_rgba32_mmx(y_in[video->x_table[w]],
+ cr_in[uv_subscript],
+ cb_in[uv_subscript],
+ (unsigned long*)data);
+ DITHER_MMX_SCALE_TAIL
+ break;
+ }
+ }
+ else
+/* Transfer row unscaled */
+ {
+ switch(video->color_model)
+ {
+/* MMX byte swap 24 and 32 bit */
+ case MPEG3_BGRA8888:
+ case MPEG3_BGR888:
+ DITHER_MMX_HEAD
+ mpeg3_bgra32_mmx(*y_in++,
+ *cr_in,
+ *cb_in,
+ (unsigned long*)data);
+ data += step;
+ mpeg3_bgra32_mmx(*y_in++,
+ *cr_in,
+ *cb_in,
+ (unsigned long*)data);
+ DITHER_MMX_TAIL
+ break;
+
+/* MMX 601 byte swap 24 and 32 bit */
+ case MPEG3_601_BGRA8888:
+ case MPEG3_601_BGR888:
+ DITHER_MMX_HEAD
+ mpeg3_601_bgra32_mmx(*y_in++,
+ *cr_in,
+ *cb_in,
+ (unsigned long*)data);
+ data += step;
+ mpeg3_601_bgra32_mmx(*y_in++,
+ *cr_in,
+ *cb_in,
+ (unsigned long*)data);
+ DITHER_MMX_TAIL
+ break;
+
+/* MMX 24 and 32 bit no byte swap */
+ case MPEG3_RGBA8888:
+ case MPEG3_RGB888:
+ DITHER_MMX_HEAD
+ mpeg3_rgba32_mmx(*y_in++,
+ *cr_in,
+ *cb_in,
+ (unsigned long*)data);
+ data += step;
+ mpeg3_rgba32_mmx(*y_in++,
+ *cr_in,
+ *cb_in,
+ (unsigned long*)data);
+ DITHER_MMX_TAIL
+ break;
+
+/* MMX 601 24 and 32 bit no byte swap */
+ case MPEG3_601_RGBA8888:
+ case MPEG3_601_RGB888:
+ DITHER_MMX_HEAD
+ mpeg3_601_rgba32_mmx(*y_in++,
+ *cr_in,
+ *cb_in,
+ (unsigned long*)data);
+ data += step;
+ mpeg3_601_rgba32_mmx(*y_in++,
+ *cr_in,
+ *cb_in,
+ (unsigned long*)data);
+ DITHER_MMX_TAIL
+ break;
+ }
+ }
+ DITHER_ROW_TAIL
+ }
+ else
+#endif
+/* ================================== NO MMX ==================================== */
+ {
+ DITHER_ROW_HEAD
+/* Transfer row with scaling */
+ if(video->out_w != video->horizontal_size)
+ {
+ switch(video->color_model)
+ {
+ case MPEG3_BGR888:
+ DITHER_SCALE_HEAD
+ STORE_PIXEL_BGR888
+ DITHER_SCALE_TAIL
+ break;
+ case MPEG3_BGRA8888:
+ DITHER_SCALE_HEAD
+ STORE_PIXEL_BGRA8888
+ DITHER_SCALE_TAIL
+ break;
+ case MPEG3_RGB565:
+ DITHER_SCALE_HEAD
+ STORE_PIXEL_RGB565
+ DITHER_SCALE_TAIL
+ break;
+ case MPEG3_RGB888:
+ DITHER_SCALE_HEAD
+ STORE_PIXEL_RGB888
+ DITHER_SCALE_TAIL
+ break;
+ case MPEG3_RGBA8888:
+ DITHER_SCALE_HEAD
+ STORE_PIXEL_RGBA8888
+ DITHER_SCALE_TAIL
+ break;
+ case MPEG3_601_BGR888:
+ DITHER_SCALE_601_HEAD
+ STORE_PIXEL_BGR888
+ DITHER_SCALE_TAIL
+ break;
+ case MPEG3_601_BGRA8888:
+ DITHER_SCALE_601_HEAD
+ STORE_PIXEL_BGRA8888
+ DITHER_SCALE_TAIL
+ break;
+ case MPEG3_601_RGB565:
+ DITHER_SCALE_601_HEAD
+ STORE_PIXEL_RGB565
+ DITHER_SCALE_TAIL
+ break;
+ case MPEG3_601_RGB888:
+ DITHER_SCALE_601_HEAD
+ STORE_PIXEL_RGB888
+ DITHER_SCALE_TAIL
+ break;
+ case MPEG3_601_RGBA8888:
+ DITHER_SCALE_601_HEAD
+ STORE_PIXEL_RGBA8888
+ DITHER_SCALE_TAIL
+ break;
+ case MPEG3_RGBA16161616:
+ {
+ register unsigned short *data_s = (unsigned short*)data;
+ DITHER_SCALE_HEAD
+ STORE_PIXEL_RGBA16161616
+ DITHER_SCALE_TAIL
+ }
+ break;
+ }
+ }
+ else
+ {
+/* Transfer row unscaled */
+ switch(video->color_model)
+ {
+ case MPEG3_BGR888:
+ DITHER_HEAD
+ STORE_PIXEL_BGR888
+ DITHER_TAIL
+ break;
+ case MPEG3_BGRA8888:
+ DITHER_HEAD
+ STORE_PIXEL_BGRA8888
+ DITHER_TAIL
+ break;
+ case MPEG3_RGB565:
+ DITHER_HEAD
+ STORE_PIXEL_RGB565
+ DITHER_TAIL
+ break;
+ case MPEG3_RGB888:
+ DITHER_HEAD
+ STORE_PIXEL_RGB888
+ DITHER_TAIL
+ break;
+ case MPEG3_RGBA8888:
+ DITHER_HEAD
+ STORE_PIXEL_RGBA8888
+ DITHER_TAIL
+ break;
+ case MPEG3_601_BGR888:
+ DITHER_601_HEAD
+ STORE_PIXEL_BGR888
+ DITHER_TAIL
+ break;
+ case MPEG3_601_BGRA8888:
+ DITHER_601_HEAD
+ STORE_PIXEL_RGB565
+ DITHER_TAIL
+ break;
+ case MPEG3_601_RGB565:
+ DITHER_601_HEAD
+ STORE_PIXEL_RGB565
+ DITHER_TAIL
+ break;
+ case MPEG3_601_RGB888:
+ DITHER_601_HEAD
+ STORE_PIXEL_RGB888
+ DITHER_TAIL
+ break;
+ case MPEG3_601_RGBA8888:
+ DITHER_601_HEAD
+ STORE_PIXEL_RGBA8888
+ DITHER_TAIL
+ break;
+ case MPEG3_RGBA16161616:
+ {
+ register unsigned short *data_s = (unsigned short*)data;
+ DITHER_HEAD
+ STORE_PIXEL_RGBA16161616
+ DITHER_TAIL
+ }
+ break;
+ }
+ }
+ DITHER_ROW_TAIL
+ } /* End of non-MMX */
+
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ __asm__ __volatile__ ("emms");
+#endif
+ return 0;
+}
+
+int mpeg3video_ditherframe444(mpeg3video_t *video, unsigned char *src[])
+{
+ return 0;
+}
+
+int mpeg3video_dithertop(mpeg3video_t *video, unsigned char *src[])
+{
+ return mpeg3video_ditherframe(video, src, video->output_rows);
+}
+
+int mpeg3video_dithertop444(mpeg3video_t *video, unsigned char *src[])
+{
+ return 0;
+}
+
+int mpeg3video_ditherbot(mpeg3video_t *video, unsigned char *src[])
+{
+ return 0;
+}
+
+int mpeg3video_ditherbot444(mpeg3video_t *video, unsigned char *src[])
+{
+ return 0;
+}
+
+void memcpy_fast(unsigned char *output, unsigned char *input, long len)
+{
+ int i, len2;
+/* 8 byte alignment */
+/*
+ * if(!((long)input & 0x7))
+ * {
+ * len2 = len >> 4;
+ * for(i = 0; i < len2; )
+ * {
+ * ((MPEG3_INT64*)output)[i] = ((MPEG3_INT64*)input)[i];
+ * i++;
+ * ((MPEG3_INT64*)output)[i] = ((MPEG3_INT64*)input)[i];
+ * i++;
+ * }
+ *
+ * for(i *= 16; i < len; i++)
+ * {
+ * output[i] = input[i];
+ * }
+ * }
+ * else
+ */
+ memcpy(output, input, len);
+}
+
+int mpeg3video_init_output()
+{
+ int i, value;
+ for(i = 0; i < 256; i++)
+ {
+ value = (int)(1.1644 * i - 255 * 0.0627 + 0.5);
+ if(value < 0) value = 0;
+ else
+ if(value > 255) value = 255;
+ mpeg3_601_to_rgb[i] = value;
+ }
+ return 0;
+}
+
+int mpeg3video_present_frame(mpeg3video_t *video)
+{
+ int i, j, k, l;
+ unsigned char **src = video->output_src;
+
+/* Copy YUV buffers */
+ if(video->want_yvu)
+ {
+ long size[2];
+ long offset[2];
+
+/* Drop a frame */
+ if(!video->y_output) return 0;
+
+/* Copy a frame */
+ if(video->in_x == 0 &&
+ video->in_w >= video->coded_picture_width)
+ {
+ size[0] = video->coded_picture_width * video->in_h;
+ size[1] = video->chrom_width * (int)((float)video->in_h / 2 + 0.5);
+ offset[0] = video->coded_picture_width * video->in_y;
+ offset[1] = video->chrom_width * (int)((float)video->in_y / 2 + 0.5);
+
+/*
+ * if(video->in_y > 0)
+ * {
+ * offset[1] += video->chrom_width / 2;
+ * size[1] += video->chrom_width / 2;
+ * }
+ */
+
+ memcpy(video->y_output, src[0] + offset[0], size[0]);
+ memcpy(video->u_output, src[1] + offset[1], size[1]);
+ memcpy(video->v_output, src[2] + offset[1], size[1]);
+ }
+ else
+ {
+ for(i = 0, j = video->in_y; i < video->in_h; i++, j++)
+ {
+ memcpy(video->y_output + i * video->in_w,
+ src[0] + j * video->coded_picture_width + video->in_x,
+ video->in_w);
+ memcpy(video->u_output + i * video->in_w / 4,
+ src[1] + j * video->chrom_width / 2 + video->in_x / 4,
+ video->in_w / 4);
+ memcpy(video->v_output + i * video->in_w / 4,
+ src[2] + j * video->chrom_width / 2 + video->in_x / 4,
+ video->in_w / 4);
+ }
+ }
+
+ return 0;
+ }
+
+/* Want RGB buffer */
+/* Copy the frame to the output with YUV to RGB conversion */
+ if(video->prog_seq)
+ {
+ if(video->chroma_format != CHROMA444)
+ {
+ mpeg3video_ditherframe(video, src, video->output_rows);
+ }
+ else
+ mpeg3video_ditherframe444(video, src);
+ }
+ else
+ {
+ if((video->pict_struct == FRAME_PICTURE && video->topfirst) ||
+ video->pict_struct == BOTTOM_FIELD)
+ {
+/* top field first */
+ if(video->chroma_format != CHROMA444)
+ {
+ mpeg3video_dithertop(video, src);
+ mpeg3video_ditherbot(video, src);
+ }
+ else
+ {
+ mpeg3video_dithertop444(video, src);
+ mpeg3video_ditherbot444(video, src);
+ }
+ }
+ else
+ {
+/* bottom field first */
+ if(video->chroma_format != CHROMA444)
+ {
+ mpeg3video_ditherbot(video, src);
+ mpeg3video_dithertop(video, src);
+ }
+ else
+ {
+ mpeg3video_ditherbot444(video, src);
+ mpeg3video_dithertop444(video, src);
+ }
+ }
+ }
+ return 0;
+}
+
+int mpeg3video_display_second_field(mpeg3video_t *video)
+{
+/* Not used */
+ return 0;
+}
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 @@
+ADD_1: dd 01010101h, 01010101h
+MASK_AND: dd 7f7f7f7fh, 7f7f7f7fh
+PLUS_384: dd 01800180h, 01800180h
+PLUS_128: dd 00800080h, 00800080h
+
+%assign LocalFrameSize 0
+%assign RegisterStorageSize 16
+
+; Arguments:
+%assign source LocalFrameSize + RegisterStorageSize + 4
+%assign dest LocalFrameSize + RegisterStorageSize + 8
+%assign lx2 LocalFrameSize + RegisterStorageSize + 12
+%assign h LocalFrameSize + RegisterStorageSize + 16
+
+; Locals (on local stack frame)
+
+
+; extern void C rec_mmx (
+; unsigned char *source,
+; unsigned char *dest,
+; int lx2,
+; int h
+;
+; The local variables are on the stack,
+;
+
+global recva_mmx
+global recvac_mmx
+global rech_mmx
+global rechc_mmx
+global add_block_mmx
+global set_block_mmx
+
+
+ align 16
+rech_mmx:
+ push esi
+ push edi
+ push ecx
+ push ebx
+ mov esi, [esp+source]
+ mov edi, [esp+dest]
+ mov ecx, [esp+h]
+ mov ebx, [esp+lx2]
+ movq mm5, [MASK_AND]
+ movq mm6, [ADD_1]
+.rech1:
+ movq mm0,[esi]
+ movq mm1,[esi+1]
+ movq mm2,[esi+8]
+ movq mm3,[esi+9]
+ psrlw mm0,1
+ psrlw mm1,1
+ psrlw mm2,1
+ psrlw mm3,1
+ pand mm0,mm5
+ pand mm1,mm5
+ pand mm2,mm5
+ pand mm3,mm5
+ paddusb mm0,mm1
+ paddusb mm2,mm3
+ paddusb mm0,mm6
+ paddusb mm2,mm6
+ movq [edi],mm0
+ add esi,ebx
+ movq [edi+8],mm2
+ add edi,ebx
+ dec ecx
+ jnz .rech1
+ emms
+ pop ebx
+ pop ecx
+ pop edi
+ pop esi
+ ret
+
+ align 16
+rechc_mmx:
+ push esi
+ push edi
+ push ecx
+ push ebx
+; sub esp, LocalFrameSize
+ mov esi, [esp+source]
+ mov edi, [esp+dest]
+ mov ecx, [esp+h]
+ mov ebx, [esp+lx2]
+ movq mm5, [MASK_AND]
+ movq mm6, [ADD_1]
+.rechc1:
+ movq mm0,[esi]
+ movq mm1,[esi+1]
+ psrlw mm0,1
+ psrlw mm1,1
+ pand mm0,mm5
+ pand mm1,mm5
+ paddusb mm0,mm1
+ paddusb mm0,mm6
+ movq [edi],mm0
+ add edi,ebx
+ add esi,ebx
+ dec ecx
+ jnz .rechc1
+ emms
+; add esp, LocalFrameSize
+ pop ebx
+ pop ecx
+ pop edi
+ pop esi
+ ret
+
+
+
+%assign RegisterStorageSize 20
+%assign source LocalFrameSize + RegisterStorageSize + 4
+%assign dest LocalFrameSize + RegisterStorageSize + 8
+%assign lx LocalFrameSize + RegisterStorageSize + 12
+%assign lx2 LocalFrameSize + RegisterStorageSize + 16
+%assign h LocalFrameSize + RegisterStorageSize + 20
+
+ align 16
+recva_mmx:
+ push esi
+ push edi
+ push ecx
+ push ebx
+ push edx
+ mov esi, [esp+source]
+ mov edi, [esp+dest]
+ mov ecx, [esp+h]
+ mov ebx, [esp+lx2]
+ mov edx, [esp+lx]
+ movq mm7, [MASK_AND]
+ movq mm6, [ADD_1]
+.recva1:
+ movq mm0,[esi]
+ movq mm1,[esi+edx]
+ movq mm2,[esi+8]
+ movq mm3,[esi+edx+8]
+ movq mm4,[edi]
+ movq mm5,[edi+8]
+ psrlw mm0,1
+ psrlw mm1,1
+ psrlw mm2,1
+ psrlw mm3,1
+ psrlw mm4,1
+ psrlw mm5,1
+ pand mm0,mm7
+ pand mm1,mm7
+ pand mm2,mm7
+ pand mm3,mm7
+ pand mm4,mm7
+ pand mm5,mm7
+ paddusb mm0,mm1
+ paddusb mm2,mm3
+ paddusb mm0,mm6
+ paddusb mm2,mm6
+ psrlw mm0,1
+ psrlw mm2,1
+ pand mm0,mm7
+ pand mm2,mm7
+ paddusb mm4,mm0
+ paddusb mm5,mm2
+ paddusb mm4,mm6
+ paddusb mm5,mm6
+ movq [edi],mm4
+ movq [edi+8],mm5
+ add edi,ebx
+ add esi,ebx
+ dec ecx
+ jnz near .recva1
+ emms
+ pop edx
+ pop ebx
+ pop ecx
+ pop edi
+ pop esi
+ ret
+
+ align 16
+recvac_mmx:
+ push esi
+ push edi
+ push ecx
+ push ebx
+ push edx
+ mov esi, [esp+source]
+ mov edi, [esp+dest]
+ mov ecx, [esp+h]
+ mov ebx, [esp+lx2]
+ mov edx, [esp+lx]
+ movq mm5, [MASK_AND]
+ movq mm6, [ADD_1]
+.recvac1:
+ movq mm0,[esi]
+ movq mm1,[esi+edx]
+ movq mm4,[edi]
+ psrlw mm0,1
+ psrlw mm1,1
+ psrlw mm4,1
+ pand mm0,mm5
+ pand mm1,mm5
+ pand mm4,mm5
+ paddusb mm0,mm1
+ paddusb mm0,mm6
+ psrlw mm0,1
+ pand mm0,mm5
+ paddusb mm4,mm0
+ paddusb mm4,mm6
+ movq [edi],mm4
+ add edi,ebx
+ add esi,ebx
+ dec ecx
+ jnz .recvac1
+ emms
+ pop edx
+ pop ebx
+ pop ecx
+ pop edi
+ pop esi
+ ret
+
+%assign RegisterStorageSize 20
+%assign rfp LocalFrameSize + RegisterStorageSize + 4
+%assign bp LocalFrameSize + RegisterStorageSize + 8
+%assign iincr LocalFrameSize + RegisterStorageSize + 12
+
+; FIXME clipping needs to be done
+
+ align 16
+add_block_mmx:
+ push esi
+ push edi
+ push ecx
+ push ebx
+ push edx
+ mov esi, [esp+bp]
+ mov edi, [esp+rfp]
+ mov ebx, [esp+iincr]
+; movq mm7, [PLUS_384]
+ mov ecx,8
+ pxor mm2,mm2 ; clear
+%rep 8
+ movq mm0, [edi] ; get dest
+ movq mm1,mm0
+ punpcklbw mm0,mm2
+ punpckhbw mm1,mm2
+ paddsw mm0, [esi]
+ paddsw mm1, [esi+8]
+; paddsw mm0, mm7
+; paddsw mm1, mm7
+ packuswb mm0,mm1
+ movq [edi], mm0
+ add edi,ebx
+ add esi,16
+%endrep
+ emms
+ pop edx
+ pop ebx
+ pop ecx
+ pop edi
+ pop esi
+ ret
+
+ align 16
+set_block_mmx:
+ push esi
+ push edi
+ push ecx
+ push ebx
+ push edx
+ mov esi, [esp+bp]
+ mov edi, [esp+rfp]
+ mov ebx, [esp+iincr]
+ movq mm7, [PLUS_128]
+%rep 4
+ movq mm0, [esi]
+ movq mm1, [esi+8]
+ paddsw mm0, mm7
+ movq mm2, [esi+16]
+ paddsw mm1, mm7
+ movq mm3, [esi+24]
+ paddsw mm2, mm7
+ packuswb mm0, mm1
+ paddsw mm3, mm7
+ movq [edi], mm0
+ packuswb mm2, mm3
+ add edi, ebx
+ add esi, 32
+ movq [edi], mm2
+ add edi, ebx
+%endrep
+ emms
+ pop edx
+ pop ebx
+ pop ecx
+ pop edi
+ pop esi
+ ret
+
+
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 @@
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include "mpeg3video.h"
+#include <stdio.h>
+
+#ifdef HAVE_MMX
+
+#ifdef HAVE_3Dnow
+static inline void recva_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
+{
+ __asm__(
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq 8(%1), %%mm1\n" /* 8 s */
+ "movq (%4), %%mm2\n" /* 8 s +lx */
+ "movq 8(%4), %%mm3\n" /* 8 s +lx **/
+
+ "pavgusb %%mm2, %%mm0\n"
+ "addl %3, %1\n"
+ "pavgusb %%mm3, %%mm1\n"
+
+ "movq (%2), %%mm2\n" /* 8 d */
+ "movq 8(%2), %%mm3\n" /* 8 d */
+ "pavgusb %%mm2, %%mm0\n"
+ "addl %3, %4\n"
+ "pavgusb %%mm3, %%mm1\n"
+
+ "movq %%mm0, (%2)\n"
+ "movq %%mm1, 8(%2)\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
+ );
+}
+
+static inline void recvac_mmx(unsigned char *s, unsigned char *d, int lx,int lx2, int h)
+{
+ __asm__(
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq (%4), %%mm2\n" /* 8 s +lx */
+ "addl %3, %1\n"
+ "pavgusb %%mm2, %%mm0\n"
+ "movq (%2), %%mm3\n" /* 8 d */
+ "addl %3, %4\n"
+ "pavgusb %%mm3, %%mm0\n"
+ "movq %%mm0, (%2)\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
+ );
+}
+
+static inline void rech_mmx(unsigned char *s, unsigned char *d, int lx2, int h)
+{
+ __asm__ (
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq 8(%1), %%mm1\n" /* 8 s */
+ "movq 1(%1), %%mm2\n" /* 8 s */
+ "movq 9(%1), %%mm3\n" /* 8 s */
+
+ "pavgusb %%mm2, %%mm0\n"
+ "addl %3, %1\n"
+ "pavgusb %%mm3, %%mm1\n"
+
+ "movq %%mm0, (%2)\n"
+ "movq %%mm1, 8(%2)\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2)
+ );
+}
+
+static inline void rechc_mmx(unsigned char *s, unsigned char *d, int lx2, int h)
+{
+ __asm__ (
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq 1(%1), %%mm2\n" /* 8 s +1 */
+ "addl %3, %1\n"
+ "pavgusb %%mm2, %%mm0\n"
+ "movq %%mm0, (%2)\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2)
+ );
+}
+
+static inline void recha_mmx(unsigned char *s, unsigned char *d,int lx2, int h)
+{
+ __asm__ (
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq 8(%1), %%mm1\n" /* 8 s */
+ "movq 1(%1), %%mm2\n" /* 8 s */
+ "movq 9(%1), %%mm3\n" /* 8 s */
+
+ "pavgusb %%mm2, %%mm0\n"
+ "addl %3, %1\n"
+ "pavgusb %%mm3, %%mm1\n"
+
+ "movq (%2), %%mm2\n" /* 8 d */
+ "movq 8(%2), %%mm3\n" /* 8 d */
+ "pavgusb %%mm2, %%mm0\n"
+ "pavgusb %%mm3, %%mm1\n"
+
+ "movq %%mm0, (%2)\n"
+ "movq %%mm1, 8(%2)\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2)
+ );
+}
+
+static inline void rechac_mmx(unsigned char *s,unsigned char *d, int lx2, int h)
+{
+ __asm__ (
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq 1(%1), %%mm2\n" /* 8 s */
+
+ "addl %3, %1\n"
+ "pavgusb %%mm2, %%mm0\n"
+
+ "movq (%2), %%mm1\n" /* 8 d */
+ "pavgusb %%mm1, %%mm0\n"
+
+ "movq %%mm0, (%2)\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2)
+ );
+}
+
+static inline void rec4_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
+{
+ __asm__ __volatile__(
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq 8(%1), %%mm1\n" /* 8 s */
+ "movq 1(%1), %%mm2\n" /* 8 s +1*/
+ "movq 9(%1), %%mm3\n" /* 8 s +1*/
+ ".align 8\n"
+ "1:"
+ "movq (%4), %%mm4\n" /* 8 s+lx */
+ "pavgusb %%mm2, %%mm0\n"
+ "movq 8(%4), %%mm5\n" /* 8 s+lx */
+ "pavgusb %%mm3, %%mm1\n"
+
+ "movq 1(%4), %%mm6\n" /* 8 s+lx +1*/
+ "pavgusb %%mm4, %%mm0\n"
+ "movq 9(%4), %%mm7\n" /* 8 s+lx +1*/
+ "pavgusb %%mm5, %%mm1\n"
+
+ "pavgusb %%mm6, %%mm0\n"
+ "addl %3, %4\n"
+ "pavgusb %%mm7, %%mm1\n"
+ "movq %%mm0, (%2)\n"
+ "movq %%mm6, %%mm2\n"
+ "movq %%mm7, %%mm3\n"
+ "movq %%mm1, 8(%2)\n"
+ "movq %%mm4, %%mm0\n"
+ "movq %%mm5, %%mm1\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
+ );
+}
+
+static inline void rec4c_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
+{
+ __asm__ __volatile__(
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq 1(%1), %%mm2\n" /* 8 s +1*/
+ ".align 8\n"
+ "1:"
+ "movq (%4), %%mm4\n" /* 8 s+lx */
+ "pavgusb %%mm2, %%mm0\n"
+
+ "movq 1(%4), %%mm6\n" /* 8 s+lx +1*/
+ "pavgusb %%mm4, %%mm0\n"
+
+ "addl %3, %4\n"
+ "pavgusb %%mm6, %%mm0\n"
+ "movq %%mm0, (%2)\n"
+ "movq %%mm6, %%mm2\n"
+ "movq %%mm4, %%mm0\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
+ );
+}
+
+static inline void rec4a_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
+{
+ __asm__ __volatile__(
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq 8(%1), %%mm1\n" /* 8 s */
+ "movq 1(%1), %%mm2\n" /* 8 s +1*/
+ "movq 9(%1), %%mm3\n" /* 8 s +1*/
+ ".align 8\n"
+ "1:"
+ "movq (%4), %%mm4\n" /* 8 s+lx */
+ "pavgusb %%mm2, %%mm0\n"
+ "movq 8(%4), %%mm5\n" /* 8 s+lx */
+ "pavgusb %%mm3, %%mm1\n"
+
+ "movq 1(%4), %%mm6\n" /* 8 s+lx +1*/
+ "pavgusb %%mm4, %%mm0\n"
+ "movq 9(%4), %%mm7\n" /* 8 s+lx +1*/
+ "pavgusb %%mm5, %%mm1\n"
+ "movq (%2), %%mm2\n"
+ "pavgusb %%mm6, %%mm0\n"
+ "movq 8(%2), %%mm3\n"
+
+ "pavgusb %%mm2, %%mm0\n"
+ "addl %3, %4\n"
+ "pavgusb %%mm3, %%mm1\n"
+ "movq %%mm0, (%2)\n"
+
+ "pavgusb %%mm7, %%mm1\n"
+ "movq %%mm6, %%mm2\n"
+ "movq %%mm7, %%mm3\n"
+ "movq %%mm1, 8(%2)\n"
+ "movq %%mm4, %%mm0\n"
+ "movq %%mm5, %%mm1\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
+ );
+}
+
+static inline void rec4ac_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
+{
+ __asm__ __volatile__(
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq 1(%1), %%mm2\n" /* 8 s +1*/
+ ".align 8\n"
+ "1:"
+ "movq (%4), %%mm4\n" /* 8 s+lx */
+ "pavgusb %%mm2, %%mm0\n"
+
+ "movq 1(%4), %%mm6\n" /* 8 s+lx +1*/
+ "pavgusb %%mm4, %%mm0\n"
+ "movq (%2), %%mm1\n" /* 8 d */
+ "pavgusb %%mm6, %%mm0\n"
+ "addl %3, %4\n"
+ "pavgusb %%mm1, %%mm0\n"
+ "movq %%mm6, %%mm2\n"
+ "movq %%mm0, (%2)\n"
+ "movq %%mm4, %%mm0\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
+ );
+}
+
+#else // HAVE_3DNOW
+ static LONGLONG ADD_1 = 0x0101010101010101LL;
+ static LONGLONG MASK_AND = 0x7f7f7f7f7f7f7f7fLL;
+#endif
+
+static inline void rec_mmx(unsigned char *s, unsigned char *d, int lx2, int h)
+{
+ __asm__ __volatile__(
+ ".align 8\n"
+ "1:\t"
+ "movq ( %1 ), %%mm0\n" /* 8 s */
+ "movq 8( %1 ), %%mm2\n" /* 16 s */
+ "movq %%mm0, ( %2 )\n"
+ "addl %3, %1\n"
+ "movq %%mm2, 8( %2 )\n"
+ "decl %0\n"
+ "leal (%2, %3), %2\n"
+ "jnz 1b"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2)
+ );
+}
+
+
+static inline void recc_mmx(unsigned char *s, unsigned char *d, int lx2, int h)
+{
+ __asm__ __volatile__(
+ ".align 8\n"
+ "1:\t"
+ "movq ( %1 ), %%mm0\n"
+ "addl %3, %1\n"
+ "movq %%mm0, ( %2 )\n"
+ "decl %0\n"
+ "leal (%2, %3), %2\n"
+ "jnz 1b"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2)
+ );
+}
+
+
+static inline void reca_mmx(unsigned char *s, unsigned char *d, int lx2, int h)
+{
+#ifdef HAVE_3Dnow
+ __asm__ (
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq (%2), %%mm2\n" /* 8 d */
+ "movq 8(%1), %%mm1\n" /* 8 s */
+ "movq 8(%2), %%mm3\n" /* 8 d */
+ "pavgusb %%mm2, %%mm0\n"
+ "addl %3, %1\n"
+ "pavgusb %%mm3, %%mm1\n"
+
+ "movq %%mm0, (%2)\n"
+ "movq %%mm1, 8(%2)\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2)
+ );
+#else /* No 3dnow */
+ __asm__ (
+ "movq MASK_AND, %%mm5\n"
+ "movq ADD_1, %%mm6\n"
+ "1:\t"
+ "movq (%1),%%mm0\n" /* Load 16 pixels from each row */
+ "movq (%2),%%mm1\n"
+ "movq 8(%1),%%mm2\n"
+ "movq 8(%2),%%mm3\n"
+ "psrlw $1,%%mm0\n" /* Shift pixels down */
+ "psrlw $1,%%mm1\n"
+ "pand %%mm5,%%mm0\n" /* Zero out significant bit */
+ "psrlw $1,%%mm2\n"
+ "pand %%mm5,%%mm1\n"
+ "psrlw $1,%%mm3\n"
+ "pand %%mm5,%%mm2\n"
+ "paddusb %%mm1,%%mm0\n" /* Add pixels */
+ "pand %%mm5,%%mm3\n"
+ "paddusb %%mm3,%%mm2\n"
+ "paddusb %%mm6,%%mm0\n" /* Add 1 to results */
+ "paddusb %%mm6,%%mm2\n"
+ "movq %%mm0,(%2)\n"
+ "addl %3,%1\n"
+ "movq %%mm2, 8(%2)\n"
+ "decl %0\n"
+ "leal (%2, %3), %2\n"
+ "jnz 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2)
+ );
+#endif
+}
+
+
+static inline void recac_mmx(unsigned char *s, unsigned char *d, int lx2, int h)
+{
+#ifdef HAVE_3Dnow
+ __asm__ (
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq (%2), %%mm2\n" /* 8 d */
+ "pavgusb %%mm2, %%mm0\n"
+ "addl %3, %1\n"
+ "movq %%mm0, (%2)\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2)
+ );
+#else /* No 3dnow */
+ __asm__ (
+ "movq MASK_AND, %%mm5\n"
+ "movq ADD_1, %%mm6\n"
+ "1:\t"
+ "movq (%1),%%mm0\n"
+ "movq (%2),%%mm1\n"
+ "psrlw $1,%%mm0\n"
+ "psrlw $1,%%mm1\n"
+ "pand %%mm5,%%mm0\n"
+ "pand %%mm5,%%mm1\n"
+ "paddusb %%mm1,%%mm0\n"
+ "paddusb %%mm6,%%mm0\n"
+ "addl %3,%1\n"
+ "movq %%mm0,(%2)\n"
+ "decl %0\n"
+ "leal (%2, %3), %2\n"
+ "jnz 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2)
+ );
+#endif
+}
+
+
+static inline void recv_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
+{
+#ifdef HAVE_3Dnow
+ __asm__(
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq (%4), %%mm2\n" /* 8 s +lx */
+ "movq 8(%1), %%mm1\n" /* 8 s */
+ "movq 8(%4), %%mm3\n" /* 8 s +lx **/
+
+ "pavgusb %%mm2, %%mm0\n"
+ "addl %3, %1\n"
+ "pavgusb %%mm3, %%mm1\n"
+
+ "movq %%mm0, (%2)\n"
+ "addl %3, %4\n"
+ "movq %%mm1, 8(%2)\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
+ );
+#else
+ __asm__ (
+ "movq MASK_AND, %%mm5\n"
+ "movq ADD_1, %%mm6\n"
+ "1:\t"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq (%4), %%mm1\n" /* 8 s +lx */
+ "movq 8(%1), %%mm2\n" /* 8 s */
+ "movq 8(%4), %%mm3\n" /* 8 s +lx **/
+ "psrlw $1,%%mm0\n"
+ "psrlw $1,%%mm1\n"
+ "pand %%mm5,%%mm0\n"
+ "psrlw $1,%%mm2\n"
+ "pand %%mm5,%%mm1\n"
+ "psrlw $1,%%mm3\n"
+ "pand %%mm5,%%mm2\n"
+ "paddusb %%mm1,%%mm0\n"
+ "pand %%mm5,%%mm3\n"
+ "paddusb %%mm3,%%mm2\n"
+ "paddusb %%mm6,%%mm0\n"
+ "paddusb %%mm6,%%mm2\n"
+ "movq %%mm0,(%2)\n"
+ "addl %3,%1\n"
+ "movq %%mm2, 8(%2)\n"
+ "addl %3,%4\n"
+ "decl %0\n"
+ "leal (%2, %3), %2\n"
+ "jnz 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
+ );
+#endif
+}
+
+
+static inline void recvc_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
+{
+#ifdef HAVE_3Dnow
+ __asm__(
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq (%4), %%mm2\n" /* 8 s +lx */
+ "addl %3, %1\n"
+ "pavgusb %%mm2, %%mm0\n"
+ "addl %3, %4\n"
+ "movq %%mm0, (%2)\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
+ );
+#else
+ __asm__ (
+ "movq MASK_AND, %%mm5\n"
+ "movq ADD_1, %%mm6\n"
+ "1:\t"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq (%4), %%mm1\n" /* 8 s +lx */
+ "psrlw $1,%%mm0\n"
+ "psrlw $1,%%mm1\n"
+ "pand %%mm5,%%mm0\n"
+ "pand %%mm5,%%mm1\n"
+ "paddusb %%mm1,%%mm0\n"
+ "addl %3,%1\n"
+ "paddusb %%mm6,%%mm0\n"
+ "addl %3,%4\n"
+ "movq %%mm0,(%2)\n"
+ "decl %0\n"
+ "leal (%2, %3), %2\n"
+ "jnz 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
+ );
+#endif
+}
+
+#endif // HAVE_MMX
+
+static inline void rec(unsigned char *s, unsigned char *d, int lx2, int h)
+{
+ int j;
+ for(j = 0; j < h; j++, s += lx2, d += lx2)
+ {
+ d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; d[3] = s[3];
+ d[4] = s[4]; d[5] = s[5]; d[6] = s[6]; d[7] = s[7];
+ d[8] = s[8]; d[9] = s[9]; d[10] = s[10]; d[11] = s[11];
+ d[12] = s[12]; d[13] = s[13]; d[14] = s[14]; d[15] = s[15];
+ }
+}
+
+
+
+static inline void recc(unsigned char *s, unsigned char *d, int lx2, int h)
+{
+ int j;
+ for(j = 0; j < h; j++, s += lx2, d += lx2)
+ {
+ d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; d[3] = s[3];
+ d[4] = s[4]; d[5] = s[5]; d[6] = s[6]; d[7] = s[7];
+ }
+}
+
+static inline void reca(unsigned char *s, unsigned char *d, int lx2, int h)
+{
+ int j;
+ for(j = 0; j < h; j++, s +=lx2, d +=lx2)
+ {
+ d[0] = (unsigned int)(d[0] + s[0] + 1) >> 1;
+ d[1] = (unsigned int)(d[1] + s[1] + 1) >> 1;
+ d[2] = (unsigned int)(d[2] + s[2] + 1) >> 1;
+ d[3] = (unsigned int)(d[3] + s[3] + 1) >> 1;
+ d[4] = (unsigned int)(d[4] + s[4] + 1) >> 1;
+ d[5] = (unsigned int)(d[5] + s[5] + 1) >> 1;
+ d[6] = (unsigned int)(d[6] + s[6] + 1) >> 1;
+ d[7] = (unsigned int)(d[7] + s[7] + 1) >> 1;
+ d[8] = (unsigned int)(d[8] + s[8] + 1) >> 1;
+ d[9] = (unsigned int)(d[9] + s[9] + 1) >> 1;
+ d[10] = (unsigned int)(d[10] + s[10] + 1) >> 1;
+ d[11] = (unsigned int)(d[11] + s[11] + 1) >> 1;
+ d[12] = (unsigned int)(d[12] + s[12] + 1) >> 1;
+ d[13] = (unsigned int)(d[13] + s[13] + 1) >> 1;
+ d[14] = (unsigned int)(d[14] + s[14] + 1) >> 1;
+ d[15] = (unsigned int)(d[15] + s[15] + 1) >> 1;
+ }
+}
+
+static inline void recac(unsigned char *s, unsigned char *d, int lx2, int h)
+{
+ int j;
+ for(j = 0; j < h; j++, s += lx2, d += lx2)
+ {
+ d[0] = (unsigned int)(d[0] + s[0] + 1)>>1;
+ d[1] = (unsigned int)(d[1] + s[1] + 1)>>1;
+ d[2] = (unsigned int)(d[2] + s[2] + 1)>>1;
+ d[3] = (unsigned int)(d[3] + s[3] + 1)>>1;
+ d[4] = (unsigned int)(d[4] + s[4] + 1)>>1;
+ d[5] = (unsigned int)(d[5] + s[5] + 1)>>1;
+ d[6] = (unsigned int)(d[6] + s[6] + 1)>>1;
+ d[7] = (unsigned int)(d[7] + s[7] + 1)>>1;
+ }
+}
+
+static inline void recv_(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
+{
+ unsigned char *dp,*sp,*sp2;
+ int j;
+ sp = s;
+ sp2 = s + lx;
+ dp = d;
+ for(j = 0; j < h; j++)
+ {
+ dp[0] = (unsigned int)(sp[0] + sp2[0] + 1) >> 1;
+ dp[1] = (unsigned int)(sp[1] + sp2[1] + 1) >> 1;
+ dp[2] = (unsigned int)(sp[2] + sp2[2] + 1) >> 1;
+ dp[3] = (unsigned int)(sp[3] + sp2[3] + 1) >> 1;
+ dp[4] = (unsigned int)(sp[4] + sp2[4] + 1) >> 1;
+ dp[5] = (unsigned int)(sp[5] + sp2[5] + 1) >> 1;
+ dp[6] = (unsigned int)(sp[6] + sp2[6] + 1) >> 1;
+ dp[7] = (unsigned int)(sp[7] + sp2[7] + 1) >> 1;
+ dp[8] = (unsigned int)(sp[8] + sp2[8] + 1) >> 1;
+ dp[9] = (unsigned int)(sp[9] + sp2[9] + 1) >> 1;
+ dp[10] = (unsigned int)(sp[10] + sp2[10] + 1) >> 1;
+ dp[11] = (unsigned int)(sp[11] + sp2[11] + 1) >> 1;
+ dp[12] = (unsigned int)(sp[12] + sp2[12] + 1) >> 1;
+ dp[13] = (unsigned int)(sp[13] + sp2[13] + 1) >> 1;
+ dp[14] = (unsigned int)(sp[14] + sp2[14] + 1) >> 1;
+ dp[15] = (unsigned int)(sp[15] + sp2[15] + 1) >> 1;
+ sp+= lx2;
+ sp2+= lx2;
+ dp+= lx2;
+ }
+}
+
+static inline void recvc(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
+{
+ unsigned char *dp,*sp,*sp2;
+ int j;
+
+ sp = s;
+ sp2 = s+lx;
+ dp = d;
+ for(j = 0; j < h; j++)
+ {
+ dp[0] = (unsigned int)(sp[0]+sp2[0]+1)>>1;
+ dp[1] = (unsigned int)(sp[1]+sp2[1]+1)>>1;
+ dp[2] = (unsigned int)(sp[2]+sp2[2]+1)>>1;
+ dp[3] = (unsigned int)(sp[3]+sp2[3]+1)>>1;
+ dp[4] = (unsigned int)(sp[4]+sp2[4]+1)>>1;
+ dp[5] = (unsigned int)(sp[5]+sp2[5]+1)>>1;
+ dp[6] = (unsigned int)(sp[6]+sp2[6]+1)>>1;
+ dp[7] = (unsigned int)(sp[7]+sp2[7]+1)>>1;
+ sp+= lx2;
+ sp2+= lx2;
+ dp+= lx2;
+ }
+}
+
+
+static inline void recva(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
+{
+ unsigned char *dp,*sp,*sp2;
+ int j;
+
+ sp = s;
+ sp2 = s+lx;
+ dp = d;
+ for (j=0; j<h; j++){
+ dp[0] = (dp[0] + ((unsigned int)(sp[0]+sp2[0]+1)>>1) + 1)>>1;
+ dp[1] = (dp[1] + ((unsigned int)(sp[1]+sp2[1]+1)>>1) + 1)>>1;
+ dp[2] = (dp[2] + ((unsigned int)(sp[2]+sp2[2]+1)>>1) + 1)>>1;
+ dp[3] = (dp[3] + ((unsigned int)(sp[3]+sp2[3]+1)>>1) + 1)>>1;
+ dp[4] = (dp[4] + ((unsigned int)(sp[4]+sp2[4]+1)>>1) + 1)>>1;
+ dp[5] = (dp[5] + ((unsigned int)(sp[5]+sp2[5]+1)>>1) + 1)>>1;
+ dp[6] = (dp[6] + ((unsigned int)(sp[6]+sp2[6]+1)>>1) + 1)>>1;
+ dp[7] = (dp[7] + ((unsigned int)(sp[7]+sp2[7]+1)>>1) + 1)>>1;
+ dp[8] = (dp[8] + ((unsigned int)(sp[8]+sp2[8]+1)>>1) + 1)>>1;
+ dp[9] = (dp[9] + ((unsigned int)(sp[9]+sp2[9]+1)>>1) + 1)>>1;
+ dp[10] = (dp[10] + ((unsigned int)(sp[10]+sp2[10]+1)>>1) + 1)>>1;
+ dp[11] = (dp[11] + ((unsigned int)(sp[11]+sp2[11]+1)>>1) + 1)>>1;
+ dp[12] = (dp[12] + ((unsigned int)(sp[12]+sp2[12]+1)>>1) + 1)>>1;
+ dp[13] = (dp[13] + ((unsigned int)(sp[13]+sp2[13]+1)>>1) + 1)>>1;
+ dp[14] = (dp[14] + ((unsigned int)(sp[14]+sp2[14]+1)>>1) + 1)>>1;
+ dp[15] = (dp[15] + ((unsigned int)(sp[15]+sp2[15]+1)>>1) + 1)>>1;
+ sp+= lx2;
+ sp2+= lx2;
+ dp+= lx2;
+ }
+}
+
+
+static inline void recvac(unsigned char *s, unsigned char *d, int lx,int lx2, int h){
+ unsigned char *dp,*sp,*sp2;
+ int j;
+
+ sp = s;
+ sp2 = s+lx;
+ dp = d;
+ for (j=0; j<h; j++){
+ dp[0] = (dp[0] + ((unsigned int)(sp[0]+sp2[0]+1)>>1) + 1)>>1;
+ dp[1] = (dp[1] + ((unsigned int)(sp[1]+sp2[1]+1)>>1) + 1)>>1;
+ dp[2] = (dp[2] + ((unsigned int)(sp[2]+sp2[2]+1)>>1) + 1)>>1;
+ dp[3] = (dp[3] + ((unsigned int)(sp[3]+sp2[3]+1)>>1) + 1)>>1;
+ dp[4] = (dp[4] + ((unsigned int)(sp[4]+sp2[4]+1)>>1) + 1)>>1;
+ dp[5] = (dp[5] + ((unsigned int)(sp[5]+sp2[5]+1)>>1) + 1)>>1;
+ dp[6] = (dp[6] + ((unsigned int)(sp[6]+sp2[6]+1)>>1) + 1)>>1;
+ dp[7] = (dp[7] + ((unsigned int)(sp[7]+sp2[7]+1)>>1) + 1)>>1;
+ sp+= lx2;
+ sp2+= lx2;
+ dp+= lx2;
+ }
+}
+
+
+static inline void rech(unsigned char *s, unsigned char *d, int lx2, int h){
+ unsigned char *dp,*sp;
+ unsigned int s1,s2;
+ int j;
+
+ sp = s;
+ dp = d;
+ for (j=0; j<h; j++){
+ s1=sp[0];
+ dp[0] = (unsigned int)(s1+(s2=sp[1])+1)>>1;
+ dp[1] = (unsigned int)(s2+(s1=sp[2])+1)>>1;
+ dp[2] = (unsigned int)(s1+(s2=sp[3])+1)>>1;
+ dp[3] = (unsigned int)(s2+(s1=sp[4])+1)>>1;
+ dp[4] = (unsigned int)(s1+(s2=sp[5])+1)>>1;
+ dp[5] = (unsigned int)(s2+(s1=sp[6])+1)>>1;
+ dp[6] = (unsigned int)(s1+(s2=sp[7])+1)>>1;
+ dp[7] = (unsigned int)(s2+(s1=sp[8])+1)>>1;
+ dp[8] = (unsigned int)(s1+(s2=sp[9])+1)>>1;
+ dp[9] = (unsigned int)(s2+(s1=sp[10])+1)>>1;
+ dp[10] = (unsigned int)(s1+(s2=sp[11])+1)>>1;
+ dp[11] = (unsigned int)(s2+(s1=sp[12])+1)>>1;
+ dp[12] = (unsigned int)(s1+(s2=sp[13])+1)>>1;
+ dp[13] = (unsigned int)(s2+(s1=sp[14])+1)>>1;
+ dp[14] = (unsigned int)(s1+(s2=sp[15])+1)>>1;
+ dp[15] = (unsigned int)(s2+sp[16]+1)>>1;
+ sp+= lx2;
+ dp+= lx2;
+ }
+}
+
+
+static inline void rechc(unsigned char *s,unsigned char *d, int lx2, int h){
+ unsigned char *dp,*sp;
+ unsigned int s1,s2;
+ int j;
+
+ sp = s;
+ dp = d;
+ for (j=0; j<h; j++){
+ s1=sp[0];
+ dp[0] = (unsigned int)(s1+(s2=sp[1])+1)>>1;
+ dp[1] = (unsigned int)(s2+(s1=sp[2])+1)>>1;
+ dp[2] = (unsigned int)(s1+(s2=sp[3])+1)>>1;
+ dp[3] = (unsigned int)(s2+(s1=sp[4])+1)>>1;
+ dp[4] = (unsigned int)(s1+(s2=sp[5])+1)>>1;
+ dp[5] = (unsigned int)(s2+(s1=sp[6])+1)>>1;
+ dp[6] = (unsigned int)(s1+(s2=sp[7])+1)>>1;
+ dp[7] = (unsigned int)(s2+sp[8]+1)>>1;
+ sp+= lx2;
+ dp+= lx2;
+ }
+}
+
+static inline void recha(unsigned char *s, unsigned char *d,int lx2, int h)
+{
+ unsigned char *dp,*sp;
+ unsigned int s1,s2;
+ int j;
+
+ sp = s;
+ dp = d;
+ for (j = 0; j < h; j++)
+ {
+ s1 = sp[0];
+ dp[0] = (dp[0] + ((unsigned int)(s1 + (s2 = sp[1]) + 1) >> 1) + 1) >> 1;
+ dp[1] = (dp[1] + ((unsigned int)(s2 + (s1 = sp[2]) + 1) >> 1) + 1) >> 1;
+ dp[2] = (dp[2] + ((unsigned int)(s1 + (s2 = sp[3]) + 1) >> 1) + 1) >> 1;
+ dp[3] = (dp[3] + ((unsigned int)(s2 + (s1 = sp[4]) + 1) >> 1) + 1) >> 1;
+ dp[4] = (dp[4] + ((unsigned int)(s1 + (s2 = sp[5]) + 1) >> 1) + 1) >> 1;
+ dp[5] = (dp[5] + ((unsigned int)(s2 + (s1 = sp[6]) + 1) >> 1) + 1) >> 1;
+ dp[6] = (dp[6] + ((unsigned int)(s1 + (s2 = sp[7]) + 1) >> 1) + 1) >> 1;
+ dp[7] = (dp[7] + ((unsigned int)(s2 + (s1 = sp[8]) + 1) >> 1) + 1) >> 1;
+ dp[8] = (dp[8] + ((unsigned int)(s1 + (s2 = sp[9]) + 1) >> 1) + 1) >> 1;
+ dp[9] = (dp[9] + ((unsigned int)(s2 + (s1 = sp[10]) + 1) >> 1) + 1) >> 1;
+ dp[10] = (dp[10] + ((unsigned int)(s1 + (s2 = sp[11]) + 1) >> 1) + 1) >> 1;
+ dp[11] = (dp[11] + ((unsigned int)(s2 + (s1 = sp[12]) + 1) >> 1) + 1) >> 1;
+ dp[12] = (dp[12] + ((unsigned int)(s1 + (s2 = sp[13]) + 1) >> 1) + 1) >> 1;
+ dp[13] = (dp[13] + ((unsigned int)(s2 + (s1 = sp[14]) + 1) >> 1) + 1) >> 1;
+ dp[14] = (dp[14] + ((unsigned int)(s1 + (s2 = sp[15]) + 1) >> 1) + 1) >> 1;
+ dp[15] = (dp[15] + ((unsigned int)(s2 + sp[16] + 1) >> 1) + 1) >> 1;
+ sp += lx2;
+ dp += lx2;
+ }
+}
+
+
+static inline void rechac(unsigned char *s,unsigned char *d, int lx2, int h)
+{
+ unsigned char *dp,*sp;
+ unsigned int s1,s2;
+ int j;
+
+ sp = s;
+ dp = d;
+ for(j = 0; j < h; j++)
+ {
+ s1 = sp[0];
+ dp[0] = (dp[0] + ((unsigned int)(s1 + (s2 = sp[1]) + 1) >> 1) + 1) >> 1;
+ dp[1] = (dp[1] + ((unsigned int)(s2 + (s1 = sp[2]) + 1) >> 1) + 1) >> 1;
+ dp[2] = (dp[2] + ((unsigned int)(s1 + (s2 = sp[3]) + 1) >> 1) + 1) >> 1;
+ dp[3] = (dp[3] + ((unsigned int)(s2 + (s1 = sp[4]) + 1) >> 1) + 1) >> 1;
+ dp[4] = (dp[4] + ((unsigned int)(s1 + (s2 = sp[5]) + 1) >> 1) + 1) >> 1;
+ dp[5] = (dp[5] + ((unsigned int)(s2 + (s1 = sp[6]) + 1) >> 1) + 1) >> 1;
+ dp[6] = (dp[6] + ((unsigned int)(s1 + (s2 = sp[7]) + 1) >> 1) + 1) >> 1;
+ dp[7] = (dp[7] + ((unsigned int)(s2 + sp[8] + 1) >> 1) + 1) >> 1;
+ sp += lx2;
+ dp += lx2;
+ }
+}
+
+
+static inline void rec4(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
+{
+ unsigned char *dp,*sp,*sp2;
+ unsigned int s1,s2,s3,s4;
+ int j;
+
+ sp = s;
+ sp2 = s+lx;
+ dp = d;
+ for (j=0; j<h; j++){
+ s1=sp[0]; s3=sp2[0];
+ dp[0] = (unsigned int)(s1+(s2=sp[1])+s3+(s4=sp2[1])+2)>>2;
+ dp[1] = (unsigned int)(s2+(s1=sp[2])+s4+(s3=sp2[2])+2)>>2;
+ dp[2] = (unsigned int)(s1+(s2=sp[3])+s3+(s4=sp2[3])+2)>>2;
+ dp[3] = (unsigned int)(s2+(s1=sp[4])+s4+(s3=sp2[4])+2)>>2;
+ dp[4] = (unsigned int)(s1+(s2=sp[5])+s3+(s4=sp2[5])+2)>>2;
+ dp[5] = (unsigned int)(s2+(s1=sp[6])+s4+(s3=sp2[6])+2)>>2;
+ dp[6] = (unsigned int)(s1+(s2=sp[7])+s3+(s4=sp2[7])+2)>>2;
+ dp[7] = (unsigned int)(s2+(s1=sp[8])+s4+(s3=sp2[8])+2)>>2;
+ dp[8] = (unsigned int)(s1+(s2=sp[9])+s3+(s4=sp2[9])+2)>>2;
+ dp[9] = (unsigned int)(s2+(s1=sp[10])+s4+(s3=sp2[10])+2)>>2;
+ dp[10] = (unsigned int)(s1+(s2=sp[11])+s3+(s4=sp2[11])+2)>>2;
+ dp[11] = (unsigned int)(s2+(s1=sp[12])+s4+(s3=sp2[12])+2)>>2;
+ dp[12] = (unsigned int)(s1+(s2=sp[13])+s3+(s4=sp2[13])+2)>>2;
+ dp[13] = (unsigned int)(s2+(s1=sp[14])+s4+(s3=sp2[14])+2)>>2;
+ dp[14] = (unsigned int)(s1+(s2=sp[15])+s3+(s4=sp2[15])+2)>>2;
+ dp[15] = (unsigned int)(s2+sp[16]+s4+sp2[16]+2)>>2;
+ sp+= lx2;
+ sp2+= lx2;
+ dp+= lx2;
+ }
+}
+
+
+static inline void rec4c(unsigned char *s,unsigned char *d, int lx, int lx2, int h)
+{
+ unsigned char *dp,*sp,*sp2;
+ unsigned int s1,s2,s3,s4;
+ int j;
+
+ sp = s;
+ sp2 = s+lx;
+ dp = d;
+ for (j=0; j<h; j++){
+ s1=sp[0]; s3=sp2[0];
+ dp[0] = (unsigned int)(s1+(s2=sp[1])+s3+(s4=sp2[1])+2)>>2;
+ dp[1] = (unsigned int)(s2+(s1=sp[2])+s4+(s3=sp2[2])+2)>>2;
+ dp[2] = (unsigned int)(s1+(s2=sp[3])+s3+(s4=sp2[3])+2)>>2;
+ dp[3] = (unsigned int)(s2+(s1=sp[4])+s4+(s3=sp2[4])+2)>>2;
+ dp[4] = (unsigned int)(s1+(s2=sp[5])+s3+(s4=sp2[5])+2)>>2;
+ dp[5] = (unsigned int)(s2+(s1=sp[6])+s4+(s3=sp2[6])+2)>>2;
+ dp[6] = (unsigned int)(s1+(s2=sp[7])+s3+(s4=sp2[7])+2)>>2;
+ dp[7] = (unsigned int)(s2+sp[8]+s4+sp2[8]+2)>>2;
+ sp+= lx2;
+ sp2+= lx2;
+ dp+= lx2;
+ }
+}
+
+
+static inline void rec4a(unsigned char *s,unsigned char *d, int lx, int lx2, int h)
+{
+ unsigned char *dp=d, *sp=s, *sp2=s+lx;
+ unsigned int s1, s2, s3, s4;
+ int j;
+
+/*
+ sp = s;
+ sp2 = s+lx;
+ dp = d;
+*/
+ for (j=0; j<h; j++){
+ s1=sp[0]; s3=sp2[0];
+ dp[0] = (dp[0] + ((unsigned int)(s1+(s2=sp[1])+s3+(s4=sp2[1])+2)>>2) + 1)>>1;
+ dp[1] = (dp[1] + ((unsigned int)(s2+(s1=sp[2])+s4+(s3=sp2[2])+2)>>2) + 1)>>1;
+ dp[2] = (dp[2] + ((unsigned int)(s1+(s2=sp[3])+s3+(s4=sp2[3])+2)>>2) + 1)>>1;
+ dp[3] = (dp[3] + ((unsigned int)(s2+(s1=sp[4])+s4+(s3=sp2[4])+2)>>2) + 1)>>1;
+ dp[4] = (dp[4] + ((unsigned int)(s1+(s2=sp[5])+s3+(s4=sp2[5])+2)>>2) + 1)>>1;
+ dp[5] = (dp[5] + ((unsigned int)(s2+(s1=sp[6])+s4+(s3=sp2[6])+2)>>2) + 1)>>1;
+ dp[6] = (dp[6] + ((unsigned int)(s1+(s2=sp[7])+s3+(s4=sp2[7])+2)>>2) + 1)>>1;
+ dp[7] = (dp[7] + ((unsigned int)(s2+(s1=sp[8])+s4+(s3=sp2[8])+2)>>2) + 1)>>1;
+ dp[8] = (dp[8] + ((unsigned int)(s1+(s2=sp[9])+s3+(s4=sp2[9])+2)>>2) + 1)>>1;
+ dp[9] = (dp[9] + ((unsigned int)(s2+(s1=sp[10])+s4+(s3=sp2[10])+2)>>2) + 1)>>1;
+ dp[10] = (dp[10] + ((unsigned int)(s1+(s2=sp[11])+s3+(s4=sp2[11])+2)>>2) + 1)>>1;
+ dp[11] = (dp[11] + ((unsigned int)(s2+(s1=sp[12])+s4+(s3=sp2[12])+2)>>2) + 1)>>1;
+ dp[12] = (dp[12] + ((unsigned int)(s1+(s2=sp[13])+s3+(s4=sp2[13])+2)>>2) + 1)>>1;
+ dp[13] = (dp[13] + ((unsigned int)(s2+(s1=sp[14])+s4+(s3=sp2[14])+2)>>2) + 1)>>1;
+ dp[14] = (dp[14] + ((unsigned int)(s1+(s2=sp[15])+s3+(s4=sp2[15])+2)>>2) + 1)>>1;
+ dp[15] = (dp[15] + ((unsigned int)(s2+sp[16]+s4+sp2[16]+2)>>2) + 1)>>1;
+ sp+= lx2;
+ sp2+= lx2;
+ dp+= lx2;
+ }
+}
+
+
+static inline void rec4ac(unsigned char *s,unsigned char *d, int lx, int lx2, int h)
+{
+ unsigned char *dp=d, *sp=s, *sp2=s+lx;
+ unsigned int s1,s2,s3,s4;
+ int j;
+
+/*
+ sp = s;
+ sp2 = s+lx;
+ dp = d;
+*/
+ for (j=0; j<h; j++)
+ {
+ s1=sp[0]; s3=sp2[0];
+ dp[0] = (dp[0] + ((unsigned int)(s1+(s2=sp[1])+s3+(s4=sp2[1])+2)>>2) + 1)>>1;
+ dp[1] = (dp[1] + ((unsigned int)(s2+(s1=sp[2])+s4+(s3=sp2[2])+2)>>2) + 1)>>1;
+ dp[2] = (dp[2] + ((unsigned int)(s1+(s2=sp[3])+s3+(s4=sp2[3])+2)>>2) + 1)>>1;
+ dp[3] = (dp[3] + ((unsigned int)(s2+(s1=sp[4])+s4+(s3=sp2[4])+2)>>2) + 1)>>1;
+ dp[4] = (dp[4] + ((unsigned int)(s1+(s2=sp[5])+s3+(s4=sp2[5])+2)>>2) + 1)>>1;
+ dp[5] = (dp[5] + ((unsigned int)(s2+(s1=sp[6])+s4+(s3=sp2[6])+2)>>2) + 1)>>1;
+ dp[6] = (dp[6] + ((unsigned int)(s1+(s2=sp[7])+s3+(s4=sp2[7])+2)>>2) + 1)>>1;
+ dp[7] = (dp[7] + ((unsigned int)(s2+sp[8]+s4+sp2[8]+2)>>2) + 1)>>1;
+ sp+= lx2;
+ sp2+= lx2;
+ dp+= lx2;
+ }
+}
+
+static inline
+void recon_comp(mpeg3video_t *video,
+ unsigned char *src,
+ unsigned char *dst,
+ int lx,
+ int lx2,
+ int w,
+ int h,
+ int x,
+ int y,
+ int dx,
+ int dy,
+ int addflag)
+{
+ int switcher;
+ unsigned char *s, *d;
+
+/* half pel scaling */
+ switcher = (dx & 1) << 3 | (dy & 1) << 2 | w;
+ if(addflag) switcher |= 2;
+/* origins */
+ s = src + lx * (y + (dy >> 1)) + x + (dx >> 1);
+ d = dst + lx * y + x;
+
+// Accelerated functions
+#ifdef HAVE_3Dnow
+ if(video->have_mmx)
+ {
+ switch(switcher)
+ {
+ case 0x3: reca_mmx(s, d, lx2, h); break;
+ case 0x2: recac_mmx(s, d, lx2, h); break;
+ case 0x1: rec_mmx(s, d, lx2, h); break;
+ case 0x0: recc_mmx(s, d, lx2, h); break;
+ case 0x7: recva_mmx(s, d, lx, lx2, h); break;
+ case 0x6: recvac_mmx(s, d, lx, lx2, h); break;
+ case 0x5: recv_mmx(s, d, lx, lx2, h); break;
+ case 0x4: recvc_mmx(s, d, lx, lx2, h); break;
+ case 0x9: rech_mmx(s, d, lx2, h); break;
+ case 0x8: rechc_mmx(s, d, lx2, h); break;
+ }
+ }
+ else
+#endif
+ {
+ switch(switcher)
+ {
+ case 0x3: reca(s, d, lx2, h); break;
+ case 0x2: recac(s, d, lx2, h); break;
+ case 0x1: rec(s, d, lx2, h); break;
+ case 0x0: recc(s, d, lx2, h); break;
+ case 0x7: recva(s, d, lx, lx2, h); break;
+ case 0x6: recvac(s, d, lx, lx2, h); break;
+ case 0x5: recv_(s, d, lx, lx2, h); break;
+ case 0x4: recvc(s, d, lx, lx2, h); break;
+ case 0x9: rech(s, d, lx2, h); break;
+ case 0x8: rechc(s, d, lx2, h); break;
+ }
+ }
+
+// Unaccelerated functions
+ switch(switcher)
+ {
+ case 0xb: recha(s, d, lx2, h); break;
+ case 0xa: rechac(s, d, lx2, h); break;
+ case 0xf: rec4a(s, d, lx, lx2, h); break;
+ case 0xe: rec4ac(s, d, lx, lx2, h); break;
+ case 0xd: rec4(s, d, lx, lx2, h); break;
+ case 0xc: rec4c(s, d, lx, lx2, h); break;
+ }
+}
+
+/*
+ unsigned char *src[]; * prediction source buffer *
+ int sfield; * prediction source field number (0 or 1) *
+ unsigned char *dst[]; * prediction destination buffer *
+ int dfield; * prediction destination field number (0 or 1)*
+ int lx,lx2; * horizontal offsets *
+ int w,h; * prediction block/sub-block width, height *
+ int x,y; * pixel co-ordinates of top-left sample in current MB *
+ int dx,dy; * horizontal, vertical motion vector *
+ int addflag; * add prediction error to prediction ? *
+*/
+static void recon(mpeg3video_t *video,
+ unsigned char *src[],
+ int sfield,
+ unsigned char *dst[],
+ int dfield,
+ int lx,
+ int lx2,
+ int w,
+ int h,
+ int x,
+ int y,
+ int dx,
+ int dy,
+ int addflag)
+{
+
+/* Y */
+ recon_comp(video, (src[0] + (sfield ? (lx2 >> 1) : 0)),
+ dst[0] + (dfield ? (lx2 >> 1) : 0),
+ lx, lx2, w, h, x, y, dx, dy, addflag);
+
+ if(video->chroma_format != CHROMA444)
+ {
+ lx >>= 1;
+ dx /= 2;
+ lx2 >>= 1;
+ w = 0;
+ x >>= 1;
+ }
+
+ if(video->chroma_format == CHROMA420)
+ {
+ h >>= 1;
+ dy /= 2;
+ y >>= 1;
+ }
+
+/* Cb */
+ recon_comp(video, (src[1] + (sfield ? (lx2 >> 1) : 0)),
+ dst[1] + (dfield ? (lx2 >> 1) : 0),
+ lx, lx2, w, h, x, y, dx, dy, addflag);
+
+/* Cr */
+ recon_comp(video, (src[2] + (sfield ? (lx2 >> 1) : 0)),
+ dst[2] + (dfield ? (lx2 >> 1) : 0),
+ lx, lx2, w, h, x, y, dx, dy, addflag);
+}
+
+#define WIDTH 1
+
+int mpeg3video_reconstruct(mpeg3video_t *video,
+ int bx,
+ int by,
+ int mb_type,
+ int motion_type,
+ int PMV[2][2][2],
+ int mv_field_sel[2][2],
+ int dmvector[2],
+ int stwtype)
+{
+ int currentfield;
+ unsigned char **predframe;
+ int DMV[2][2];
+ int stwtop, stwbot;
+
+ stwtop = stwtype % 3; /* 0:temporal, 1 : (spat+temp) / 2, 2 : spatial */
+ stwbot = stwtype / 3;
+
+ if((mb_type & MB_FORWARD) || (video->pict_type == P_TYPE))
+ {
+ if(video->pict_struct == FRAME_PICTURE)
+ {
+ if((motion_type == MC_FRAME) || !(mb_type & MB_FORWARD))
+ {
+/* frame-based prediction */
+ {
+ if(stwtop < 2)
+ recon(video, video->oldrefframe, 0, video->newframe, 0,
+ video->coded_picture_width, video->coded_picture_width << 1, WIDTH, 8, bx, by,
+ PMV[0][0][0], PMV[0][0][1], stwtop);
+
+ if(stwbot < 2)
+ recon(video, video->oldrefframe, 1, video->newframe, 1,
+ video->coded_picture_width, video->coded_picture_width << 1, WIDTH, 8, bx, by,
+ PMV[0][0][0], PMV[0][0][1], stwbot);
+ }
+ }
+ else if(motion_type == MC_FIELD) /* field-based prediction */
+ {
+/* top field prediction */
+ if(stwtop < 2)
+ recon(video, video->oldrefframe, mv_field_sel[0][0], video->newframe, 0,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by >> 1,
+ PMV[0][0][0], PMV[0][0][1] >> 1, stwtop);
+
+/* bottom field prediction */
+ if(stwbot < 2)
+ recon(video, video->oldrefframe, mv_field_sel[1][0], video->newframe, 1,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by >> 1,
+ PMV[1][0][0], PMV[1][0][1] >> 1, stwbot);
+ }
+ else if(motion_type == MC_DMV)
+ {
+/* dual prime prediction */
+/* calculate derived motion vectors */
+ mpeg3video_calc_dmv(video,
+ DMV,
+ dmvector,
+ PMV[0][0][0],
+ PMV[0][0][1] >> 1);
+
+ if(stwtop < 2)
+ {
+/* predict top field from top field */
+ recon(video, video->oldrefframe, 0, video->newframe, 0,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by>>1,
+ PMV[0][0][0], PMV[0][0][1] >> 1, 0);
+
+/* predict and add to top field from bottom field */
+ recon(video, video->oldrefframe, 1, video->newframe, 0,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by>>1,
+ DMV[0][0], DMV[0][1], 1);
+ }
+
+ if(stwbot < 2)
+ {
+/* predict bottom field from bottom field */
+ recon(video, video->oldrefframe, 1, video->newframe, 1,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by>>1,
+ PMV[0][0][0], PMV[0][0][1]>>1, 0);
+
+/* predict and add to bottom field from top field */
+ recon(video, video->oldrefframe, 0, video->newframe, 1,
+ video->coded_picture_width << 1, video->coded_picture_width<<1, WIDTH, 8, bx, by>>1,
+ DMV[1][0], DMV[1][1], 1);
+ }
+ }
+ else
+/* invalid motion_type */
+/* fprintf(stderr, "reconstruct: invalid motion_type\n"); */
+ ;
+ }
+ else
+ {
+/* TOP_FIELD or BOTTOM_FIELD */
+/* field picture */
+ currentfield = (video->pict_struct == BOTTOM_FIELD);
+
+/* determine which frame to use for prediction */
+ if((video->pict_type == P_TYPE) && video->secondfield
+ && (currentfield != mv_field_sel[0][0]))
+ predframe = video->refframe; /* same frame */
+ else
+ predframe = video->oldrefframe; /* previous frame */
+
+ if((motion_type == MC_FIELD) || !(mb_type & MB_FORWARD))
+ {
+/* field-based prediction */
+ if(stwtop < 2)
+ recon(video, predframe,mv_field_sel[0][0],video->newframe,0,
+ video->coded_picture_width << 1,video->coded_picture_width << 1,WIDTH,16,bx,by,
+ PMV[0][0][0],PMV[0][0][1],stwtop);
+ }
+ else
+ if(motion_type == MC_16X8)
+ {
+ if(stwtop < 2)
+ {
+ recon(video, predframe, mv_field_sel[0][0], video->newframe, 0,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by,
+ PMV[0][0][0], PMV[0][0][1], stwtop);
+
+ /* determine which frame to use for lower half prediction */
+ if((video->pict_type==P_TYPE) && video->secondfield
+ && (currentfield!=mv_field_sel[1][0]))
+ predframe = video->refframe; /* same frame */
+ else
+ predframe = video->oldrefframe; /* previous frame */
+
+ recon(video, predframe, mv_field_sel[1][0], video->newframe, 0,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by+8,
+ PMV[1][0][0], PMV[1][0][1], stwtop);
+ }
+ }
+ else
+ if(motion_type == MC_DMV) /* dual prime prediction */
+ {
+ if(video->secondfield)
+ predframe = video->refframe; /* same frame */
+ else
+ predframe = video->oldrefframe; /* previous frame */
+
+/* calculate derived motion vectors */
+ mpeg3video_calc_dmv(video,
+ DMV,
+ dmvector,
+ PMV[0][0][0],
+ PMV[0][0][1]);
+
+/* predict from field of same parity */
+ recon(video, video->oldrefframe, currentfield, video->newframe, 0,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 16, bx, by,
+ PMV[0][0][0], PMV[0][0][1], 0);
+
+/* predict from field of opposite parity */
+ recon(video, predframe, !currentfield, video->newframe, 0,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 16, bx, by,
+ DMV[0][0], DMV[0][1], 1);
+ }
+ else
+/* invalid motion_type */
+/* fprintf(stderr, "reconstruct: invalid motion_type\n"); */
+ ;
+ }
+ stwtop = stwbot = 1;
+ }
+
+ if(mb_type & MB_BACKWARD)
+ {
+ if(video->pict_struct == FRAME_PICTURE)
+ {
+ if(motion_type == MC_FRAME)
+ {
+/* frame-based prediction */
+ if(stwtop < 2)
+ recon(video, video->refframe, 0, video->newframe, 0,
+ video->coded_picture_width, video->coded_picture_width << 1, WIDTH, 8, bx, by,
+ PMV[0][1][0], PMV[0][1][1], stwtop);
+
+ if(stwbot < 2)
+ recon(video, video->refframe, 1, video->newframe, 1,
+ video->coded_picture_width, video->coded_picture_width << 1, WIDTH, 8, bx, by,
+ PMV[0][1][0], PMV[0][1][1], stwbot);
+ }
+ else
+ {
+/* field-based prediction */
+/* top field prediction */
+ if(stwtop < 2)
+ {
+ recon(video, video->refframe, mv_field_sel[0][1], video->newframe, 0,
+ (video->coded_picture_width << 1), (video->coded_picture_width<<1), WIDTH, 8, bx, (by >> 1),
+ PMV[0][1][0], (PMV[0][1][1] >> 1), stwtop);
+ }
+
+/* bottom field prediction */
+ if(stwbot < 2)
+ {
+ recon(video, video->refframe, mv_field_sel[1][1], video->newframe, 1, (video->coded_picture_width << 1),
+ (video->coded_picture_width << 1), WIDTH, 8, bx, (by>>1),
+ PMV[1][1][0], (PMV[1][1][1]>>1), stwbot);
+ }
+ }
+ }
+ else
+ {
+/* TOP_FIELD or BOTTOM_FIELD */
+/* field picture */
+ if(motion_type == MC_FIELD)
+ {
+/* field-based prediction */
+ recon(video, video->refframe, mv_field_sel[0][1], video->newframe, 0,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 16, bx, by,
+ PMV[0][1][0], PMV[0][1][1], stwtop);
+ }
+ else if(motion_type==MC_16X8)
+ {
+ recon(video, video->refframe, mv_field_sel[0][1], video->newframe, 0,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by,
+ PMV[0][1][0], PMV[0][1][1], stwtop);
+
+ recon(video, video->refframe, mv_field_sel[1][1], video->newframe, 0,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by+8,
+ PMV[1][1][0], PMV[1][1][1], stwtop);
+ }
+ else
+/* invalid motion_type */
+/* fprintf(stderr, "reconstruct: invalid motion_type\n"); */
+ ;
+ }
+ } /* mb_type & MB_BACKWARD */
+ return 0;
+}
+
+
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 @@
+#include "../mpeg3private.h"
+#include "../mpeg3protos.h"
+#include "mpeg3video.h"
+#include <stdlib.h>
+#include <string.h>
+
+unsigned int mpeg3bits_next_startcode(mpeg3_bits_t* stream)
+{
+/* Perform forwards search */
+ mpeg3bits_byte_align(stream);
+
+/* Perform search */
+ while((mpeg3bits_showbits32_noptr(stream) >> 8) != MPEG3_PACKET_START_CODE_PREFIX &&
+ !mpeg3bits_eof(stream))
+ {
+ mpeg3bits_getbyte_noptr(stream);
+ }
+ return mpeg3bits_showbits32_noptr(stream);
+}
+
+/* Line up on the beginning of the next code. */
+int mpeg3video_next_code(mpeg3_bits_t* stream, unsigned int code)
+{
+ while(!mpeg3bits_eof(stream) &&
+ mpeg3bits_showbits32_noptr(stream) != code)
+ {
+ mpeg3bits_getbyte_noptr(stream);
+ }
+ return mpeg3bits_eof(stream);
+}
+
+/* Line up on the beginning of the previous code. */
+int mpeg3video_prev_code(mpeg3_bits_t* stream, unsigned int code)
+{
+ while(!mpeg3bits_bof(stream) &&
+ mpeg3bits_showbits_reverse(stream, 32) != code)
+ {
+ mpeg3bits_getbits_reverse(stream, 8);
+ }
+ return mpeg3bits_bof(stream);
+}
+
+long mpeg3video_goptimecode_to_frame(mpeg3video_t *video)
+{
+/* printf("mpeg3video_goptimecode_to_frame %d %d %d %d %f\n", */
+/* video->gop_timecode.hour, video->gop_timecode.minute, video->gop_timecode.second, video->gop_timecode.frame, video->frame_rate); */
+ return (long)(video->gop_timecode.hour * 3600 * video->frame_rate +
+ video->gop_timecode.minute * 60 * video->frame_rate +
+ video->gop_timecode.second * video->frame_rate +
+ video->gop_timecode.frame) - 1 - video->first_frame;
+}
+
+int mpeg3video_match_refframes(mpeg3video_t *video)
+{
+ unsigned char *dst, *src;
+ int i, j, size;
+
+ for(i = 0; i < 3; i++)
+ {
+ if(video->newframe[i])
+ {
+ if(video->newframe[i] == video->refframe[i])
+ {
+ src = video->refframe[i];
+ dst = video->oldrefframe[i];
+ }
+ else
+ {
+ src = video->oldrefframe[i];
+ dst = video->refframe[i];
+ }
+
+ if(i == 0)
+ size = video->coded_picture_width * video->coded_picture_height + 32 * video->coded_picture_width;
+ else
+ size = video->chrom_width * video->chrom_height + 32 * video->chrom_width;
+
+ memcpy(dst, src, size);
+ }
+ }
+ return 0;
+}
+
+int mpeg3video_seek(mpeg3video_t *video)
+{
+ long this_gop_start;
+ int result = 0;
+ int back_step;
+ int attempts;
+ mpeg3_t *file = video->file;
+ mpeg3_bits_t *vstream = video->vstream;
+ double percentage;
+ long frame_number;
+ int match_refframes = 1;
+
+/* Seek to a percentage */
+ if(video->percentage_seek >= 0)
+ {
+ percentage = video->percentage_seek;
+ video->percentage_seek = -1;
+ mpeg3bits_seek_percentage(vstream, percentage);
+// Go to previous I-frame
+ mpeg3bits_start_reverse(vstream);
+ result = mpeg3video_prev_code(vstream, MPEG3_GOP_START_CODE);
+ if(!result) mpeg3bits_getbits_reverse(vstream, 32);
+ mpeg3bits_start_forward(vstream);
+
+ if(mpeg3bits_tell_percentage(vstream) < 0) mpeg3bits_seek_percentage(vstream, 0);
+
+// Read up to the correct percentage
+ result = 0;
+ while(!result && mpeg3bits_tell_percentage(vstream) < percentage)
+ {
+ result = mpeg3video_read_frame_backend(video, 0);
+ if(match_refframes)
+ mpeg3video_match_refframes(video);
+ match_refframes = 0;
+ }
+ }
+ else
+/* Seek to a frame */
+ if(video->frame_seek >= 0)
+ {
+ frame_number = video->frame_seek;
+ video->frame_seek = -1;
+ if(frame_number < 0) frame_number = 0;
+ if(frame_number > video->maxframe) frame_number = video->maxframe;
+
+/* Seek to start of file */
+ if(frame_number < 16)
+ {
+ video->repeat_count = video->current_repeat = 0;
+ mpeg3bits_seek_start(vstream);
+ video->framenum = 0;
+ result = mpeg3video_drop_frames(video, frame_number - video->framenum);
+ }
+ else
+ {
+/* Seek to an I frame. */
+ if((frame_number < video->framenum || frame_number - video->framenum > MPEG3_SEEK_THRESHOLD))
+ {
+/* Elementary stream */
+ if(file->is_video_stream)
+ {
+ mpeg3_t *file = video->file;
+ mpeg3_vtrack_t *track = video->track;
+ long byte = (long)((float)(mpeg3demuxer_total_bytes(vstream->demuxer) /
+ track->total_frames) *
+ frame_number);
+ long minimum = 65535;
+ int done = 0;
+
+//printf("seek elementary %d\n", frame_number);
+/* Get GOP just before frame */
+ do
+ {
+ result = mpeg3bits_seek_byte(vstream, byte);
+ mpeg3bits_start_reverse(vstream);
+ if(!result) result = mpeg3video_prev_code(vstream, MPEG3_GOP_START_CODE);
+ mpeg3bits_start_forward(vstream);
+ mpeg3bits_getbits(vstream, 8);
+ if(!result) result = mpeg3video_getgophdr(video);
+ this_gop_start = mpeg3video_goptimecode_to_frame(video);
+
+//printf("wanted %ld guessed %ld byte %ld result %d\n", frame_number, this_gop_start, byte, result);
+ if(labs(this_gop_start - frame_number) >= labs(minimum))
+ done = 1;
+ else
+ {
+ minimum = this_gop_start - frame_number;
+ byte += (long)((float)(frame_number - this_gop_start) *
+ (float)(mpeg3demuxer_total_bytes(vstream->demuxer) /
+ track->total_frames));
+ if(byte < 0) byte = 0;
+ }
+ }while(!result && !done);
+
+//printf("wanted %d guessed %d\n", frame_number, this_gop_start);
+ if(!result)
+ {
+ video->framenum = this_gop_start;
+ result = mpeg3video_drop_frames(video, frame_number - video->framenum);
+ }
+ }
+ else
+/* System stream */
+ {
+ mpeg3bits_seek_time(vstream, (double)frame_number / video->frame_rate);
+ percentage = mpeg3bits_tell_percentage(vstream);
+//printf("seek frame %ld percentage %f byte %ld\n", frame_number, percentage, mpeg3bits_tell(vstream));
+ mpeg3bits_start_reverse(vstream);
+ mpeg3video_prev_code(vstream, MPEG3_GOP_START_CODE);
+ mpeg3bits_getbits_reverse(vstream, 32);
+ mpeg3bits_start_forward(vstream);
+//printf("seek system 1 %f\n", (double)frame_number / video->frame_rate);
+
+ while(!result && mpeg3bits_tell_percentage(vstream) < percentage)
+ {
+ result = mpeg3video_read_frame_backend(video, 0);
+ if(match_refframes)
+ mpeg3video_match_refframes(video);
+
+//printf("seek system 2 %f %f\n", mpeg3bits_tell_percentage(vstream) / percentage);
+ match_refframes = 0;
+ }
+//printf("seek system 3 %f\n", (double)frame_number / video->frame_rate);
+ }
+
+ video->framenum = frame_number;
+ }
+ else
+// Drop frames
+ {
+ mpeg3video_drop_frames(video, frame_number - video->framenum);
+ }
+ }
+ }
+
+ return result;
+}
+
+int mpeg3video_drop_frames(mpeg3video_t *video, long frames)
+{
+ int result = 0;
+ long frame_number = video->framenum + frames;
+
+/* Read the selected number of frames and skip b-frames */
+ while(!result && frame_number > video->framenum)
+ {
+ result = mpeg3video_read_frame_backend(video, frame_number - video->framenum);
+ }
+ return result;
+}
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 @@
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include "mpeg3video.h"
+#include "mpeg3videoprotos.h"
+#include "slice.h"
+
+#include <stdlib.h>
+
+static ULONGLONG MMX_128 = 0x80008000800080LL;
+
+int mpeg3_new_slice_buffer(mpeg3_slice_buffer_t *slice_buffer)
+{
+ pthread_mutexattr_t mutex_attr;
+ slice_buffer->data = (unsigned char*)malloc(1024);
+ slice_buffer->buffer_size = 0;
+ slice_buffer->buffer_allocation = 1024;
+ slice_buffer->current_position = 0;
+ slice_buffer->bits_size = 0;
+ slice_buffer->bits = 0;
+ slice_buffer->done = 0;
+ pthread_mutexattr_init(&mutex_attr);
+ pthread_mutex_init(&(slice_buffer->completion_lock), &mutex_attr);
+ return 0;
+}
+
+int mpeg3_delete_slice_buffer(mpeg3_slice_buffer_t *slice_buffer)
+{
+ free(slice_buffer->data);
+ pthread_mutex_destroy(&(slice_buffer->completion_lock));
+ return 0;
+}
+
+int mpeg3_expand_slice_buffer(mpeg3_slice_buffer_t *slice_buffer)
+{
+ int i;
+ unsigned char *new_buffer =
+ (unsigned char*)malloc(slice_buffer->buffer_allocation * 2);
+ for(i = 0; i < slice_buffer->buffer_size; i++)
+ new_buffer[i] = slice_buffer->data[i];
+ free(slice_buffer->data);
+ slice_buffer->data = new_buffer;
+ slice_buffer->buffer_allocation *= 2;
+ return 0;
+}
+
+/* limit coefficients to -2048..2047 */
+
+/* move/add 8x8-Block from block[comp] to refframe */
+
+static inline int mpeg3video_addblock(mpeg3_slice_t *slice,
+ mpeg3video_t *video,
+ int comp,
+ int bx,
+ int by,
+ int dct_type,
+ int addflag)
+{
+ int cc, i, iincr;
+ unsigned char *rfp;
+ short *bp;
+ int spar = slice->sparse[comp];
+/* color component index */
+ cc = (comp < 4) ? 0 : (comp & 1) + 1;
+
+ if(cc == 0)
+ {
+/* luminance */
+ if(video->pict_struct == FRAME_PICTURE)
+ {
+ if(dct_type)
+ {
+/* field DCT coding */
+ rfp = video->newframe[0] +
+ video->coded_picture_width * (by + ((comp & 2) >> 1)) + bx + ((comp & 1) << 3);
+ iincr = (video->coded_picture_width << 1);
+ }
+ else
+ {
+/* frame DCT coding */
+ rfp = video->newframe[0] +
+ video->coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
+ iincr = video->coded_picture_width;
+ }
+ }
+ else
+ {
+/* field picture */
+ rfp = video->newframe[0] +
+ (video->coded_picture_width << 1) * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
+ iincr = (video->coded_picture_width << 1);
+ }
+ }
+ else
+ {
+/* chrominance */
+
+/* scale coordinates */
+ if(video->chroma_format != CHROMA444) bx >>= 1;
+ if(video->chroma_format == CHROMA420) by >>= 1;
+ if(video->pict_struct == FRAME_PICTURE)
+ {
+ if(dct_type && (video->chroma_format != CHROMA420))
+ {
+/* field DCT coding */
+ rfp = video->newframe[cc]
+ + video->chrom_width * (by + ((comp & 2) >> 1)) + bx + (comp & 8);
+ iincr = (video->chrom_width << 1);
+ }
+ else
+ {
+/* frame DCT coding */
+ rfp = video->newframe[cc]
+ + video->chrom_width * (by + ((comp & 2) << 2)) + bx + (comp & 8);
+ iincr = video->chrom_width;
+ }
+ }
+ else
+ {
+/* field picture */
+ rfp = video->newframe[cc]
+ + (video->chrom_width << 1) * (by + ((comp & 2) << 2)) + bx + (comp & 8);
+ iincr = (video->chrom_width << 1);
+ }
+ }
+
+ bp = slice->block[comp];
+
+ if(addflag)
+ {
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ {
+ if(spar)
+ {
+ __asm__ __volatile__(
+ "movq (%2), %%mm6\n" /* 4 blockvals */
+ "pxor %%mm4, %%mm4\n"
+ "punpcklwd %%mm6, %%mm6\n"
+ "punpcklwd %%mm6, %%mm6\n"
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n" /* 8 rindex1 */
+ "movq %%mm0, %%mm2\n"
+ "punpcklbw %%mm4, %%mm0\n"
+ "punpckhbw %%mm4, %%mm2\n"
+ "paddw %%mm6, %%mm0\n"
+ "paddw %%mm6, %%mm2\n"
+
+ "packuswb %%mm2, %%mm0\n"
+ "movq %%mm0, (%1)\n"
+
+ "leal (%1, %3), %1\n"
+ "loop 1b\n"
+ : /* scr dest */
+ : "c" (8),"r" (rfp), "r" (bp), "r" (iincr)
+ );
+ }
+ else
+ {
+ __asm__ __volatile__(
+ "pxor %%mm4, %%mm4\n"
+
+ ".align 8\n"
+ "1:"
+ "movq (%2), %%mm0\n" /* 8 rfp 0 1 2 3 4 5 6 7*/
+ "movq (%1), %%mm6\n" /* 4 blockvals 0 1 2 3 */
+
+ "movq %%mm0, %%mm2\n"
+ "movq 8(%1), %%mm5\n" /* 4 blockvals 0 1 2 3 */
+ "punpcklbw %%mm4, %%mm0\n" /* 0 2 4 6 */
+ "punpckhbw %%mm4, %%mm2\n" /* 1 3 5 7 */
+
+ "paddw %%mm6, %%mm0\n"
+ "paddw %%mm5, %%mm2\n"
+ "packuswb %%mm2, %%mm0\n"
+
+ "addl $16, %1\n"
+ "movq %%mm0, (%2)\n"
+
+ "leal (%2,%3), %2\n"
+ "loop 1b\n"
+ : /* scr dest */
+ : "c" (8),"r" (bp), "r" (rfp), "r" (iincr)
+ );
+ }
+ }
+ else
+#endif
+ for(i = 0; i < 8; i++)
+ {
+ rfp[0] = CLIP(bp[0] + rfp[0]);
+ rfp[1] = CLIP(bp[1] + rfp[1]);
+ rfp[2] = CLIP(bp[2] + rfp[2]);
+ rfp[3] = CLIP(bp[3] + rfp[3]);
+ rfp[4] = CLIP(bp[4] + rfp[4]);
+ rfp[5] = CLIP(bp[5] + rfp[5]);
+ rfp[6] = CLIP(bp[6] + rfp[6]);
+ rfp[7] = CLIP(bp[7] + rfp[7]);
+ rfp += iincr;
+ bp += 8;
+ }
+ }
+ else
+ {
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ {
+ if(spar)
+ {
+ __asm__ __volatile__(
+ "movd (%2), %%mm0\n" /* " 0 0 0 v1" */
+ "punpcklwd %%mm0, %%mm0\n" /* " 0 0 v1 v1" */
+ "punpcklwd %%mm0, %%mm0\n"
+ "paddw MMX_128, %%mm0\n"
+ "packuswb %%mm0, %%mm0\n"
+ "leal (%0,%1,2), %%eax\n"
+
+ "movq %%mm0, (%0, %1)\n"
+ "movq %%mm0, (%%eax)\n"
+ "leal (%%eax,%1,2), %0\n"
+ "movq %%mm0, (%%eax, %1)\n"
+
+ "movq %%mm0, (%0)\n"
+ "leal (%0,%1,2), %%eax\n"
+ "movq %%mm0, (%0, %1)\n"
+
+ "movq %%mm0, (%%eax)\n"
+ "movq %%mm0, (%%eax, %1)\n"
+ :
+ : "D" (rfp), "c" (iincr), "b" (bp)
+ : "eax");
+ }
+ else
+ {
+ __asm__ __volatile__(
+ "movq MMX_128,%%mm4\n"
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n"
+ "movq 8(%1), %%mm1\n"
+ "paddw %%mm4, %%mm0\n"
+
+ "movq 16(%1), %%mm2\n"
+ "paddw %%mm4, %%mm1\n"
+
+ "movq 24(%1), %%mm3\n"
+ "paddw %%mm4, %%mm2\n"
+
+ "packuswb %%mm1, %%mm0\n"
+ "paddw %%mm4, %%mm3\n"
+
+ "addl $32, %1\n"
+ "packuswb %%mm3, %%mm2\n"
+
+ "movq %%mm0, (%2)\n"
+
+ "movq %%mm2, (%2,%3)\n"
+
+ "leal (%2,%3,2), %2\n"
+ "loop 1b\n"
+ :
+ : "c" (4), "r" (bp), "r" (rfp), "r" (iincr)
+ );
+ }
+ }
+ else
+#endif
+ for(i = 0; i < 8; i++)
+ {
+ rfp[0] = CLIP(bp[0] + 128);
+ rfp[1] = CLIP(bp[1] + 128);
+ rfp[2] = CLIP(bp[2] + 128);
+ rfp[3] = CLIP(bp[3] + 128);
+ rfp[4] = CLIP(bp[4] + 128);
+ rfp[5] = CLIP(bp[5] + 128);
+ rfp[6] = CLIP(bp[6] + 128);
+ rfp[7] = CLIP(bp[7] + 128);
+ rfp+= iincr;
+ bp += 8;
+ }
+ }
+ return 0;
+}
+
+int mpeg3_decode_slice(mpeg3_slice_t *slice)
+{
+ mpeg3video_t *video = slice->video;
+ int comp;
+ int mb_type, cbp, motion_type = 0, dct_type;
+ int macroblock_address, mba_inc, mba_max;
+ int slice_vert_pos_ext;
+ unsigned int code;
+ int bx, by;
+ int dc_dct_pred[3];
+ int mv_count, mv_format, mvscale;
+ int pmv[2][2][2], mv_field_sel[2][2];
+ int dmv, dmvector[2];
+ int qs;
+ int stwtype, stwclass;
+ int snr_cbp;
+ int i;
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+
+/* number of macroblocks per picture */
+ mba_max = video->mb_width * video->mb_height;
+
+/* field picture has half as many macroblocks as frame */
+ if(video->pict_struct != FRAME_PICTURE)
+ mba_max >>= 1;
+
+/* macroblock address */
+ macroblock_address = 0;
+/* first macroblock in slice is not skipped */
+ mba_inc = 0;
+ slice->fault = 0;
+
+ code = mpeg3slice_getbits(slice_buffer, 32);
+/* decode slice header (may change quant_scale) */
+ slice_vert_pos_ext = mpeg3video_getslicehdr(slice, video);
+
+/* reset all DC coefficient and motion vector predictors */
+ dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;
+ pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
+ pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0;
+
+ for(i = 0;
+ slice_buffer->current_position < slice_buffer->buffer_size;
+ i++)
+ {
+ if(mba_inc == 0)
+ {
+/* Done */
+ if(!mpeg3slice_showbits(slice_buffer, 23)) return 0;
+/* decode macroblock address increment */
+ mba_inc = mpeg3video_get_macroblock_address(slice);
+
+ if(slice->fault) return 1;
+
+ if(i == 0)
+ {
+/* Get the macroblock_address */
+ macroblock_address = ((slice_vert_pos_ext << 7) + (code & 255) - 1) * video->mb_width + mba_inc - 1;
+/* first macroblock in slice: not skipped */
+ mba_inc = 1;
+ }
+ }
+
+ if(slice->fault) return 1;
+
+ if(macroblock_address >= mba_max)
+ {
+/* mba_inc points beyond picture dimensions */
+ /*fprintf(stderr, "mpeg3_decode_slice: too many macroblocks in picture\n"); */
+ return 1;
+ }
+
+/* not skipped */
+ if(mba_inc == 1)
+ {
+ mpeg3video_macroblock_modes(slice,
+ video,
+ &mb_type,
+ &stwtype,
+ &stwclass,
+ &motion_type,
+ &mv_count,
+ &mv_format,
+ &dmv,
+ &mvscale,
+ &dct_type);
+
+ if(slice->fault) return 1;
+
+ if(mb_type & MB_QUANT)
+ {
+ qs = mpeg3slice_getbits(slice_buffer, 5);
+
+ if(video->mpeg2)
+ slice->quant_scale = video->qscale_type ? mpeg3_non_linear_mquant_table[qs] : (qs << 1);
+ else
+ slice->quant_scale = qs;
+
+ if(video->scalable_mode == SC_DP)
+/* make sure quant_scale is valid */
+ slice->quant_scale = slice->quant_scale;
+ }
+
+/* motion vectors */
+
+
+/* decode forward motion vectors */
+ if((mb_type & MB_FORWARD) || ((mb_type & MB_INTRA) && video->conceal_mv))
+ {
+ if(video->mpeg2)
+ mpeg3video_motion_vectors(slice,
+ video,
+ pmv,
+ dmvector,
+ mv_field_sel,
+ 0,
+ mv_count,
+ mv_format,
+ video->h_forw_r_size,
+ video->v_forw_r_size,
+ dmv,
+ mvscale);
+ else
+ mpeg3video_motion_vector(slice,
+ video,
+ pmv[0][0],
+ dmvector,
+ video->forw_r_size,
+ video->forw_r_size,
+ 0,
+ 0,
+ video->full_forw);
+ }
+ if(slice->fault) return 1;
+
+/* decode backward motion vectors */
+ if(mb_type & MB_BACKWARD)
+ {
+ if(video->mpeg2)
+ mpeg3video_motion_vectors(slice,
+ video,
+ pmv,
+ dmvector,
+ mv_field_sel,
+ 1,
+ mv_count,
+ mv_format,
+ video->h_back_r_size,
+ video->v_back_r_size,
+ 0,
+ mvscale);
+ else
+ mpeg3video_motion_vector(slice,
+ video,
+ pmv[0][1],
+ dmvector,
+ video->back_r_size,
+ video->back_r_size,
+ 0,
+ 0,
+ video->full_back);
+ }
+
+ if(slice->fault) return 1;
+
+/* remove marker_bit */
+ if((mb_type & MB_INTRA) && video->conceal_mv)
+ mpeg3slice_flushbit(slice_buffer);
+
+/* macroblock_pattern */
+ if(mb_type & MB_PATTERN)
+ {
+ cbp = mpeg3video_get_cbp(slice);
+ if(video->chroma_format == CHROMA422)
+ {
+/* coded_block_pattern_1 */
+ cbp = (cbp << 2) | mpeg3slice_getbits2(slice_buffer);
+ }
+ else
+ if(video->chroma_format == CHROMA444)
+ {
+/* coded_block_pattern_2 */
+ cbp = (cbp << 6) | mpeg3slice_getbits(slice_buffer, 6);
+ }
+ }
+ else
+ cbp = (mb_type & MB_INTRA) ? ((1 << video->blk_cnt) - 1) : 0;
+
+ if(slice->fault) return 1;
+/* decode blocks */
+ mpeg3video_clearblock(slice, 0, video->blk_cnt);
+ for(comp = 0; comp < video->blk_cnt; comp++)
+ {
+ if(cbp & (1 << (video->blk_cnt - comp - 1)))
+ {
+ if(mb_type & MB_INTRA)
+ {
+ if(video->mpeg2)
+ mpeg3video_getmpg2intrablock(slice, video, comp, dc_dct_pred);
+ else
+ mpeg3video_getintrablock(slice, video, comp, dc_dct_pred);
+ }
+ else
+ {
+ if(video->mpeg2)
+ mpeg3video_getmpg2interblock(slice, video, comp);
+ else
+ mpeg3video_getinterblock(slice, video, comp);
+ }
+ if(slice->fault) return 1;
+ }
+ }
+
+/* reset intra_dc predictors */
+ if(!(mb_type & MB_INTRA))
+ dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;
+
+/* reset motion vector predictors */
+ if((mb_type & MB_INTRA) && !video->conceal_mv)
+ {
+/* intra mb without concealment motion vectors */
+ pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
+ pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0;
+ }
+
+ if((video->pict_type == P_TYPE) && !(mb_type & (MB_FORWARD | MB_INTRA)))
+ {
+/* non-intra mb without forward mv in a P picture */
+ pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
+
+/* derive motion_type */
+ if(video->pict_struct == FRAME_PICTURE)
+ motion_type = MC_FRAME;
+ else
+ {
+ motion_type = MC_FIELD;
+/* predict from field of same parity */
+ mv_field_sel[0][0] = (video->pict_struct == BOTTOM_FIELD);
+ }
+ }
+
+ if(stwclass == 4)
+ {
+/* purely spatially predicted macroblock */
+ pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
+ pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0;
+ }
+ }
+ else
+ {
+/* mba_inc!=1: skipped macroblock */
+ mpeg3video_clearblock(slice, 0, video->blk_cnt);
+
+/* reset intra_dc predictors */
+ dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;
+
+/* reset motion vector predictors */
+ if(video->pict_type == P_TYPE)
+ pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
+
+/* derive motion_type */
+ if(video->pict_struct == FRAME_PICTURE)
+ motion_type = MC_FRAME;
+ else
+ {
+ motion_type = MC_FIELD;
+/* predict from field of same parity */
+ mv_field_sel[0][0] = mv_field_sel[0][1] = (video->pict_struct == BOTTOM_FIELD);
+ }
+
+/* skipped I are spatial-only predicted, */
+/* skipped P and B are temporal-only predicted */
+ stwtype = (video->pict_type == I_TYPE) ? 8 : 0;
+
+/* clear MB_INTRA */
+ mb_type &= ~MB_INTRA;
+
+/* no block data */
+ cbp = 0;
+ }
+
+ snr_cbp = 0;
+
+/* pixel coordinates of top left corner of current macroblock */
+ bx = 16 * (macroblock_address % video->mb_width);
+ by = 16 * (macroblock_address / video->mb_width);
+
+/* motion compensation */
+ if(!(mb_type & MB_INTRA))
+ mpeg3video_reconstruct(video,
+ bx,
+ by,
+ mb_type,
+ motion_type,
+ pmv,
+ mv_field_sel,
+ dmvector,
+ stwtype);
+
+/* copy or add block data into picture */
+ for(comp = 0; comp < video->blk_cnt; comp++)
+ {
+ if((cbp | snr_cbp) & (1 << (video->blk_cnt - 1 - comp)))
+ {
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ IDCT_mmx(slice->block[comp]);
+ else
+#endif
+ mpeg3video_idct_conversion(slice->block[comp]);
+
+ mpeg3video_addblock(slice,
+ video,
+ comp,
+ bx,
+ by,
+ dct_type,
+ (mb_type & MB_INTRA) == 0);
+ }
+ }
+
+/* advance to next macroblock */
+ macroblock_address++;
+ mba_inc--;
+ }
+
+ return 0;
+}
+
+void mpeg3_slice_loop(mpeg3_slice_t *slice)
+{
+ mpeg3video_t *video = slice->video;
+ int result = 1;
+
+ while(!slice->done)
+ {
+ pthread_mutex_lock(&(slice->input_lock));
+
+ if(!slice->done)
+ {
+/* Get a buffer to decode */
+ result = 1;
+ pthread_mutex_lock(&(video->slice_lock));
+ if(slice->buffer_step > 0)
+ {
+ while(slice->current_buffer <= slice->last_buffer)
+ {
+ if(!video->slice_buffers[slice->current_buffer].done &&
+ slice->current_buffer <= slice->last_buffer)
+ {
+ result = 0;
+ break;
+ }
+ slice->current_buffer += slice->buffer_step;
+ }
+ }
+ else
+ {
+ while(slice->current_buffer >= slice->last_buffer)
+ {
+ if(!video->slice_buffers[slice->current_buffer].done &&
+ slice->current_buffer >= slice->last_buffer)
+ {
+ result = 0;
+ break;
+ }
+ slice->current_buffer += slice->buffer_step;
+ }
+ }
+
+/* Got one */
+ if(!result && slice->current_buffer >= 0 && slice->current_buffer < video->total_slice_buffers)
+ {
+ slice->slice_buffer = &(video->slice_buffers[slice->current_buffer]);
+ slice->slice_buffer->done = 1;
+ pthread_mutex_unlock(&(video->slice_lock));
+ pthread_mutex_unlock(&(slice->input_lock));
+ mpeg3_decode_slice(slice);
+ pthread_mutex_unlock(&(slice->slice_buffer->completion_lock));
+ }
+ else
+ pthread_mutex_unlock(&(video->slice_lock));
+ }
+
+ pthread_mutex_unlock(&(slice->output_lock));
+ }
+}
+
+int mpeg3_new_slice_decoder(mpeg3video_t *video, mpeg3_slice_t *slice)
+{
+ pthread_attr_t attr;
+ //struct sched_param param;
+ pthread_mutexattr_t mutex_attr;
+
+ slice->video = video;
+ slice->done = 0;
+ pthread_mutexattr_init(&mutex_attr);
+ pthread_mutex_init(&(slice->input_lock), &mutex_attr);
+ pthread_mutex_lock(&(slice->input_lock));
+ pthread_mutex_init(&(slice->output_lock), &mutex_attr);
+ pthread_mutex_lock(&(slice->output_lock));
+
+ pthread_attr_init(&attr);
+ pthread_create(&(slice->tid), &attr,
+ (void * (*)(void *))mpeg3_slice_loop, slice);
+
+ return 0;
+}
+
+int mpeg3_delete_slice_decoder(mpeg3_slice_t *slice)
+{
+ slice->done = 1;
+ pthread_mutex_unlock(&(slice->input_lock));
+ pthread_join(slice->tid, 0);
+ pthread_mutex_destroy(&(slice->input_lock));
+ pthread_mutex_destroy(&(slice->output_lock));
+ return 0;
+}
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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef SLICE_H
+#define SLICE_H
+
+#ifndef _WIN32
+#include <pthread.h>
+#endif
+
+/* Array of these feeds the slice decoders */
+typedef struct
+{
+ unsigned char *data; /* Buffer for holding the slice data */
+ int buffer_size; /* Size of buffer */
+ int buffer_allocation; /* Space allocated for buffer */
+ int current_position; /* Position in buffer */
+ unsigned MPEG3_INT32 bits;
+ int bits_size;
+ pthread_mutex_t completion_lock; /* Lock slice until completion */
+ int done; /* Signal for slice decoder to skip */
+} mpeg3_slice_buffer_t;
+
+/* Each slice decoder */
+typedef struct
+{
+ struct mpeg3video_rec *video;
+ mpeg3_slice_buffer_t *slice_buffer;
+
+ int thread_number; /* Number of this thread */
+ int current_buffer; /* Buffer this slice decoder is on */
+ int buffer_step; /* Number of buffers to skip */
+ int last_buffer; /* Last buffer this decoder should process */
+ int fault;
+ int done;
+ int quant_scale;
+ int pri_brk; /* slice/macroblock */
+ short block[12][64];
+ int sparse[12];
+ pthread_t tid; /* ID of thread */
+ pthread_mutex_t input_lock, output_lock;
+} mpeg3_slice_t;
+
+#define mpeg3slice_fillbits(buffer, nbits) \
+ while(((mpeg3_slice_buffer_t*)(buffer))->bits_size < (nbits)) \
+ { \
+ if(((mpeg3_slice_buffer_t*)(buffer))->current_position < ((mpeg3_slice_buffer_t*)(buffer))->buffer_size) \
+ { \
+ ((mpeg3_slice_buffer_t*)(buffer))->bits <<= 8; \
+ ((mpeg3_slice_buffer_t*)(buffer))->bits |= ((mpeg3_slice_buffer_t*)(buffer))->data[((mpeg3_slice_buffer_t*)(buffer))->current_position++]; \
+ } \
+ ((mpeg3_slice_buffer_t*)(buffer))->bits_size += 8; \
+ }
+
+#define mpeg3slice_flushbits(buffer, nbits) \
+ { \
+ mpeg3slice_fillbits((buffer), (nbits)); \
+ ((mpeg3_slice_buffer_t*)(buffer))->bits_size -= (nbits); \
+ }
+
+#define mpeg3slice_flushbit(buffer) \
+{ \
+ if(((mpeg3_slice_buffer_t*)(buffer))->bits_size) \
+ ((mpeg3_slice_buffer_t*)(buffer))->bits_size--; \
+ else \
+ if(((mpeg3_slice_buffer_t*)(buffer))->current_position < ((mpeg3_slice_buffer_t*)(buffer))->buffer_size) \
+ { \
+ ((mpeg3_slice_buffer_t*)(buffer))->bits = \
+ ((mpeg3_slice_buffer_t*)(buffer))->data[((mpeg3_slice_buffer_t*)(buffer))->current_position++]; \
+ ((mpeg3_slice_buffer_t*)(buffer))->bits_size = 7; \
+ } \
+}
+
+extern inline unsigned int mpeg3slice_getbit(mpeg3_slice_buffer_t *buffer)
+{
+ if(buffer->bits_size)
+ return (buffer->bits >> (--buffer->bits_size)) & 0x1;
+ else
+ if(buffer->current_position < buffer->buffer_size)
+ {
+ buffer->bits = buffer->data[buffer->current_position++];
+ buffer->bits_size = 7;
+ return (buffer->bits >> 7) & 0x1;
+ }
+ return 0; // WWA - stop warn
+}
+
+extern inline unsigned int mpeg3slice_getbits2(mpeg3_slice_buffer_t *buffer)
+{
+ if(buffer->bits_size >= 2)
+ return (buffer->bits >> (buffer->bits_size -= 2)) & 0x3;
+ else
+ if(buffer->current_position < buffer->buffer_size)
+ {
+ buffer->bits <<= 8;
+ buffer->bits |= buffer->data[buffer->current_position++];
+ buffer->bits_size += 6;
+ return (buffer->bits >> buffer->bits_size) & 0x3;
+ }
+ return 0; // WWA - stop warn
+}
+
+extern inline unsigned int mpeg3slice_getbyte(mpeg3_slice_buffer_t *buffer)
+{
+ if(buffer->bits_size >= 8)
+ return (buffer->bits >> (buffer->bits_size -= 8)) & 0xff;
+ else
+ if(buffer->current_position < buffer->buffer_size)
+ {
+ buffer->bits <<= 8;
+ buffer->bits |= buffer->data[buffer->current_position++];
+ return (buffer->bits >> buffer->bits_size) & 0xff;
+ }
+ return 0; // WWA - stop warn
+}
+
+
+extern inline unsigned int mpeg3slice_getbits(mpeg3_slice_buffer_t *slice_buffer, int bits)
+{
+ if(bits == 1) return mpeg3slice_getbit(slice_buffer);
+ mpeg3slice_fillbits(slice_buffer, bits);
+ return (slice_buffer->bits >> (slice_buffer->bits_size -= bits)) & (0xffffffff >> (32 - bits));
+}
+
+extern inline unsigned int mpeg3slice_showbits16(mpeg3_slice_buffer_t *buffer)
+{
+ if(buffer->bits_size >= 16)
+ return (buffer->bits >> (buffer->bits_size - 16)) & 0xffff;
+ else
+ if(buffer->current_position < buffer->buffer_size)
+ {
+ buffer->bits <<= 16;
+ buffer->bits_size += 16;
+ buffer->bits |= (unsigned int)buffer->data[buffer->current_position++] << 8;
+ buffer->bits |= buffer->data[buffer->current_position++];
+ return (buffer->bits >> (buffer->bits_size - 16)) & 0xffff;
+ }
+ return 0; // WWA - stop warn
+}
+
+extern inline unsigned int mpeg3slice_showbits9(mpeg3_slice_buffer_t *buffer)
+{
+ if(buffer->bits_size >= 9)
+ return (buffer->bits >> (buffer->bits_size - 9)) & 0x1ff;
+ else
+ if(buffer->current_position < buffer->buffer_size)
+ {
+ buffer->bits <<= 16;
+ buffer->bits_size += 16;
+ buffer->bits |= (unsigned int)buffer->data[buffer->current_position++] << 8;
+ buffer->bits |= buffer->data[buffer->current_position++];
+ return (buffer->bits >> (buffer->bits_size - 9)) & 0x1ff;
+ }
+ return 0; // WWA - stop warn
+}
+
+extern inline unsigned int mpeg3slice_showbits5(mpeg3_slice_buffer_t *buffer)
+{
+ if(buffer->bits_size >= 5)
+ return (buffer->bits >> (buffer->bits_size - 5)) & 0x1f;
+ else
+ if(buffer->current_position < buffer->buffer_size)
+ {
+ buffer->bits <<= 8;
+ buffer->bits_size += 8;
+ buffer->bits |= buffer->data[buffer->current_position++];
+ return (buffer->bits >> (buffer->bits_size - 5)) & 0x1f;
+ }
+ return 0; // WWA - stop warn
+}
+
+extern inline unsigned int mpeg3slice_showbits(mpeg3_slice_buffer_t *slice_buffer, int bits)
+{
+ mpeg3slice_fillbits(slice_buffer, bits);
+ return (slice_buffer->bits >> (slice_buffer->bits_size - bits)) & (0xffffffff >> (32 - bits));
+}
+
+#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 @@
+#include "mpeg3video.h"
+#include "vlc.h"
+
+/* variable length code tables */
+
+/* Table B-3, mb_type in P-pictures, codes 001..1xx */
+mpeg3_VLCtab_t mpeg3_PMBtab0[8] = {
+ {ERROR,0},
+ {MB_FORWARD,3},
+ {MB_PATTERN,2}, {MB_PATTERN,2},
+ {MB_FORWARD|MB_PATTERN,1}, {MB_FORWARD|MB_PATTERN,1},
+ {MB_FORWARD|MB_PATTERN,1}, {MB_FORWARD|MB_PATTERN,1}
+};
+
+/* Table B-3, mb_type in P-pictures, codes 000001..00011x */
+mpeg3_VLCtab_t mpeg3_PMBtab1[8] = {
+ {ERROR,0},
+ {MB_QUANT|MB_INTRA,6},
+ {MB_QUANT|MB_PATTERN,5}, {MB_QUANT|MB_PATTERN,5},
+ {MB_QUANT|MB_FORWARD|MB_PATTERN,5}, {MB_QUANT|MB_FORWARD|MB_PATTERN,5},
+ {MB_INTRA,5}, {MB_INTRA,5}
+};
+
+/* Table B-4, mb_type in B-pictures, codes 0010..11xx */
+mpeg3_VLCtab_t mpeg3_BMBtab0[16] = {
+ {ERROR,0}, {ERROR,0},
+ {MB_FORWARD,4},
+ {MB_FORWARD|MB_PATTERN,4},
+ {MB_BACKWARD,3}, {MB_BACKWARD,3},
+ {MB_BACKWARD|MB_PATTERN,3}, {MB_BACKWARD|MB_PATTERN,3},
+ {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2},
+ {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2},
+ {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2},
+ {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2},
+ {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2},
+ {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}
+};
+
+/* Table B-4, mb_type in B-pictures, codes 000001..00011x */
+mpeg3_VLCtab_t mpeg3_BMBtab1[8] = {
+ {ERROR,0},
+ {MB_QUANT|MB_INTRA,6},
+ {MB_QUANT|MB_BACKWARD|MB_PATTERN,6},
+ {MB_QUANT|MB_FORWARD|MB_PATTERN,6},
+ {MB_QUANT|MB_FORWARD|MB_BACKWARD|MB_PATTERN,5},
+ {MB_QUANT|MB_FORWARD|MB_BACKWARD|MB_PATTERN,5},
+ {MB_INTRA,5}, {MB_INTRA,5}
+};
+
+/* Table B-5, mb_type in spat. scal. I-pictures, codes 0001..1xxx */
+mpeg3_VLCtab_t mpeg3_spIMBtab[16] = {
+ {ERROR,0},
+ {MB_CLASS4,4},
+ {MB_QUANT|MB_INTRA,4},
+ {MB_INTRA,4},
+ {MB_CLASS4|MB_QUANT|MB_PATTERN,2}, {MB_CLASS4|MB_QUANT|MB_PATTERN,2},
+ {MB_CLASS4|MB_QUANT|MB_PATTERN,2}, {MB_CLASS4|MB_QUANT|MB_PATTERN,2},
+ {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1},
+ {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1},
+ {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1},
+ {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1}
+};
+
+/* Table B-6, mb_type in spat. scal. P-pictures, codes 0010..11xx */
+mpeg3_VLCtab_t mpeg3_spPMBtab0[16] =
+{
+ {ERROR,0},{ERROR,0},
+ {MB_FORWARD,4},
+ {MB_WEIGHT|MB_FORWARD,4},
+ {MB_QUANT|MB_FORWARD|MB_PATTERN,3}, {MB_QUANT|MB_FORWARD|MB_PATTERN,3},
+ {MB_WEIGHT|MB_FORWARD|MB_PATTERN,3}, {MB_WEIGHT|MB_FORWARD|MB_PATTERN,3},
+ {MB_FORWARD|MB_PATTERN,2}, {MB_FORWARD|MB_PATTERN,2},
+ {MB_FORWARD|MB_PATTERN,2}, {MB_FORWARD|MB_PATTERN,2},
+ {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2},
+ {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2},
+ {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2},
+ {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2}
+};
+
+/* Table B-6, mb_type in spat. scal. P-pictures, codes 0000010..000111x */
+mpeg3_VLCtab_t mpeg3_spPMBtab1[16] = {
+ {ERROR,0},{ERROR,0},
+ {MB_CLASS4|MB_QUANT|MB_PATTERN,7},
+ {MB_CLASS4,7},
+ {MB_PATTERN,7},
+ {MB_CLASS4|MB_PATTERN,7},
+ {MB_QUANT|MB_INTRA,7},
+ {MB_INTRA,7},
+ {MB_QUANT|MB_PATTERN,6}, {MB_QUANT|MB_PATTERN,6},
+ {MB_WEIGHT|MB_QUANT|MB_PATTERN,6}, {MB_WEIGHT|MB_QUANT|MB_PATTERN,6},
+ {MB_WEIGHT,6}, {MB_WEIGHT,6},
+ {MB_WEIGHT|MB_PATTERN,6}, {MB_WEIGHT|MB_PATTERN,6}
+};
+
+/* Table B-7, mb_type in spat. scal. B-pictures, codes 0010..11xx */
+mpeg3_VLCtab_t mpeg3_spBMBtab0[14] = {
+ {MB_FORWARD,4},
+ {MB_FORWARD|MB_PATTERN,4},
+ {MB_BACKWARD,3}, {MB_BACKWARD,3},
+ {MB_BACKWARD|MB_PATTERN,3}, {MB_BACKWARD|MB_PATTERN,3},
+ {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2},
+ {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2},
+ {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2},
+ {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2},
+ {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2},
+ {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}
+};
+
+/* Table B-7, mb_type in spat. scal. B-pictures, codes 0000100..000111x */
+mpeg3_VLCtab_t mpeg3_spBMBtab1[12] = {
+ {MB_QUANT|MB_FORWARD|MB_PATTERN,7},
+ {MB_QUANT|MB_BACKWARD|MB_PATTERN,7},
+ {MB_INTRA,7},
+ {MB_QUANT|MB_FORWARD|MB_BACKWARD|MB_PATTERN,7},
+ {MB_WEIGHT|MB_FORWARD,6}, {MB_WEIGHT|MB_FORWARD,6},
+ {MB_WEIGHT|MB_FORWARD|MB_PATTERN,6}, {MB_WEIGHT|MB_FORWARD|MB_PATTERN,6},
+ {MB_WEIGHT|MB_BACKWARD,6}, {MB_WEIGHT|MB_BACKWARD,6},
+ {MB_WEIGHT|MB_BACKWARD|MB_PATTERN,6}, {MB_WEIGHT|MB_BACKWARD|MB_PATTERN,6}
+};
+
+/* Table B-7, mb_type in spat. scal. B-pictures, codes 00000100x..000001111 */
+mpeg3_VLCtab_t mpeg3_spBMBtab2[8] = {
+ {MB_QUANT|MB_INTRA,8}, {MB_QUANT|MB_INTRA,8},
+ {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,8},
+ {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,8},
+ {MB_WEIGHT|MB_QUANT|MB_BACKWARD|MB_PATTERN,9},
+ {MB_CLASS4|MB_QUANT|MB_PATTERN,9},
+ {MB_CLASS4,9},
+ {MB_CLASS4|MB_PATTERN,9}
+};
+
+/* Table B-8, mb_type in spat. scal. B-pictures, codes 001..1xx */
+mpeg3_VLCtab_t mpeg3_SNRMBtab[8] = {
+ {ERROR,0},
+ {0,3},
+ {MB_QUANT|MB_PATTERN,2}, {MB_QUANT|MB_PATTERN,2},
+ {MB_PATTERN,1}, {MB_PATTERN,1}, {MB_PATTERN,1}, {MB_PATTERN,1}
+};
+
+/* Table B-10, motion_code, codes 0001 ... 01xx */
+mpeg3_VLCtab_t mpeg3_MVtab0[8] =
+{ {ERROR,0}, {3,3}, {2,2}, {2,2}, {1,1}, {1,1}, {1,1}, {1,1}
+};
+
+/* Table B-10, motion_code, codes 0000011 ... 000011x */
+mpeg3_VLCtab_t mpeg3_MVtab1[8] =
+{ {ERROR,0}, {ERROR,0}, {ERROR,0}, {7,6}, {6,6}, {5,6}, {4,5}, {4,5}
+};
+
+/* Table B-10, motion_code, codes 0000001100 ... 000001011x */
+mpeg3_VLCtab_t mpeg3_MVtab2[12] =
+{ {16,9}, {15,9}, {14,9}, {13,9},
+ {12,9}, {11,9}, {10,8}, {10,8},
+ {9,8}, {9,8}, {8,8}, {8,8}
+};
+
+/* Table B-9, coded_block_pattern, codes 01000 ... 111xx */
+mpeg3_VLCtab_t mpeg3_CBPtab0[32] =
+{ {ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0},
+ {ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0},
+ {62,5}, {2,5}, {61,5}, {1,5}, {56,5}, {52,5}, {44,5}, {28,5},
+ {40,5}, {20,5}, {48,5}, {12,5}, {32,4}, {32,4}, {16,4}, {16,4},
+ {8,4}, {8,4}, {4,4}, {4,4}, {60,3}, {60,3}, {60,3}, {60,3}
+};
+
+/* Table B-9, coded_block_pattern, codes 00000100 ... 001111xx */
+mpeg3_VLCtab_t mpeg3_CBPtab1[64] =
+{ {ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0},
+ {58,8}, {54,8}, {46,8}, {30,8},
+ {57,8}, {53,8}, {45,8}, {29,8}, {38,8}, {26,8}, {37,8}, {25,8},
+ {43,8}, {23,8}, {51,8}, {15,8}, {42,8}, {22,8}, {50,8}, {14,8},
+ {41,8}, {21,8}, {49,8}, {13,8}, {35,8}, {19,8}, {11,8}, {7,8},
+ {34,7}, {34,7}, {18,7}, {18,7}, {10,7}, {10,7}, {6,7}, {6,7},
+ {33,7}, {33,7}, {17,7}, {17,7}, {9,7}, {9,7}, {5,7}, {5,7},
+ {63,6}, {63,6}, {63,6}, {63,6}, {3,6}, {3,6}, {3,6}, {3,6},
+ {36,6}, {36,6}, {36,6}, {36,6}, {24,6}, {24,6}, {24,6}, {24,6}
+};
+
+/* Table B-9, coded_block_pattern, codes 000000001 ... 000000111 */
+mpeg3_VLCtab_t mpeg3_CBPtab2[8] =
+{ {ERROR,0}, {0,9}, {39,9}, {27,9}, {59,9}, {55,9}, {47,9}, {31,9}
+};
+
+/* Table B-1, macroblock_address_increment, codes 00010 ... 011xx */
+mpeg3_VLCtab_t mpeg3_MBAtab1[16] =
+{ {ERROR,0}, {ERROR,0}, {7,5}, {6,5}, {5,4}, {5,4}, {4,4}, {4,4},
+ {3,3}, {3,3}, {3,3}, {3,3}, {2,3}, {2,3}, {2,3}, {2,3}
+};
+
+/* Table B-1, macroblock_address_increment, codes 00000011000 ... 0000111xxxx */
+mpeg3_VLCtab_t mpeg3_MBAtab2[104] =
+{
+ {33,11}, {32,11}, {31,11}, {30,11}, {29,11}, {28,11}, {27,11}, {26,11},
+ {25,11}, {24,11}, {23,11}, {22,11}, {21,10}, {21,10}, {20,10}, {20,10},
+ {19,10}, {19,10}, {18,10}, {18,10}, {17,10}, {17,10}, {16,10}, {16,10},
+ {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8},
+ {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, {14,8},
+ {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, {13,8},
+ {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, {12,8},
+ {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, {11,8},
+ {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, {10,8},
+ {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7},
+ {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7},
+ {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7},
+ {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}
+};
+
+/* Table B-12, dct_dc_size_luminance, codes 00xxx ... 11110 */
+mpeg3_VLCtab_t mpeg3_DClumtab0[32] =
+{ {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
+ {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2},
+ {0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3},
+ {4, 3}, {4, 3}, {4, 3}, {4, 3}, {5, 4}, {5, 4}, {6, 5}, {ERROR, 0}
+};
+
+/* Table B-12, dct_dc_size_luminance, codes 111110xxx ... 111111111 */
+mpeg3_VLCtab_t mpeg3_DClumtab1[16] =
+{ {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6},
+ {8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10,9}, {11,9}
+};
+
+/* Table B-13, dct_dc_size_chrominance, codes 00xxx ... 11110 */
+mpeg3_VLCtab_t mpeg3_DCchromtab0[32] =
+{ {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2},
+ {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
+ {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2},
+ {3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 4}, {4, 4}, {5, 5}, {ERROR, 0}
+};
+
+/* Table B-13, dct_dc_size_chrominance, codes 111110xxxx ... 1111111111 */
+mpeg3_VLCtab_t mpeg3_DCchromtab1[32] =
+{ {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6},
+ {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6},
+ {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7},
+ {8, 8}, {8, 8}, {8, 8}, {8, 8}, {9, 9}, {9, 9}, {10,10}, {11,10}
+};
+
+/* Table B-14, DCT coefficients table zero,
+ * codes 0100 ... 1xxx (used for first (DC) coefficient)
+ */
+mpeg3_DCTtab_t mpeg3_DCTtabfirst[12] =
+{
+ {0,2,4}, {2,1,4}, {1,1,3}, {1,1,3},
+ {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1},
+ {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1}
+};
+
+/* Table B-14, DCT coefficients table zero,
+ * codes 0100 ... 1xxx (used for all other coefficients)
+ */
+mpeg3_DCTtab_t mpeg3_DCTtabnext[12] =
+{
+ {0,2,4}, {2,1,4}, {1,1,3}, {1,1,3},
+ {64,0,2}, {64,0,2}, {64,0,2}, {64,0,2}, /* EOB */
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}
+};
+
+/* Table B-14, DCT coefficients table zero,
+ * codes 000001xx ... 00111xxx
+ */
+mpeg3_DCTtab_t mpeg3_DCTtab0[60] =
+{
+ {65,0,6}, {65,0,6}, {65,0,6}, {65,0,6}, /* Escape */
+ {2,2,7}, {2,2,7}, {9,1,7}, {9,1,7},
+ {0,4,7}, {0,4,7}, {8,1,7}, {8,1,7},
+ {7,1,6}, {7,1,6}, {7,1,6}, {7,1,6},
+ {6,1,6}, {6,1,6}, {6,1,6}, {6,1,6},
+ {1,2,6}, {1,2,6}, {1,2,6}, {1,2,6},
+ {5,1,6}, {5,1,6}, {5,1,6}, {5,1,6},
+ {13,1,8}, {0,6,8}, {12,1,8}, {11,1,8},
+ {3,2,8}, {1,3,8}, {0,5,8}, {10,1,8},
+ {0,3,5}, {0,3,5}, {0,3,5}, {0,3,5},
+ {0,3,5}, {0,3,5}, {0,3,5}, {0,3,5},
+ {4,1,5}, {4,1,5}, {4,1,5}, {4,1,5},
+ {4,1,5}, {4,1,5}, {4,1,5}, {4,1,5},
+ {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5},
+ {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}
+};
+
+/* Table B-15, DCT coefficients table one,
+ * codes 000001xx ... 11111111
+*/
+mpeg3_DCTtab_t mpeg3_DCTtab0a[252] =
+{
+ {65,0,6}, {65,0,6}, {65,0,6}, {65,0,6}, /* Escape */
+ {7,1,7}, {7,1,7}, {8,1,7}, {8,1,7},
+ {6,1,7}, {6,1,7}, {2,2,7}, {2,2,7},
+ {0,7,6}, {0,7,6}, {0,7,6}, {0,7,6},
+ {0,6,6}, {0,6,6}, {0,6,6}, {0,6,6},
+ {4,1,6}, {4,1,6}, {4,1,6}, {4,1,6},
+ {5,1,6}, {5,1,6}, {5,1,6}, {5,1,6},
+ {1,5,8}, {11,1,8}, {0,11,8}, {0,10,8},
+ {13,1,8}, {12,1,8}, {3,2,8}, {1,4,8},
+ {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5},
+ {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5},
+ {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5},
+ {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5},
+ {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5},
+ {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5},
+ {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
+ {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
+ {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
+ {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
+ {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
+ {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
+ {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
+ {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
+ {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, /* EOB */
+ {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4},
+ {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4},
+ {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4},
+ {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4},
+ {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4},
+ {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4},
+ {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
+ {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
+ {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
+ {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
+ {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
+ {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
+ {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
+ {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
+ {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5},
+ {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5},
+ {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5},
+ {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5},
+ {9,1,7}, {9,1,7}, {1,3,7}, {1,3,7},
+ {10,1,7}, {10,1,7}, {0,8,7}, {0,8,7},
+ {0,9,7}, {0,9,7}, {0,12,8}, {0,13,8},
+ {2,3,8}, {4,2,8}, {0,14,8}, {0,15,8}
+};
+
+/* Table B-14, DCT coefficients table zero,
+ * codes 0000001000 ... 0000001111
+ */
+mpeg3_DCTtab_t mpeg3_DCTtab1[8] =
+{
+ {16,1,10}, {5,2,10}, {0,7,10}, {2,3,10},
+ {1,4,10}, {15,1,10}, {14,1,10}, {4,2,10}
+};
+
+/* Table B-15, DCT coefficients table one,
+ * codes 000000100x ... 000000111x
+ */
+mpeg3_DCTtab_t mpeg3_DCTtab1a[8] =
+{
+ {5,2,9}, {5,2,9}, {14,1,9}, {14,1,9},
+ {2,4,10}, {16,1,10}, {15,1,9}, {15,1,9}
+};
+
+/* Table B-14/15, DCT coefficients table zero / one,
+ * codes 000000010000 ... 000000011111
+ */
+mpeg3_DCTtab_t mpeg3_DCTtab2[16] =
+{
+ {0,11,12}, {8,2,12}, {4,3,12}, {0,10,12},
+ {2,4,12}, {7,2,12}, {21,1,12}, {20,1,12},
+ {0,9,12}, {19,1,12}, {18,1,12}, {1,5,12},
+ {3,3,12}, {0,8,12}, {6,2,12}, {17,1,12}
+};
+
+/* Table B-14/15, DCT coefficients table zero / one,
+ * codes 0000000010000 ... 0000000011111
+ */
+mpeg3_DCTtab_t mpeg3_DCTtab3[16] =
+{
+ {10,2,13}, {9,2,13}, {5,3,13}, {3,4,13},
+ {2,5,13}, {1,7,13}, {1,6,13}, {0,15,13},
+ {0,14,13}, {0,13,13}, {0,12,13}, {26,1,13},
+ {25,1,13}, {24,1,13}, {23,1,13}, {22,1,13}
+};
+
+/* Table B-14/15, DCT coefficients table zero / one,
+ * codes 00000000010000 ... 00000000011111
+ */
+mpeg3_DCTtab_t mpeg3_DCTtab4[16] =
+{
+ {0,31,14}, {0,30,14}, {0,29,14}, {0,28,14},
+ {0,27,14}, {0,26,14}, {0,25,14}, {0,24,14},
+ {0,23,14}, {0,22,14}, {0,21,14}, {0,20,14},
+ {0,19,14}, {0,18,14}, {0,17,14}, {0,16,14}
+};
+
+/* Table B-14/15, DCT coefficients table zero / one,
+ * codes 000000000010000 ... 000000000011111
+ */
+mpeg3_DCTtab_t mpeg3_DCTtab5[16] =
+{
+ {0,40,15}, {0,39,15}, {0,38,15}, {0,37,15},
+ {0,36,15}, {0,35,15}, {0,34,15}, {0,33,15},
+ {0,32,15}, {1,14,15}, {1,13,15}, {1,12,15},
+ {1,11,15}, {1,10,15}, {1,9,15}, {1,8,15}
+};
+
+/* Table B-14/15, DCT coefficients table zero / one,
+ * codes 0000000000010000 ... 0000000000011111
+ */
+mpeg3_DCTtab_t mpeg3_DCTtab6[16] =
+{
+ {1,18,16}, {1,17,16}, {1,16,16}, {1,15,16},
+ {6,3,16}, {16,2,16}, {15,2,16}, {14,2,16},
+ {13,2,16}, {12,2,16}, {11,2,16}, {31,1,16},
+ {30,1,16}, {29,1,16}, {28,1,16}, {27,1,16}
+};
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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef VLC_H
+#define VLC_H
+
+/* variable length code tables */
+
+typedef struct {
+ char val, len;
+} mpeg3_VLCtab_t;
+
+typedef struct {
+ char run, level, len;
+} mpeg3_DCTtab_t;
+
+/* Added 03/38/96 by Alex de Jong : avoid IRIX GNU warning */
+#ifdef ERROR
+#undef ERROR
+#define ERROR 99
+#endif
+
+/* Table B-3, mb_type in P-pictures, codes 001..1xx */
+extern mpeg3_VLCtab_t mpeg3_PMBtab0[8];
+
+/* Table B-3, mb_type in P-pictures, codes 000001..00011x */
+extern mpeg3_VLCtab_t mpeg3_PMBtab1[8];
+
+/* Table B-4, mb_type in B-pictures, codes 0010..11xx */
+extern mpeg3_VLCtab_t mpeg3_BMBtab0[16];
+
+/* Table B-4, mb_type in B-pictures, codes 000001..00011x */
+extern mpeg3_VLCtab_t mpeg3_BMBtab1[8];
+
+/* Table B-5, mb_type in spat. scal. I-pictures, codes 0001..1xxx */
+extern mpeg3_VLCtab_t mpeg3_spIMBtab[16];
+
+/* Table B-6, mb_type in spat. scal. P-pictures, codes 0010..11xx */
+extern mpeg3_VLCtab_t mpeg3_spPMBtab0[16];
+
+/* Table B-6, mb_type in spat. scal. P-pictures, codes 0000010..000111x */
+extern mpeg3_VLCtab_t mpeg3_spPMBtab1[16];
+
+/* Table B-7, mb_type in spat. scal. B-pictures, codes 0010..11xx */
+extern mpeg3_VLCtab_t mpeg3_spBMBtab0[14];
+
+/* Table B-7, mb_type in spat. scal. B-pictures, codes 0000100..000111x */
+extern mpeg3_VLCtab_t mpeg3_spBMBtab1[12];
+
+/* Table B-7, mb_type in spat. scal. B-pictures, codes 00000100x..000001111 */
+extern mpeg3_VLCtab_t mpeg3_spBMBtab2[8];
+
+/* Table B-8, mb_type in spat. scal. B-pictures, codes 001..1xx */
+extern mpeg3_VLCtab_t mpeg3_SNRMBtab[8];
+
+/* Table B-10, motion_code, codes 0001 ... 01xx */
+extern mpeg3_VLCtab_t mpeg3_MVtab0[8];
+
+/* Table B-10, motion_code, codes 0000011 ... 000011x */
+extern mpeg3_VLCtab_t mpeg3_MVtab1[8];
+
+/* Table B-10, motion_code, codes 0000001100 ... 000001011x */
+extern mpeg3_VLCtab_t mpeg3_MVtab2[12];
+
+/* Table B-9, coded_block_pattern, codes 01000 ... 111xx */
+extern mpeg3_VLCtab_t mpeg3_CBPtab0[32];
+
+/* Table B-9, coded_block_pattern, codes 00000100 ... 001111xx */
+extern mpeg3_VLCtab_t mpeg3_CBPtab1[64];
+
+/* Table B-9, coded_block_pattern, codes 000000001 ... 000000111 */
+extern mpeg3_VLCtab_t mpeg3_CBPtab2[8];
+
+/* Table B-1, macroblock_address_increment, codes 00010 ... 011xx */
+extern mpeg3_VLCtab_t mpeg3_MBAtab1[16];
+
+/* Table B-1, macroblock_address_increment, codes 00000011000 ... 0000111xxxx */
+extern mpeg3_VLCtab_t mpeg3_MBAtab2[104];
+
+/* Table B-12, dct_dc_size_luminance, codes 00xxx ... 11110 */
+extern mpeg3_VLCtab_t mpeg3_DClumtab0[32];
+
+/* Table B-12, dct_dc_size_luminance, codes 111110xxx ... 111111111 */
+extern mpeg3_VLCtab_t mpeg3_DClumtab1[16];
+
+/* Table B-13, dct_dc_size_chrominance, codes 00xxx ... 11110 */
+extern mpeg3_VLCtab_t mpeg3_DCchromtab0[32];
+
+/* Table B-13, dct_dc_size_chrominance, codes 111110xxxx ... 1111111111 */
+extern mpeg3_VLCtab_t mpeg3_DCchromtab1[32];
+
+/* Table B-14, DCT coefficients table zero,
+ * codes 0100 ... 1xxx (used for first (DC) coefficient)
+ */
+extern mpeg3_DCTtab_t mpeg3_DCTtabfirst[12];
+
+/* Table B-14, DCT coefficients table zero,
+ * codes 0100 ... 1xxx (used for all other coefficients)
+ */
+extern mpeg3_DCTtab_t mpeg3_DCTtabnext[12];
+
+/* Table B-14, DCT coefficients table zero,
+ * codes 000001xx ... 00111xxx
+ */
+extern mpeg3_DCTtab_t mpeg3_DCTtab0[60];
+
+/* Table B-15, DCT coefficients table one,
+ * codes 000001xx ... 11111111
+*/
+extern mpeg3_DCTtab_t mpeg3_DCTtab0a[252];
+
+/* Table B-14, DCT coefficients table zero,
+ * codes 0000001000 ... 0000001111
+ */
+extern mpeg3_DCTtab_t mpeg3_DCTtab1[8];
+
+/* Table B-15, DCT coefficients table one,
+ * codes 000000100x ... 000000111x
+ */
+extern mpeg3_DCTtab_t mpeg3_DCTtab1a[8];
+
+/* Table B-14/15, DCT coefficients table zero / one,
+ * codes 000000010000 ... 000000011111
+ */
+extern mpeg3_DCTtab_t mpeg3_DCTtab2[16];
+
+/* Table B-14/15, DCT coefficients table zero / one,
+ * codes 0000000010000 ... 0000000011111
+ */
+extern mpeg3_DCTtab_t mpeg3_DCTtab3[16];
+
+/* Table B-14/15, DCT coefficients table zero / one,
+ * codes 00000000010000 ... 00000000011111
+ */
+extern mpeg3_DCTtab_t mpeg3_DCTtab4[16];
+
+/* Table B-14/15, DCT coefficients table zero / one,
+ * codes 000000000010000 ... 000000000011111
+ */
+extern mpeg3_DCTtab_t mpeg3_DCTtab5[16];
+
+/* Table B-14/15, DCT coefficients table zero / one,
+ * codes 0000000000010000 ... 0000000000011111
+ */
+extern mpeg3_DCTtab_t mpeg3_DCTtab6[16];
+
+
+#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 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+
+static LONGLONG mpeg3_MMX_601_Y_COEF = 0x0000004000400040;
+
+inline void mpeg3_601_mmx(unsigned long y,
+ unsigned long *output)
+{
+asm("
+/* Output will be 0x00rrggbb */
+ movd (%0), %%mm0; /* Load y 0x00000000000000yy */
+/* pmullw mpeg3_MMX_601_Y_COEF, %%mm0; // Scale y 0x00000000000000yy */
+ psllw $6, %%mm0; /* Shift y coeffs 0x0000yyy0yyy0yyy0 */
+ movd %%mm0, (%1); /* Store output */
+ "
+:
+: "r" (&y), "r" (output));
+}
+
+
+int main(int argc, char *argv[])
+{
+ unsigned char output[1024];
+
+ memset(output, 0, 1024);
+ mpeg3_601_mmx(1, (unsigned long*)output);
+ printf("%02x%02x\n", *(unsigned char*)&output[1], *(unsigned char*)&output[0]);
+}