diff options
author | Brian Foley <bfoley@compsoc.nuigalway.ie> | 2002-11-22 07:53:06 +0000 |
---|---|---|
committer | Zdenek Kabelac <kabi@informatics.muni.cz> | 2002-11-22 07:53:06 +0000 |
commit | 9c76bd48aa318eaf74a3d9c4cac3d8a9ada3fe04 (patch) | |
tree | f0dfc2c1261b7122aa10861605c05a5f55a884cb /libavcodec | |
parent | 3aca208a7b5084a6202e44a82baeaac0026f3dce (diff) | |
download | ffmpeg-streaming-9c76bd48aa318eaf74a3d9c4cac3d8a9ada3fe04.zip ffmpeg-streaming-9c76bd48aa318eaf74a3d9c4cac3d8a9ada3fe04.tar.gz |
* altivec and pix_norm patch by Brian Foley
Originally committed as revision 1269 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/dsputil.c | 26 | ||||
-rw-r--r-- | libavcodec/dsputil.h | 1 | ||||
-rw-r--r-- | libavcodec/motion_est.c | 27 | ||||
-rw-r--r-- | libavcodec/ppc/dsputil_altivec.c | 70 | ||||
-rw-r--r-- | libavcodec/ppc/dsputil_altivec.h | 1 | ||||
-rw-r--r-- | libavcodec/ppc/dsputil_ppc.c | 5 |
6 files changed, 79 insertions, 51 deletions
diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c index a8e060b..9039d26 100644 --- a/libavcodec/dsputil.c +++ b/libavcodec/dsputil.c @@ -144,6 +144,31 @@ static int pix_norm1_c(UINT8 * pix, int line_size) } +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 @@ void dsputil_init(DSPContext* c, unsigned mask) 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; diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h index 4f036b0..0b1d34f 100644 --- a/libavcodec/dsputil.h +++ b/libavcodec/dsputil.h @@ -98,6 +98,7 @@ typedef struct DSPContext { 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]; diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c index 95e67f6..b1a3c61 100644 --- a/libavcodec/motion_est.c +++ b/libavcodec/motion_est.c @@ -63,31 +63,6 @@ static int pix_dev(UINT8 * pix, int line_size, int mean) 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 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, 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; diff --git a/libavcodec/ppc/dsputil_altivec.c b/libavcodec/ppc/dsputil_altivec.c index 1e877d5..ed34a2d 100644 --- a/libavcodec/ppc/dsputil_altivec.c +++ b/libavcodec/ppc/dsputil_altivec.c @@ -137,13 +137,11 @@ int pix_abs16x16_xy2_altivec(uint8_t *pix1, uint8_t *pix2, int line_size) 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 @@ int pix_abs16x16_xy2_altivec(uint8_t *pix1, uint8_t *pix2, int line_size) 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 pix_norm1_altivec(uint8_t *pix, int line_size) 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 @@ int pix_norm1_altivec(uint8_t *pix, int line_size) 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 @@ int pix_norm1_altivec(uint8_t *pix, int line_size) 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) { diff --git a/libavcodec/ppc/dsputil_altivec.h b/libavcodec/ppc/dsputil_altivec.h index d4d259d..94fe3a0 100644 --- a/libavcodec/ppc/dsputil_altivec.h +++ b/libavcodec/ppc/dsputil_altivec.h @@ -23,6 +23,7 @@ extern int pix_abs16x16_xy2_altivec(uint8_t *pix1, uint8_t *pix2, int line_size) 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); diff --git a/libavcodec/ppc/dsputil_ppc.c b/libavcodec/ppc/dsputil_ppc.c index a515cf3..c4dae6c 100644 --- a/libavcodec/ppc/dsputil_ppc.c +++ b/libavcodec/ppc/dsputil_ppc.c @@ -34,10 +34,11 @@ void dsputil_init_ppc(DSPContext* c, unsigned mask) // 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; |