diff options
author | Brian Foley <bfoley@compsoc.nuigalway.ie> | 2002-08-28 13:14:36 +0000 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2002-08-28 13:14:36 +0000 |
commit | 59925ef2044e3ba2b5be49a35d37929550e3d6bc (patch) | |
tree | 97c7de71ccfd22da770139d0ed750b8c95597300 | |
parent | 68bd11f5de271a1a674f196a9e8ca2e7fe40ab6e (diff) | |
download | ffmpeg-59925ef2044e3ba2b5be49a35d37929550e3d6bc.tar.gz |
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-x | configure | 2 | ||||
-rw-r--r-- | libavcodec/Makefile | 6 | ||||
-rw-r--r-- | libavcodec/dsputil.c | 3 | ||||
-rw-r--r-- | libavcodec/dsputil.h | 7 | ||||
-rw-r--r-- | libavcodec/ppc/dsputil_altivec.c | 152 |
5 files changed, 169 insertions, 1 deletions
@@ -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; +} |