summaryrefslogtreecommitdiffstats
path: root/libmpeg2
diff options
context:
space:
mode:
authorarpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2003-04-06 16:41:49 +0000
committerarpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2003-04-06 16:41:49 +0000
commit134008a53427140cd2c23e2c5507c3c12af17a01 (patch)
tree126f91c5270f5e54e00df05689ac59ad800a3342 /libmpeg2
parent4ffd483b4832126e6155ac3174a7d4a939e455e2 (diff)
downloadmpv-134008a53427140cd2c23e2c5507c3c12af17a01.tar.bz2
mpv-134008a53427140cd2c23e2c5507c3c12af17a01.tar.xz
Importing libmpeg2 from mpeg2dec-0.3.1
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@9858 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpeg2')
-rw-r--r--libmpeg2/alloc.c76
-rw-r--r--libmpeg2/alpha_asm.h184
-rw-r--r--libmpeg2/convert.h56
-rw-r--r--libmpeg2/cpu_accel.c175
-rw-r--r--libmpeg2/cpu_state.c119
-rw-r--r--libmpeg2/decode.c439
-rw-r--r--libmpeg2/idct_alpha.c380
-rw-r--r--libmpeg2/idct_altivec.c705
-rw-r--r--libmpeg2/motion_comp_alpha.c253
-rw-r--r--libmpeg2/motion_comp_altivec.c2019
10 files changed, 4406 insertions, 0 deletions
diff --git a/libmpeg2/alloc.c b/libmpeg2/alloc.c
new file mode 100644
index 0000000000..0a434d9782
--- /dev/null
+++ b/libmpeg2/alloc.c
@@ -0,0 +1,76 @@
+/*
+ * alloc.c
+ * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ * See http://libmpeg2.sourceforge.net/ for updates.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include "mpeg2.h"
+#include "mpeg2_internal.h"
+
+#if defined(HAVE_MEMALIGN) && !defined(__cplusplus)
+/* some systems have memalign() but no declaration for it */
+void * memalign (size_t align, size_t size);
+#endif
+
+void * (* mpeg2_malloc_hook) (int size, int reason) = NULL;
+int (* mpeg2_free_hook) (void * buf) = NULL;
+
+void * mpeg2_malloc (int size, int reason)
+{
+ char * buf;
+
+ if (mpeg2_malloc_hook) {
+ buf = (char *) mpeg2_malloc_hook (size, reason);
+ if (buf)
+ return buf;
+ }
+
+#if defined(HAVE_MEMALIGN) && !defined(__cplusplus) && !defined(DEBUG)
+ return memalign (16, size);
+#else
+ buf = (char *) malloc (size + 15 + sizeof (void **));
+ if (buf) {
+ char * align_buf;
+
+ align_buf = buf + 15 + sizeof (void **);
+ align_buf -= (long)align_buf & 15;
+ *(((void **)align_buf) - 1) = buf;
+ return align_buf;
+ }
+ return NULL;
+#endif
+}
+
+void mpeg2_free (void * buf)
+{
+ if (mpeg2_free_hook && mpeg2_free_hook (buf))
+ return;
+
+#if defined(HAVE_MEMALIGN) && !defined(__cplusplus) && !defined(DEBUG)
+ free (buf);
+#else
+ free (*(((void **)buf) - 1));
+#endif
+}
diff --git a/libmpeg2/alpha_asm.h b/libmpeg2/alpha_asm.h
new file mode 100644
index 0000000000..6864ccc2e7
--- /dev/null
+++ b/libmpeg2/alpha_asm.h
@@ -0,0 +1,184 @@
+/*
+ * Alpha assembly macros
+ * Copyright (c) 2002 Falk Hueffner <falk@debian.org>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ * See http://libmpeg2.sourceforge.net/ for updates.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef ALPHA_ASM_H
+#define ALPHA_ASM_H
+
+#include <inttypes.h>
+
+#if defined __GNUC__
+# define GNUC_PREREQ(maj, min) \
+ ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+#else
+# define GNUC_PREREQ(maj, min) 0
+#endif
+
+#define AMASK_BWX (1 << 0)
+#define AMASK_FIX (1 << 1)
+#define AMASK_CIX (1 << 2)
+#define AMASK_MVI (1 << 8)
+
+#ifdef __alpha_bwx__
+# define HAVE_BWX() 1
+#else
+# define HAVE_BWX() (amask(AMASK_BWX) == 0)
+#endif
+#ifdef __alpha_fix__
+# define HAVE_FIX() 1
+#else
+# define HAVE_FIX() (amask(AMASK_FIX) == 0)
+#endif
+#ifdef __alpha_max__
+# define HAVE_MVI() 1
+#else
+# define HAVE_MVI() (amask(AMASK_MVI) == 0)
+#endif
+#ifdef __alpha_cix__
+# define HAVE_CIX() 1
+#else
+# define HAVE_CIX() (amask(AMASK_CIX) == 0)
+#endif
+
+inline static uint64_t BYTE_VEC(uint64_t x)
+{
+ x |= x << 8;
+ x |= x << 16;
+ x |= x << 32;
+ return x;
+}
+inline static uint64_t WORD_VEC(uint64_t x)
+{
+ x |= x << 16;
+ x |= x << 32;
+ return x;
+}
+
+#define ldq(p) (*(const uint64_t *) (p))
+#define ldl(p) (*(const int32_t *) (p))
+#define stl(l, p) do { *(uint32_t *) (p) = (l); } while (0)
+#define stq(l, p) do { *(uint64_t *) (p) = (l); } while (0)
+#define sextw(x) ((int16_t) (x))
+
+#ifdef __GNUC__
+struct unaligned_long { uint64_t l; } __attribute__((packed));
+#define ldq_u(p) (*(const uint64_t *) (((uint64_t) (p)) & ~7ul))
+#define uldq(a) (((const struct unaligned_long *) (a))->l)
+
+#if GNUC_PREREQ(3,0)
+/* Unfortunately, __builtin_prefetch is slightly buggy on Alpha. The
+ defines here are kludged so we still get the right
+ instruction. This needs to be adapted as soon as gcc is fixed. */
+# define prefetch(p) __builtin_prefetch((p), 0, 1)
+# define prefetch_en(p) __builtin_prefetch((p), 1, 1)
+# define prefetch_m(p) __builtin_prefetch((p), 0, 0)
+# define prefetch_men(p) __builtin_prefetch((p), 1, 0)
+#else
+# define prefetch(p) asm volatile("ldl $31,%0" : : "m"(*(const char *) (p)) : "memory")
+# define prefetch_en(p) asm volatile("ldq $31,%0" : : "m"(*(const char *) (p)) : "memory")
+# define prefetch_m(p) asm volatile("lds $f31,%0" : : "m"(*(const char *) (p)) : "memory")
+# define prefetch_men(p) asm volatile("ldt $f31,%0" : : "m"(*(const char *) (p)) : "memory")
+#endif
+
+#if GNUC_PREREQ(3,3)
+#define cmpbge __builtin_alpha_cmpbge
+/* Avoid warnings. */
+#define extql(a, b) __builtin_alpha_extql(a, (uint64_t) (b))
+#define extwl(a, b) __builtin_alpha_extwl(a, (uint64_t) (b))
+#define extqh(a, b) __builtin_alpha_extqh(a, (uint64_t) (b))
+#define zap __builtin_alpha_zap
+#define zapnot __builtin_alpha_zapnot
+#define amask __builtin_alpha_amask
+#define implver __builtin_alpha_implver
+#define rpcc __builtin_alpha_rpcc
+#define minub8 __builtin_alpha_minub8
+#define minsb8 __builtin_alpha_minsb8
+#define minuw4 __builtin_alpha_minuw4
+#define minsw4 __builtin_alpha_minsw4
+#define maxub8 __builtin_alpha_maxub8
+#define maxsb8 __builtin_alpha_maxsb8
+#define maxuw4 __builtin_alpha_maxuw4
+#define maxsw4 __builtin_alpha_maxsw4
+#define perr __builtin_alpha_perr
+#define pklb __builtin_alpha_pklb
+#define pkwb __builtin_alpha_pkwb
+#define unpkbl __builtin_alpha_unpkbl
+#define unpkbw __builtin_alpha_unpkbw
+#else
+#define cmpbge(a, b) ({ uint64_t __r; asm ("cmpbge %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; })
+#define extql(a, b) ({ uint64_t __r; asm ("extql %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; })
+#define extwl(a, b) ({ uint64_t __r; asm ("extwl %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; })
+#define extqh(a, b) ({ uint64_t __r; asm ("extqh %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; })
+#define zap(a, b) ({ uint64_t __r; asm ("zap %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; })
+#define zapnot(a, b) ({ uint64_t __r; asm ("zapnot %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; })
+#define amask(a) ({ uint64_t __r; asm ("amask %1,%0" : "=r" (__r) : "rI" (a)); __r; })
+#define implver() ({ uint64_t __r; asm ("implver %0" : "=r" (__r)); __r; })
+#define rpcc() ({ uint64_t __r; asm volatile ("rpcc %0" : "=r" (__r)); __r; })
+#define minub8(a, b) ({ uint64_t __r; asm ("minub8 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; })
+#define minsb8(a, b) ({ uint64_t __r; asm ("minsb8 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; })
+#define minuw4(a, b) ({ uint64_t __r; asm ("minuw4 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; })
+#define minsw4(a, b) ({ uint64_t __r; asm ("minsw4 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; })
+#define maxub8(a, b) ({ uint64_t __r; asm ("maxub8 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; })
+#define maxsb8(a, b) ({ uint64_t __r; asm ("maxsb8 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; })
+#define maxuw4(a, b) ({ uint64_t __r; asm ("maxuw4 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; })
+#define maxsw4(a, b) ({ uint64_t __r; asm ("maxsw4 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; })
+#define perr(a, b) ({ uint64_t __r; asm ("perr %r1,%r2,%0" : "=r" (__r) : "%rJ" (a), "rJ" (b)); __r; })
+#define pklb(a) ({ uint64_t __r; asm ("pklb %r1,%0" : "=r" (__r) : "rJ" (a)); __r; })
+#define pkwb(a) ({ uint64_t __r; asm ("pkwb %r1,%0" : "=r" (__r) : "rJ" (a)); __r; })
+#define unpkbl(a) ({ uint64_t __r; asm ("unpkbl %r1,%0" : "=r" (__r) : "rJ" (a)); __r; })
+#define unpkbw(a) ({ uint64_t __r; asm ("unpkbw %r1,%0" : "=r" (__r) : "rJ" (a)); __r; })
+#endif
+#define wh64(p) asm volatile("wh64 (%0)" : : "r"(p) : "memory")
+
+#elif defined(__DECC) /* Digital/Compaq/hp "ccc" compiler */
+
+#include <c_asm.h>
+#define ldq_u(a) asm ("ldq_u %v0,0(%a0)", a)
+#define uldq(a) (*(const __unaligned uint64_t *) (a))
+#define cmpbge(a, b) asm ("cmpbge %a0,%a1,%v0", a, b)
+#define extql(a, b) asm ("extql %a0,%a1,%v0", a, b)
+#define extwl(a, b) asm ("extwl %a0,%a1,%v0", a, b)
+#define extqh(a, b) asm ("extqh %a0,%a1,%v0", a, b)
+#define zap(a, b) asm ("zap %a0,%a1,%v0", a, b)
+#define zapnot(a, b) asm ("zapnot %a0,%a1,%v0", a, b)
+#define amask(a) asm ("amask %a0,%v0", a)
+#define implver() asm ("implver %v0")
+#define rpcc() asm ("rpcc %v0")
+#define minub8(a, b) asm ("minub8 %a0,%a1,%v0", a, b)
+#define minsb8(a, b) asm ("minsb8 %a0,%a1,%v0", a, b)
+#define minuw4(a, b) asm ("minuw4 %a0,%a1,%v0", a, b)
+#define minsw4(a, b) asm ("minsw4 %a0,%a1,%v0", a, b)
+#define maxub8(a, b) asm ("maxub8 %a0,%a1,%v0", a, b)
+#define maxsb8(a, b) asm ("maxsb8 %a0,%a1,%v0", a, b)
+#define maxuw4(a, b) asm ("maxuw4 %a0,%a1,%v0", a, b)
+#define maxsw4(a, b) asm ("maxsw4 %a0,%a1,%v0", a, b)
+#define perr(a, b) asm ("perr %a0,%a1,%v0", a, b)
+#define pklb(a) asm ("pklb %a0,%v0", a)
+#define pkwb(a) asm ("pkwb %a0,%v0", a)
+#define unpkbl(a) asm ("unpkbl %a0,%v0", a)
+#define unpkbw(a) asm ("unpkbw %a0,%v0", a)
+#define wh64(a) asm ("wh64 %a0", a)
+
+#else
+#error "Unknown compiler!"
+#endif
+
+#endif /* ALPHA_ASM_H */
diff --git a/libmpeg2/convert.h b/libmpeg2/convert.h
new file mode 100644
index 0000000000..fd51fd84c2
--- /dev/null
+++ b/libmpeg2/convert.h
@@ -0,0 +1,56 @@
+/*
+ * convert.h
+ * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ * See http://libmpeg2.sourceforge.net/ for updates.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef CONVERT_H
+#define CONVERT_H
+
+#define CONVERT_FRAME 0
+#define CONVERT_TOP_FIELD 1
+#define CONVERT_BOTTOM_FIELD 2
+#define CONVERT_BOTH_FIELDS 3
+
+typedef struct convert_init_s {
+ void * id;
+ int id_size;
+ int buf_size[3];
+ void (* start) (void * id, uint8_t * const * dest, int flags);
+ void (* copy) (void * id, uint8_t * const * src, unsigned int v_offset);
+} convert_init_t;
+
+typedef void convert_t (int width, int height, uint32_t accel, void * arg,
+ convert_init_t * result);
+
+convert_t convert_rgb32;
+convert_t convert_rgb24;
+convert_t convert_rgb16;
+convert_t convert_rgb15;
+convert_t convert_bgr32;
+convert_t convert_bgr24;
+convert_t convert_bgr16;
+convert_t convert_bgr15;
+
+#define CONVERT_RGB 0
+#define CONVERT_BGR 1
+convert_t * convert_rgb (int order, int bpp);
+
+#endif /* CONVERT_H */
diff --git a/libmpeg2/cpu_accel.c b/libmpeg2/cpu_accel.c
new file mode 100644
index 0000000000..809deabcd7
--- /dev/null
+++ b/libmpeg2/cpu_accel.c
@@ -0,0 +1,175 @@
+/*
+ * cpu_accel.c
+ * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ * See http://libmpeg2.sourceforge.net/ for updates.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <inttypes.h>
+
+#include "mpeg2.h"
+
+#ifdef ACCEL_DETECT
+#ifdef ARCH_X86
+static inline uint32_t arch_accel (void)
+{
+ uint32_t eax, ebx, ecx, edx;
+ int AMD;
+ uint32_t caps;
+
+#ifndef PIC
+#define cpuid(op,eax,ebx,ecx,edx) \
+ __asm__ ("cpuid" \
+ : "=a" (eax), \
+ "=b" (ebx), \
+ "=c" (ecx), \
+ "=d" (edx) \
+ : "a" (op) \
+ : "cc")
+#else /* PIC version : save ebx */
+#define cpuid(op,eax,ebx,ecx,edx) \
+ __asm__ ("push %%ebx\n\t" \
+ "cpuid\n\t" \
+ "movl %%ebx,%1\n\t" \
+ "pop %%ebx" \
+ : "=a" (eax), \
+ "=r" (ebx), \
+ "=c" (ecx), \
+ "=d" (edx) \
+ : "a" (op) \
+ : "cc")
+#endif
+
+ __asm__ ("pushf\n\t"
+ "pushf\n\t"
+ "pop %0\n\t"
+ "movl %0,%1\n\t"
+ "xorl $0x200000,%0\n\t"
+ "push %0\n\t"
+ "popf\n\t"
+ "pushf\n\t"
+ "pop %0\n\t"
+ "popf"
+ : "=r" (eax),
+ "=r" (ebx)
+ :
+ : "cc");
+
+ if (eax == ebx) /* no cpuid */
+ return 0;
+
+ cpuid (0x00000000, eax, ebx, ecx, edx);
+ if (!eax) /* vendor string only */
+ return 0;
+
+ AMD = (ebx == 0x68747541) && (ecx == 0x444d4163) && (edx == 0x69746e65);
+
+ cpuid (0x00000001, eax, ebx, ecx, edx);
+ if (! (edx & 0x00800000)) /* no MMX */
+ return 0;
+
+ caps = MPEG2_ACCEL_X86_MMX;
+ if (edx & 0x02000000) /* SSE - identical to AMD MMX extensions */
+ caps = MPEG2_ACCEL_X86_MMX | MPEG2_ACCEL_X86_MMXEXT;
+
+ cpuid (0x80000000, eax, ebx, ecx, edx);
+ if (eax < 0x80000001) /* no extended capabilities */
+ return caps;
+
+ cpuid (0x80000001, eax, ebx, ecx, edx);
+
+ if (edx & 0x80000000)
+ caps |= MPEG2_ACCEL_X86_3DNOW;
+
+ if (AMD && (edx & 0x00400000)) /* AMD MMX extensions */
+ caps |= MPEG2_ACCEL_X86_MMXEXT;
+
+ return caps;
+}
+#endif /* ARCH_X86 */
+
+#ifdef ARCH_PPC
+#include <signal.h>
+#include <setjmp.h>
+
+static sigjmp_buf jmpbuf;
+static volatile sig_atomic_t canjump = 0;
+
+static RETSIGTYPE sigill_handler (int sig)
+{
+ if (!canjump) {
+ signal (sig, SIG_DFL);
+ raise (sig);
+ }
+
+ canjump = 0;
+ siglongjmp (jmpbuf, 1);
+}
+
+static inline uint32_t arch_accel (void)
+{
+ signal (SIGILL, sigill_handler);
+ if (sigsetjmp (jmpbuf, 1)) {
+ signal (SIGILL, SIG_DFL);
+ return 0;
+ }
+
+ canjump = 1;
+
+ asm volatile ("mtspr 256, %0\n\t"
+ "vand %%v0, %%v0, %%v0"
+ :
+ : "r" (-1));
+
+ signal (SIGILL, SIG_DFL);
+ return MPEG2_ACCEL_PPC_ALTIVEC;
+}
+#endif /* ARCH_PPC */
+
+#ifdef ARCH_ALPHA
+static inline uint32_t arch_accel (void)
+{
+ uint64_t no_mvi;
+
+ asm volatile ("amask %1, %0"
+ : "=r" (no_mvi)
+ : "rI" (256)); /* AMASK_MVI */
+ return no_mvi ? MPEG2_ACCEL_ALPHA : (MPEG2_ACCEL_ALPHA |
+ MPEG2_ACCEL_ALPHA_MVI);
+}
+#endif /* ARCH_ALPHA */
+#endif
+
+uint32_t mpeg2_detect_accel (void)
+{
+ uint32_t accel;
+
+ accel = 0;
+#ifdef ACCEL_DETECT
+#ifdef LIBMPEG2_MLIB
+ accel = MPEG2_ACCEL_MLIB;
+#endif
+#if defined (ARCH_X86) || defined (ARCH_PPC) || defined (ARCH_ALPHA)
+ accel |= arch_accel ();
+#endif
+#endif
+ return accel;
+}
diff --git a/libmpeg2/cpu_state.c b/libmpeg2/cpu_state.c
new file mode 100644
index 0000000000..7ba5133679
--- /dev/null
+++ b/libmpeg2/cpu_state.c
@@ -0,0 +1,119 @@
+/*
+ * cpu_state.c
+ * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ * See http://libmpeg2.sourceforge.net/ for updates.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include "mpeg2.h"
+#include "mpeg2_internal.h"
+#include "attributes.h"
+#ifdef ARCH_X86
+#include "mmx.h"
+#endif
+
+void (* mpeg2_cpu_state_save) (cpu_state_t * state) = NULL;
+void (* mpeg2_cpu_state_restore) (cpu_state_t * state) = NULL;
+
+#ifdef ARCH_X86
+static void state_restore_mmx (cpu_state_t * state)
+{
+ emms ();
+}
+#endif
+
+#ifdef ARCH_PPC
+static void state_save_altivec (cpu_state_t * state)
+{
+ asm (" \n"
+ " li %r9, 16 \n"
+ " stvx %v20, 0, %r3 \n"
+ " li %r11, 32 \n"
+ " stvx %v21, %r9, %r3 \n"
+ " li %r9, 48 \n"
+ " stvx %v22, %r11, %r3 \n"
+ " li %r11, 64 \n"
+ " stvx %v23, %r9, %r3 \n"
+ " li %r9, 80 \n"
+ " stvx %v24, %r11, %r3 \n"
+ " li %r11, 96 \n"
+ " stvx %v25, %r9, %r3 \n"
+ " li %r9, 112 \n"
+ " stvx %v26, %r11, %r3 \n"
+ " li %r11, 128 \n"
+ " stvx %v27, %r9, %r3 \n"
+ " li %r9, 144 \n"
+ " stvx %v28, %r11, %r3 \n"
+ " li %r11, 160 \n"
+ " stvx %v29, %r9, %r3 \n"
+ " li %r9, 176 \n"
+ " stvx %v30, %r11, %r3 \n"
+ " stvx %v31, %r9, %r3 \n"
+ );
+}
+
+static void state_restore_altivec (cpu_state_t * state)
+{
+ asm (" \n"
+ " li %r9, 16 \n"
+ " lvx %v20, 0, %r3 \n"
+ " li %r11, 32 \n"
+ " lvx %v21, %r9, %r3 \n"
+ " li %r9, 48 \n"
+ " lvx %v22, %r11, %r3 \n"
+ " li %r11, 64 \n"
+ " lvx %v23, %r9, %r3 \n"
+ " li %r9, 80 \n"
+ " lvx %v24, %r11, %r3 \n"
+ " li %r11, 96 \n"
+ " lvx %v25, %r9, %r3 \n"
+ " li %r9, 112 \n"
+ " lvx %v26, %r11, %r3 \n"
+ " li %r11, 128 \n"
+ " lvx %v27, %r9, %r3 \n"
+ " li %r9, 144 \n"
+ " lvx %v28, %r11, %r3 \n"
+ " li %r11, 160 \n"
+ " lvx %v29, %r9, %r3 \n"
+ " li %r9, 176 \n"
+ " lvx %v30, %r11, %r3 \n"
+ " lvx %v31, %r9, %r3 \n"
+ );
+}
+#endif
+
+void mpeg2_cpu_state_init (uint32_t accel)
+{
+#ifdef ARCH_X86
+ if (accel & MPEG2_ACCEL_X86_MMX) {
+ mpeg2_cpu_state_restore = state_restore_mmx;
+ }
+#endif
+#ifdef ARCH_PPC
+ if (accel & MPEG2_ACCEL_PPC_ALTIVEC) {
+ mpeg2_cpu_state_save = state_save_altivec;
+ mpeg2_cpu_state_restore = state_restore_altivec;
+ }
+#endif
+}
diff --git a/libmpeg2/decode.c b/libmpeg2/decode.c
new file mode 100644
index 0000000000..8d59056c26
--- /dev/null
+++ b/libmpeg2/decode.c
@@ -0,0 +1,439 @@
+/*
+ * decode.c
+ * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ * See http://libmpeg2.sourceforge.net/ for updates.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <string.h> /* memcmp/memset, try to remove */
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include "mpeg2.h"
+#include "mpeg2_internal.h"
+#include "convert.h"
+
+static int mpeg2_accels = 0;
+
+#define BUFFER_SIZE (1194 * 1024)
+
+const mpeg2_info_t * mpeg2_info (mpeg2dec_t * mpeg2dec)
+{
+ return &(mpeg2dec->info);
+}
+
+static inline int skip_chunk (mpeg2dec_t * mpeg2dec, int bytes)
+{
+ uint8_t * current;
+ uint32_t shift;
+ uint8_t * chunk_ptr;
+ uint8_t * limit;
+ uint8_t byte;
+
+ if (!bytes)
+ return 0;
+
+ current = mpeg2dec->buf_start;
+ shift = mpeg2dec->shift;
+ chunk_ptr = mpeg2dec->chunk_ptr;
+ limit = current + bytes;
+
+ do {
+ byte = *current++;
+ if (shift == 0x00000100) {
+ int skipped;
+
+ mpeg2dec->shift = 0xffffff00;
+ skipped = current - mpeg2dec->buf_start;
+ mpeg2dec->buf_start = current;
+ return skipped;
+ }
+ shift = (shift | byte) << 8;
+ } while (current < limit);
+
+ mpeg2dec->shift = shift;
+ mpeg2dec->buf_start = current;
+ return 0;
+}
+
+static inline int copy_chunk (mpeg2dec_t * mpeg2dec, int bytes)
+{
+ uint8_t * current;
+ uint32_t shift;
+ uint8_t * chunk_ptr;
+ uint8_t * limit;
+ uint8_t byte;
+
+ if (!bytes)
+ return 0;
+
+ current = mpeg2dec->buf_start;
+ shift = mpeg2dec->shift;
+ chunk_ptr = mpeg2dec->chunk_ptr;
+ limit = current + bytes;
+
+ do {
+ byte = *current++;
+ if (shift == 0x00000100) {
+ int copied;
+
+ mpeg2dec->shift = 0xffffff00;
+ mpeg2dec->chunk_ptr = chunk_ptr + 1;
+ copied = current - mpeg2dec->buf_start;
+ mpeg2dec->buf_start = current;
+ return copied;
+ }
+ shift = (shift | byte) << 8;
+ *chunk_ptr++ = byte;
+ } while (current < limit);
+
+ mpeg2dec->shift = shift;
+ mpeg2dec->buf_start = current;
+ return 0;
+}
+
+void mpeg2_buffer (mpeg2dec_t * mpeg2dec, uint8_t * start, uint8_t * end)
+{
+ mpeg2dec->buf_start = start;
+ mpeg2dec->buf_end = end;
+}
+
+static inline int seek_chunk (mpeg2dec_t * mpeg2dec)
+{
+ int size, skipped;
+
+ size = mpeg2dec->buf_end - mpeg2dec->buf_start;
+ skipped = skip_chunk (mpeg2dec, size);
+ if (!skipped) {
+ mpeg2dec->bytes_since_pts += size;
+ return -1;
+ }
+ mpeg2dec->bytes_since_pts += skipped;
+ mpeg2dec->code = mpeg2dec->buf_start[-1];
+ return 0;
+}
+
+int mpeg2_seek_header (mpeg2dec_t * mpeg2dec)
+{
+ while (mpeg2dec->code != 0xb3 &&
+ ((mpeg2dec->code != 0xb7 && mpeg2dec->code != 0xb8 &&
+ mpeg2dec->code) || mpeg2dec->sequence.width == -1))
+ if (seek_chunk (mpeg2dec))
+ return -1;
+ mpeg2dec->chunk_start = mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer;
+ return mpeg2_parse_header (mpeg2dec);
+}
+
+int mpeg2_seek_sequence (mpeg2dec_t * mpeg2dec)
+{
+ mpeg2dec->sequence.width = -1;
+ return mpeg2_seek_header (mpeg2dec);
+}
+
+#define RECEIVED(code,state) (((state) << 8) + (code))
+
+int mpeg2_parse (mpeg2dec_t * mpeg2dec)
+{
+ int size_buffer, size_chunk, copied;
+
+ if (mpeg2dec->action) {
+ int state;
+
+ state = mpeg2dec->action (mpeg2dec);
+ if (state)
+ return state;
+ }
+
+ while (1) {
+ while ((unsigned) (mpeg2dec->code - mpeg2dec->first_decode_slice) <
+ mpeg2dec->nb_decode_slices) {
+ size_buffer = mpeg2dec->buf_end - mpeg2dec->buf_start;
+ size_chunk = (mpeg2dec->chunk_buffer + BUFFER_SIZE -
+ mpeg2dec->chunk_ptr);
+ if (size_buffer <= size_chunk) {
+ copied = copy_chunk (mpeg2dec, size_buffer);
+ if (!copied) {
+ mpeg2dec->bytes_since_pts += size_buffer;
+ mpeg2dec->chunk_ptr += size_buffer;
+ return -1;
+ }
+ } else {
+ copied = copy_chunk (mpeg2dec, size_chunk);
+ if (!copied) {
+ /* filled the chunk buffer without finding a start code */
+ mpeg2dec->bytes_since_pts += size_chunk;
+ mpeg2dec->action = seek_chunk;
+ return STATE_INVALID;
+ }
+ }
+ mpeg2dec->bytes_since_pts += copied;
+
+ mpeg2_slice (&(mpeg2dec->decoder), mpeg2dec->code,
+ mpeg2dec->chunk_start);
+ mpeg2dec->code = mpeg2dec->buf_start[-1];
+ mpeg2dec->chunk_ptr = mpeg2dec->chunk_start;
+ }
+ if ((unsigned) (mpeg2dec->code - 1) >= 0xb0 - 1)
+ break;
+ if (seek_chunk (mpeg2dec))
+ return -1;
+ }
+
+ switch (RECEIVED (mpeg2dec->code, mpeg2dec->state)) {
+ case RECEIVED (0x00, STATE_SLICE_1ST):
+ case RECEIVED (0x00, STATE_SLICE):
+ mpeg2dec->action = mpeg2_header_picture_start;
+ break;
+ case RECEIVED (0xb7, STATE_SLICE):
+ mpeg2dec->action = mpeg2_header_end;
+ break;
+ case RECEIVED (0xb3, STATE_SLICE):
+ case RECEIVED (0xb8, STATE_SLICE):
+ mpeg2dec->action = mpeg2_parse_header;
+ break;
+ default:
+ mpeg2dec->action = mpeg2_seek_header;
+ return STATE_INVALID;
+ }
+ return mpeg2dec->state;
+}
+
+int mpeg2_parse_header (mpeg2dec_t * mpeg2dec)
+{
+ static int (* process_header[]) (mpeg2dec_t * mpeg2dec) = {
+ mpeg2_header_picture, mpeg2_header_extension, mpeg2_header_user_data,
+ mpeg2_header_sequence, NULL, NULL, NULL, NULL, mpeg2_header_gop
+ };
+ int size_buffer, size_chunk, copied;
+
+ mpeg2dec->action = mpeg2_parse_header;
+ while (1) {
+ size_buffer = mpeg2dec->buf_end - mpeg2dec->buf_start;
+ size_chunk = (mpeg2dec->chunk_buffer + BUFFER_SIZE -
+ mpeg2dec->chunk_ptr);
+ if (size_buffer <= size_chunk) {
+ copied = copy_chunk (mpeg2dec, size_buffer);
+ if (!copied) {
+ mpeg2dec->bytes_since_pts += size_buffer;
+ mpeg2dec->chunk_ptr += size_buffer;
+ return -1;
+ }
+ } else {
+ copied = copy_chunk (mpeg2dec, size_chunk);
+ if (!copied) {
+ /* filled the chunk buffer without finding a start code */
+ mpeg2dec->bytes_since_pts += size_chunk;
+ mpeg2dec->code = 0xb4;
+ mpeg2dec->action = mpeg2_seek_header;
+ return STATE_INVALID;
+ }
+ }
+ mpeg2dec->bytes_since_pts += copied;
+
+ if (process_header[mpeg2dec->code & 0x0b] (mpeg2dec)) {
+ mpeg2dec->code = mpeg2dec->buf_start[-1];
+ mpeg2dec->action = mpeg2_seek_header;
+ return STATE_INVALID;
+ }
+
+ mpeg2dec->code = mpeg2dec->buf_start[-1];
+ switch (RECEIVED (mpeg2dec->code, mpeg2dec->state)) {
+
+ /* state transition after a sequence header */
+ case RECEIVED (0x00, STATE_SEQUENCE):
+ mpeg2dec->action = mpeg2_header_picture_start;
+ case RECEIVED (0xb8, STATE_SEQUENCE):
+ mpeg2_header_sequence_finalize (mpeg2dec);
+ break;
+
+ /* other legal state transitions */
+ case RECEIVED (0x00, STATE_GOP):
+ mpeg2dec->action = mpeg2_header_picture_start;
+ break;
+ case RECEIVED (0x01, STATE_PICTURE):
+ case RECEIVED (0x01, STATE_PICTURE_2ND):
+ mpeg2dec->action = mpeg2_header_slice_start;
+ break;
+
+ /* legal headers within a given state */
+ case RECEIVED (0xb2, STATE_SEQUENCE):
+ case RECEIVED (0xb2, STATE_GOP):
+ case RECEIVED (0xb2, STATE_PICTURE):
+ case RECEIVED (0xb2, STATE_PICTURE_2ND):
+ case RECEIVED (0xb5, STATE_SEQUENCE):
+ case RECEIVED (0xb5, STATE_PICTURE):
+ case RECEIVED (0xb5, STATE_PICTURE_2ND):
+ mpeg2dec->chunk_ptr = mpeg2dec->chunk_start;
+ continue;
+
+ default:
+ mpeg2dec->action = mpeg2_seek_header;
+ return STATE_INVALID;
+ }
+
+ mpeg2dec->chunk_start = mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer;
+ return mpeg2dec->state;
+ }
+}
+
+void mpeg2_convert (mpeg2dec_t * mpeg2dec,
+ void (* convert) (int, int, uint32_t, void *,
+ struct convert_init_s *), void * arg)
+{
+ convert_init_t convert_init;
+ int size;
+
+ convert_init.id = NULL;
+ convert (mpeg2dec->decoder.width, mpeg2dec->decoder.height,
+ mpeg2_accels, arg, &convert_init);
+ if (convert_init.id_size) {
+ convert_init.id = mpeg2dec->convert_id =
+ mpeg2_malloc (convert_init.id_size, ALLOC_CONVERT_ID);
+ convert (mpeg2dec->decoder.width, mpeg2dec->decoder.height,
+ mpeg2_accels, arg, &convert_init);
+ }
+ mpeg2dec->convert_size[0] = size = convert_init.buf_size[0];
+ mpeg2dec->convert_size[1] = size += convert_init.buf_size[1];
+ mpeg2dec->convert_size[2] = size += convert_init.buf_size[2];
+ mpeg2dec->convert_start = convert_init.start;
+ mpeg2dec->convert_copy = convert_init.copy;
+
+ size = mpeg2dec->decoder.width * mpeg2dec->decoder.height >> 2;
+ mpeg2dec->yuv_buf[0][0] = (uint8_t *) mpeg2_malloc (6 * size, ALLOC_YUV);
+ mpeg2dec->yuv_buf[0][1] = mpeg2dec->yuv_buf[0][0] + 4 * size;
+ mpeg2dec->yuv_buf[0][2] = mpeg2dec->yuv_buf[0][0] + 5 * size;
+ mpeg2dec->yuv_buf[1][0] = (uint8_t *) mpeg2_malloc (6 * size, ALLOC_YUV);
+ mpeg2dec->yuv_buf[1][1] = mpeg2dec->yuv_buf[1][0] + 4 * size;
+ mpeg2dec->yuv_buf[1][2] = mpeg2dec->yuv_buf[1][0] + 5 * size;
+ size = mpeg2dec->decoder.width * 8;
+ mpeg2dec->yuv_buf[2][0] = (uint8_t *) mpeg2_malloc (6 * size, ALLOC_YUV);
+ mpeg2dec->yuv_buf[2][1] = mpeg2dec->yuv_buf[2][0] + 4 * size;
+ mpeg2dec->yuv_buf[2][2] = mpeg2dec->yuv_buf[2][0] + 5 * size;
+}
+
+void mpeg2_set_buf (mpeg2dec_t * mpeg2dec, uint8_t * buf[3], void * id)
+{
+ fbuf_t * fbuf;
+
+ if (mpeg2dec->custom_fbuf) {
+ mpeg2_set_fbuf (mpeg2dec, mpeg2dec->decoder.coding_type);
+ fbuf = mpeg2dec->fbuf[0];
+ if (mpeg2dec->state == STATE_SEQUENCE) {
+ mpeg2dec->fbuf[2] = mpeg2dec->fbuf[1];
+ mpeg2dec->fbuf[1] = mpeg2dec->fbuf[0];
+ }
+ } else {
+ fbuf = &(mpeg2dec->fbuf_alloc[mpeg2dec->