aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuca Barbato <lu_zero@gentoo.org>2008-08-23 21:09:46 +0000
committerLuca Barbato <lu_zero@gentoo.org>2008-08-23 21:09:46 +0000
commite1f27dc22b5b441553e84d3ed0c8aa504591c278 (patch)
tree0ed13ca7ef389ea02569bd33826650204dcb5868
parent8d3d51005a81d45914c548f0c3c7810b7bef5457 (diff)
downloadffmpeg-e1f27dc22b5b441553e84d3ed0c8aa504591c278.tar.gz
Introduce float_to_int16_interleave_altivec, tested with vorbis
Originally committed as revision 14928 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavcodec/ppc/float_altivec.c55
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;
+ }
}