summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Foley <bfoley@compsoc.nuigalway.ie>2002-08-28 13:14:36 +0000
committerMichael Niedermayer <michaelni@gmx.at>2002-08-28 13:14:36 +0000
commit59925ef2044e3ba2b5be49a35d37929550e3d6bc (patch)
tree97c7de71ccfd22da770139d0ed750b8c95597300
parent68bd11f5de271a1a674f196a9e8ca2e7fe40ab6e (diff)
first cut at altivec support on darwin patch by (Brian Foley <bfoley at compsoc dot nuigalway dot ie>)
Originally committed as revision 875 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rwxr-xr-xconfigure2
-rw-r--r--libavcodec/Makefile6
-rw-r--r--libavcodec/dsputil.c3
-rw-r--r--libavcodec/dsputil.h7
-rw-r--r--libavcodec/ppc/dsputil_altivec.c152
5 files changed, 169 insertions, 1 deletions
diff --git a/configure b/configure
index 09cda4212f..e7821697da 100755
--- a/configure
+++ b/configure
@@ -479,7 +479,7 @@ echo "#define restrict $_restrict" >> $TMPH
# build tree in object directory if source path is different from current one
if test "$source_path_used" = "yes" ; then
DIRS="libav libavcodec libavcodec/alpha libavcodec/armv4l libavcodec/i386 \
- libavcodec/liba52 libavcodec/mlib tests"
+ libavcodec/ppc libavcodec/liba52 libavcodec/mlib tests"
FILES="Makefile libav/Makefile libavcodec/Makefile tests/Makefile"
for dir in $DIRS ; do
mkdir -p $dir
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 2d3b490018..2c4c69db60 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -67,6 +67,11 @@ ASM_OBJS += alpha/dsputil_alpha_asm.o
CFLAGS += -Wa,-mpca56 -finline-limit=8000 -fforce-addr -freduce-all-givs
endif
+ifeq ($(TARGET_ARCH_POWERPC),yes)
+CFLAGS += -faltivec
+OBJS += ppc/dsputil_altivec.o
+endif
+
SRCS := $(OBJS:.o=.c) $(ASM_OBJS:.o=.S)
OBJS := $(OBJS) $(ASM_OBJS)
@@ -106,6 +111,7 @@ clean:
armv4l/*.o armv4l/*~ \
mlib/*.o mlib/*~ \
alpha/*.o alpha/*~ \
+ ppc/*.o ppc/*~ \
liba52/*.o liba52/*~ \
apiexample $(TESTS)
diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c
index a510ece213..5f3d89f54b 100644
--- a/libavcodec/dsputil.c
+++ b/libavcodec/dsputil.c
@@ -1341,6 +1341,9 @@ void dsputil_init(void)
dsputil_init_alpha();
use_permuted_idct = 0;
#endif
+#ifdef ARCH_POWERPC
+ dsputil_init_altivec();
+#endif
#ifdef SIMPLE_IDCT
if (ff_idct == NULL) {
diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h
index 2617dc666b..28655f79c3 100644
--- a/libavcodec/dsputil.h
+++ b/libavcodec/dsputil.h
@@ -163,6 +163,13 @@ void dsputil_init_mlib(void);
void dsputil_init_alpha(void);
+#elif defined(ARCH_POWERPC)
+
+#define emms_c()
+#define __align8 __attribute__ ((aligned (16)))
+
+void dsputil_init_altivec(void);
+
#else
#define emms_c()
diff --git a/libavcodec/ppc/dsputil_altivec.c b/libavcodec/ppc/dsputil_altivec.c
new file mode 100644
index 0000000000..aab5ea6431
--- /dev/null
+++ b/libavcodec/ppc/dsputil_altivec.c
@@ -0,0 +1,152 @@
+#include "../dsputil.h"
+
+#if CONFIG_DARWIN
+#include <sys/sysctl.h>
+#endif
+
+int pix_abs16x16_altivec(uint8_t *pix1, uint8_t *pix2, int line_size);
+int pix_abs8x8_altivec(uint8_t *pix1, uint8_t *pix2, int line_size);
+int pix_sum_altivec(UINT8 * pix, int line_size);
+
+int has_altivec(void);
+
+int pix_abs16x16_altivec(uint8_t *pix1, uint8_t *pix2, int line_size)
+{
+ int i, s;
+ vector unsigned char perm1, perm2, *pix1v, *pix2v;
+ vector unsigned char t1, t2, t3,t4, t5;
+ vector unsigned int sad, zero;
+ vector signed int sumdiffs;
+
+ zero = (vector unsigned int) (0);
+ sad = (vector unsigned int) (0);
+
+
+ for(i=0;i<16;i++) {
+ /* Read potentially unaligned pixels into t1 and t2 */
+ perm1 = vec_lvsl(0, pix1);
+ pix1v = (vector unsigned char *) pix1;
+ perm2 = vec_lvsl(0, pix2);
+ pix2v = (vector unsigned char *) pix2;
+ t1 = vec_perm(pix1v[0], pix1v[1], perm1);
+ t2 = vec_perm(pix2v[0], pix2v[1], perm2);
+
+ /* Calculate a sum of abs differences vector */
+ t3 = vec_max(t1, t2);
+ t4 = vec_min(t1, t2);
+ t5 = vec_sub(t3, t4);
+
+ /* Add each 4 pixel group together and put 4 results into sad */
+ sad = vec_sum4s(t5, sad);
+
+ pix1 += line_size;
+ pix2 += line_size;
+ }
+
+ /* Sum up the four partial sums, and put the result into s */
+ sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero);
+ sumdiffs = vec_splat(sumdiffs, 3);
+ vec_ste(sumdiffs, 0, &s);
+
+ return s;
+}
+
+int pix_abs8x8_altivec(uint8_t *pix1, uint8_t *pix2, int line_size)
+{
+ int i, s;
+ vector unsigned char perm1, perm2, permclear, *pix1v, *pix2v;
+ vector unsigned char t1, t2, t3,t4, t5;
+ vector unsigned int sad, zero;
+ vector signed int sumdiffs;
+
+ zero = (vector unsigned int) (0);
+ sad = (vector unsigned int) (0);
+ permclear = (vector unsigned char) (255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0);
+
+ for(i=0;i<8;i++) {
+ /* Read potentially unaligned pixels into t1 and t2
+ Since we're reading 16 pixels, and actually only want 8,
+ mask out the last 8 pixels. The 0s don't change the sum. */
+ perm1 = vec_lvsl(0, pix1);
+ pix1v = (vector unsigned char *) pix1;
+ perm2 = vec_lvsl(0, pix2);
+ pix2v = (vector unsigned char *) pix2;
+ t1 = vec_and(vec_perm(pix1v[0], pix1v[1], perm1), permclear);
+ t2 = vec_and(vec_perm(pix2v[0], pix2v[1], perm2), permclear);
+
+ /* Calculate a sum of abs differences vector */
+ t3 = vec_max(t1, t2);
+ t4 = vec_min(t1, t2);
+ t5 = vec_sub(t3, t4);
+
+ /* Add each 4 pixel group together and put 4 results into sad */
+ sad = vec_sum4s(t5, sad);
+
+ pix1 += line_size;
+ pix2 += line_size;
+ }
+
+ /* Sum up the four partial sums, and put the result into s */
+ sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero);
+ sumdiffs = vec_splat(sumdiffs, 3);
+ vec_ste(sumdiffs, 0, &s);
+
+ return s;
+}
+
+int pix_sum_altivec(UINT8 * pix, int line_size)
+{
+
+ vector unsigned char perm, *pixv;
+ vector unsigned char t1;
+ vector unsigned int sad, zero;
+ vector signed int sumdiffs;
+
+ int s, i;
+
+ zero = (vector unsigned int) (0);
+ sad = (vector unsigned int) (0);
+
+ for (i = 0; i < 16; i++) {
+ /* Read the potentially unaligned 16 pixels into t1 */
+ perm = vec_lvsl(0, pix);
+ pixv = (vector unsigned char *) pix;
+ t1 = vec_perm(pixv[0], pixv[1], perm);
+
+ /* Add each 4 pixel group together and put 4 results into sad */
+ sad = vec_sum4s(t1, sad);
+
+ pix += line_size;
+ }
+
+ /* Sum up the four partial sums, and put the result into s */
+ sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero);
+ sumdiffs = vec_splat(sumdiffs, 3);
+ vec_ste(sumdiffs, 0, &s);
+
+ return s;
+}
+
+void dsputil_init_altivec(void)
+{
+ if (has_altivec()) {
+ pix_abs16x16 = pix_abs16x16_altivec;
+ pix_abs8x8 = pix_abs8x8_altivec;
+ pix_sum = pix_sum_altivec;
+ }
+}
+
+int has_altivec(void)
+{
+#if CONFIG_DARWIN
+ int sels[2] = {CTL_HW, HW_VECTORUNIT};
+ int has_vu = 0;
+ size_t len = sizeof(has_vu);
+ int err;
+
+ err = sysctl(sels, 2, &has_vu, &len, NULL, 0);
+
+ if (err == 0) return (has_vu != 0);
+#endif
+ return 0;
+}