Mercurial > libavcodec.hg
changeset 884:2cef5c4c0ca6 libavcodec
* altivec and pix_norm patch by Brian Foley
author | kabi |
---|---|
date | Fri, 22 Nov 2002 07:53:06 +0000 |
parents | b0d29bf1cecd |
children | 35d28522a1c5 |
files | dsputil.c dsputil.h motion_est.c ppc/dsputil_altivec.c ppc/dsputil_altivec.h ppc/dsputil_ppc.c |
diffstat | 6 files changed, 79 insertions(+), 51 deletions(-) [+] |
line wrap: on
line diff
--- a/dsputil.c Fri Nov 22 07:27:13 2002 +0000 +++ b/dsputil.c Fri Nov 22 07:53:06 2002 +0000 @@ -144,6 +144,31 @@ } +static int pix_norm_c(UINT8 * pix1, UINT8 * pix2, int line_size) +{ + int s, i, j; + UINT32 *sq = squareTbl + 256; + + s = 0; + for (i = 0; i < 16; i++) { + for (j = 0; j < 16; j += 8) { + s += sq[pix1[0] - pix2[0]]; + s += sq[pix1[1] - pix2[1]]; + s += sq[pix1[2] - pix2[2]]; + s += sq[pix1[3] - pix2[3]]; + s += sq[pix1[4] - pix2[4]]; + s += sq[pix1[5] - pix2[5]]; + s += sq[pix1[6] - pix2[6]]; + s += sq[pix1[7] - pix2[7]]; + pix1 += 8; + pix2 += 8; + } + pix1 += line_size - 16; + pix2 += line_size - 16; + } + return s; +} + static void get_pixels_c(DCTELEM *restrict block, const UINT8 *pixels, int line_size) { int i; @@ -1404,6 +1429,7 @@ c->clear_blocks = clear_blocks_c; c->pix_sum = pix_sum_c; c->pix_norm1 = pix_norm1_c; + c->pix_norm = pix_norm_c; /* TODO [0] 16 [1] 8 */ c->pix_abs16x16 = pix_abs16x16_c;
--- a/dsputil.h Fri Nov 22 07:27:13 2002 +0000 +++ b/dsputil.h Fri Nov 22 07:53:06 2002 +0000 @@ -98,6 +98,7 @@ void (*clear_blocks)(DCTELEM *blocks/*align 16*/); int (*pix_sum)(UINT8 * pix, int line_size); int (*pix_norm1)(UINT8 * pix, int line_size); + int (*pix_norm)(UINT8 * pix1, UINT8 * pix2, int line_size); /* maybe create an array for 16/8 functions */ op_pixels_func put_pixels_tab[2][4];
--- a/motion_est.c Fri Nov 22 07:27:13 2002 +0000 +++ b/motion_est.c Fri Nov 22 07:53:06 2002 +0000 @@ -63,31 +63,6 @@ return s; } -static int pix_norm(UINT8 * pix1, UINT8 * pix2, int line_size) -{ - int s, i, j; - UINT32 *sq = squareTbl + 256; - - s = 0; - for (i = 0; i < 16; i++) { - for (j = 0; j < 16; j += 8) { - s += sq[pix1[0] - pix2[0]]; - s += sq[pix1[1] - pix2[1]]; - s += sq[pix1[2] - pix2[2]]; - s += sq[pix1[3] - pix2[3]]; - s += sq[pix1[4] - pix2[4]]; - s += sq[pix1[5] - pix2[5]]; - s += sq[pix1[6] - pix2[6]]; - s += sq[pix1[7] - pix2[7]]; - pix1 += 8; - pix2 += 8; - } - pix1 += line_size - 16; - pix2 += line_size - 16; - } - return s; -} - static inline void no_motion_search(MpegEncContext * s, int *mx_ptr, int *my_ptr) { @@ -1137,7 +1112,7 @@ varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500 + 128)>>8; // FIXME: MMX OPTIMIZE - vard = (pix_norm(pix, ppix, s->linesize)+128)>>8; + vard = (s->dsp.pix_norm(pix, ppix, s->linesize)+128)>>8; //printf("%d %d %d %X %X %X\n", s->mb_width, mb_x, mb_y,(int)s, (int)s->mb_var, (int)s->mc_mb_var); fflush(stdout); s->mb_var [s->mb_width * mb_y + mb_x] = varc;
--- a/ppc/dsputil_altivec.c Fri Nov 22 07:27:13 2002 +0000 +++ b/ppc/dsputil_altivec.c Fri Nov 22 07:53:06 2002 +0000 @@ -137,13 +137,11 @@ 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, two, shift_mask; + vector unsigned short avghv, avglv, two; vector unsigned short t1, t2, t3, t4; vector unsigned int sad; vector signed int sumdiffs; - shift_mask = (vector unsigned short) (0x3fff, 0x3fff, 0x3fff, 0x3fff, - 0x3fff, 0x3fff, 0x3fff, 0x3fff); zero = vec_splat_u8(0); two = vec_splat_u16(2); sad = vec_splat_u32(0); @@ -205,11 +203,8 @@ t3 = vec_add(pix3hv, pix3ihv); t4 = vec_add(pix3lv, pix3ilv); - avghv = vec_add(vec_add(t1, t3), two); - avghv= vec_and(vec_srl(avghv, two), shift_mask); - - avglv = vec_add(vec_add(t2, t4), two); - avglv = vec_and(vec_srl(avglv, two), shift_mask); + 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); @@ -323,17 +318,10 @@ int s, i; vector unsigned char *tv, zero; vector unsigned char pixv; - vector unsigned short pixlv, pixhv, zeros; vector unsigned int sv; vector signed int sum; - vector unsigned char perm_stoint_h = (vector unsigned char) - (16, 16, 0, 1, 16, 16, 2, 3, 16, 16, 4, 5, 16, 16, 6, 7); - - vector unsigned char perm_stoint_l = (vector unsigned char) - (16, 16, 8, 9, 16, 16, 10, 11, 16, 16, 12, 13, 16, 16, 14, 15); zero = vec_splat_u8(0); - zeros = vec_splat_u16(0); sv = vec_splat_u32(0); s = 0; @@ -342,14 +330,8 @@ tv = (vector unsigned char *) pix; pixv = vec_perm(tv[0], tv[1], vec_lvsl(0, pix)); - /* Split them into two vectors of shorts */ - pixhv = (vector unsigned short) vec_mergeh(zero, pixv); - pixlv = (vector unsigned short) vec_mergel(zero, pixv); - - - /* Square the values and add them to our sum */ - sv = vec_msum(pixhv, pixhv, sv); - sv = vec_msum(pixlv, pixlv, sv); + /* Square the values, and add them to our sum */ + sv = vec_msum(pixv, pixv, sv); pix += line_size; } @@ -361,6 +343,48 @@ return s; } + +int pix_norm_altivec(uint8_t *pix1, uint8_t *pix2, int line_size) +{ + int s, i; + vector unsigned char *tv, zero; + vector unsigned char pix1v, pix2v, t5; + vector unsigned int sv; + vector signed int sum; + + zero = vec_splat_u8(0); + sv = vec_splat_u32(0); + s = 0; + for (i = 0; i < 16; i++) { + /* Read in the potentially unaligned pixels */ + tv = (vector unsigned char *) pix1; + pix1v = vec_perm(tv[0], tv[1], vec_lvsl(0, pix1)); + + tv = (vector unsigned char *) pix2; + pix2v = vec_perm(tv[0], tv[1], vec_lvsl(0, pix2)); + + /* + Since we want to use unsigned chars, we can take advantage + of the fact that abs(a-b)^2 = (a-b)^2. + */ + + /* Calculate a sum of abs differences vector */ + t5 = vec_sub(vec_max(pix1v, pix2v), vec_min(pix1v, pix2v)); + + /* Square the values and add them to our sum */ + sv = vec_msum(t5, t5, sv); + + pix1 += line_size; + pix2 += 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; +} + + int pix_sum_altivec(UINT8 * pix, int line_size) {
--- a/ppc/dsputil_altivec.h Fri Nov 22 07:27:13 2002 +0000 +++ b/ppc/dsputil_altivec.h Fri Nov 22 07:53:06 2002 +0000 @@ -23,6 +23,7 @@ extern int pix_abs16x16_altivec(uint8_t *pix1, uint8_t *pix2, int line_size); extern int pix_abs8x8_altivec(uint8_t *pix1, uint8_t *pix2, int line_size); extern int pix_norm1_altivec(uint8_t *pix, int line_size); +extern int pix_norm_altivec(uint8_t *pix1, uint8_t *pix2, int line_size); extern int pix_sum_altivec(UINT8 * pix, int line_size); extern void diff_pixels_altivec(DCTELEM* block, const UINT8* s1, const UINT8* s2, int stride); extern void get_pixels_altivec(DCTELEM* block, const UINT8 * pixels, int line_size);
--- a/ppc/dsputil_ppc.c Fri Nov 22 07:27:13 2002 +0000 +++ b/ppc/dsputil_ppc.c Fri Nov 22 07:53:06 2002 +0000 @@ -34,10 +34,11 @@ // 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_abs16x16_xy2 = pix_abs16x16_xy2_altivec; + c->pix_abs16x16 = pix_abs16x16_altivec; c->pix_abs8x8 = pix_abs8x8_altivec; c->pix_norm1 = pix_norm1_altivec; + c->pix_norm = pix_norm_altivec; c->pix_sum = pix_sum_altivec; c->diff_pixels = diff_pixels_altivec; c->get_pixels = get_pixels_altivec;