]> git.pld-linux.org Git - packages/avifile.git/commitdiff
- missing files+update from ffmpeg 0.4.8
authorJakub Bogusz <qboosh@pld-linux.org>
Thu, 13 Nov 2003 23:44:44 +0000 (23:44 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    avifile-ffmpeg-ppc.patch -> 1.1

avifile-ffmpeg-ppc.patch [new file with mode: 0644]

diff --git a/avifile-ffmpeg-ppc.patch b/avifile-ffmpeg-ppc.patch
new file mode 100644 (file)
index 0000000..356b511
--- /dev/null
@@ -0,0 +1,3140 @@
+diff -Nur avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc.orig/dsputil_altivec.c avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc/dsputil_altivec.c
+--- avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc.orig/dsputil_altivec.c    1970-01-01 01:00:00.000000000 +0100
++++ avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc/dsputil_altivec.c 2003-09-28 17:26:40.000000000 +0200
+@@ -0,0 +1,1345 @@
++/*
++ * Copyright (c) 2002 Brian Foley
++ * Copyright (c) 2002 Dieter Shirley
++ * Copyright (c) 2003 Romain Dolbeau <romain@dolbeau.org>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++ 
++#include "../dsputil.h"
++
++#include "gcc_fixes.h"
++
++#include "dsputil_altivec.h"
++
++#ifdef CONFIG_DARWIN
++#include <sys/sysctl.h>
++#else /* CONFIG_DARWIN */
++#include <signal.h>
++#include <setjmp.h>
++
++static sigjmp_buf jmpbuf;
++static volatile sig_atomic_t canjump = 0;
++
++static void sigill_handler (int sig)
++{
++    if (!canjump) {
++        signal (sig, SIG_DFL);
++        raise (sig);
++    }
++    
++    canjump = 0;
++    siglongjmp (jmpbuf, 1);
++}
++#endif /* CONFIG_DARWIN */
++
++int pix_abs16x16_x2_altivec(uint8_t *pix1, uint8_t *pix2, int line_size)
++{
++    int i;
++    int s __attribute__((aligned(16)));
++    const vector unsigned char zero = (const vector unsigned char)vec_splat_u8(0);
++    vector unsigned char *tv;
++    vector unsigned char pix1v, pix2v, pix2iv, avgv, t5;
++    vector unsigned int sad;
++    vector signed int sumdiffs;
++
++    s = 0;
++    sad = (vector unsigned int)vec_splat_u32(0);
++    for(i=0;i<16;i++) {
++        /*
++           Read unaligned pixels into our vectors. The vectors are as follows:
++           pix1v: pix1[0]-pix1[15]
++           pix2v: pix2[0]-pix2[15]    pix2iv: pix2[1]-pix2[16]
++        */
++        tv = (vector unsigned char *) pix1;
++        pix1v = vec_perm(tv[0], tv[1], vec_lvsl(0, pix1));
++        
++        tv = (vector unsigned char *) &pix2[0];
++        pix2v = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix2[0]));
++
++        tv = (vector unsigned char *) &pix2[1];
++        pix2iv = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix2[1]));
++
++        /* Calculate the average vector */
++        avgv = vec_avg(pix2v, pix2iv);
++
++        /* Calculate a sum of abs differences vector */
++        t5 = vec_sub(vec_max(pix1v, avgv), vec_min(pix1v, avgv));
++
++        /* 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_abs16x16_y2_altivec(uint8_t *pix1, uint8_t *pix2, int line_size)
++{
++    int i;
++    int s __attribute__((aligned(16)));
++    const vector unsigned char zero = (const vector unsigned char)vec_splat_u8(0);
++    vector unsigned char *tv;
++    vector unsigned char pix1v, pix2v, pix3v, avgv, t5;
++    vector unsigned int sad;
++    vector signed int sumdiffs;
++    uint8_t *pix3 = pix2 + line_size;
++
++    s = 0;
++    sad = (vector unsigned int)vec_splat_u32(0);
++
++    /*
++       Due to the fact that pix3 = pix2 + line_size, the pix3 of one
++       iteration becomes pix2 in the next iteration. We can use this
++       fact to avoid a potentially expensive unaligned read, each
++       time around the loop.
++       Read unaligned pixels into our vectors. The vectors are as follows:
++       pix2v: pix2[0]-pix2[15]
++       Split the pixel vectors into shorts
++    */
++    tv = (vector unsigned char *) &pix2[0];
++    pix2v = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix2[0]));
++    
++    for(i=0;i<16;i++) {
++        /*
++           Read unaligned pixels into our vectors. The vectors are as follows:
++           pix1v: pix1[0]-pix1[15]
++           pix3v: pix3[0]-pix3[15]
++        */
++        tv = (vector unsigned char *) pix1;
++        pix1v = vec_perm(tv[0], tv[1], vec_lvsl(0, pix1));
++
++        tv = (vector unsigned char *) &pix3[0];
++        pix3v = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix3[0]));
++
++        /* Calculate the average vector */
++        avgv = vec_avg(pix2v, pix3v);
++
++        /* Calculate a sum of abs differences vector */
++        t5 = vec_sub(vec_max(pix1v, avgv), vec_min(pix1v, avgv));
++
++        /* Add each 4 pixel group together and put 4 results into sad */
++        sad = vec_sum4s(t5, sad);
++        
++        pix1 += line_size;
++        pix2v = pix3v;
++        pix3 += 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_abs16x16_xy2_altivec(uint8_t *pix1, uint8_t *pix2, int line_size)
++{
++    int i;
++    int s __attribute__((aligned(16)));
++    uint8_t *pix3 = pix2 + line_size;
++    const vector unsigned char zero = (const vector unsigned char)vec_splat_u8(0);
++    const vector unsigned short two = (const vector unsigned short)vec_splat_u16(2);
++    vector unsigned char *tv, avgv, t5;
++    vector unsigned char pix1v, pix2v, pix3v, pix2iv, pix3iv;
++    vector unsigned short pix2lv, pix2hv, pix2ilv, pix2ihv;
++    vector unsigned short pix3lv, pix3hv, pix3ilv, pix3ihv;
++    vector unsigned short avghv, avglv;
++    vector unsigned short t1, t2, t3, t4;
++    vector unsigned int sad;
++    vector signed int sumdiffs;
++
++    sad = (vector unsigned int)vec_splat_u32(0);
++    
++    s = 0;
++
++    /*
++       Due to the fact that pix3 = pix2 + line_size, the pix3 of one
++       iteration becomes pix2 in the next iteration. We can use this
++       fact to avoid a potentially expensive unaligned read, as well
++       as some splitting, and vector addition each time around the loop.
++       Read unaligned pixels into our vectors. The vectors are as follows:
++       pix2v: pix2[0]-pix2[15]        pix2iv: pix2[1]-pix2[16]
++       Split the pixel vectors into shorts
++    */
++    tv = (vector unsigned char *) &pix2[0];
++    pix2v = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix2[0]));
++
++    tv = (vector unsigned char *) &pix2[1];
++    pix2iv = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix2[1]));
++
++    pix2hv = (vector unsigned short) vec_mergeh(zero, pix2v);
++    pix2lv = (vector unsigned short) vec_mergel(zero, pix2v);
++    pix2ihv = (vector unsigned short) vec_mergeh(zero, pix2iv);
++    pix2ilv = (vector unsigned short) vec_mergel(zero, pix2iv);
++    t1 = vec_add(pix2hv, pix2ihv);
++    t2 = vec_add(pix2lv, pix2ilv);
++    
++    for(i=0;i<16;i++) {
++        /*
++           Read unaligned pixels into our vectors. The vectors are as follows:
++           pix1v: pix1[0]-pix1[15]
++           pix3v: pix3[0]-pix3[15]    pix3iv: pix3[1]-pix3[16]
++        */
++        tv = (vector unsigned char *) pix1;
++        pix1v = vec_perm(tv[0], tv[1], vec_lvsl(0, pix1));
++
++        tv = (vector unsigned char *) &pix3[0];
++        pix3v = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix3[0]));
++
++        tv = (vector unsigned char *) &pix3[1];
++        pix3iv = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix3[1]));
++
++        /*
++          Note that Altivec does have vec_avg, but this works on vector pairs
++          and rounds up. We could do avg(avg(a,b),avg(c,d)), but the rounding
++          would mean that, for example, avg(3,0,0,1) = 2, when it should be 1.
++          Instead, we have to split the pixel vectors into vectors of shorts,
++          and do the averaging by hand.
++        */
++
++        /* Split the pixel vectors into shorts */
++        pix3hv = (vector unsigned short) vec_mergeh(zero, pix3v);
++        pix3lv = (vector unsigned short) vec_mergel(zero, pix3v);
++        pix3ihv = (vector unsigned short) vec_mergeh(zero, pix3iv);
++        pix3ilv = (vector unsigned short) vec_mergel(zero, pix3iv);
++
++        /* Do the averaging on them */
++        t3 = vec_add(pix3hv, pix3ihv);
++        t4 = vec_add(pix3lv, pix3ilv);
++
++        avghv = vec_sr(vec_add(vec_add(t1, t3), two), two);
++        avglv = vec_sr(vec_add(vec_add(t2, t4), two), two);
++
++        /* Pack the shorts back into a result */
++        avgv = vec_pack(avghv, avglv);
++
++        /* Calculate a sum of abs differences vector */
++        t5 = vec_sub(vec_max(pix1v, avgv), vec_min(pix1v, avgv));
++
++        /* Add each 4 pixel group together and put 4 results into sad */
++        sad = vec_sum4s(t5, sad);
++
++        pix1 += line_size;
++        pix3 += line_size;
++        /* Transfer the calculated values for pix3 into pix2 */
++        t1 = t3;
++        t2 = t4;
++    }
++    /* 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_abs16x16_altivec(uint8_t *pix1, uint8_t *pix2, int line_size)
++{
++    int i;
++    int s __attribute__((aligned(16)));
++    const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0);
++    vector unsigned char perm1, perm2, *pix1v, *pix2v;
++    vector unsigned char t1, t2, t3,t4, t5;
++    vector unsigned int sad;
++    vector signed int sumdiffs;
++    
++    sad = (vector unsigned int)vec_splat_u32(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;
++    int s __attribute__((aligned(16)));
++    const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0);
++    vector unsigned char perm1, perm2, permclear, *pix1v, *pix2v;
++    vector unsigned char t1, t2, t3,t4, t5;
++    vector unsigned int sad;
++    vector signed int sumdiffs;
++
++    sad = (vector unsigned int)vec_splat_u32(0);
++
++    permclear = (vector unsigned char)AVV(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_norm1_altivec(uint8_t *pix, int line_size)
++{
++    int i;
++    int s __attribute__((aligned(16)));
++    const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0);
++    vector unsigned char *tv;
++    vector unsigned char pixv;
++    vector unsigned int sv;
++    vector signed int sum;
++    
++    sv = (vector unsigned int)vec_splat_u32(0);
++    
++    s = 0;
++    for (i = 0; i < 16; i++) {
++        /* Read in the potentially unaligned pixels */
++        tv = (vector unsigned char *) pix;
++        pixv = vec_perm(tv[0], tv[1], vec_lvsl(0, pix));
++
++        /* Square the values, and add them to our sum */
++        sv = vec_msum(pixv, pixv, sv);
++
++        pix += line_size;
++    }
++    /* Sum up the four partial sums, and put the result into s */
++    sum = vec_sums((vector signed int) sv, (vector signed int) zero);
++    sum = vec_splat(sum, 3);
++    vec_ste(sum, 0, &s);
++
++    return s;
++}
++
++/**
++ * Sum of Squared Errors for a 8x8 block.
++ * AltiVec-enhanced.
++ * It's the pix_abs8x8_altivec code above w/ squaring added.
++ */
++int sse8_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size)
++{
++    int i;
++    int s __attribute__((aligned(16)));
++    const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0);
++    vector unsigned char perm1, perm2, permclear, *pix1v, *pix2v;
++    vector unsigned char t1, t2, t3,t4, t5;
++    vector unsigned int sum;
++    vector signed int sumsqr;
++    
++    sum = (vector unsigned int)vec_splat_u32(0);
++
++    permclear = (vector unsigned char)AVV(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);
++
++        /*
++          Since we want to use unsigned chars, we can take advantage
++          of the fact that abs(a-b)^2 = (a-b)^2.
++        */
++        
++      /* Calculate abs differences vector */ 
++        t3 = vec_max(t1, t2);
++        t4 = vec_min(t1, t2);
++        t5 = vec_sub(t3, t4);
++        
++        /* Square the values and add them to our sum */
++        sum = vec_msum(t5, t5, sum);
++        
++        pix1 += line_size;
++        pix2 += line_size;
++    }
++    
++    /* Sum up the four partial sums, and put the result into s */
++    sumsqr = vec_sums((vector signed int) sum, (vector signed int) zero);
++    sumsqr = vec_splat(sumsqr, 3);
++    vec_ste(sumsqr, 0, &s);
++    
++    return s;
++}
++
++/**
++ * Sum of Squared Errors for a 16x16 block.
++ * AltiVec-enhanced.
++ * It's the pix_abs16x16_altivec code above w/ squaring added.
++ */
++int sse16_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size)
++{
++    int i;
++    int s __attribute__((aligned(16)));
++    const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0);
++    vector unsigned char perm1, perm2, *pix1v, *pix2v;
++    vector unsigned char t1, t2, t3,t4, t5;
++    vector unsigned int sum;
++    vector signed int sumsqr;
++    
++    sum = (vector unsigned int)vec_splat_u32(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);
++
++        /*
++          Since we want to use unsigned chars, we can take advantage
++          of the fact that abs(a-b)^2 = (a-b)^2.
++        */
++        
++      /* Calculate abs differences vector */ 
++        t3 = vec_max(t1, t2);
++        t4 = vec_min(t1, t2);
++        t5 = vec_sub(t3, t4);
++        
++        /* Square the values and add them to our sum */
++        sum = vec_msum(t5, t5, sum);
++        
++        pix1 += line_size;
++        pix2 += line_size;
++    }
++    
++    /* Sum up the four partial sums, and put the result into s */
++    sumsqr = vec_sums((vector signed int) sum, (vector signed int) zero);
++    sumsqr = vec_splat(sumsqr, 3);
++    vec_ste(sumsqr, 0, &s);
++    
++    return s;
++}
++
++int pix_sum_altivec(uint8_t * pix, int line_size)
++{
++    const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0);
++    vector unsigned char perm, *pixv;
++    vector unsigned char t1;
++    vector unsigned int sad;
++    vector signed int sumdiffs;
++
++    int i;
++    int s __attribute__((aligned(16)));
++    
++    sad = (vector unsigned int)vec_splat_u32(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 get_pixels_altivec(DCTELEM *restrict block, const uint8_t *pixels, int line_size)
++{
++    int i;
++    vector unsigned char perm, bytes, *pixv;
++    const vector unsigned char zero = (const vector unsigned char)vec_splat_u8(0);
++    vector signed short shorts;
++
++    for(i=0;i<8;i++)
++    {
++        // Read potentially unaligned pixels.
++        // We're reading 16 pixels, and actually only want 8,
++        // but we simply ignore the extras.
++        perm = vec_lvsl(0, pixels);
++        pixv = (vector unsigned char *) pixels;
++        bytes = vec_perm(pixv[0], pixv[1], perm);
++
++        // convert the bytes into shorts
++        shorts = (vector signed short)vec_mergeh(zero, bytes);
++
++        // save the data to the block, we assume the block is 16-byte aligned
++        vec_st(shorts, i*16, (vector signed short*)block);
++
++        pixels += line_size;
++    }
++}
++
++void diff_pixels_altivec(DCTELEM *restrict block, const uint8_t *s1,
++        const uint8_t *s2, int stride)
++{
++    int i;
++    vector unsigned char perm, bytes, *pixv;
++    const vector unsigned char zero = (const vector unsigned char)vec_splat_u8(0);
++    vector signed short shorts1, shorts2;
++
++    for(i=0;i<4;i++)
++    {
++        // Read potentially unaligned pixels
++        // We're reading 16 pixels, and actually only want 8,
++        // but we simply ignore the extras.
++        perm = vec_lvsl(0, s1);
++        pixv = (vector unsigned char *) s1;
++        bytes = vec_perm(pixv[0], pixv[1], perm);
++
++        // convert the bytes into shorts
++        shorts1 = (vector signed short)vec_mergeh(zero, bytes);
++
++        // Do the same for the second block of pixels
++        perm = vec_lvsl(0, s2);
++        pixv = (vector unsigned char *) s2;
++        bytes = vec_perm(pixv[0], pixv[1], perm);
++
++        // convert the bytes into shorts
++        shorts2 = (vector signed short)vec_mergeh(zero, bytes);
++
++        // Do the subtraction
++        shorts1 = vec_sub(shorts1, shorts2);
++
++        // save the data to the block, we assume the block is 16-byte aligned
++        vec_st(shorts1, 0, (vector signed short*)block);
++
++        s1 += stride;
++        s2 += stride;
++        block += 8;
++
++
++        // The code below is a copy of the code above... This is a manual
++        // unroll.
++
++        // Read potentially unaligned pixels
++        // We're reading 16 pixels, and actually only want 8,
++        // but we simply ignore the extras.
++        perm = vec_lvsl(0, s1);
++        pixv = (vector unsigned char *) s1;
++        bytes = vec_perm(pixv[0], pixv[1], perm);
++
++        // convert the bytes into shorts
++        shorts1 = (vector signed short)vec_mergeh(zero, bytes);
++
++        // Do the same for the second block of pixels
++        perm = vec_lvsl(0, s2);
++        pixv = (vector unsigned char *) s2;
++        bytes = vec_perm(pixv[0], pixv[1], perm);
++
++        // convert the bytes into shorts
++        shorts2 = (vector signed short)vec_mergeh(zero, bytes);
++
++        // Do the subtraction
++        shorts1 = vec_sub(shorts1, shorts2);
++
++        // save the data to the block, we assume the block is 16-byte aligned
++        vec_st(shorts1, 0, (vector signed short*)block);
++
++        s1 += stride;
++        s2 += stride;
++        block += 8;
++    }
++}
++
++int sad16x16_altivec(void *s, uint8_t *a, uint8_t *b, int stride) {
++  return pix_abs16x16_altivec(a,b,stride);
++}
++
++int sad8x8_altivec(void *s, uint8_t *a, uint8_t *b, int stride) {
++  return pix_abs8x8_altivec(a,b,stride);
++}
++
++void add_bytes_altivec(uint8_t *dst, uint8_t *src, int w) {
++#ifdef ALTIVEC_USE_REFERENCE_C_CODE
++    int i;
++    for(i=0; i+7<w; i++){
++        dst[i+0] += src[i+0];
++        dst[i+1] += src[i+1];
++        dst[i+2] += src[i+2];
++        dst[i+3] += src[i+3];
++        dst[i+4] += src[i+4];
++        dst[i+5] += src[i+5];
++        dst[i+6] += src[i+6];
++        dst[i+7] += src[i+7];
++    }
++    for(; i<w; i++)
++        dst[i+0] += src[i+0];
++#else /* ALTIVEC_USE_REFERENCE_C_CODE */
++    register int i;
++    register vector unsigned char vdst, vsrc;
++    
++    /* dst and src are 16 bytes-aligned (guaranteed) */
++    for(i = 0 ; (i + 15) < w ; i++)
++    {
++      vdst = vec_ld(i << 4, (unsigned char*)dst);
++      vsrc = vec_ld(i << 4, (unsigned char*)src);
++      vdst = vec_add(vsrc, vdst);
++      vec_st(vdst, i << 4, (unsigned char*)dst);
++    }
++    /* if w is not a multiple of 16 */
++    for (; (i < w) ; i++)
++    {
++      dst[i] = src[i];
++    }
++#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
++}
++
++/* next one assumes that ((line_size % 16) == 0) */
++void put_pixels16_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h)
++{
++POWERPC_PERF_DECLARE(altivec_put_pixels16_num, 1);
++#ifdef ALTIVEC_USE_REFERENCE_C_CODE
++    int i;
++
++POWERPC_PERF_START_COUNT(altivec_put_pixels16_num, 1);
++
++    for(i=0; i<h; i++) {
++      *((uint32_t*)(block )) = (((const struct unaligned_32 *) (pixels))->l);
++      *((uint32_t*)(block+4)) = (((const struct unaligned_32 *) (pixels+4))->l);
++      *((uint32_t*)(block+8)) = (((const struct unaligned_32 *) (pixels+8))->l);
++      *((uint32_t*)(block+12)) = (((const struct unaligned_32 *) (pixels+12))->l);
++      pixels+=line_size;
++      block +=line_size;
++    }
++
++POWERPC_PERF_STOP_COUNT(altivec_put_pixels16_num, 1);
++
++#else /* ALTIVEC_USE_REFERENCE_C_CODE */
++    register vector unsigned char pixelsv1, pixelsv2;
++    register vector unsigned char pixelsv1B, pixelsv2B;
++    register vector unsigned char pixelsv1C, pixelsv2C;
++    register vector unsigned char pixelsv1D, pixelsv2D;
++
++    register vector unsigned char perm = vec_lvsl(0, pixels);
++    int i;
++    register int line_size_2 = line_size << 1;
++    register int line_size_3 = line_size + line_size_2;
++    register int line_size_4 = line_size << 2;
++
++POWERPC_PERF_START_COUNT(altivec_put_pixels16_num, 1);
++// hand-unrolling the loop by 4 gains about 15%
++// mininum execution time goes from 74 to 60 cycles
++// it's faster than -funroll-loops, but using
++// -funroll-loops w/ this is bad - 74 cycles again.
++// all this is on a 7450, tuning for the 7450
++#if 0
++    for(i=0; i<h; i++) {
++      pixelsv1 = vec_ld(0, (unsigned char*)pixels);
++      pixelsv2 = vec_ld(16, (unsigned char*)pixels);
++      vec_st(vec_perm(pixelsv1, pixelsv2, perm),
++             0, (unsigned char*)block);
++      pixels+=line_size;
++      block +=line_size;
++    }
++#else
++    for(i=0; i<h; i+=4) {
++      pixelsv1 = vec_ld(0, (unsigned char*)pixels);
++      pixelsv2 = vec_ld(16, (unsigned char*)pixels);
++      pixelsv1B = vec_ld(line_size, (unsigned char*)pixels);
++      pixelsv2B = vec_ld(16 + line_size, (unsigned char*)pixels);
++      pixelsv1C = vec_ld(line_size_2, (unsigned char*)pixels);
++      pixelsv2C = vec_ld(16 + line_size_2, (unsigned char*)pixels);
++      pixelsv1D = vec_ld(line_size_3, (unsigned char*)pixels);
++      pixelsv2D = vec_ld(16 + line_size_3, (unsigned char*)pixels);
++      vec_st(vec_perm(pixelsv1, pixelsv2, perm),
++             0, (unsigned char*)block);
++      vec_st(vec_perm(pixelsv1B, pixelsv2B, perm),
++             line_size, (unsigned char*)block);
++      vec_st(vec_perm(pixelsv1C, pixelsv2C, perm),
++             line_size_2, (unsigned char*)block);
++      vec_st(vec_perm(pixelsv1D, pixelsv2D, perm),
++             line_size_3, (unsigned char*)block);
++      pixels+=line_size_4;
++      block +=line_size_4;
++    }
++#endif
++POWERPC_PERF_STOP_COUNT(altivec_put_pixels16_num, 1);
++
++#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
++}
++
++/* next one assumes that ((line_size % 16) == 0) */
++#define op_avg(a,b)  a = ( ((a)|(b)) - ((((a)^(b))&0xFEFEFEFEUL)>>1) )
++void avg_pixels16_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h)
++{
++POWERPC_PERF_DECLARE(altivec_avg_pixels16_num, 1);
++#ifdef ALTIVEC_USE_REFERENCE_C_CODE
++    int i;
++
++POWERPC_PERF_START_COUNT(altivec_avg_pixels16_num, 1);
++
++    for(i=0; i<h; i++) {
++      op_avg(*((uint32_t*)(block)),(((const struct unaligned_32 *)(pixels))->l));
++      op_avg(*((uint32_t*)(block+4)),(((const struct unaligned_32 *)(pixels+4))->l));
++      op_avg(*((uint32_t*)(block+8)),(((const struct unaligned_32 *)(pixels+8))->l));
++      op_avg(*((uint32_t*)(block+12)),(((const struct unaligned_32 *)(pixels+12))->l));
++      pixels+=line_size;
++      block +=line_size;
++    }
++
++POWERPC_PERF_STOP_COUNT(altivec_avg_pixels16_num, 1);
++
++#else /* ALTIVEC_USE_REFERENCE_C_CODE */
++    register vector unsigned char pixelsv1, pixelsv2, pixelsv, blockv;
++    register vector unsigned char perm = vec_lvsl(0, pixels);
++    int i;
++
++POWERPC_PERF_START_COUNT(altivec_avg_pixels16_num, 1);
++
++    for(i=0; i<h; i++) {
++      pixelsv1 = vec_ld(0, (unsigned char*)pixels);
++      pixelsv2 = vec_ld(16, (unsigned char*)pixels);
++      blockv = vec_ld(0, block);
++      pixelsv = vec_perm(pixelsv1, pixelsv2, perm);
++      blockv = vec_avg(blockv,pixelsv);
++      vec_st(blockv, 0, (unsigned char*)block);
++      pixels+=line_size;
++      block +=line_size;
++    }
++
++POWERPC_PERF_STOP_COUNT(altivec_avg_pixels16_num, 1);
++
++#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
++}
++
++/* next one assumes that ((line_size % 8) == 0) */
++void avg_pixels8_altivec(uint8_t * block, const uint8_t * pixels, int line_size, int h)
++{
++POWERPC_PERF_DECLARE(altivec_avg_pixels8_num, 1);
++#ifdef ALTIVEC_USE_REFERENCE_C_CODE
++    int i;
++POWERPC_PERF_START_COUNT(altivec_avg_pixels8_num, 1);
++    for (i = 0; i < h; i++) {
++        *((uint32_t *) (block)) =
++            (((*((uint32_t *) (block))) |
++              ((((const struct unaligned_32 *) (pixels))->l))) -
++             ((((*((uint32_t *) (block))) ^
++                ((((const struct unaligned_32 *) (pixels))->
++                  l))) & 0xFEFEFEFEUL) >> 1));
++        *((uint32_t *) (block + 4)) =
++            (((*((uint32_t *) (block + 4))) |
++              ((((const struct unaligned_32 *) (pixels + 4))->l))) -
++             ((((*((uint32_t *) (block + 4))) ^
++                ((((const struct unaligned_32 *) (pixels +
++                                                  4))->
++                  l))) & 0xFEFEFEFEUL) >> 1));
++        pixels += line_size;
++        block += line_size;
++    }
++POWERPC_PERF_STOP_COUNT(altivec_avg_pixels8_num, 1);
++
++#else /* ALTIVEC_USE_REFERENCE_C_CODE */
++    register vector unsigned char pixelsv1, pixelsv2, pixelsv, blockv;
++    int i;
++
++POWERPC_PERF_START_COUNT(altivec_avg_pixels8_num, 1);
++ 
++   for (i = 0; i < h; i++) {
++     /*
++       block is 8 bytes-aligned, so we're either in the
++       left block (16 bytes-aligned) or in the right block (not)
++     */
++     int rightside = ((unsigned long)block & 0x0000000F);
++     
++     blockv = vec_ld(0, block);
++     pixelsv1 = vec_ld(0, (unsigned char*)pixels);
++     pixelsv2 = vec_ld(16, (unsigned char*)pixels);
++     pixelsv = vec_perm(pixelsv1, pixelsv2, vec_lvsl(0, pixels));
++     
++     if (rightside)
++     {
++       pixelsv = vec_perm(blockv, pixelsv, vcprm(0,1,s0,s1));
++     }
++     else
++     {
++       pixelsv = vec_perm(blockv, pixelsv, vcprm(s0,s1,2,3));
++     }
++     
++     blockv = vec_avg(blockv, pixelsv);
++
++     vec_st(blockv, 0, block);
++     
++     pixels += line_size;
++     block += line_size;
++   }
++   
++POWERPC_PERF_STOP_COUNT(altivec_avg_pixels8_num, 1);
++ 
++#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
++}
++
++/* next one assumes that ((line_size % 8) == 0) */
++void put_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h)
++{
++POWERPC_PERF_DECLARE(altivec_put_pixels8_xy2_num, 1);
++#ifdef ALTIVEC_USE_REFERENCE_C_CODE
++    int j;
++POWERPC_PERF_START_COUNT(altivec_put_pixels8_xy2_num, 1);
++    for (j = 0; j < 2; j++) {
++      int i;
++      const uint32_t a = (((const struct unaligned_32 *) (pixels))->l);
++      const uint32_t b =
++        (((const struct unaligned_32 *) (pixels + 1))->l);
++      uint32_t l0 =
++        (a & 0x03030303UL) + (b & 0x03030303UL) + 0x02020202UL;
++      uint32_t h0 =
++        ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
++      uint32_t l1, h1;
++      pixels += line_size;
++      for (i = 0; i < h; i += 2) {
++        uint32_t a = (((const struct unaligned_32 *) (pixels))->l);
++        uint32_t b = (((const struct unaligned_32 *) (pixels + 1))->l);
++        l1 = (a & 0x03030303UL) + (b & 0x03030303UL);
++        h1 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
++        *((uint32_t *) block) =
++          h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
++        pixels += line_size;
++        block += line_size;
++        a = (((const struct unaligned_32 *) (pixels))->l);
++        b = (((const struct unaligned_32 *) (pixels + 1))->l);
++        l0 = (a & 0x03030303UL) + (b & 0x03030303UL) + 0x02020202UL;
++        h0 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
++        *((uint32_t *) block) =
++          h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
++        pixels += line_size;
++        block += line_size;
++      } pixels += 4 - line_size * (h + 1);
++      block += 4 - line_size * h;
++    }
++
++POWERPC_PERF_STOP_COUNT(altivec_put_pixels8_xy2_num, 1);
++
++#else /* ALTIVEC_USE_REFERENCE_C_CODE */
++   register int i;
++   register vector unsigned char
++     pixelsv1, pixelsv2,
++     pixelsavg;
++   register vector unsigned char
++     blockv, temp1, temp2;
++   register vector unsigned short
++     pixelssum1, pixelssum2, temp3;
++   register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0);
++   register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2);
++   
++   temp1 = vec_ld(0, pixels);
++   temp2 = vec_ld(16, pixels);
++   pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
++   if ((((unsigned long)pixels) & 0x0000000F) ==  0x0000000F)
++   {
++     pixelsv2 = temp2;
++   }
++   else
++   {
++     pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
++   }
++   pixelsv1 = vec_mergeh(vczero, pixelsv1);
++   pixelsv2 = vec_mergeh(vczero, pixelsv2);
++   pixelssum1 = vec_add((vector unsigned short)pixelsv1,
++                        (vector unsigned short)pixelsv2);
++   pixelssum1 = vec_add(pixelssum1, vctwo);
++   
++POWERPC_PERF_START_COUNT(altivec_put_pixels8_xy2_num, 1); 
++   for (i = 0; i < h ; i++) {
++     int rightside = ((unsigned long)block & 0x0000000F);
++     blockv = vec_ld(0, block);
++
++     temp1 = vec_ld(line_size, pixels);
++     temp2 = vec_ld(line_size + 16, pixels);
++     pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
++     if (((((unsigned long)pixels) + line_size) & 0x0000000F) ==  0x0000000F)
++     {
++       pixelsv2 = temp2;
++     }
++     else
++     {
++       pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
++     }
++
++     pixelsv1 = vec_mergeh(vczero, pixelsv1);
++     pixelsv2 = vec_mergeh(vczero, pixelsv2);
++     pixelssum2 = vec_add((vector unsigned short)pixelsv1,
++                          (vector unsigned short)pixelsv2);
++     temp3 = vec_add(pixelssum1, pixelssum2);
++     temp3 = vec_sra(temp3, vctwo);
++     pixelssum1 = vec_add(pixelssum2, vctwo);
++     pixelsavg = vec_packsu(temp3, (vector unsigned short) vczero);
++     
++     if (rightside)
++     {
++       blockv = vec_perm(blockv, pixelsavg, vcprm(0, 1, s0, s1));
++     }
++     else
++     {
++       blockv = vec_perm(blockv, pixelsavg, vcprm(s0, s1, 2, 3));
++     }
++     
++     vec_st(blockv, 0, block);
++     
++     block += line_size;
++     pixels += line_size;
++   }
++   
++POWERPC_PERF_STOP_COUNT(altivec_put_pixels8_xy2_num, 1);
++#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
++}
++
++/* next one assumes that ((line_size % 8) == 0) */
++void put_no_rnd_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h)
++{
++POWERPC_PERF_DECLARE(altivec_put_no_rnd_pixels8_xy2_num, 1);
++#ifdef ALTIVEC_USE_REFERENCE_C_CODE
++    int j;
++POWERPC_PERF_START_COUNT(altivec_put_no_rnd_pixels8_xy2_num, 1);
++    for (j = 0; j < 2; j++) {
++      int i;
++      const uint32_t a = (((const struct unaligned_32 *) (pixels))->l);
++      const uint32_t b =
++        (((const struct unaligned_32 *) (pixels + 1))->l);
++      uint32_t l0 =
++        (a & 0x03030303UL) + (b & 0x03030303UL) + 0x01010101UL;
++      uint32_t h0 =
++        ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
++      uint32_t l1, h1;
++      pixels += line_size;
++      for (i = 0; i < h; i += 2) {
++        uint32_t a = (((const struct unaligned_32 *) (pixels))->l);
++        uint32_t b = (((const struct unaligned_32 *) (pixels + 1))->l);
++        l1 = (a & 0x03030303UL) + (b & 0x03030303UL);
++        h1 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
++        *((uint32_t *) block) =
++          h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
++        pixels += line_size;
++        block += line_size;
++        a = (((const struct unaligned_32 *) (pixels))->l);
++        b = (((const struct unaligned_32 *) (pixels + 1))->l);
++        l0 = (a & 0x03030303UL) + (b & 0x03030303UL) + 0x01010101UL;
++        h0 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
++        *((uint32_t *) block) =
++          h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
++        pixels += line_size;
++        block += line_size;
++      } pixels += 4 - line_size * (h + 1);
++      block += 4 - line_size * h;
++    }
++    
++POWERPC_PERF_STOP_COUNT(altivec_put_no_rnd_pixels8_xy2_num, 1);
++
++#else /* ALTIVEC_USE_REFERENCE_C_CODE */
++   register int i;
++   register vector unsigned char
++     pixelsv1, pixelsv2,
++     pixelsavg;
++   register vector unsigned char
++     blockv, temp1, temp2;
++   register vector unsigned short
++     pixelssum1, pixelssum2, temp3;
++   register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0);
++   register const vector unsigned short vcone = (const vector unsigned short)vec_splat_u16(1);
++   register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2);
++   
++   temp1 = vec_ld(0, pixels);
++   temp2 = vec_ld(16, pixels);
++   pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
++   if ((((unsigned long)pixels) & 0x0000000F) ==  0x0000000F)
++   {
++     pixelsv2 = temp2;
++   }
++   else
++   {
++     pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
++   }
++   pixelsv1 = vec_mergeh(vczero, pixelsv1);
++   pixelsv2 = vec_mergeh(vczero, pixelsv2);
++   pixelssum1 = vec_add((vector unsigned short)pixelsv1,
++                        (vector unsigned short)pixelsv2);
++   pixelssum1 = vec_add(pixelssum1, vcone);
++   
++POWERPC_PERF_START_COUNT(altivec_put_no_rnd_pixels8_xy2_num, 1); 
++   for (i = 0; i < h ; i++) {
++     int rightside = ((unsigned long)block & 0x0000000F);
++     blockv = vec_ld(0, block);
++
++     temp1 = vec_ld(line_size, pixels);
++     temp2 = vec_ld(line_size + 16, pixels);
++     pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
++     if (((((unsigned long)pixels) + line_size) & 0x0000000F) ==  0x0000000F)
++     {
++       pixelsv2 = temp2;
++     }
++     else
++     {
++       pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
++     }
++
++     pixelsv1 = vec_mergeh(vczero, pixelsv1);
++     pixelsv2 = vec_mergeh(vczero, pixelsv2);
++     pixelssum2 = vec_add((vector unsigned short)pixelsv1,
++                          (vector unsigned short)pixelsv2);
++     temp3 = vec_add(pixelssum1, pixelssum2);
++     temp3 = vec_sra(temp3, vctwo);
++     pixelssum1 = vec_add(pixelssum2, vcone);
++     pixelsavg = vec_packsu(temp3, (vector unsigned short) vczero);
++     
++     if (rightside)
++     {
++       blockv = vec_perm(blockv, pixelsavg, vcprm(0, 1, s0, s1));
++     }
++     else
++     {
++       blockv = vec_perm(blockv, pixelsavg, vcprm(s0, s1, 2, 3));
++     }
++     
++     vec_st(blockv, 0, block);
++     
++     block += line_size;
++     pixels += line_size;
++   }
++   
++POWERPC_PERF_STOP_COUNT(altivec_put_no_rnd_pixels8_xy2_num, 1);
++#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
++}
++
++/* next one assumes that ((line_size % 16) == 0) */
++void put_pixels16_xy2_altivec(uint8_t * block, const uint8_t * pixels, int line_size, int h)
++{
++POWERPC_PERF_DECLARE(altivec_put_pixels16_xy2_num, 1);
++#ifdef ALTIVEC_USE_REFERENCE_C_CODE
++    int j;
++POWERPC_PERF_START_COUNT(altivec_put_pixels16_xy2_num, 1);
++      for (j = 0; j < 4; j++) {
++      int i;
++      const uint32_t a = (((const struct unaligned_32 *) (pixels))->l);
++      const uint32_t b =
++        (((const struct unaligned_32 *) (pixels + 1))->l);
++      uint32_t l0 =
++        (a & 0x03030303UL) + (b & 0x03030303UL) + 0x02020202UL;
++      uint32_t h0 =
++        ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
++      uint32_t l1, h1;
++      pixels += line_size;
++      for (i = 0; i < h; i += 2) {
++        uint32_t a = (((const struct unaligned_32 *) (pixels))->l);
++        uint32_t b = (((const struct unaligned_32 *) (pixels + 1))->l);
++        l1 = (a & 0x03030303UL) + (b & 0x03030303UL);
++        h1 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
++        *((uint32_t *) block) =
++          h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
++        pixels += line_size;
++        block += line_size;
++        a = (((const struct unaligned_32 *) (pixels))->l);
++        b = (((const struct unaligned_32 *) (pixels + 1))->l);
++        l0 = (a & 0x03030303UL) + (b & 0x03030303UL) + 0x02020202UL;
++        h0 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
++        *((uint32_t *) block) =
++          h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
++        pixels += line_size;
++        block += line_size;
++      } pixels += 4 - line_size * (h + 1);
++      block += 4 - line_size * h;
++    }
++
++POWERPC_PERF_STOP_COUNT(altivec_put_pixels16_xy2_num, 1);
++
++#else /* ALTIVEC_USE_REFERENCE_C_CODE */
++   register int i;
++   register vector unsigned char
++     pixelsv1, pixelsv2, pixelsv3, pixelsv4;
++   register vector unsigned char
++     blockv, temp1, temp2;
++   register vector unsigned short
++     pixelssum1, pixelssum2, temp3,
++     pixelssum3, pixelssum4, temp4;
++   register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0);
++   register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2);
++
++POWERPC_PERF_START_COUNT(altivec_put_pixels16_xy2_num, 1);
++ 
++   temp1 = vec_ld(0, pixels);
++   temp2 = vec_ld(16, pixels);
++   pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
++   if ((((unsigned long)pixels) & 0x0000000F) ==  0x0000000F)
++   {
++     pixelsv2 = temp2;
++   }
++   else
++   {
++     pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
++   }
++   pixelsv3 = vec_mergel(vczero, pixelsv1);
++   pixelsv4 = vec_mergel(vczero, pixelsv2);
++   pixelsv1 = vec_mergeh(vczero, pixelsv1);
++   pixelsv2 = vec_mergeh(vczero, pixelsv2);
++   pixelssum3 = vec_add((vector unsigned short)pixelsv3,
++                        (vector unsigned short)pixelsv4);
++   pixelssum3 = vec_add(pixelssum3, vctwo);
++   pixelssum1 = vec_add((vector unsigned short)pixelsv1,
++                        (vector unsigned short)pixelsv2);
++   pixelssum1 = vec_add(pixelssum1, vctwo);
++   
++   for (i = 0; i < h ; i++) {
++     blockv = vec_ld(0, block);
++
++     temp1 = vec_ld(line_size, pixels);
++     temp2 = vec_ld(line_size + 16, pixels);
++     pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
++     if (((((unsigned long)pixels) + line_size) & 0x0000000F) ==  0x0000000F)
++     {
++       pixelsv2 = temp2;
++     }
++     else
++     {
++       pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
++     }
++
++     pixelsv3 = vec_mergel(vczero, pixelsv1);
++     pixelsv4 = vec_mergel(vczero, pixelsv2);
++     pixelsv1 = vec_mergeh(vczero, pixelsv1);
++     pixelsv2 = vec_mergeh(vczero, pixelsv2);
++     
++     pixelssum4 = vec_add((vector unsigned short)pixelsv3,
++                          (vector unsigned short)pixelsv4);
++     pixelssum2 = vec_add((vector unsigned short)pixelsv1,
++                          (vector unsigned short)pixelsv2);
++     temp4 = vec_add(pixelssum3, pixelssum4);
++     temp4 = vec_sra(temp4, vctwo);
++     temp3 = vec_add(pixelssum1, pixelssum2);
++     temp3 = vec_sra(temp3, vctwo);
++
++     pixelssum3 = vec_add(pixelssum4, vctwo);
++     pixelssum1 = vec_add(pixelssum2, vctwo);
++
++     blockv = vec_packsu(temp3, temp4);
++     
++     vec_st(blockv, 0, block);
++     
++     block += line_size;
++     pixels += line_size;
++   }
++   
++POWERPC_PERF_STOP_COUNT(altivec_put_pixels16_xy2_num, 1);
++#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
++}
++
++/* next one assumes that ((line_size % 16) == 0) */
++void put_no_rnd_pixels16_xy2_altivec(uint8_t * block, const uint8_t * pixels, int line_size, int h)
++{
++POWERPC_PERF_DECLARE(altivec_put_no_rnd_pixels16_xy2_num, 1);
++#ifdef ALTIVEC_USE_REFERENCE_C_CODE
++    int j;
++POWERPC_PERF_START_COUNT(altivec_put_no_rnd_pixels16_xy2_num, 1);
++      for (j = 0; j < 4; j++) {
++      int i;
++      const uint32_t a = (((const struct unaligned_32 *) (pixels))->l);
++      const uint32_t b =
++        (((const struct unaligned_32 *) (pixels + 1))->l);
++      uint32_t l0 =
++        (a & 0x03030303UL) + (b & 0x03030303UL) + 0x01010101UL;
++      uint32_t h0 =
++        ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
++      uint32_t l1, h1;
++      pixels += line_size;
++      for (i = 0; i < h; i += 2) {
++        uint32_t a = (((const struct unaligned_32 *) (pixels))->l);
++        uint32_t b = (((const struct unaligned_32 *) (pixels + 1))->l);
++        l1 = (a & 0x03030303UL) + (b & 0x03030303UL);
++        h1 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
++        *((uint32_t *) block) =
++          h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
++        pixels += line_size;
++        block += line_size;
++        a = (((const struct unaligned_32 *) (pixels))->l);
++        b = (((const struct unaligned_32 *) (pixels + 1))->l);
++        l0 = (a & 0x03030303UL) + (b & 0x03030303UL) + 0x01010101UL;
++        h0 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
++        *((uint32_t *) block) =
++          h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
++        pixels += line_size;
++        block += line_size;
++      } pixels += 4 - line_size * (h + 1);
++      block += 4 - line_size * h;
++    }
++
++POWERPC_PERF_STOP_COUNT(altivec_put_no_rnd_pixels16_xy2_num, 1);
++
++#else /* ALTIVEC_USE_REFERENCE_C_CODE */
++   register int i;
++   register vector unsigned char
++     pixelsv1, pixelsv2, pixelsv3, pixelsv4;
++   register vector unsigned char
++     blockv, temp1, temp2;
++   register vector unsigned short
++     pixelssum1, pixelssum2, temp3,
++     pixelssum3, pixelssum4, temp4;
++   register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0);
++   register const vector unsigned short vcone = (const vector unsigned short)vec_splat_u16(1);
++   register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2);
++
++POWERPC_PERF_START_COUNT(altivec_put_no_rnd_pixels16_xy2_num, 1);
++ 
++   temp1 = vec_ld(0, pixels);
++   temp2 = vec_ld(16, pixels);
++   pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
++   if ((((unsigned long)pixels) & 0x0000000F) ==  0x0000000F)
++   {
++     pixelsv2 = temp2;
++   }
++   else
++   {
++     pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
++   }
++   pixelsv3 = vec_mergel(vczero, pixelsv1);
++   pixelsv4 = vec_mergel(vczero, pixelsv2);
++   pixelsv1 = vec_mergeh(vczero, pixelsv1);
++   pixelsv2 = vec_mergeh(vczero, pixelsv2);
++   pixelssum3 = vec_add((vector unsigned short)pixelsv3,
++                        (vector unsigned short)pixelsv4);
++   pixelssum3 = vec_add(pixelssum3, vcone);
++   pixelssum1 = vec_add((vector unsigned short)pixelsv1,
++                        (vector unsigned short)pixelsv2);
++   pixelssum1 = vec_add(pixelssum1, vcone);
++   
++   for (i = 0; i < h ; i++) {
++     blockv = vec_ld(0, block);
++
++     temp1 = vec_ld(line_size, pixels);
++     temp2 = vec_ld(line_size + 16, pixels);
++     pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
++     if (((((unsigned long)pixels) + line_size) & 0x0000000F) ==  0x0000000F)
++     {
++       pixelsv2 = temp2;
++     }
++     else
++     {
++       pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
++     }
++
++     pixelsv3 = vec_mergel(vczero, pixelsv1);
++     pixelsv4 = vec_mergel(vczero, pixelsv2);
++     pixelsv1 = vec_mergeh(vczero, pixelsv1);
++     pixelsv2 = vec_mergeh(vczero, pixelsv2);
++     
++     pixelssum4 = vec_add((vector unsigned short)pixelsv3,
++                          (vector unsigned short)pixelsv4);
++     pixelssum2 = vec_add((vector unsigned short)pixelsv1,
++                          (vector unsigned short)pixelsv2);
++     temp4 = vec_add(pixelssum3, pixelssum4);
++     temp4 = vec_sra(temp4, vctwo);
++     temp3 = vec_add(pixelssum1, pixelssum2);
++     temp3 = vec_sra(temp3, vctwo);
++
++     pixelssum3 = vec_add(pixelssum4, vcone);
++     pixelssum1 = vec_add(pixelssum2, vcone);
++
++     blockv = vec_packsu(temp3, temp4);
++     
++     vec_st(blockv, 0, block);
++     
++     block += line_size;
++     pixels += line_size;
++   }
++   
++POWERPC_PERF_STOP_COUNT(altivec_put_no_rnd_pixels16_xy2_num, 1);
++#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
++}
++
++int has_altivec(void)
++{
++#ifdef 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);
++#else /* CONFIG_DARWIN */
++/* no Darwin, do it the brute-force way */
++/* this is borrowed from the libmpeg2 library */
++    {
++      signal (SIGILL, sigill_handler);
++      if (sigsetjmp (jmpbuf, 1)) {
++        signal (SIGILL, SIG_DFL);
++      } else {
++        canjump = 1;
++        
++        asm volatile ("mtspr 256, %0\n\t"
++                      "vand %%v0, %%v0, %%v0"
++                      :
++                      : "r" (-1));
++        
++        signal (SIGILL, SIG_DFL);
++        return 1;
++      }
++    }
++#endif /* CONFIG_DARWIN */
++    return 0;
++}
+diff -Nur avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc.orig/dsputil_ppc.c avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc/dsputil_ppc.c
+--- avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc.orig/dsputil_ppc.c        1970-01-01 01:00:00.000000000 +0100
++++ avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc/dsputil_ppc.c     2003-09-28 17:26:40.000000000 +0200
+@@ -0,0 +1,307 @@
++/*
++ * Copyright (c) 2002 Brian Foley
++ * Copyright (c) 2002 Dieter Shirley
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++#include "../dsputil.h"
++
++#include "dsputil_ppc.h"
++
++#ifdef HAVE_ALTIVEC
++#include "dsputil_altivec.h"
++#endif
++
++extern void idct_put_altivec(uint8_t *dest, int line_size, int16_t *block);
++extern void idct_add_altivec(uint8_t *dest, int line_size, int16_t *block);
++
++int mm_flags = 0;
++
++int mm_support(void)
++{
++    int result = 0;
++#if HAVE_ALTIVEC
++    if (has_altivec()) {
++        result |= MM_ALTIVEC;
++    }
++#endif /* result */
++    return result;
++}
++
++#ifdef POWERPC_PERFORMANCE_REPORT
++unsigned long long perfdata[POWERPC_NUM_PMC_ENABLED][powerpc_perf_total][powerpc_data_total];
++/* list below must match enum in dsputil_ppc.h */
++static unsigned char* perfname[] = {
++  "fft_calc_altivec",
++  "gmc1_altivec",
++  "dct_unquantize_h263_altivec",
++  "idct_add_altivec",
++  "idct_put_altivec",
++  "put_pixels16_altivec",
++  "avg_pixels16_altivec",
++  "avg_pixels8_altivec",
++  "put_pixels8_xy2_altivec",
++  "put_no_rnd_pixels8_xy2_altivec",
++  "put_pixels16_xy2_altivec",
++  "put_no_rnd_pixels16_xy2_altivec",
++  "clear_blocks_dcbz32_ppc",
++  "clear_blocks_dcbz128_ppc"
++};
++#include <stdio.h>
++#endif
++
++#ifdef POWERPC_PERFORMANCE_REPORT
++void powerpc_display_perf_report(void)
++{
++  int i, j;
++  fprintf(stderr, "PowerPC performance report\n Values are from the PMC registers, and represent whatever the registers are set to record.\n");
++  for(i = 0 ; i < powerpc_perf_total ; i++)
++  {
++    for (j = 0; j < POWERPC_NUM_PMC_ENABLED ; j++)
++      {
++      if (perfdata[j][i][powerpc_data_num] != (unsigned long long)0)
++        fprintf(stderr,
++                " Function \"%s\" (pmc%d):\n\tmin: %llu\n\tmax: %llu\n\tavg: %1.2lf (%llu)\n",
++                perfname[i],
++                j+1,
++                perfdata[j][i][powerpc_data_min],
++                perfdata[j][i][powerpc_data_max],
++                (double)perfdata[j][i][powerpc_data_sum] /
++                (double)perfdata[j][i][powerpc_data_num],
++                perfdata[j][i][powerpc_data_num]);
++      }
++  }
++}
++#endif /* POWERPC_PERFORMANCE_REPORT */
++
++/* ***** WARNING ***** WARNING ***** WARNING ***** */
++/*
++  clear_blocks_dcbz32_ppc will not work properly
++  on PowerPC processors with a cache line size
++  not equal to 32 bytes.
++  Fortunately all processor used by Apple up to
++  at least the 7450 (aka second generation G4)
++  use 32 bytes cache line.
++  This is due to the use of the 'dcbz' instruction.
++  It simply clear to zero a single cache line,
++  so you need to know the cache line size to use it !
++  It's absurd, but it's fast...
++
++  update 24/06/2003 : Apple released yesterday the G5,
++  with a PPC970. cache line size : 128 bytes. Oups.
++  The semantic of dcbz was changed, it always clear
++  32 bytes. so the function below will work, but will
++  be slow. So I fixed check_dcbz_effect to use dcbzl,
++  which is defined to clear a cache line (as dcbz before).
++  So we still can distinguish, and use dcbz (32 bytes)
++  or dcbzl (one cache line) as required.
++
++  see <http://developer.apple.com/technotes/tn/tn2087.html>
++  and <http://developer.apple.com/technotes/tn/tn2086.html>
++*/
++void clear_blocks_dcbz32_ppc(DCTELEM *blocks)
++{
++POWERPC_PERF_DECLARE(powerpc_clear_blocks_dcbz32, 1);
++    register int misal = ((unsigned long)blocks & 0x00000010);
++    register int i = 0;
++POWERPC_PERF_START_COUNT(powerpc_clear_blocks_dcbz32, 1);
++#if 1
++    if (misal) {
++      ((unsigned long*)blocks)[0] = 0L;
++      ((unsigned long*)blocks)[1] = 0L;
++      ((unsigned long*)blocks)[2] = 0L;
++      ((unsigned long*)blocks)[3] = 0L;
++      i += 16;
++    }
++    for ( ; i < sizeof(DCTELEM)*6*64 ; i += 32) {
++      asm volatile("dcbz %0,%1" : : "b" (blocks), "r" (i) : "memory");
++    }
++    if (misal) {
++      ((unsigned long*)blocks)[188] = 0L;
++      ((unsigned long*)blocks)[189] = 0L;
++      ((unsigned long*)blocks)[190] = 0L;
++      ((unsigned long*)blocks)[191] = 0L;
++      i += 16;
++    }
++#else
++    memset(blocks, 0, sizeof(DCTELEM)*6*64);
++#endif
++POWERPC_PERF_STOP_COUNT(powerpc_clear_blocks_dcbz32, 1);
++}
++
++/* same as above, when dcbzl clear a whole 128B cache line
++   i.e. the PPC970 aka G5 */
++#ifndef NO_DCBZL
++void clear_blocks_dcbz128_ppc(DCTELEM *blocks)
++{
++POWERPC_PERF_DECLARE(powerpc_clear_blocks_dcbz128, 1);
++    register int misal = ((unsigned long)blocks & 0x0000007f);
++    register int i = 0;
++POWERPC_PERF_START_COUNT(powerpc_clear_blocks_dcbz128, 1);
++#if 1
++ if (misal) {
++   // we could probably also optimize this case,
++   // but there's not much point as the machines
++   // aren't available yet (2003-06-26)
++      memset(blocks, 0, sizeof(DCTELEM)*6*64);
++    }
++    else
++      for ( ; i < sizeof(DCTELEM)*6*64 ; i += 128) {
++      asm volatile("dcbzl %0,%1" : : "b" (blocks), "r" (i) : "memory");
++      }
++#else
++    memset(blocks, 0, sizeof(DCTELEM)*6*64);
++#endif
++POWERPC_PERF_STOP_COUNT(powerpc_clear_blocks_dcbz128, 1);
++}
++#else
++void clear_blocks_dcbz128_ppc(DCTELEM *blocks)
++{
++  memset(blocks, 0, sizeof(DCTELEM)*6*64);
++}
++#endif
++
++#ifndef NO_DCBZL
++/* check dcbz report how many bytes are set to 0 by dcbz */
++/* update 24/06/2003 : replace dcbz by dcbzl to get
++   the intended effect (Apple "fixed" dcbz)
++   unfortunately this cannot be used unless the assembler
++   knows about dcbzl ... */
++long check_dcbzl_effect(void)
++{
++  register char *fakedata = (char*)av_malloc(1024);
++  register char *fakedata_middle;
++  register long zero = 0;
++  register long i = 0;
++  long count = 0;
++
++  if (!fakedata)
++  {
++    return 0L;
++  }
++
++  fakedata_middle = (fakedata + 512);
++
++  memset(fakedata, 0xFF, 1024);
++
++  /* below the constraint "b" seems to mean "Address base register"
++     in gcc-3.3 / RS/6000 speaks. seems to avoid using r0, so.... */
++  asm volatile("dcbzl %0, %1" : : "b" (fakedata_middle), "r" (zero));
++
++  for (i = 0; i < 1024 ; i ++)
++  {
++    if (fakedata[i] == (char)0)
++      count++;
++  }
++
++  av_free(fakedata);
++  
++  return count;
++}
++#else
++long check_dcbzl_effect(void)
++{
++  return 0;
++}
++#endif
++
++void dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx)
++{
++    // Common optimizations whether Altivec is available or not
++
++  switch (check_dcbzl_effect()) {
++  case 32:
++    c->clear_blocks = clear_blocks_dcbz32_ppc;
++    break;
++  case 128:
++    c->clear_blocks = clear_blocks_dcbz128_ppc;
++    break;
++  default:
++    break;
++  }
++  
++#if HAVE_ALTIVEC
++    if (has_altivec()) {
++        mm_flags |= MM_ALTIVEC;
++        
++        // Altivec specific optimisations
++        c->pix_abs16x16_x2 = pix_abs16x16_x2_altivec;
++        c->pix_abs16x16_y2 = pix_abs16x16_y2_altivec;
++        c->pix_abs16x16_xy2 = pix_abs16x16_xy2_altivec;
++        c->pix_abs16x16 = pix_abs16x16_altivec;
++        c->pix_abs8x8 = pix_abs8x8_altivec;
++        c->sad[0]= sad16x16_altivec;
++        c->sad[1]= sad8x8_altivec;
++        c->pix_norm1 = pix_norm1_altivec;
++        c->sse[1]= sse8_altivec;
++        c->sse[0]= sse16_altivec;
++        c->pix_sum = pix_sum_altivec;
++        c->diff_pixels = diff_pixels_altivec;
++        c->get_pixels = get_pixels_altivec;
++// next one disabled as it's untested.
++#if 0
++        c->add_bytes= add_bytes_altivec;
++#endif /* 0 */
++        c->put_pixels_tab[0][0] = put_pixels16_altivec;
++        /* the tow functions do the same thing, so use the same code */
++        c->put_no_rnd_pixels_tab[0][0] = put_pixels16_altivec;
++        c->avg_pixels_tab[0][0] = avg_pixels16_altivec;
++// next one disabled as it's untested.
++#if 0
++        c->avg_pixels_tab[1][0] = avg_pixels8_altivec;
++#endif /* 0 */
++        c->put_pixels_tab[1][3] = put_pixels8_xy2_altivec;
++        c->put_no_rnd_pixels_tab[1][3] = put_no_rnd_pixels8_xy2_altivec;
++        c->put_pixels_tab[0][3] = put_pixels16_xy2_altivec;
++        c->put_no_rnd_pixels_tab[0][3] = put_no_rnd_pixels16_xy2_altivec;
++        
++      c->gmc1 = gmc1_altivec;
++
++        if ((avctx->idct_algo == FF_IDCT_AUTO) ||
++                (avctx->idct_algo == FF_IDCT_ALTIVEC))
++        {
++            c->idct_put = idct_put_altivec;
++            c->idct_add = idct_add_altivec;
++#ifndef ALTIVEC_USE_REFERENCE_C_CODE
++            c->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM;
++#else /* ALTIVEC_USE_REFERENCE_C_CODE */
++            c->idct_permutation_type = FF_NO_IDCT_PERM;
++#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
++        }
++        
++#ifdef POWERPC_PERFORMANCE_REPORT
++        {
++          int i, j;
++          for (i = 0 ; i < powerpc_perf_total ; i++)
++          {
++          for (j = 0; j < POWERPC_NUM_PMC_ENABLED ; j++)
++            {
++              perfdata[j][i][powerpc_data_min] = (unsigned long long)0xFFFFFFFFFFFFFFFF;
++              perfdata[j][i][powerpc_data_max] = (unsigned long long)0x0000000000000000;
++              perfdata[j][i][powerpc_data_sum] = (unsigned long long)0x0000000000000000;
++              perfdata[j][i][powerpc_data_num] = (unsigned long long)0x0000000000000000;
++            }
++        }
++        }
++#endif /* POWERPC_PERFORMANCE_REPORT */
++    } else
++#endif /* HAVE_ALTIVEC */
++    {
++        // Non-AltiVec PPC optimisations
++
++        // ... pending ...
++    }
++}
+diff -Nur avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc.orig/fft_altivec.c avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc/fft_altivec.c
+--- avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc.orig/fft_altivec.c        1970-01-01 01:00:00.000000000 +0100
++++ avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc/fft_altivec.c     2003-09-28 17:26:40.000000000 +0200
+@@ -0,0 +1,247 @@
++/*
++ * FFT/IFFT transforms
++ * AltiVec-enabled
++ * Copyright (c) 2003 Romain Dolbeau <romain@dolbeau.org>
++ * Based on code Copyright (c) 2002 Fabrice Bellard.
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++#include "../dsputil.h"
++
++#include "gcc_fixes.h"
++
++#include "dsputil_altivec.h"
++
++/*
++  those three macros are from libavcodec/fft.c
++  and are required for the reference C code
++*/
++/* butter fly op */
++#define BF(pre, pim, qre, qim, pre1, pim1, qre1, qim1) \
++{\
++  FFTSample ax, ay, bx, by;\
++  bx=pre1;\
++  by=pim1;\
++  ax=qre1;\
++  ay=qim1;\
++  pre = (bx + ax);\
++  pim = (by + ay);\
++  qre = (bx - ax);\
++  qim = (by - ay);\
++}
++#define MUL16(a,b) ((a) * (b))
++#define CMUL(pre, pim, are, aim, bre, bim) \
++{\
++   pre = (MUL16(are, bre) - MUL16(aim, bim));\
++   pim = (MUL16(are, bim) + MUL16(bre, aim));\
++}
++
++
++/**
++ * Do a complex FFT with the parameters defined in fft_init(). The
++ * input data must be permuted before with s->revtab table. No
++ * 1.0/sqrt(n) normalization is done.
++ * AltiVec-enabled
++ * This code assumes that the 'z' pointer is 16 bytes-aligned
++ * It also assumes all FFTComplex are 8 bytes-aligned pair of float
++ * The code is exactly the same as the SSE version, except
++ * that successive MUL + ADD/SUB have been merged into
++ * fused multiply-add ('vec_madd' in altivec)
++ */
++void fft_calc_altivec(FFTContext *s, FFTComplex *z)
++{
++POWERPC_PERF_DECLARE(altivec_fft_num, s->nbits >= 6);
++#ifdef ALTIVEC_USE_REFERENCE_C_CODE
++    int ln = s->nbits;
++    int       j, np, np2;
++    int       nblocks, nloops;
++    register FFTComplex *p, *q;
++    FFTComplex *exptab = s->exptab;
++    int l;
++    FFTSample tmp_re, tmp_im;
++    
++POWERPC_PERF_START_COUNT(altivec_fft_num, s->nbits >= 6);
++ 
++    np = 1 << ln;
++
++    /* pass 0 */
++
++    p=&z[0];
++    j=(np >> 1);
++    do {
++        BF(p[0].re, p[0].im, p[1].re, p[1].im, 
++           p[0].re, p[0].im, p[1].re, p[1].im);
++        p+=2;
++    } while (--j != 0);
++
++    /* pass 1 */
++
++    
++    p=&z[0];
++    j=np >> 2;
++    if (s->inverse) {
++        do {
++            BF(p[0].re, p[0].im, p[2].re, p[2].im, 
++               p[0].re, p[0].im, p[2].re, p[2].im);
++            BF(p[1].re, p[1].im, p[3].re, p[3].im, 
++               p[1].re, p[1].im, -p[3].im, p[3].re);
++            p+=4;
++        } while (--j != 0);
++    } else {
++        do {
++            BF(p[0].re, p[0].im, p[2].re, p[2].im, 
++               p[0].re, p[0].im, p[2].re, p[2].im);
++            BF(p[1].re, p[1].im, p[3].re, p[3].im, 
++               p[1].re, p[1].im, p[3].im, -p[3].re);
++            p+=4;
++        } while (--j != 0);
++    }
++    /* pass 2 .. ln-1 */
++
++    nblocks = np >> 3;
++    nloops = 1 << 2;
++    np2 = np >> 1;
++    do {
++        p = z;
++        q = z + nloops;
++        for (j = 0; j < nblocks; ++j) {
++            BF(p->re, p->im, q->re, q->im,
++               p->re, p->im, q->re, q->im);
++            
++            p++;
++            q++;
++            for(l = nblocks; l < np2; l += nblocks) {
++                CMUL(tmp_re, tmp_im, exptab[l].re, exptab[l].im, q->re, q->im);
++                BF(p->re, p->im, q->re, q->im,
++                   p->re, p->im, tmp_re, tmp_im);
++                p++;
++                q++;
++            }
++
++            p += nloops;
++            q += nloops;
++        }
++        nblocks = nblocks >> 1;
++        nloops = nloops << 1;
++    } while (nblocks != 0);
++
++POWERPC_PERF_STOP_COUNT(altivec_fft_num, s->nbits >= 6);
++
++#else /* ALTIVEC_USE_REFERENCE_C_CODE */
++#ifdef CONFIG_DARWIN
++    register const vector float vczero = (const vector float)(0.);
++#else
++    register const vector float vczero = (const vector float){0.,0.,0.,0.};
++#endif
++    
++    int ln = s->nbits;
++    int       j, np, np2;
++    int       nblocks, nloops;
++    register FFTComplex *p, *q;
++    FFTComplex *cptr, *cptr1;
++    int k;
++
++POWERPC_PERF_START_COUNT(altivec_fft_num, s->nbits >= 6);
++
++    np = 1 << ln;
++
++    {
++        vector float *r, a, b, a1, c1, c2;
++
++        r = (vector float *)&z[0];
++
++        c1 = vcii(p,p,n,n);
++        
++        if (s->inverse)
++            {
++                c2 = vcii(p,p,n,p);
++            }
++        else
++            {
++                c2 = vcii(p,p,p,n);
++            }
++        
++        j = (np >> 2);
++        do {
++            a = vec_ld(0, r);
++            a1 = vec_ld(sizeof(vector float), r);
++            
++            b = vec_perm(a,a,vcprmle(1,0,3,2));
++            a = vec_madd(a,c1,b);
++            /* do the pass 0 butterfly */
++            
++            b = vec_perm(a1,a1,vcprmle(1,0,3,2));
++            b = vec_madd(a1,c1,b);
++            /* do the pass 0 butterfly */
++            
++            /* multiply third by -i */
++            b = vec_perm(b,b,vcprmle(2,3,1,0));
++            
++            /* do the pass 1 butterfly */
++            vec_st(vec_madd(b,c2,a), 0, r);
++            vec_st(vec_nmsub(b,c2,a), sizeof(vector float), r);
++            
++            r += 2;
++        } while (--j != 0);
++    }
++    /* pass 2 .. ln-1 */
++
++    nblocks = np >> 3;
++    nloops = 1 << 2;
++    np2 = np >> 1;
++
++    cptr1 = s->exptab1;
++    do {
++        p = z;
++        q = z + nloops;
++        j = nblocks;
++        do {
++            cptr = cptr1;
++            k = nloops >> 1;
++            do {
++                vector float a,b,c,t1;
++
++                a = vec_ld(0, (float*)p);
++                b = vec_ld(0, (float*)q);
++                
++                /* complex mul */
++                c = vec_ld(0, (float*)cptr);
++                /*  cre*re cim*re */
++                t1 = vec_madd(c, vec_perm(b,b,vcprmle(2,2,0,0)),vczero);
++                c = vec_ld(sizeof(vector float), (float*)cptr);
++                /*  -cim*im cre*im */
++                b = vec_madd(c, vec_perm(b,b,vcprmle(3,3,1,1)),t1);
++                
++                /* butterfly */
++                vec_st(vec_add(a,b), 0, (float*)p);
++                vec_st(vec_sub(a,b), 0, (float*)q);
++                
++                p += 2;
++                q += 2;
++                cptr += 4;
++            } while (--k);
++            
++            p += nloops;
++            q += nloops;
++        } while (--j);
++        cptr1 += nloops * 2;
++        nblocks = nblocks >> 1;
++        nloops = nloops << 1;
++    } while (nblocks != 0);
++
++POWERPC_PERF_STOP_COUNT(altivec_fft_num, s->nbits >= 6);
++
++#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
++}
+diff -Nur avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc.orig/gcc_fixes.h avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc/gcc_fixes.h
+--- avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc.orig/gcc_fixes.h  2003-07-04 15:40:29.000000000 +0200
++++ avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc/gcc_fixes.h       2003-09-28 17:26:40.000000000 +0200
+@@ -25,7 +25,7 @@
+  * http://gcc.gnu.org/ml/gcc/2003-04/msg00967.html
+  */
+-static inline vector signed char my_vmrglb (vector signed char const A,
++static inline vector signed char ff_vmrglb (vector signed char const A,
+                                         vector signed char const B)
+ {
+     static const vector unsigned char lowbyte = {
+@@ -35,7 +35,7 @@
+     return vec_perm (A, B, lowbyte);
+ }
+-static inline vector signed short my_vmrglh (vector signed short const A,
++static inline vector signed short ff_vmrglh (vector signed short const A,
+                                         vector signed short const B)
+ {
+     static const vector unsigned char lowhalf = {
+@@ -45,7 +45,7 @@
+     return vec_perm (A, B, lowhalf);
+ }
+-static inline vector signed int my_vmrglw (vector signed int const A,
++static inline vector signed int ff_vmrglw (vector signed int const A,
+                                         vector signed int const B)
+ {
+     static const vector unsigned char lowword = {
+@@ -54,27 +54,27 @@
+     };
+     return vec_perm (A, B, lowword);
+ }
+-/*#define my_vmrglb my_vmrglb 
+-#define my_vmrglh my_vmrglh 
+-#define my_vmrglw my_vmrglw 
++/*#define ff_vmrglb ff_vmrglb 
++#define ff_vmrglh ff_vmrglh 
++#define ff_vmrglw ff_vmrglw 
+ */
+ #undef vec_mergel
+ #define vec_mergel(a1, a2) \
+ __ch (__bin_args_eq (vector signed char, (a1), vector signed char, (a2)), \
+-      ((vector signed char) my_vmrglb ((vector signed char) (a1), (vector signed char) (a2))), \
++      ((vector signed char) ff_vmrglb ((vector signed char) (a1), (vector signed char) (a2))), \
+ __ch (__bin_args_eq (vector unsigned char, (a1), vector unsigned char, (a2)), \
+-      ((vector unsigned char) my_vmrglb ((vector signed char) (a1), (vector signed char) (a2))), \
++      ((vector unsigned char) ff_vmrglb ((vector signed char) (a1), (vector signed char) (a2))), \
+ __ch (__bin_args_eq (vector signed short, (a1), vector signed short, (a2)), \
+-      ((vector signed short) my_vmrglh ((vector signed short) (a1), (vector signed short) (a2))), \
++      ((vector signed short) ff_vmrglh ((vector signed short) (a1), (vector signed short) (a2))), \
+ __ch (__bin_args_eq (vector unsigned short, (a1), vector unsigned short, (a2)), \
+-      ((vector unsigned short) my_vmrglh ((vector signed short) (a1), (vector signed short) (a2))), \
++      ((vector unsigned short) ff_vmrglh ((vector signed short) (a1), (vector signed short) (a2))), \
+ __ch (__bin_args_eq (vector float, (a1), vector float, (a2)), \
+-      ((vector float) my_vmrglw ((vector signed int) (a1), (vector signed int) (a2))), \
++      ((vector float) ff_vmrglw ((vector signed int) (a1), (vector signed int) (a2))), \
+ __ch (__bin_args_eq (vector signed int, (a1), vector signed int, (a2)), \
+-      ((vector signed int) my_vmrglw ((vector signed int) (a1), (vector signed int) (a2))), \
++      ((vector signed int) ff_vmrglw ((vector signed int) (a1), (vector signed int) (a2))), \
+ __ch (__bin_args_eq (vector unsigned int, (a1), vector unsigned int, (a2)), \
+-      ((vector unsigned int) my_vmrglw ((vector signed int) (a1), (vector signed int) (a2))), \
++      ((vector unsigned int) ff_vmrglw ((vector signed int) (a1), (vector signed int) (a2))), \
+     __altivec_link_error_invalid_argument ())))))))
+ #endif
+diff -Nur avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc.orig/gmc_altivec.c avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc/gmc_altivec.c
+--- avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc.orig/gmc_altivec.c        1970-01-01 01:00:00.000000000 +0100
++++ avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc/gmc_altivec.c     2003-09-28 17:26:40.000000000 +0200
+@@ -0,0 +1,172 @@
++/*
++ * GMC (Global Motion Compensation)
++ * AltiVec-enabled
++ * Copyright (c) 2003 Romain Dolbeau <romain@dolbeau.org>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++#include "../dsputil.h"
++
++#include "gcc_fixes.h"
++
++#include "dsputil_altivec.h"
++
++/*
++  altivec-enhanced gmc1. ATM this code assume stride is a multiple of 8,
++  to preserve proper dst alignement.
++*/
++#define GMC1_PERF_COND (h==8)
++void gmc1_altivec(uint8_t *dst /* align 8 */, uint8_t *src /* align1 */, int stride, int h, int x16, int y16, int rounder)
++{
++POWERPC_PERF_DECLARE(altivec_gmc1_num, GMC1_PERF_COND);
++#ifdef ALTIVEC_USE_REFERENCE_C_CODE
++    const int A=(16-x16)*(16-y16);
++    const int B=(   x16)*(16-y16);
++    const int C=(16-x16)*(   y16);
++    const int D=(   x16)*(   y16);
++    int i;
++
++POWERPC_PERF_START_COUNT(altivec_gmc1_num, GMC1_PERF_COND);
++    
++    for(i=0; i<h; i++)
++    {
++        dst[0]= (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1] + rounder)>>8;
++        dst[1]= (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2] + rounder)>>8;
++        dst[2]= (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3] + rounder)>>8;
++        dst[3]= (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4] + rounder)>>8;
++        dst[4]= (A*src[4] + B*src[5] + C*src[stride+4] + D*src[stride+5] + rounder)>>8;
++        dst[5]= (A*src[5] + B*src[6] + C*src[stride+5] + D*src[stride+6] + rounder)>>8;
++        dst[6]= (A*src[6] + B*src[7] + C*src[stride+6] + D*src[stride+7] + rounder)>>8;
++        dst[7]= (A*src[7] + B*src[8] + C*src[stride+7] + D*src[stride+8] + rounder)>>8;
++        dst+= stride;
++        src+= stride;
++    }
++
++POWERPC_PERF_STOP_COUNT(altivec_gmc1_num, GMC1_PERF_COND);
++
++#else /* ALTIVEC_USE_REFERENCE_C_CODE */
++    const unsigned short __attribute__ ((aligned(16))) rounder_a[8] =
++      {rounder, rounder, rounder, rounder,
++       rounder, rounder, rounder, rounder};
++    const unsigned short __attribute__ ((aligned(16))) ABCD[8] =
++      {
++        (16-x16)*(16-y16), /* A */
++        (   x16)*(16-y16), /* B */
++        (16-x16)*(   y16), /* C */
++        (   x16)*(   y16), /* D */
++        0, 0, 0, 0         /* padding */
++      };
++    register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0);
++    register const vector unsigned short vcsr8 = (const vector unsigned short)vec_splat_u16(8);
++    register vector unsigned char dstv, dstv2, src_0, src_1, srcvA, srcvB, srcvC, srcvD;
++    register vector unsigned short Av, Bv, Cv, Dv, rounderV, tempA, tempB, tempC, tempD;
++    int i;
++    unsigned long dst_odd = (unsigned long)dst & 0x0000000F;
++    unsigned long src_really_odd = (unsigned long)src & 0x0000000F;
++
++
++POWERPC_PERF_START_COUNT(altivec_gmc1_num, GMC1_PERF_COND);
++
++    tempA = vec_ld(0, (unsigned short*)ABCD);
++    Av = vec_splat(tempA, 0);
++    Bv = vec_splat(tempA, 1);
++    Cv = vec_splat(tempA, 2);
++    Dv = vec_splat(tempA, 3);
++
++    rounderV = vec_ld(0, (unsigned short*)rounder_a);
++    
++    // we'll be able to pick-up our 9 char elements
++    // at src from those 32 bytes
++    // we load the first batch here, as inside the loop
++    // we can re-use 'src+stride' from one iteration
++    // as the 'src' of the next.
++    src_0 = vec_ld(0, src);
++    src_1 = vec_ld(16, src);
++    srcvA = vec_perm(src_0, src_1, vec_lvsl(0, src));
++    
++    if (src_really_odd != 0x0000000F)
++    { // if src & 0xF == 0xF, then (src+1) is properly aligned on the second vector.
++      srcvB = vec_perm(src_0, src_1, vec_lvsl(1, src));
++    }
++    else
++    {
++      srcvB = src_1;
++    }
++    srcvA = vec_mergeh(vczero, srcvA);
++    srcvB = vec_mergeh(vczero, srcvB);
++    
++    for(i=0; i<h; i++)
++    {
++      dst_odd = (unsigned long)dst & 0x0000000F;
++      src_really_odd = (((unsigned long)src) + stride) & 0x0000000F;
++      
++      dstv = vec_ld(0, dst);
++      
++      // we we'll be able to pick-up our 9 char elements
++      // at src + stride from those 32 bytes
++      // then reuse the resulting 2 vectors srvcC and srcvD
++      // as the next srcvA and srcvB
++      src_0 = vec_ld(stride + 0, src);
++      src_1 = vec_ld(stride + 16, src);
++      srcvC = vec_perm(src_0, src_1, vec_lvsl(stride + 0, src));
++      
++      if (src_really_odd != 0x0000000F)
++      { // if src & 0xF == 0xF, then (src+1) is properly aligned on the second vector.
++        srcvD = vec_perm(src_0, src_1, vec_lvsl(stride + 1, src));
++      }
++      else
++      {
++        srcvD = src_1;
++      }
++      
++      srcvC = vec_mergeh(vczero, srcvC);
++      srcvD = vec_mergeh(vczero, srcvD);
++      
++
++      // OK, now we (finally) do the math :-)
++      // those four instructions replaces 32 int muls & 32 int adds.
++      // isn't AltiVec nice ?
++      tempA = vec_mladd((vector unsigned short)srcvA, Av, rounderV);
++      tempB = vec_mladd((vector unsigned short)srcvB, Bv, tempA);
++      tempC = vec_mladd((vector unsigned short)srcvC, Cv, tempB);
++      tempD = vec_mladd((vector unsigned short)srcvD, Dv, tempC);
++      
++      srcvA = srcvC;
++      srcvB = srcvD;
++      
++      tempD = vec_sr(tempD, vcsr8);
++      
++      dstv2 = vec_pack(tempD, (vector unsigned short)vczero);
++      
++      if (dst_odd)
++      {
++        dstv2 = vec_perm(dstv, dstv2, vcprm(0,1,s0,s1));
++      }
++      else
++      {
++        dstv2 = vec_perm(dstv, dstv2, vcprm(s0,s1,2,3));
++      }
++      
++      vec_st(dstv2, 0, dst);
++      
++      dst += stride;
++      src += stride;
++    }
++
++POWERPC_PERF_STOP_COUNT(altivec_gmc1_num, GMC1_PERF_COND);
++
++#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
++}
+diff -Nur avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc.orig/idct_altivec.c avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc/idct_altivec.c
+--- avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc.orig/idct_altivec.c       1970-01-01 01:00:00.000000000 +0100
++++ avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc/idct_altivec.c    2003-09-28 17:26:40.000000000 +0200
+@@ -0,0 +1,245 @@
++/*
++ * Copyright (c) 2001 Michel Lespinasse
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
++ */
++
++/*
++ * NOTE: This code is based on GPL code from the libmpeg2 project.  The
++ * author, Michel Lespinasses, has given explicit permission to release
++ * under LGPL as part of ffmpeg.
++ *
++ */
++
++/*
++ * FFMpeg integration by Dieter Shirley
++ *
++ * This file is a direct copy of the altivec idct module from the libmpeg2
++ * project.  I've deleted all of the libmpeg2 specific code, renamed the functions and
++ * re-ordered the function parameters.  The only change to the IDCT function
++ * itself was to factor out the partial transposition, and to perform a full
++ * transpose at the end of the function.
++ */
++
++
++#include <stdlib.h>                                      /* malloc(), free() */
++#include <string.h>
++#include "../dsputil.h"
++
++#include "gcc_fixes.h"
++
++#include "dsputil_altivec.h"
++
++#define vector_s16_t vector signed short
++#define vector_u16_t vector unsigned short
++#define vector_s8_t vector signed char
++#define vector_u8_t vector unsigned char
++#define vector_s32_t vector signed int
++#define vector_u32_t vector unsigned int
++
++#define IDCT_HALF                                     \
++    /* 1st stage */                                   \
++    t1 = vec_mradds (a1, vx7, vx1 );                  \
++    t8 = vec_mradds (a1, vx1, vec_subs (zero, vx7));  \
++    t7 = vec_mradds (a2, vx5, vx3);                   \
++    t3 = vec_mradds (ma2, vx3, vx5);                  \
++                                                      \
++    /* 2nd stage */                                   \
++    t5 = vec_adds (vx0, vx4);                         \
++    t0 = vec_subs (vx0, vx4);                         \
++    t2 = vec_mradds (a0, vx6, vx2);                   \
++    t4 = vec_mradds (a0, vx2, vec_subs (zero, vx6));  \
++    t6 = vec_adds (t8, t3);                           \
++    t3 = vec_subs (t8, t3);                           \
++    t8 = vec_subs (t1, t7);                           \
++    t1 = vec_adds (t1, t7);                           \
++                                                      \
++    /* 3rd stage */                                   \
++    t7 = vec_adds (t5, t2);                           \
++    t2 = vec_subs (t5, t2);                           \
++    t5 = vec_adds (t0, t4);                           \
++    t0 = vec_subs (t0, t4);                           \
++    t4 = vec_subs (t8, t3);                           \
++    t3 = vec_adds (t8, t3);                           \
++                                                      \
++    /* 4th stage */                                   \
++    vy0 = vec_adds (t7, t1);                          \
++    vy7 = vec_subs (t7, t1);                          \
++    vy1 = vec_mradds (c4, t3, t5);                    \
++    vy6 = vec_mradds (mc4, t3, t5);                   \
++    vy2 = vec_mradds (c4, t4, t0);                    \
++    vy5 = vec_mradds (mc4, t4, t0);                   \
++    vy3 = vec_adds (t2, t6);                          \
++    vy4 = vec_subs (t2, t6);
++
++      
++#define IDCT                                                          \
++    vector_s16_t vx0, vx1, vx2, vx3, vx4, vx5, vx6, vx7;              \
++    vector_s16_t vy0, vy1, vy2, vy3, vy4, vy5, vy6, vy7;              \
++    vector_s16_t a0, a1, a2, ma2, c4, mc4, zero, bias;                        \
++    vector_s16_t t0, t1, t2, t3, t4, t5, t6, t7, t8;                  \
++    vector_u16_t shift;                                                       \
++                                                                      \
++    c4 = vec_splat (constants[0], 0);                                 \
++    a0 = vec_splat (constants[0], 1);                                 \
++    a1 = vec_splat (constants[0], 2);                                 \
++    a2 = vec_splat (constants[0], 3);                                 \
++    mc4 = vec_splat (constants[0], 4);                                        \
++    ma2 = vec_splat (constants[0], 5);                                        \
++    bias = (vector_s16_t)vec_splat ((vector_s32_t)constants[0], 3);   \
++                                                                      \
++    zero = vec_splat_s16 (0);                                         \
++    shift = vec_splat_u16 (4);                                                \
++                                                                      \
++    vx0 = vec_mradds (vec_sl (block[0], shift), constants[1], zero);  \
++    vx1 = vec_mradds (vec_sl (block[1], shift), constants[2], zero);  \
++    vx2 = vec_mradds (vec_sl (block[2], shift), constants[3], zero);  \
++    vx3 = vec_mradds (vec_sl (block[3], shift), constants[4], zero);  \
++    vx4 = vec_mradds (vec_sl (block[4], shift), constants[1], zero);  \
++    vx5 = vec_mradds (vec_sl (block[5], shift), constants[4], zero);  \
++    vx6 = vec_mradds (vec_sl (block[6], shift), constants[3], zero);  \
++    vx7 = vec_mradds (vec_sl (block[7], shift), constants[2], zero);  \
++                                                                      \
++    IDCT_HALF                                                         \
++                                                                      \
++    vx0 = vec_mergeh (vy0, vy4);                                      \
++    vx1 = vec_mergel (vy0, vy4);                                      \
++    vx2 = vec_mergeh (vy1, vy5);                                      \
++    vx3 = vec_mergel (vy1, vy5);                                      \
++    vx4 = vec_mergeh (vy2, vy6);                                      \
++    vx5 = vec_mergel (vy2, vy6);                                      \
++    vx6 = vec_mergeh (vy3, vy7);                                      \
++    vx7 = vec_mergel (vy3, vy7);                                      \
++                                                                      \
++    vy0 = vec_mergeh (vx0, vx4);                                      \
++    vy1 = vec_mergel (vx0, vx4);                                      \
++    vy2 = vec_mergeh (vx1, vx5);                                      \
++    vy3 = vec_mergel (vx1, vx5);                                      \
++    vy4 = vec_mergeh (vx2, vx6);                                      \
++    vy5 = vec_mergel (vx2, vx6);                                      \
++    vy6 = vec_mergeh (vx3, vx7);                                      \
++    vy7 = vec_mergel (vx3, vx7);                                      \
++                                                                      \
++    vx0 = vec_adds (vec_mergeh (vy0, vy4), bias);                     \
++    vx1 = vec_mergel (vy0, vy4);                                      \
++    vx2 = vec_mergeh (vy1, vy5);                                      \
++    vx3 = vec_mergel (vy1, vy5);                                      \
++    vx4 = vec_mergeh (vy2, vy6);                                      \
++    vx5 = vec_mergel (vy2, vy6);                                      \
++    vx6 = vec_mergeh (vy3, vy7);                                      \
++    vx7 = vec_mergel (vy3, vy7);                                      \
++                                                                      \
++    IDCT_HALF                                                         \
++                                                                      \
++    shift = vec_splat_u16 (6);                                                \
++    vx0 = vec_sra (vy0, shift);                                               \
++    vx1 = vec_sra (vy1, shift);                                               \
++    vx2 = vec_sra (vy2, shift);                                               \
++    vx3 = vec_sra (vy3, shift);                                               \
++    vx4 = vec_sra (vy4, shift);                                               \
++    vx5 = vec_sra (vy5, shift);                                               \
++    vx6 = vec_sra (vy6, shift);                                               \
++    vx7 = vec_sra (vy7, shift);
++
++
++static const vector_s16_t constants[5] = {
++    (vector_s16_t) AVV(23170, 13573, 6518, 21895, -23170, -21895, 32, 31),
++    (vector_s16_t) AVV(16384, 22725, 21407, 19266, 16384, 19266, 21407, 22725),
++    (vector_s16_t) AVV(22725, 31521, 29692, 26722, 22725, 26722, 29692, 31521),
++    (vector_s16_t) AVV(21407, 29692, 27969, 25172, 21407, 25172, 27969, 29692),
++    (vector_s16_t) AVV(19266, 26722, 25172, 22654, 19266, 22654, 25172, 26722)
++};
++
++void idct_put_altivec(uint8_t* dest, int stride, vector_s16_t* block)
++{
++POWERPC_PERF_DECLARE(altivec_idct_put_num, 1);
++#ifdef ALTIVEC_USE_REFERENCE_C_CODE
++POWERPC_PERF_START_COUNT(altivec_idct_put_num, 1);
++    void simple_idct_put(uint8_t *dest, int line_size, int16_t *block);
++    simple_idct_put(dest, stride, (int16_t*)block);
++POWERPC_PERF_STOP_COUNT(altivec_idct_put_num, 1);
++#else /* ALTIVEC_USE_REFERENCE_C_CODE */
++    vector_u8_t tmp;
++
++POWERPC_PERF_START_COUNT(altivec_idct_put_num, 1);
++
++    IDCT
++
++#define COPY(dest,src)                                                \
++    tmp = vec_packsu (src, src);                              \
++    vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest);     \
++    vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest);
++
++    COPY (dest, vx0)  dest += stride;
++    COPY (dest, vx1)  dest += stride;
++    COPY (dest, vx2)  dest += stride;
++    COPY (dest, vx3)  dest += stride;
++    COPY (dest, vx4)  dest += stride;
++    COPY (dest, vx5)  dest += stride;
++    COPY (dest, vx6)  dest += stride;
++    COPY (dest, vx7)
++
++POWERPC_PERF_STOP_COUNT(altivec_idct_put_num, 1);
++#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
++}
++
++void idct_add_altivec(uint8_t* dest, int stride, vector_s16_t* block)
++{
++POWERPC_PERF_DECLARE(altivec_idct_add_num, 1);
++#ifdef ALTIVEC_USE_REFERENCE_C_CODE
++POWERPC_PERF_START_COUNT(altivec_idct_add_num, 1);
++    void simple_idct_add(uint8_t *dest, int line_size, int16_t *block);
++    simple_idct_add(dest, stride, (int16_t*)block);
++POWERPC_PERF_STOP_COUNT(altivec_idct_add_num, 1);
++#else /* ALTIVEC_USE_REFERENCE_C_CODE */
++    vector_u8_t tmp;
++    vector_s16_t tmp2, tmp3;
++    vector_u8_t perm0;
++    vector_u8_t perm1;
++    vector_u8_t p0, p1, p;
++
++POWERPC_PERF_START_COUNT(altivec_idct_add_num, 1);
++
++    IDCT
++
++    p0 = vec_lvsl (0, dest);
++    p1 = vec_lvsl (stride, dest);
++    p = vec_splat_u8 (-1);
++    perm0 = vec_mergeh (p, p0);
++    perm1 = vec_mergeh (p, p1);
++
++#define ADD(dest,src,perm)                                            \
++    /* *(uint64_t *)&tmp = *(uint64_t *)dest; */                      \
++    tmp = vec_ld (0, dest);                                           \
++    tmp2 = (vector_s16_t)vec_perm (tmp, (vector_u8_t)zero, perm);     \
++    tmp3 = vec_adds (tmp2, src);                                      \
++    tmp = vec_packsu (tmp3, tmp3);                                    \
++    vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest);             \
++    vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest);
++
++    ADD (dest, vx0, perm0)    dest += stride;
++    ADD (dest, vx1, perm1)    dest += stride;
++    ADD (dest, vx2, perm0)    dest += stride;
++    ADD (dest, vx3, perm1)    dest += stride;
++    ADD (dest, vx4, perm0)    dest += stride;
++    ADD (dest, vx5, perm1)    dest += stride;
++    ADD (dest, vx6, perm0)    dest += stride;
++    ADD (dest, vx7, perm1)
++
++POWERPC_PERF_STOP_COUNT(altivec_idct_add_num, 1);
++#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
++}
++
+diff -Nur avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc.orig/mpegvideo_altivec.c avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc/mpegvideo_altivec.c
+--- avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc.orig/mpegvideo_altivec.c  1970-01-01 01:00:00.000000000 +0100
++++ avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc/mpegvideo_altivec.c       2003-09-28 17:26:40.000000000 +0200
+@@ -0,0 +1,645 @@
++/*
++ * Copyright (c) 2002 Dieter Shirley
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++#include <stdlib.h>
++#include <stdio.h>
++#include "../dsputil.h"
++#include "../mpegvideo.h"
++
++#include "gcc_fixes.h"
++ 
++#include "dsputil_altivec.h"
++
++// Swaps two variables (used for altivec registers)
++#define SWAP(a,b) \
++do { \
++    __typeof__(a) swap_temp=a; \
++    a=b; \
++    b=swap_temp; \
++} while (0)
++
++// transposes a matrix consisting of four vectors with four elements each
++#define TRANSPOSE4(a,b,c,d) \
++do { \
++  __typeof__(a) _trans_ach = vec_mergeh(a, c); \
++  __typeof__(a) _trans_acl = vec_mergel(a, c); \
++  __typeof__(a) _trans_bdh = vec_mergeh(b, d); \
++  __typeof__(a) _trans_bdl = vec_mergel(b, d); \
++ \
++  a = vec_mergeh(_trans_ach, _trans_bdh); \
++  b = vec_mergel(_trans_ach, _trans_bdh); \
++  c = vec_mergeh(_trans_acl, _trans_bdl); \
++  d = vec_mergel(_trans_acl, _trans_bdl); \
++} while (0)
++
++#define TRANSPOSE8(a,b,c,d,e,f,g,h) \
++do { \
++    __typeof__(a)  _A1, _B1, _C1, _D1, _E1, _F1, _G1, _H1; \
++    __typeof__(a)  _A2, _B2, _C2, _D2, _E2, _F2, _G2, _H2; \
++ \
++    _A1 = vec_mergeh (a, e); \
++    _B1 = vec_mergel (a, e); \
++    _C1 = vec_mergeh (b, f); \
++    _D1 = vec_mergel (b, f); \
++    _E1 = vec_mergeh (c, g); \
++    _F1 = vec_mergel (c, g); \
++    _G1 = vec_mergeh (d, h); \
++    _H1 = vec_mergel (d, h); \
++ \
++    _A2 = vec_mergeh (_A1, _E1); \
++    _B2 = vec_mergel (_A1, _E1); \
++    _C2 = vec_mergeh (_B1, _F1); \
++    _D2 = vec_mergel (_B1, _F1); \
++    _E2 = vec_mergeh (_C1, _G1); \
++    _F2 = vec_mergel (_C1, _G1); \
++    _G2 = vec_mergeh (_D1, _H1); \
++    _H2 = vec_mergel (_D1, _H1); \
++ \
++    a = vec_mergeh (_A2, _E2); \
++    b = vec_mergel (_A2, _E2); \
++    c = vec_mergeh (_B2, _F2); \
++    d = vec_mergel (_B2, _F2); \
++    e = vec_mergeh (_C2, _G2); \
++    f = vec_mergel (_C2, _G2); \
++    g = vec_mergeh (_D2, _H2); \
++    h = vec_mergel (_D2, _H2); \
++} while (0)
++
++
++// Loads a four-byte value (int or float) from the target address
++// into every element in the target vector.  Only works if the
++// target address is four-byte aligned (which should be always).
++#define LOAD4(vec, address) \
++{ \
++    __typeof__(vec)* _load_addr = (__typeof__(vec)*)(address); \
++    vector unsigned char _perm_vec = vec_lvsl(0,(address)); \
++    vec = vec_ld(0, _load_addr); \
++    vec = vec_perm(vec, vec, _perm_vec); \
++    vec = vec_splat(vec, 0); \
++}
++
++
++#ifdef CONFIG_DARWIN
++#define FOUROF(a) (a)
++#else
++// slower, for dumb non-apple GCC
++#define FOUROF(a) {a,a,a,a}
++#endif
++int dct_quantize_altivec(MpegEncContext* s, 
++                        DCTELEM* data, int n,
++                        int qscale, int* overflow)
++{
++    int lastNonZero;
++    vector float row0, row1, row2, row3, row4, row5, row6, row7;
++    vector float alt0, alt1, alt2, alt3, alt4, alt5, alt6, alt7;
++    const vector float zero = (const vector float)FOUROF(0.);
++
++    // Load the data into the row/alt vectors
++    {
++        vector signed short data0, data1, data2, data3, data4, data5, data6, data7;
++
++        data0 = vec_ld(0, data);
++        data1 = vec_ld(16, data);
++        data2 = vec_ld(32, data);
++        data3 = vec_ld(48, data);
++        data4 = vec_ld(64, data);
++        data5 = vec_ld(80, data);
++        data6 = vec_ld(96, data);
++        data7 = vec_ld(112, data);
++
++        // Transpose the data before we start
++        TRANSPOSE8(data0, data1, data2, data3, data4, data5, data6, data7);
++
++        // load the data into floating point vectors.  We load
++        // the high half of each row into the main row vectors
++        // and the low half into the alt vectors.
++        row0 = vec_ctf(vec_unpackh(data0), 0);
++        alt0 = vec_ctf(vec_unpackl(data0), 0);
++        row1 = vec_ctf(vec_unpackh(data1), 0);
++        alt1 = vec_ctf(vec_unpackl(data1), 0);
++        row2 = vec_ctf(vec_unpackh(data2), 0);
++        alt2 = vec_ctf(vec_unpackl(data2), 0);
++        row3 = vec_ctf(vec_unpackh(data3), 0);
++        alt3 = vec_ctf(vec_unpackl(data3), 0);
++        row4 = vec_ctf(vec_unpackh(data4), 0);
++        alt4 = vec_ctf(vec_unpackl(data4), 0);
++        row5 = vec_ctf(vec_unpackh(data5), 0);
++        alt5 = vec_ctf(vec_unpackl(data5), 0);
++        row6 = vec_ctf(vec_unpackh(data6), 0);
++        alt6 = vec_ctf(vec_unpackl(data6), 0);
++        row7 = vec_ctf(vec_unpackh(data7), 0);
++        alt7 = vec_ctf(vec_unpackl(data7), 0);
++    }
++
++    // The following block could exist as a separate an altivec dct
++              // function.  However, if we put it inline, the DCT data can remain
++              // in the vector local variables, as floats, which we'll use during the
++              // quantize step...
++    {
++        const vector float vec_0_298631336 = (vector float)FOUROF(0.298631336f);
++        const vector float vec_0_390180644 = (vector float)FOUROF(-0.390180644f);
++        const vector float vec_0_541196100 = (vector float)FOUROF(0.541196100f);
++        const vector float vec_0_765366865 = (vector float)FOUROF(0.765366865f);
++        const vector float vec_0_899976223 = (vector float)FOUROF(-0.899976223f);
++        const vector float vec_1_175875602 = (vector float)FOUROF(1.175875602f);
++        const vector float vec_1_501321110 = (vector float)FOUROF(1.501321110f);
++        const vector float vec_1_847759065 = (vector float)FOUROF(-1.847759065f);
++        const vector float vec_1_961570560 = (vector float)FOUROF(-1.961570560f);
++        const vector float vec_2_053119869 = (vector float)FOUROF(2.053119869f);
++        const vector float vec_2_562915447 = (vector float)FOUROF(-2.562915447f);
++        const vector float vec_3_072711026 = (vector float)FOUROF(3.072711026f);
++
++
++        int whichPass, whichHalf;
++
++        for(whichPass = 1; whichPass<=2; whichPass++)
++        {
++            for(whichHalf = 1; whichHalf<=2; whichHalf++)
++            {
++                vector float tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
++                vector float tmp10, tmp11, tmp12, tmp13;
++                vector float z1, z2, z3, z4, z5;
++
++                tmp0 = vec_add(row0, row7); // tmp0 = dataptr[0] + dataptr[7];
++                tmp7 = vec_sub(row0, row7); // tmp7 = dataptr[0] - dataptr[7];
++                tmp3 = vec_add(row3, row4); // tmp3 = dataptr[3] + dataptr[4];
++                tmp4 = vec_sub(row3, row4); // tmp4 = dataptr[3] - dataptr[4];
++                tmp1 = vec_add(row1, row6); // tmp1 = dataptr[1] + dataptr[6];
++                tmp6 = vec_sub(row1, row6); // tmp6 = dataptr[1] - dataptr[6];
++                tmp2 = vec_add(row2, row5); // tmp2 = dataptr[2] + dataptr[5];
++                tmp5 = vec_sub(row2, row5); // tmp5 = dataptr[2] - dataptr[5];
++
++                tmp10 = vec_add(tmp0, tmp3); // tmp10 = tmp0 + tmp3;
++                tmp13 = vec_sub(tmp0, tmp3); // tmp13 = tmp0 - tmp3;
++                tmp11 = vec_add(tmp1, tmp2); // tmp11 = tmp1 + tmp2;
++                tmp12 = vec_sub(tmp1, tmp2); // tmp12 = tmp1 - tmp2;
++
++
++                // dataptr[0] = (DCTELEM) ((tmp10 + tmp11) << PASS1_BITS);
++                row0 = vec_add(tmp10, tmp11);
++
++                // dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS);
++                row4 = vec_sub(tmp10, tmp11);
++
++
++                // z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
++                z1 = vec_madd(vec_add(tmp12, tmp13), vec_0_541196100, (vector float)zero);
++
++                // dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
++                //               CONST_BITS-PASS1_BITS);
++                row2 = vec_madd(tmp13, vec_0_765366865, z1);
++
++                // dataptr[6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
++                //               CONST_BITS-PASS1_BITS);
++                row6 = vec_madd(tmp12, vec_1_847759065, z1);
++
++                z1 = vec_add(tmp4, tmp7); // z1 = tmp4 + tmp7;
++                z2 = vec_add(tmp5, tmp6); // z2 = tmp5 + tmp6;
++                z3 = vec_add(tmp4, tmp6); // z3 = tmp4 + tmp6;
++                z4 = vec_add(tmp5, tmp7); // z4 = tmp5 + tmp7;
++
++                // z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
++                z5 = vec_madd(vec_add(z3, z4), vec_1_175875602, (vector float)zero);
++
++                // z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
++                z3 = vec_madd(z3, vec_1_961570560, z5);
++
++                // z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
++                z4 = vec_madd(z4, vec_0_390180644, z5);
++
++                // The following adds are rolled into the multiplies above
++                // z3 = vec_add(z3, z5);  // z3 += z5;
++                // z4 = vec_add(z4, z5);  // z4 += z5;
++
++                // z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
++                // Wow!  It's actually more effecient to roll this multiply
++                // into the adds below, even thought the multiply gets done twice!
++                // z2 = vec_madd(z2, vec_2_562915447, (vector float)zero);
++
++                // z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
++                // Same with this one...
++                // z1 = vec_madd(z1, vec_0_899976223, (vector float)zero);
++
++                // tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
++                // dataptr[7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS);
++                row7 = vec_madd(tmp4, vec_0_298631336, vec_madd(z1, vec_0_899976223, z3));
++
++                // tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
++                // dataptr[5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS);
++                row5 = vec_madd(tmp5, vec_2_053119869, vec_madd(z2, vec_2_562915447, z4));
++
++                // tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
++                // dataptr[3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS);
++                row3 = vec_madd(tmp6, vec_3_072711026, vec_madd(z2, vec_2_562915447, z3));
++
++                // tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
++                // dataptr[1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS);
++                row1 = vec_madd(z1, vec_0_899976223, vec_madd(tmp7, vec_1_501321110, z4));
++
++                // Swap the row values with the alts.  If this is the first half,
++                // this sets up the low values to be acted on in the second half.
++                // If this is the second half, it puts the high values back in
++                // the row values where they are expected to be when we're done.
++                SWAP(row0, alt0);
++                SWAP(row1, alt1);
++                SWAP(row2, alt2);
++                SWAP(row3, alt3);
++                SWAP(row4, alt4);
++                SWAP(row5, alt5);
++                SWAP(row6, alt6);
++                SWAP(row7, alt7);
++            }
++
++            if (whichPass == 1)
++            {
++                // transpose the data for the second pass
++                 
++                // First, block transpose the upper right with lower left.
++                SWAP(row4, alt0);
++                SWAP(row5, alt1);
++                SWAP(row6, alt2);
++                SWAP(row7, alt3);
++
++                // Now, transpose each block of four
++                TRANSPOSE4(row0, row1, row2, row3);
++                TRANSPOSE4(row4, row5, row6, row7);
++                TRANSPOSE4(alt0, alt1, alt2, alt3);
++                TRANSPOSE4(alt4, alt5, alt6, alt7);
++            }
++        }
++    }
++
++    // used after quantise step
++    int oldBaseValue = 0;
++
++    // perform the quantise step, using the floating point data
++    // still in the row/alt registers
++    {
++        const int* biasAddr;
++        const vector signed int* qmat;
++        vector float bias, negBias;
++
++        if (s->mb_intra)
++        {
++            vector signed int baseVector;
++
++            // We must cache element 0 in the intra case
++            // (it needs special handling).
++            baseVector = vec_cts(vec_splat(row0, 0), 0);
++            vec_ste(baseVector, 0, &oldBaseValue);
++
++            qmat = (vector signed int*)s->q_intra_matrix[qscale];
++            biasAddr = &(s->intra_quant_bias);
++        }
++        else
++        {
++            qmat = (vector signed int*)s->q_inter_matrix[qscale];
++            biasAddr = &(s->inter_quant_bias);
++        }
++
++        // Load the bias vector (We add 0.5 to the bias so that we're
++                              // rounding when we convert to int, instead of flooring.)
++        {
++            vector signed int biasInt;
++            const vector float negOneFloat = (vector float)FOUROF(-1.0f);
++            LOAD4(biasInt, biasAddr);
++            bias = vec_ctf(biasInt, QUANT_BIAS_SHIFT);
++            negBias = vec_madd(bias, negOneFloat, zero);
++        }
++
++        {
++            vector float q0, q1, q2, q3, q4, q5, q6, q7;
++
++            q0 = vec_ctf(qmat[0], QMAT_SHIFT);
++            q1 = vec_ctf(qmat[2], QMAT_SHIFT);
++            q2 = vec_ctf(qmat[4], QMAT_SHIFT);
++            q3 = vec_ctf(qmat[6], QMAT_SHIFT);
++            q4 = vec_ctf(qmat[8], QMAT_SHIFT);
++            q5 = vec_ctf(qmat[10], QMAT_SHIFT);
++            q6 = vec_ctf(qmat[12], QMAT_SHIFT);
++            q7 = vec_ctf(qmat[14], QMAT_SHIFT);
++
++            row0 = vec_sel(vec_madd(row0, q0, negBias), vec_madd(row0, q0, bias),
++                    vec_cmpgt(row0, zero));
++            row1 = vec_sel(vec_madd(row1, q1, negBias), vec_madd(row1, q1, bias),
++                    vec_cmpgt(row1, zero));
++            row2 = vec_sel(vec_madd(row2, q2, negBias), vec_madd(row2, q2, bias),
++                    vec_cmpgt(row2, zero));
++            row3 = vec_sel(vec_madd(row3, q3, negBias), vec_madd(row3, q3, bias),
++                    vec_cmpgt(row3, zero));
++            row4 = vec_sel(vec_madd(row4, q4, negBias), vec_madd(row4, q4, bias),
++                    vec_cmpgt(row4, zero));
++            row5 = vec_sel(vec_madd(row5, q5, negBias), vec_madd(row5, q5, bias),
++                    vec_cmpgt(row5, zero));
++            row6 = vec_sel(vec_madd(row6, q6, negBias), vec_madd(row6, q6, bias),
++                    vec_cmpgt(row6, zero));
++            row7 = vec_sel(vec_madd(row7, q7, negBias), vec_madd(row7, q7, bias),
++                    vec_cmpgt(row7, zero));
++
++            q0 = vec_ctf(qmat[1], QMAT_SHIFT);
++            q1 = vec_ctf(qmat[3], QMAT_SHIFT);
++            q2 = vec_ctf(qmat[5], QMAT_SHIFT);
++            q3 = vec_ctf(qmat[7], QMAT_SHIFT);
++            q4 = vec_ctf(qmat[9], QMAT_SHIFT);
++            q5 = vec_ctf(qmat[11], QMAT_SHIFT);
++            q6 = vec_ctf(qmat[13], QMAT_SHIFT);
++            q7 = vec_ctf(qmat[15], QMAT_SHIFT);
++
++            alt0 = vec_sel(vec_madd(alt0, q0, negBias), vec_madd(alt0, q0, bias),
++                    vec_cmpgt(alt0, zero));
++            alt1 = vec_sel(vec_madd(alt1, q1, negBias), vec_madd(alt1, q1, bias),
++                    vec_cmpgt(alt1, zero));
++            alt2 = vec_sel(vec_madd(alt2, q2, negBias), vec_madd(alt2, q2, bias),
++                    vec_cmpgt(alt2, zero));
++            alt3 = vec_sel(vec_madd(alt3, q3, negBias), vec_madd(alt3, q3, bias),
++                    vec_cmpgt(alt3, zero));
++            alt4 = vec_sel(vec_madd(alt4, q4, negBias), vec_madd(alt4, q4, bias),
++                    vec_cmpgt(alt4, zero));
++            alt5 = vec_sel(vec_madd(alt5, q5, negBias), vec_madd(alt5, q5, bias),
++                    vec_cmpgt(alt5, zero));
++            alt6 = vec_sel(vec_madd(alt6, q6, negBias), vec_madd(alt6, q6, bias),
++                    vec_cmpgt(alt6, zero));
++            alt7 = vec_sel(vec_madd(alt7, q7, negBias), vec_madd(alt7, q7, bias),
++                    vec_cmpgt(alt7, zero));
++        }
++
++ 
++    }
++
++    // Store the data back into the original block
++    {
++        vector signed short data0, data1, data2, data3, data4, data5, data6, data7;
++
++        data0 = vec_pack(vec_cts(row0, 0), vec_cts(alt0, 0));
++        data1 = vec_pack(vec_cts(row1, 0), vec_cts(alt1, 0));
++        data2 = vec_pack(vec_cts(row2, 0), vec_cts(alt2, 0));
++        data3 = vec_pack(vec_cts(row3, 0), vec_cts(alt3, 0));
++        data4 = vec_pack(vec_cts(row4, 0), vec_cts(alt4, 0));
++        data5 = vec_pack(vec_cts(row5, 0), vec_cts(alt5, 0));
++        data6 = vec_pack(vec_cts(row6, 0), vec_cts(alt6, 0));
++        data7 = vec_pack(vec_cts(row7, 0), vec_cts(alt7, 0));
++
++        {
++            // Clamp for overflow
++            vector signed int max_q_int, min_q_int;
++            vector signed short max_q, min_q;
++
++            LOAD4(max_q_int, &(s->max_qcoeff));
++            LOAD4(min_q_int, &(s->min_qcoeff));
++
++            max_q = vec_pack(max_q_int, max_q_int);
++            min_q = vec_pack(min_q_int, min_q_int);
++
++            data0 = vec_max(vec_min(data0, max_q), min_q);
++            data1 = vec_max(vec_min(data1, max_q), min_q);
++            data2 = vec_max(vec_min(data2, max_q), min_q);
++            data4 = vec_max(vec_min(data4, max_q), min_q);
++            data5 = vec_max(vec_min(data5, max_q), min_q);
++            data6 = vec_max(vec_min(data6, max_q), min_q);
++            data7 = vec_max(vec_min(data7, max_q), min_q);
++        }
++
++        vector bool char zero_01, zero_23, zero_45, zero_67;
++        vector signed char scanIndices_01, scanIndices_23, scanIndices_45, scanIndices_67;
++        vector signed char negOne = vec_splat_s8(-1);
++        vector signed char* scanPtr =
++                (vector signed char*)(s->intra_scantable.inverse);
++
++        // Determine the largest non-zero index.
++        zero_01 = vec_pack(vec_cmpeq(data0, (vector short)zero),
++                vec_cmpeq(data1, (vector short)zero));
++        zero_23 = vec_pack(vec_cmpeq(data2, (vector short)zero),
++                vec_cmpeq(data3, (vector short)zero));
++        zero_45 = vec_pack(vec_cmpeq(data4, (vector short)zero),
++                vec_cmpeq(data5, (vector short)zero));
++        zero_67 = vec_pack(vec_cmpeq(data6, (vector short)zero),
++                vec_cmpeq(data7, (vector short)zero));
++
++        // 64 biggest values
++        scanIndices_01 = vec_sel(scanPtr[0], negOne, zero_01);
++        scanIndices_23 = vec_sel(scanPtr[1], negOne, zero_23);
++        scanIndices_45 = vec_sel(scanPtr[2], negOne, zero_45);
++        scanIndices_67 = vec_sel(scanPtr[3], negOne, zero_67);
++
++        // 32 largest values
++        scanIndices_01 = vec_max(scanIndices_01, scanIndices_23);
++        scanIndices_45 = vec_max(scanIndices_45, scanIndices_67);
++
++        // 16 largest values
++        scanIndices_01 = vec_max(scanIndices_01, scanIndices_45);
++
++        // 8 largest values
++        scanIndices_01 = vec_max(vec_mergeh(scanIndices_01, negOne),
++                vec_mergel(scanIndices_01, negOne));
++
++        // 4 largest values
++        scanIndices_01 = vec_max(vec_mergeh(scanIndices_01, negOne),
++                vec_mergel(scanIndices_01, negOne));
++
++        // 2 largest values
++        scanIndices_01 = vec_max(vec_mergeh(scanIndices_01, negOne),
++                vec_mergel(scanIndices_01, negOne));
++
++        // largest value
++        scanIndices_01 = vec_max(vec_mergeh(scanIndices_01, negOne),
++                vec_mergel(scanIndices_01, negOne));
++
++        scanIndices_01 = vec_splat(scanIndices_01, 0);
++
++        signed char lastNonZeroChar;
++
++        vec_ste(scanIndices_01, 0, &lastNonZeroChar);
++
++        lastNonZero = lastNonZeroChar;
++        
++        // While the data is still in vectors we check for the transpose IDCT permute
++        // and handle it using the vector unit if we can.  This is the permute used
++        // by the altivec idct, so it is common when using the altivec dct.
++
++        if ((lastNonZero > 0) && (s->dsp.idct_permutation_type == FF_TRANSPOSE_IDCT_PERM))
++        {
++            TRANSPOSE8(data0, data1, data2, data3, data4, data5, data6, data7);
++        }
++
++        vec_st(data0, 0, data);
++        vec_st(data1, 16, data);
++        vec_st(data2, 32, data);
++        vec_st(data3, 48, data);
++        vec_st(data4, 64, data);
++        vec_st(data5, 80, data);
++        vec_st(data6, 96, data);
++        vec_st(data7, 112, data);
++    }
++
++    // special handling of block[0]
++    if (s->mb_intra)
++    {
++        if (!s->h263_aic)
++        {
++            if (n < 4)
++                oldBaseValue /= s->y_dc_scale;
++            else
++                oldBaseValue /= s->c_dc_scale;
++        }
++
++        // Divide by 8, rounding the result
++        data[0] = (oldBaseValue + 4) >> 3;
++    }
++
++    // We handled the tranpose permutation above and we don't
++    // need to permute the "no" permutation case.
++    if ((lastNonZero > 0) &&
++        (s->dsp.idct_permutation_type != FF_TRANSPOSE_IDCT_PERM) &&
++        (s->dsp.idct_permutation_type != FF_NO_IDCT_PERM))
++    {
++        ff_block_permute(data, s->dsp.idct_permutation,
++                s->intra_scantable.scantable, lastNonZero);
++    }
++
++    return lastNonZero;
++}
++#undef FOUROF
++
++/*
++  AltiVec version of dct_unquantize_h263
++  this code assumes `block' is 16 bytes-aligned
++*/
++void dct_unquantize_h263_altivec(MpegEncContext *s, 
++                                 DCTELEM *block, int n, int qscale)
++{
++POWERPC_PERF_DECLARE(altivec_dct_unquantize_h263_num, 1);
++    int i, level, qmul, qadd;
++    int nCoeffs;
++    
++    assert(s->block_last_index[n]>=0);
++
++POWERPC_PERF_START_COUNT(altivec_dct_unquantize_h263_num, 1);
++    
++    qadd = (qscale - 1) | 1;
++    qmul = qscale << 1;
++    
++    if (s->mb_intra) {
++        if (!s->h263_aic) {
++            if (n < 4) 
++                block[0] = block[0] * s->y_dc_scale;
++            else
++                block[0] = block[0] * s->c_dc_scale;
++        }else
++            qadd = 0;
++        i = 1;
++        nCoeffs= 63; //does not allways use zigzag table 
++    } else {
++        i = 0;
++        nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ];
++    }
++
++#ifdef ALTIVEC_USE_REFERENCE_C_CODE
++    for(;i<=nCoeffs;i++) {
++        level = block[i];
++        if (level) {
++            if (level < 0) {
++                level = level * qmul - qadd;
++            } else {
++                level = level * qmul + qadd;
++            }
++            block[i] = level;
++        }
++    }
++#else /* ALTIVEC_USE_REFERENCE_C_CODE */
++    {
++      register const vector short vczero = (const vector short)vec_splat_s16(0);
++      short __attribute__ ((aligned(16))) qmul8[] =
++          {
++            qmul, qmul, qmul, qmul,
++            qmul, qmul, qmul, qmul
++          };
++      short __attribute__ ((aligned(16))) qadd8[] =
++          {
++            qadd, qadd, qadd, qadd,
++            qadd, qadd, qadd, qadd
++          };
++      short __attribute__ ((aligned(16))) nqadd8[] =
++          {
++            -qadd, -qadd, -qadd, -qadd,
++            -qadd, -qadd, -qadd, -qadd
++          };
++      register vector short blockv, qmulv, qaddv, nqaddv, temp1;
++      register vector bool short blockv_null, blockv_neg;
++      register short backup_0 = block[0];
++      register int j = 0;
++      
++      qmulv = vec_ld(0, qmul8);
++      qaddv = vec_ld(0, qadd8);
++      nqaddv = vec_ld(0, nqadd8);
++
++#if 0 // block *is* 16 bytes-aligned, it seems.
++      // first make sure block[j] is 16 bytes-aligned
++      for(j = 0; (j <= nCoeffs) && ((((unsigned long)block) + (j << 1)) & 0x0000000F) ; j++) {
++        level = block[j];
++        if (level) {
++          if (level < 0) {
++                level = level * qmul - qadd;
++            } else {
++                level = level * qmul + qadd;
++            }
++            block[j] = level;
++        }
++      }
++#endif
++      
++      // vectorize all the 16 bytes-aligned blocks
++      // of 8 elements
++      for(; (j + 7) <= nCoeffs ; j+=8)
++      {
++        blockv = vec_ld(j << 1, block);
++        blockv_neg = vec_cmplt(blockv, vczero);
++        blockv_null = vec_cmpeq(blockv, vczero);
++        // choose between +qadd or -qadd as the third operand
++        temp1 = vec_sel(qaddv, nqaddv, blockv_neg);
++        // multiply & add (block{i,i+7} * qmul [+-] qadd)
++        temp1 = vec_mladd(blockv, qmulv, temp1);
++        // put 0 where block[{i,i+7} used to have 0
++        blockv = vec_sel(temp1, blockv, blockv_null);
++        vec_st(blockv, j << 1, block);
++      }
++
++      // if nCoeffs isn't a multiple of 8, finish the job
++      // using good old scalar units.
++      // (we could do it using a truncated vector,
++      // but I'm not sure it's worth the hassle)
++      for(; j <= nCoeffs ; j++) {
++        level = block[j];
++        if (level) {
++          if (level < 0) {
++                level = level * qmul - qadd;
++            } else {
++                level = level * qmul + qadd;
++            }
++            block[j] = level;
++        }
++      }
++      
++      if (i == 1)
++      { // cheat. this avoid special-casing the first iteration
++        block[0] = backup_0;
++      }
++    }
++#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
++
++POWERPC_PERF_STOP_COUNT(altivec_dct_unquantize_h263_num, nCoeffs == 63);
++}
+diff -Nur avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc.orig/mpegvideo_ppc.c avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc/mpegvideo_ppc.c
+--- avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc.orig/mpegvideo_ppc.c      1970-01-01 01:00:00.000000000 +0100
++++ avifile-0.7-0.7.38/ffmpeg/libavcodec/ppc/mpegvideo_ppc.c   2003-09-28 17:26:40.000000000 +0200
+@@ -0,0 +1,83 @@
++/*\r
++ * Copyright (c) 2002 Dieter Shirley\r
++ *\r
++ * This library is free software; you can redistribute it and/or\r
++ * modify it under the terms of the GNU Lesser General Public\r
++ * License as published by the Free Software Foundation; either\r
++ * version 2 of the License, or (at your option) any later version.\r
++ *\r
++ * This library is distributed in the hope that it will be useful,\r
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
++ * Lesser General Public License for more details.\r
++ *\r
++ * You should have received a copy of the GNU Lesser General Public\r
++ * License along with this library; if not, write to the Free Software\r
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
++ */\r
++ \r
++#include "../dsputil.h"\r
++#include "../mpegvideo.h"\r
++#include <time.h>\r
++\r
++#ifdef HAVE_ALTIVEC\r
++#include "dsputil_altivec.h"\r
++#endif\r
++\r
++extern int dct_quantize_altivec(MpegEncContext *s,  \r
++        DCTELEM *block, int n,\r
++        int qscale, int *overflow);\r
++extern void dct_unquantize_h263_altivec(MpegEncContext *s,
++                                        DCTELEM *block, int n, int qscale);
++\r
++extern void idct_put_altivec(uint8_t *dest, int line_size, int16_t *block);\r
++extern void idct_add_altivec(uint8_t *dest, int line_size, int16_t *block);\r
++\r
++\r
++void MPV_common_init_ppc(MpegEncContext *s)\r
++{\r
++#if HAVE_ALTIVEC\r
++    if (has_altivec())\r
++    {\r
++        if ((s->avctx->idct_algo == FF_IDCT_AUTO) ||\r
++                (s->avctx->idct_algo == FF_IDCT_ALTIVEC))\r
++        {\r
++            s->dsp.idct_put = idct_put_altivec;\r
++            s->dsp.idct_add = idct_add_altivec;\r
++#ifndef ALTIVEC_USE_REFERENCE_C_CODE
++            s->dsp.idct_permutation_type = FF_TRANSPOSE_IDCT_PERM;\r
++#else /* ALTIVEC_USE_REFERENCE_C_CODE */
++            s->dsp.idct_permutation_type = FF_NO_IDCT_PERM;
++#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
++        }\r
++\r
++        // Test to make sure that the dct required alignments are met.\r
++        if ((((long)(s->q_intra_matrix) & 0x0f) != 0) ||\r
++                (((long)(s->q_inter_matrix) & 0x0f) != 0))\r
++        {\r
++            fprintf(stderr, "Internal Error: q-matrix blocks must be 16-byte aligned "\r
++                    "to use Altivec DCT. Reverting to non-altivec version.\n");\r
++            return;\r
++        }\r
++\r
++        if (((long)(s->intra_scantable.inverse) & 0x0f) != 0)\r
++        {\r
++            fprintf(stderr, "Internal Error: scan table blocks must be 16-byte aligned "\r
++                    "to use Altivec DCT. Reverting to non-altivec version.\n");\r
++            return;\r
++        }\r
++\r
++\r
++        if ((s->avctx->dct_algo == FF_DCT_AUTO) ||\r
++                (s->avctx->dct_algo == FF_DCT_ALTIVEC))\r
++        {\r
++            s->dct_quantize = dct_quantize_altivec;\r
++            s->dct_unquantize_h263 = dct_unquantize_h263_altivec;
++        }\r
++    } else\r
++#endif\r
++    {\r
++        /* Non-AltiVec PPC optimisations here */\r
++    }\r
++}\r
++\r
This page took 0.251193 seconds and 4 git commands to generate.