diff options
author | Luca Barbato <lu_zero@gentoo.org> | 2008-08-23 21:09:46 +0000 |
---|---|---|
committer | Luca Barbato <lu_zero@gentoo.org> | 2008-08-23 21:09:46 +0000 |
commit | e1f27dc22b5b441553e84d3ed0c8aa504591c278 (patch) | |
tree | 0ed13ca7ef389ea02569bd33826650204dcb5868 /libavcodec/ppc/float_altivec.c | |
parent | 8d3d51005a81d45914c548f0c3c7810b7bef5457 (diff) | |
download | ffmpeg-e1f27dc22b5b441553e84d3ed0c8aa504591c278.tar.gz |
Introduce float_to_int16_interleave_altivec, tested with vorbis
Originally committed as revision 14928 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/ppc/float_altivec.c')
-rw-r--r-- | libavcodec/ppc/float_altivec.c | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/libavcodec/ppc/float_altivec.c b/libavcodec/ppc/float_altivec.c index 298172554d..600ce2774e 100644 --- a/libavcodec/ppc/float_altivec.c +++ b/libavcodec/ppc/float_altivec.c @@ -186,11 +186,64 @@ void float_to_int16_altivec(int16_t *dst, const float *src, int len) } } +static void +float_to_int16_interleave_altivec(int16_t *dst, const float **src, + long len, int channels) +{ + int i; + vector signed short d0, d1, d2, c0, c1, t0, t1; + vector unsigned char align; + if(channels == 1) + float_to_int16_altivec(dst, src[0], len); + else + if (channels == 2) { + if(((long)dst)&15) + for(i=0; i<len-7; i+=8) { + d0 = vec_ld(0, dst + i); + t0 = float_to_int16_one_altivec(src[0] + i); + d1 = vec_ld(31, dst + i); + t1 = float_to_int16_one_altivec(src[1] + i); + c0 = vec_mergeh(t0, t1); + c1 = vec_mergel(t0, t1); + d2 = vec_perm(d1, d0, vec_lvsl(0, dst + i)); + align = vec_lvsr(0, dst + i); + d0 = vec_perm(d2, c0, align); + d1 = vec_perm(c0, c1, align); + vec_st(d0, 0, dst + i); + d0 = vec_perm(c1, d2, align); + vec_st(d1, 15, dst + i); + vec_st(d0, 31, dst + i); + dst+=8; + } + else + for(i=0; i<len-7; i+=8) { + t0 = float_to_int16_one_altivec(src[0] + i); + t1 = float_to_int16_one_altivec(src[1] + i); + d0 = vec_mergeh(t0, t1); + d1 = vec_mergel(t0, t1); + vec_st(d0, 0, dst + i); + vec_st(d1, 16, dst + i); + dst+=8; + } + } else { + DECLARE_ALIGNED(16, int16_t, tmp[len]); + int c, j; + for (c = 0; c < channels; c++) { + float_to_int16_altivec(tmp, src[c], len); + for (i = 0, j = c; i < len; i++, j+=channels) { + dst[j] = tmp[i]; + } + } + } +} + void float_init_altivec(DSPContext* c, AVCodecContext *avctx) { c->vector_fmul = vector_fmul_altivec; c->vector_fmul_reverse = vector_fmul_reverse_altivec; c->vector_fmul_add_add = vector_fmul_add_add_altivec; - if(!(avctx->flags & CODEC_FLAG_BITEXACT)) + if(!(avctx->flags & CODEC_FLAG_BITEXACT)) { c->float_to_int16 = float_to_int16_altivec; + c->float_to_int16_interleave = float_to_int16_interleave_altivec; + } } |