Commit 6e6e1708 authored by Michael Niedermayer's avatar Michael Niedermayer

Merge commit '42d32469'

* commit '42d32469':
  floatdsp: move vector_fmul_reverse from dsputil to avfloatdsp.

Conflicts:
	libavcodec/arm/dsputil_init_vfp.c
	libavcodec/arm/dsputil_vfp.S
	libavcodec/dsputil.c
	libavcodec/ppc/float_altivec.c
	libavcodec/x86/dsputil.asm
	libavutil/x86/float_dsp.asm
Merged-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parents b1b870fb 42d32469
...@@ -2131,9 +2131,9 @@ static void windowing_and_mdct_ltp(AACContext *ac, float *out, ...@@ -2131,9 +2131,9 @@ static void windowing_and_mdct_ltp(AACContext *ac, float *out,
ac->fdsp.vector_fmul(in + 448, in + 448, swindow_prev, 128); ac->fdsp.vector_fmul(in + 448, in + 448, swindow_prev, 128);
} }
if (ics->window_sequence[0] != LONG_START_SEQUENCE) { if (ics->window_sequence[0] != LONG_START_SEQUENCE) {
ac->dsp.vector_fmul_reverse(in + 1024, in + 1024, lwindow, 1024); ac->fdsp.vector_fmul_reverse(in + 1024, in + 1024, lwindow, 1024);
} else { } else {
ac->dsp.vector_fmul_reverse(in + 1024 + 448, in + 1024 + 448, swindow, 128); ac->fdsp.vector_fmul_reverse(in + 1024 + 448, in + 1024 + 448, swindow, 128);
memset(in + 1024 + 576, 0, 448 * sizeof(float)); memset(in + 1024 + 576, 0, 448 * sizeof(float));
} }
ac->mdct_ltp.mdct_calc(&ac->mdct_ltp, out, in); ac->mdct_ltp.mdct_calc(&ac->mdct_ltp, out, in);
...@@ -2186,17 +2186,17 @@ static void update_ltp(AACContext *ac, SingleChannelElement *sce) ...@@ -2186,17 +2186,17 @@ static void update_ltp(AACContext *ac, SingleChannelElement *sce)
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
memcpy(saved_ltp, saved, 512 * sizeof(float)); memcpy(saved_ltp, saved, 512 * sizeof(float));
memset(saved_ltp + 576, 0, 448 * sizeof(float)); memset(saved_ltp + 576, 0, 448 * sizeof(float));
ac->dsp.vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64); ac->fdsp.vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64);
for (i = 0; i < 64; i++) for (i = 0; i < 64; i++)
saved_ltp[i + 512] = ac->buf_mdct[1023 - i] * swindow[63 - i]; saved_ltp[i + 512] = ac->buf_mdct[1023 - i] * swindow[63 - i];
} else if (ics->window_sequence[0] == LONG_START_SEQUENCE) { } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
memcpy(saved_ltp, ac->buf_mdct + 512, 448 * sizeof(float)); memcpy(saved_ltp, ac->buf_mdct + 512, 448 * sizeof(float));
memset(saved_ltp + 576, 0, 448 * sizeof(float)); memset(saved_ltp + 576, 0, 448 * sizeof(float));
ac->dsp.vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64); ac->fdsp.vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64);
for (i = 0; i < 64; i++) for (i = 0; i < 64; i++)
saved_ltp[i + 512] = ac->buf_mdct[1023 - i] * swindow[63 - i]; saved_ltp[i + 512] = ac->buf_mdct[1023 - i] * swindow[63 - i];
} else { // LONG_STOP or ONLY_LONG } else { // LONG_STOP or ONLY_LONG
ac->dsp.vector_fmul_reverse(saved_ltp, ac->buf_mdct + 512, &lwindow[512], 512); ac->fdsp.vector_fmul_reverse(saved_ltp, ac->buf_mdct + 512, &lwindow[512], 512);
for (i = 0; i < 512; i++) for (i = 0; i < 512; i++)
saved_ltp[i + 512] = ac->buf_mdct[1023 - i] * lwindow[511 - i]; saved_ltp[i + 512] = ac->buf_mdct[1023 - i] * lwindow[511 - i];
} }
......
...@@ -183,7 +183,7 @@ static void put_audio_specific_config(AVCodecContext *avctx) ...@@ -183,7 +183,7 @@ static void put_audio_specific_config(AVCodecContext *avctx)
} }
#define WINDOW_FUNC(type) \ #define WINDOW_FUNC(type) \
static void apply_ ##type ##_window(DSPContext *dsp, AVFloatDSPContext *fdsp, \ static void apply_ ##type ##_window(AVFloatDSPContext *fdsp, \
SingleChannelElement *sce, \ SingleChannelElement *sce, \
const float *audio) const float *audio)
...@@ -193,8 +193,8 @@ WINDOW_FUNC(only_long) ...@@ -193,8 +193,8 @@ WINDOW_FUNC(only_long)
const float *pwindow = sce->ics.use_kb_window[1] ? ff_aac_kbd_long_1024 : ff_sine_1024; const float *pwindow = sce->ics.use_kb_window[1] ? ff_aac_kbd_long_1024 : ff_sine_1024;
float *out = sce->ret_buf; float *out = sce->ret_buf;
fdsp->vector_fmul (out, audio, lwindow, 1024); fdsp->vector_fmul (out, audio, lwindow, 1024);
dsp->vector_fmul_reverse(out + 1024, audio + 1024, pwindow, 1024); fdsp->vector_fmul_reverse(out + 1024, audio + 1024, pwindow, 1024);
} }
WINDOW_FUNC(long_start) WINDOW_FUNC(long_start)
...@@ -205,7 +205,7 @@ WINDOW_FUNC(long_start) ...@@ -205,7 +205,7 @@ WINDOW_FUNC(long_start)
fdsp->vector_fmul(out, audio, lwindow, 1024); fdsp->vector_fmul(out, audio, lwindow, 1024);
memcpy(out + 1024, audio + 1024, sizeof(out[0]) * 448); memcpy(out + 1024, audio + 1024, sizeof(out[0]) * 448);
dsp->vector_fmul_reverse(out + 1024 + 448, audio + 1024 + 448, swindow, 128); fdsp->vector_fmul_reverse(out + 1024 + 448, audio + 1024 + 448, swindow, 128);
memset(out + 1024 + 576, 0, sizeof(out[0]) * 448); memset(out + 1024 + 576, 0, sizeof(out[0]) * 448);
} }
...@@ -218,7 +218,7 @@ WINDOW_FUNC(long_stop) ...@@ -218,7 +218,7 @@ WINDOW_FUNC(long_stop)
memset(out, 0, sizeof(out[0]) * 448); memset(out, 0, sizeof(out[0]) * 448);
fdsp->vector_fmul(out + 448, audio + 448, swindow, 128); fdsp->vector_fmul(out + 448, audio + 448, swindow, 128);
memcpy(out + 576, audio + 576, sizeof(out[0]) * 448); memcpy(out + 576, audio + 576, sizeof(out[0]) * 448);
dsp->vector_fmul_reverse(out + 1024, audio + 1024, lwindow, 1024); fdsp->vector_fmul_reverse(out + 1024, audio + 1024, lwindow, 1024);
} }
WINDOW_FUNC(eight_short) WINDOW_FUNC(eight_short)
...@@ -230,15 +230,15 @@ WINDOW_FUNC(eight_short) ...@@ -230,15 +230,15 @@ WINDOW_FUNC(eight_short)
int w; int w;
for (w = 0; w < 8; w++) { for (w = 0; w < 8; w++) {
fdsp->vector_fmul (out, in, w ? pwindow : swindow, 128); fdsp->vector_fmul (out, in, w ? pwindow : swindow, 128);
out += 128; out += 128;
in += 128; in += 128;
dsp->vector_fmul_reverse(out, in, swindow, 128); fdsp->vector_fmul_reverse(out, in, swindow, 128);
out += 128; out += 128;
} }
} }
static void (*const apply_window[4])(DSPContext *dsp, AVFloatDSPContext *fdsp, static void (*const apply_window[4])(AVFloatDSPContext *fdsp,
SingleChannelElement *sce, SingleChannelElement *sce,
const float *audio) = { const float *audio) = {
[ONLY_LONG_SEQUENCE] = apply_only_long_window, [ONLY_LONG_SEQUENCE] = apply_only_long_window,
...@@ -253,7 +253,7 @@ static void apply_window_and_mdct(AACEncContext *s, SingleChannelElement *sce, ...@@ -253,7 +253,7 @@ static void apply_window_and_mdct(AACEncContext *s, SingleChannelElement *sce,
int i; int i;
float *output = sce->ret_buf; float *output = sce->ret_buf;
apply_window[sce->ics.window_sequence[0]](&s->dsp, &s->fdsp, sce, audio); apply_window[sce->ics.window_sequence[0]](&s->fdsp, sce, audio);
if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE)
s->mdct1024.mdct_calc(&s->mdct1024, sce->coeffs, output); s->mdct1024.mdct_calc(&s->mdct1024, sce->coeffs, output);
...@@ -692,7 +692,6 @@ static av_cold int dsp_init(AVCodecContext *avctx, AACEncContext *s) ...@@ -692,7 +692,6 @@ static av_cold int dsp_init(AVCodecContext *avctx, AACEncContext *s)
{ {
int ret = 0; int ret = 0;
ff_dsputil_init(&s->dsp, avctx);
avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT); avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
// window init // window init
......
...@@ -61,7 +61,6 @@ typedef struct AACEncContext { ...@@ -61,7 +61,6 @@ typedef struct AACEncContext {
PutBitContext pb; PutBitContext pb;
FFTContext mdct1024; ///< long (1024 samples) frame transform context FFTContext mdct1024; ///< long (1024 samples) frame transform context
FFTContext mdct128; ///< short (128 samples) frame transform context FFTContext mdct128; ///< short (128 samples) frame transform context
DSPContext dsp;
AVFloatDSPContext fdsp; AVFloatDSPContext fdsp;
float *planar_samples[6]; ///< saved preprocessed input float *planar_samples[6]; ///< saved preprocessed input
......
...@@ -1156,7 +1156,7 @@ static void sbr_dequant(SpectralBandReplication *sbr, int id_aac) ...@@ -1156,7 +1156,7 @@ static void sbr_dequant(SpectralBandReplication *sbr, int id_aac)
* @param x pointer to the beginning of the first sample window * @param x pointer to the beginning of the first sample window
* @param W array of complex-valued samples split into subbands * @param W array of complex-valued samples split into subbands
*/ */
static void sbr_qmf_analysis(DSPContext *dsp, FFTContext *mdct, static void sbr_qmf_analysis(AVFloatDSPContext *dsp, FFTContext *mdct,
SBRDSPContext *sbrdsp, const float *in, float *x, SBRDSPContext *sbrdsp, const float *in, float *x,
float z[320], float W[2][32][32][2], int buf_idx) float z[320], float W[2][32][32][2], int buf_idx)
{ {
...@@ -1668,7 +1668,7 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac, ...@@ -1668,7 +1668,7 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac,
} }
for (ch = 0; ch < nch; ch++) { for (ch = 0; ch < nch; ch++) {
/* decode channel */ /* decode channel */
sbr_qmf_analysis(&ac->dsp, &sbr->mdct_ana, &sbr->dsp, ch ? R : L, sbr->data[ch].analysis_filterbank_samples, sbr_qmf_analysis(&ac->fdsp, &sbr->mdct_ana, &sbr->dsp, ch ? R : L, sbr->data[ch].analysis_filterbank_samples,
(float*)sbr->qmf_filter_scratch, (float*)sbr->qmf_filter_scratch,
sbr->data[ch].W, sbr->data[ch].Ypos); sbr->data[ch].W, sbr->data[ch].Ypos);
sbr_lf_gen(ac, sbr, sbr->X_low, sbr->data[ch].W, sbr->data[ch].Ypos); sbr_lf_gen(ac, sbr, sbr->X_low, sbr->data[ch].W, sbr->data[ch].Ypos);
......
...@@ -56,9 +56,6 @@ ARMV6-OBJS += arm/dsputil_init_armv6.o \ ...@@ -56,9 +56,6 @@ ARMV6-OBJS += arm/dsputil_init_armv6.o \
VFP-OBJS-$(HAVE_ARMV6) += arm/fmtconvert_vfp.o VFP-OBJS-$(HAVE_ARMV6) += arm/fmtconvert_vfp.o
VFP-OBJS += arm/dsputil_vfp.o \
arm/dsputil_init_vfp.o \
NEON-OBJS-$(CONFIG_FFT) += arm/fft_neon.o \ NEON-OBJS-$(CONFIG_FFT) += arm/fft_neon.o \
arm/fft_fixed_neon.o \ arm/fft_fixed_neon.o \
......
...@@ -121,6 +121,5 @@ void ff_dsputil_init_arm(DSPContext* c, AVCodecContext *avctx) ...@@ -121,6 +121,5 @@ void ff_dsputil_init_arm(DSPContext* c, AVCodecContext *avctx)
if (have_armv5te(cpu_flags)) ff_dsputil_init_armv5te(c, avctx); if (have_armv5te(cpu_flags)) ff_dsputil_init_armv5te(c, avctx);
if (have_armv6(cpu_flags)) ff_dsputil_init_armv6(c, avctx); if (have_armv6(cpu_flags)) ff_dsputil_init_armv6(c, avctx);
if (have_vfp(cpu_flags)) ff_dsputil_init_vfp(c, avctx);
if (have_neon(cpu_flags)) ff_dsputil_init_neon(c, avctx); if (have_neon(cpu_flags)) ff_dsputil_init_neon(c, avctx);
} }
...@@ -144,8 +144,6 @@ void ff_avg_h264_chroma_mc2_neon(uint8_t *, uint8_t *, int, int, int, int); ...@@ -144,8 +144,6 @@ void ff_avg_h264_chroma_mc2_neon(uint8_t *, uint8_t *, int, int, int, int);
void ff_butterflies_float_neon(float *v1, float *v2, int len); void ff_butterflies_float_neon(float *v1, float *v2, int len);
float ff_scalarproduct_float_neon(const float *v1, const float *v2, int len); float ff_scalarproduct_float_neon(const float *v1, const float *v2, int len);
void ff_vector_fmul_reverse_neon(float *dst, const float *src0,
const float *src1, int len);
void ff_vector_clipf_neon(float *dst, const float *src, float min, float max, void ff_vector_clipf_neon(float *dst, const float *src, float min, float max,
int len); int len);
...@@ -298,7 +296,6 @@ void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx) ...@@ -298,7 +296,6 @@ void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx)
c->butterflies_float = ff_butterflies_float_neon; c->butterflies_float = ff_butterflies_float_neon;
c->scalarproduct_float = ff_scalarproduct_float_neon; c->scalarproduct_float = ff_scalarproduct_float_neon;
c->vector_fmul_reverse = ff_vector_fmul_reverse_neon;
c->vector_clipf = ff_vector_clipf_neon; c->vector_clipf = ff_vector_clipf_neon;
c->vector_clip_int32 = ff_vector_clip_int32_neon; c->vector_clip_int32 = ff_vector_clip_int32_neon;
......
/*
* Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavcodec/dsputil.h"
#include "dsputil_arm.h"
void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
const float *src1, int len);
void ff_dsputil_init_vfp(DSPContext* c, AVCodecContext *avctx)
{
c->vector_fmul_reverse = ff_vector_fmul_reverse_vfp;
}
...@@ -556,30 +556,6 @@ NOVFP vmov.32 r0, d0[0] ...@@ -556,30 +556,6 @@ NOVFP vmov.32 r0, d0[0]
bx lr bx lr
endfunc endfunc
function ff_vector_fmul_reverse_neon, export=1
add r2, r2, r3, lsl #2
sub r2, r2, #32
mov r12, #-32
vld1.32 {q0-q1}, [r1,:128]!
vld1.32 {q2-q3}, [r2,:128], r12
1: pld [r1, #32]
vrev64.32 q3, q3
vmul.f32 d16, d0, d7
vmul.f32 d17, d1, d6
pld [r2, #-32]
vrev64.32 q2, q2
vmul.f32 d18, d2, d5
vmul.f32 d19, d3, d4
subs r3, r3, #8
beq 2f
vld1.32 {q0-q1}, [r1,:128]!
vld1.32 {q2-q3}, [r2,:128], r12
vst1.32 {q8-q9}, [r0,:128]!
b 1b
2: vst1.32 {q8-q9}, [r0,:128]!
bx lr
endfunc
function ff_vector_clipf_neon, export=1 function ff_vector_clipf_neon, export=1
VFP vdup.32 q1, d0[1] VFP vdup.32 q1, d0[1]
VFP vdup.32 q0, d0[0] VFP vdup.32 q0, d0[0]
......
/*
* Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include "libavutil/arm/asm.S"
/*
* VFP is a floating point coprocessor used in some ARM cores. VFP11 has 1 cycle
* throughput for almost all the instructions (except for double precision
* arithmetics), but rather high latency. Latency is 4 cycles for loads and 8 cycles
* for arithmetic operations. Scheduling code to avoid pipeline stalls is very
* important for performance. One more interesting feature is that VFP has
* independent load/store and arithmetics pipelines, so it is possible to make
* them work simultaneously and get more than 1 operation per cycle. Load/store
* pipeline can process 2 single precision floating point values per cycle and
* supports bulk loads and stores for large sets of registers. Arithmetic operations
* can be done on vectors, which allows to keep the arithmetics pipeline busy,
* while the processor may issue and execute other instructions. Detailed
* optimization manuals can be found at http://www.arm.com
*/
/**
* ARM VFP optimized implementation of 'vector_fmul_reverse_c' function.
* Assume that len is a positive number and is multiple of 8
*/
@ void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
@ const float *src1, int len)
function ff_vector_fmul_reverse_vfp, export=1
vpush {d8-d15}
add r2, r2, r3, lsl #2
vldmdb r2!, {s0-s3}
vldmia r1!, {s8-s11}
vldmdb r2!, {s4-s7}
vldmia r1!, {s12-s15}
vmul.f32 s8, s3, s8
vmul.f32 s9, s2, s9
vmul.f32 s10, s1, s10
vmul.f32 s11, s0, s11
1:
subs r3, r3, #16
it ge
vldmdbge r2!, {s16-s19}
vmul.f32 s12, s7, s12
it ge
vldmiage r1!, {s24-s27}
vmul.f32 s13, s6, s13
it ge
vldmdbge r2!, {s20-s23}
vmul.f32 s14, s5, s14
it ge
vldmiage r1!, {s28-s31}
vmul.f32 s15, s4, s15
it ge
vmulge.f32 s24, s19, s24
it gt
vldmdbgt r2!, {s0-s3}
it ge
vmulge.f32 s25, s18, s25
vstmia r0!, {s8-s13}
it ge
vmulge.f32 s26, s17, s26
it gt
vldmiagt r1!, {s8-s11}
itt ge
vmulge.f32 s27, s16, s27
vmulge.f32 s28, s23, s28
it gt
vldmdbgt r2!, {s4-s7}
it ge
vmulge.f32 s29, s22, s29
vstmia r0!, {s14-s15}
ittt ge
vmulge.f32 s30, s21, s30
vmulge.f32 s31, s20, s31
vmulge.f32 s8, s3, s8
it gt
vldmiagt r1!, {s12-s15}
itttt ge
vmulge.f32 s9, s2, s9
vmulge.f32 s10, s1, s10
vstmiage r0!, {s24-s27}
vmulge.f32 s11, s0, s11
it ge
vstmiage r0!, {s28-s31}
bgt 1b
vpop {d8-d15}
bx lr
endfunc
...@@ -2483,13 +2483,6 @@ WRAPPER8_16_SQ(quant_psnr8x8_c, quant_psnr16_c) ...@@ -2483,13 +2483,6 @@ WRAPPER8_16_SQ(quant_psnr8x8_c, quant_psnr16_c)
WRAPPER8_16_SQ(rd8x8_c, rd16_c) WRAPPER8_16_SQ(rd8x8_c, rd16_c)
WRAPPER8_16_SQ(bit8x8_c, bit16_c) WRAPPER8_16_SQ(bit8x8_c, bit16_c)
static void vector_fmul_reverse_c(float *dst, const float *src0, const float *src1, int len){
int i;
src1 += len-1;
for(i=0; i<len; i++)
dst[i] = src0[i] * src1[-i];
}
static void butterflies_float_c(float *av_restrict v1, float *av_restrict v2, static void butterflies_float_c(float *av_restrict v1, float *av_restrict v2,
int len) int len)
{ {
...@@ -2888,7 +2881,6 @@ av_cold void ff_dsputil_init(DSPContext* c, AVCodecContext *avctx) ...@@ -2888,7 +2881,6 @@ av_cold void ff_dsputil_init(DSPContext* c, AVCodecContext *avctx)
c->try_8x8basis= try_8x8basis_c; c->try_8x8basis= try_8x8basis_c;
c->add_8x8basis= add_8x8basis_c; c->add_8x8basis= add_8x8basis_c;
c->vector_fmul_reverse = vector_fmul_reverse_c;
c->vector_clipf = vector_clipf_c; c->vector_clipf = vector_clipf_c;
c->scalarproduct_int16 = scalarproduct_int16_c; c->scalarproduct_int16 = scalarproduct_int16_c;
c->scalarproduct_and_madd_int16 = scalarproduct_and_madd_int16_c; c->scalarproduct_and_madd_int16 = scalarproduct_and_madd_int16_c;
......
...@@ -358,8 +358,6 @@ typedef struct DSPContext { ...@@ -358,8 +358,6 @@ typedef struct DSPContext {
void (*h261_loop_filter)(uint8_t *src, int stride); void (*h261_loop_filter)(uint8_t *src, int stride);
/* assume len is a multiple of 16, and arrays are 32-byte aligned */
void (*vector_fmul_reverse)(float *dst, const float *src0, const float *src1, int len);
/* assume len is a multiple of 8, and arrays are 16-byte aligned */ /* assume len is a multiple of 8, and arrays are 16-byte aligned */
void (*vector_clipf)(float *dst /* align 16 */, const float *src /* align 16 */, float min, float max, int len /* align 16 */); void (*vector_clipf)(float *dst /* align 16 */, const float *src /* align 16 */, float min, float max, int len /* align 16 */);
/** /**
......
...@@ -55,7 +55,6 @@ ...@@ -55,7 +55,6 @@
typedef struct NellyMoserEncodeContext { typedef struct NellyMoserEncodeContext {
AVCodecContext *avctx; AVCodecContext *avctx;
int last_frame; int last_frame;
DSPContext dsp;
AVFloatDSPContext fdsp; AVFloatDSPContext fdsp;
FFTContext mdct_ctx; FFTContext mdct_ctx;
AudioFrameQueue afq; AudioFrameQueue afq;
...@@ -122,12 +121,12 @@ static void apply_mdct(NellyMoserEncodeContext *s) ...@@ -122,12 +121,12 @@ static void apply_mdct(NellyMoserEncodeContext *s)
float *in1 = s->buf + NELLY_BUF_LEN; float *in1 = s->buf + NELLY_BUF_LEN;
float *in2 = s->buf + 2 * NELLY_BUF_LEN; float *in2 = s->buf + 2 * NELLY_BUF_LEN;
s->fdsp.vector_fmul (s->in_buff, in0, ff_sine_128, NELLY_BUF_LEN); s->fdsp.vector_fmul (s->in_buff, in0, ff_sine_128, NELLY_BUF_LEN);
s->dsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in1, ff_sine_128, NELLY_BUF_LEN); s->fdsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in1, ff_sine_128, NELLY_BUF_LEN);
s->mdct_ctx.mdct_calc(&s->mdct_ctx, s->mdct_out, s->in_buff); s->mdct_ctx.mdct_calc(&s->mdct_ctx, s->mdct_out, s->in_buff);
s->fdsp.vector_fmul (s->in_buff, in1, ff_sine_128, NELLY_BUF_LEN); s->fdsp.vector_fmul (s->in_buff, in1, ff_sine_128, NELLY_BUF_LEN);
s->dsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in2, ff_sine_128, NELLY_BUF_LEN); s->fdsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in2, ff_sine_128, NELLY_BUF_LEN);
s->mdct_ctx.mdct_calc(&s->mdct_ctx, s->mdct_out + NELLY_BUF_LEN, s->in_buff); s->mdct_ctx.mdct_calc(&s->mdct_ctx, s->mdct_out + NELLY_BUF_LEN, s->in_buff);
} }
...@@ -173,7 +172,6 @@ static av_cold int encode_init(AVCodecContext *avctx) ...@@ -173,7 +172,6 @@ static av_cold int encode_init(AVCodecContext *avctx)
s->avctx = avctx; s->avctx = avctx;
if ((ret = ff_mdct_init(&s->mdct_ctx, 8, 0, 32768.0)) < 0) if ((ret = ff_mdct_init(&s->mdct_ctx, 8, 0, 32768.0)) < 0)
goto error; goto error;
ff_dsputil_init(&s->dsp, avctx);
avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT); avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
/* Generate overlap window */ /* Generate overlap window */
......
...@@ -15,7 +15,6 @@ ALTIVEC-OBJS-$(CONFIG_VP8_DECODER) += ppc/vp8dsp_altivec.o ...@@ -15,7 +15,6 @@ ALTIVEC-OBJS-$(CONFIG_VP8_DECODER) += ppc/vp8dsp_altivec.o
ALTIVEC-OBJS += ppc/dsputil_altivec.o \ ALTIVEC-OBJS += ppc/dsputil_altivec.o \
ppc/fdct_altivec.o \ ppc/fdct_altivec.o \
ppc/float_altivec.o \
ppc/fmtconvert_altivec.o \ ppc/fmtconvert_altivec.o \
ppc/gmc_altivec.o \ ppc/gmc_altivec.o \
ppc/idct_altivec.o \ ppc/idct_altivec.o \
......
...@@ -168,7 +168,6 @@ void ff_dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx) ...@@ -168,7 +168,6 @@ void ff_dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx)
if (mm_flags & AV_CPU_FLAG_ALTIVEC) { if (mm_flags & AV_CPU_FLAG_ALTIVEC) {
ff_dsputil_init_altivec(c, avctx); ff_dsputil_init_altivec(c, avctx);
ff_float_init_altivec(c, avctx);
ff_int_init_altivec(c, avctx); ff_int_init_altivec(c, avctx);
c->gmc1 = ff_gmc1_altivec; c->gmc1 = ff_gmc1_altivec;
......
/*
* Copyright (c) 2006 Luca Barbato <lu_zero@gentoo.org>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/ppc/util_altivec.h"
#include "libavcodec/dsputil.h"
#include "dsputil_altivec.h"
static void vector_fmul_reverse_altivec(float *dst, const float *src0,
const float *src1, int len)
{
int i;
vector float d, s0, s1, h0, l0,
s2, s3, zero = (vector float)vec_splat_u32(0);
src1 += len-4;
for(i=0; i<len-7; i+=8) {
s1 = vec_ld(0, src1-i); // [a,b,c,d]
s0 = vec_ld(0, src0+i);
l0 = vec_mergel(s1, s1); // [c,c,d,d]
s3 = vec_ld(-16, src1-i);
h0 = vec_mergeh(s1, s1); // [a,a,b,b]
s2 = vec_ld(16, src0+i);
s1 = vec_mergeh(vec_mergel(l0,h0), // [d,b,d,b]
vec_mergeh(l0,h0)); // [c,a,c,a]
// [d,c,b,a]
l0 = vec_mergel(s3, s3);
d = vec_madd(s0, s1, zero);
h0 = vec_mergeh(s3, s3);
vec_st(d, 0, dst+i);
s3 = vec_mergeh(vec_mergel(l0,h0),
vec_mergeh(l0,h0));
d = vec_madd(s2, s3, zero);
vec_st(d, 16, dst+i);
}
}
void ff_float_init_altivec(DSPContext* c, AVCodecContext *avctx)
{
c->vector_fmul_reverse = vector_fmul_reverse_altivec;
}
...@@ -408,7 +408,7 @@ static void wma_window(WMACodecContext *s, float *out) ...@@ -408,7 +408,7 @@ static void wma_window(WMACodecContext *s, float *out)
block_len = s->block_len; block_len = s->block_len;
bsize = s->frame_len_bits - s->block_len_bits; bsize = s->frame_len_bits - s->block_len_bits;
s->dsp.vector_fmul_reverse(out, in, s->windows[bsize], block_len); s->fdsp.vector_fmul_reverse(out, in, s->windows[bsize], block_len);
} else { } else {
block_len = 1 << s->next_block_len_bits; block_len = 1 << s->next_block_len_bits;
...@@ -417,7 +417,7 @@ static void wma_window(WMACodecContext *s, float *out) ...@@ -417,7 +417,7 @@ static void wma_window(WMACodecContext *s, float *out)
memcpy(out, in, n*sizeof(float)); memcpy(out, in, n*sizeof(float));
s->dsp.vector_fmul_reverse(out+n, in+n, s->windows[bsize], block_len); s->fdsp.vector_fmul_reverse(out+n, in+n, s->windows[bsize], block_len);
memset(out+n+block_len, 0, n*sizeof(float)); memset(out+n+block_len, 0, n*sizeof(float));
} }
......
...@@ -109,7 +109,7 @@ static void apply_window_and_mdct(AVCodecContext * avctx, const AVFrame *frame) ...@@ -109,7 +109,7 @@ static void apply_window_and_mdct(AVCodecContext * avctx, const AVFrame *frame)
for (ch = 0; ch < avctx->channels; ch++) { for (ch = 0; ch < avctx->channels; ch++) {
memcpy(s->output, s->frame_out[ch], window_len * sizeof(*s->output)); memcpy(s->output, s->frame_out[ch], window_len * sizeof(*s->output));
s->fdsp.vector_fmul_scalar(s->frame_out[ch], audio[ch], n, len); s->fdsp.vector_fmul_scalar(s->frame_out[ch], audio[ch], n, len);
s->dsp.vector_fmul_reverse(&s->output[window_len], s->frame_out[ch], win, len); s->fdsp.vector_fmul_reverse(&s->output[window_len], s->frame_out[ch], win, len);
s->fdsp.vector_fmul(s->frame_out[ch], s->frame_out[ch], win, len); s->fdsp.vector_fmul(s->frame_out[ch], s->frame_out[ch], win, len);
mdct->mdct_calc(mdct, s->coefs[ch], s->output); mdct->mdct_calc(mdct, s->coefs[ch], s->output);
} }
......
...@@ -170,7 +170,6 @@ typedef struct WMAProDecodeCtx { ...@@ -170,7 +170,6 @@ typedef struct WMAProDecodeCtx {
/* generic decoder variables */ /* generic decoder variables */
AVCodecContext* avctx; ///< codec context for av_log AVCodecContext* avctx; ///< codec context for av_log
AVFrame frame; ///< AVFrame for decoded output AVFrame frame; ///< AVFrame for decoded output
DSPContext dsp; ///< accelerated DSP functions
AVFloatDSPContext fdsp; AVFloatDSPContext fdsp;
uint8_t frame_data[MAX_FRAMESIZE + uint8_t frame_data[MAX_FRAMESIZE +
FF_INPUT_BUFFER_PADDING_SIZE];///< compressed frame data FF_INPUT_BUFFER_PADDING_SIZE];///< compressed frame data
...@@ -281,7 +280,6 @@ static av_cold int decode_init(AVCodecContext *avctx) ...@@ -281,7 +280,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
int num_possible_block_sizes; int num_possible_block_sizes;
s->avctx = avctx; s->avctx = avctx;
ff_dsputil_init(&s->dsp, avctx);
avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT); avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE); init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE);
......
...@@ -567,45 +567,6 @@ VECTOR_CLIP_INT32 11, 1, 1, 0 ...@@ -567,45 +567,6 @@ VECTOR_CLIP_INT32 11, 1, 1, 0
VECTOR_CLIP_INT32 6, 1, 0, 0 VECTOR_CLIP_INT32 6, 1, 0, 0
%endif %endif
;-----------------------------------------------------------------------------
; void vector_fmul_reverse(float *dst, const float *src0, const float *src1,
; int len)
;-----------------------------------------------------------------------------
%macro VECTOR_FMUL_REVERSE 0
cglobal vector_fmul_reverse, 4,4,2, dst, src0, src1, len
lea lenq, [lend*4 - 2*mmsize]
ALIGN 16
.loop:
%if cpuflag(avx)
vmovaps xmm0, [src1q + 16]
vinsertf128 m0, m0, [src1q], 1
vshufps m0, m0, m0, q0123
vmovaps xmm1, [src1q + mmsize + 16]
vinsertf128 m1, m1, [src1q + mmsize], 1
vshufps m1, m1, m1, q0123
%else
mova m0, [src1q]
mova m1, [src1q + mmsize]
shufps m0, m0, q0123
shufps m1, m1, q0123
%endif
mulps m0, m0, [src0q + lenq + mmsize]
mulps m1, m1, [src0q + lenq]
mova [dstq + lenq + mmsize], m0
mova [dstq + lenq], m1
add src1q, 2*mmsize
sub lenq, 2*mmsize
jge .loop
REP_RET
%endmacro
INIT_XMM sse
VECTOR_FMUL_REVERSE
%if HAVE_AVX_EXTERNAL
INIT_YMM avx
VECTOR_FMUL_REVERSE
%endif
; %1 = aligned/unaligned ; %1 = aligned/unaligned
%macro BSWAP_LOOPS 1 %macro BSWAP_LOOPS 1
mov r3, r2 mov r3, r2
......
...@@ -1989,11 +1989,6 @@ int ff_add_hfyu_left_prediction_sse4(uint8_t *dst, const uint8_t *src, ...@@ -1989,11 +1989,6 @@ int ff_add_hfyu_left_prediction_sse4(uint8_t *dst, const uint8_t *src,
float ff_scalarproduct_float_sse(const float *v1, const float *v2, int order); float ff_scalarproduct_float_sse(const float *v1, const float *v2, int order);
void ff_vector_fmul_reverse_sse(float *dst, const float *src0,
const float *src1, int len);
void ff_vector_fmul_reverse_avx(float *dst, const float *src0,
const float *src1, int len);
void ff_vector_clip_int32_mmx (int32_t *dst, const int32_t *src, void ff_vector_clip_int32_mmx (int32_t *dst, const int32_t *src,
int32_t min, int32_t max, unsigned int len); int32_t min, int32_t max, unsigned int len);
void ff_vector_clip_int32_sse2 (int32_t *dst, const int32_t *src, void ff_vector_clip_int32_sse2 (int32_t *dst, const int32_t *src,
...@@ -2257,8 +2252,6 @@ static void dsputil_init_sse(DSPContext *c, AVCodecContext *avctx, int mm_flags) ...@@ -2257,8 +2252,6 @@ static void dsputil_init_sse(DSPContext *c, AVCodecContext *avctx, int mm_flags)
#endif /* HAVE_INLINE_ASM */ #endif /* HAVE_INLINE_ASM */
#if HAVE_YASM #if HAVE_YASM
c->vector_fmul_reverse = ff_vector_fmul_reverse_sse;
c->scalarproduct_float = ff_scalarproduct_float_sse; c->scalarproduct_float = ff_scalarproduct_float_sse;
#if HAVE_INLINE_ASM && CONFIG_VIDEODSP #if HAVE_INLINE_ASM && CONFIG_VIDEODSP
...@@ -2414,7 +2407,6 @@ static void dsputil_init_avx(DSPContext *c, AVCodecContext *avctx, int mm_flags) ...@@ -2414,7 +2407,6 @@ static void dsputil_init_avx(DSPContext *c, AVCodecContext *avctx, int mm_flags)
c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_10_avx; c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_10_avx;
} }
} }
c->vector_fmul_reverse = ff_vector_fmul_reverse_avx;
#endif /* HAVE_AVX_EXTERNAL */ #endif /* HAVE_AVX_EXTERNAL */
} }
......
...@@ -38,6 +38,9 @@ void ff_vector_fmul_window_neon(float *dst, const float *src0, ...@@ -38,6 +38,9 @@ void ff_vector_fmul_window_neon(float *dst, const float *src0,
void ff_vector_fmul_add_neon(float *dst, const float *src0, const float *src1, void ff_vector_fmul_add_neon(float *dst, const float *src0, const float *src1,
const float *src2, int len); const float *src2, int len);
void ff_vector_fmul_reverse_neon(float *dst, const float *src0,
const float *src1, int len);
void ff_float_dsp_init_neon(AVFloatDSPContext *fdsp) void ff_float_dsp_init_neon(AVFloatDSPContext *fdsp)
{ {
fdsp->vector_fmul = ff_vector_fmul_neon; fdsp->vector_fmul = ff_vector_fmul_neon;
...@@ -45,4 +48,5 @@ void ff_float_dsp_init_neon(AVFloatDSPContext *fdsp) ...@@ -45,4 +48,5 @@ void ff_float_dsp_init_neon(AVFloatDSPContext *fdsp)
fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_neon; fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_neon;
fdsp->vector_fmul_window = ff_vector_fmul_window_neon; fdsp->vector_fmul_window = ff_vector_fmul_window_neon;
fdsp->vector_fmul_add = ff_vector_fmul_add_neon; fdsp->vector_fmul_add = ff_vector_fmul_add_neon;
fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_neon;
} }
...@@ -25,10 +25,14 @@ ...@@ -25,10 +25,14 @@
void ff_vector_fmul_vfp(float *dst, const float *src0, const float *src1, void ff_vector_fmul_vfp(float *dst, const float *src0, const float *src1,
int len); int len);
void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
const float *src1, int len);
void ff_float_dsp_init_vfp(AVFloatDSPContext *fdsp) void ff_float_dsp_init_vfp(AVFloatDSPContext *fdsp)
{ {
int cpu_flags = av_get_cpu_flags(); int cpu_flags = av_get_cpu_flags();
if (!have_vfpv3(cpu_flags)) if (!have_vfpv3(cpu_flags))
fdsp->vector_fmul = ff_vector_fmul_vfp; fdsp->vector_fmul = ff_vector_fmul_vfp;
fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_vfp;
} }
...@@ -220,3 +220,27 @@ function ff_vector_fmul_add_neon, export=1 ...@@ -220,3 +220,27 @@ function ff_vector_fmul_add_neon, export=1
2: vst1.32 {q12-q13},[r0,:128]! 2: vst1.32 {q12-q13},[r0,:128]!
bx lr bx lr
endfunc endfunc
function ff_vector_fmul_reverse_neon, export=1
add r2, r2, r3, lsl #2
sub r2, r2, #32
mov r12, #-32
vld1.32 {q0-q1}, [r1,:128]!
vld1.32 {q2-q3}, [r2,:128], r12
1: pld [r1, #32]
vrev64.32 q3, q3
vmul.f32 d16, d0, d7
vmul.f32 d17, d1, d6
pld [r2, #-32]
vrev64.32 q2, q2
vmul.f32 d18, d2, d5
vmul.f32 d19, d3, d4
subs r3, r3, #8
beq 2f
vld1.32 {q0-q1}, [r1,:128]!
vld1.32 {q2-q3}, [r2,:128], r12
vst1.32 {q8-q9}, [r0,:128]!
b 1b
2: vst1.32 {q8-q9}, [r0,:128]!
bx lr
endfunc
...@@ -66,3 +66,72 @@ function ff_vector_fmul_vfp, export=1 ...@@ -66,3 +66,72 @@ function ff_vector_fmul_vfp, export=1
vpop {d8-d15} vpop {d8-d15}
bx lr bx lr
endfunc endfunc
/**
* ARM VFP optimized implementation of 'vector_fmul_reverse_c' function.
* Assume that len is a positive number and is multiple of 8
*/
@ void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
@ const float *src1, int len)
function ff_vector_fmul_reverse_vfp, export=1
vpush {d8-d15}
add r2, r2, r3, lsl #2
vldmdb r2!, {s0-s3}
vldmia r1!, {s8-s11}
vldmdb r2!, {s4-s7}
vldmia r1!, {s12-s15}
vmul.f32 s8, s3, s8
vmul.f32 s9, s2, s9
vmul.f32 s10, s1, s10
vmul.f32 s11, s0, s11
1:
subs r3, r3, #16
it ge
vldmdbge r2!, {s16-s19}
vmul.f32 s12, s7, s12
it ge
vldmiage r1!, {s24-s27}
vmul.f32 s13, s6, s13
it ge
vldmdbge r2!, {s20-s23}
vmul.f32 s14, s5, s14
it ge
vldmiage r1!, {s28-s31}
vmul.f32 s15, s4, s15
it ge
vmulge.f32 s24, s19, s24
it gt
vldmdbgt r2!, {s0-s3}
it ge
vmulge.f32 s25, s18, s25
vstmia r0!, {s8-s13}
it ge
vmulge.f32 s26, s17, s26
it gt
vldmiagt r1!, {s8-s11}
itt ge
vmulge.f32 s27, s16, s27
vmulge.f32 s28, s23, s28
it gt
vldmdbgt r2!, {s4-s7}
it ge
vmulge.f32 s29, s22, s29
vstmia r0!, {s14-s15}
ittt ge
vmulge.f32 s30, s21, s30
vmulge.f32 s31, s20, s31
vmulge.f32 s8, s3, s8
it gt
vldmiagt r1!, {s12-s15}
itttt ge
vmulge.f32 s9, s2, s9
vmulge.f32 s10, s1, s10
vstmiage r0!, {s24-s27}
vmulge.f32 s11, s0, s11
it ge
vstmiage r0!, {s28-s31}
bgt 1b
vpop {d8-d15}
bx lr
endfunc
...@@ -82,6 +82,16 @@ static void vector_fmul_add_c(float *dst, const float *src0, const float *src1, ...@@ -82,6 +82,16 @@ static void vector_fmul_add_c(float *dst, const float *src0, const float *src1,
dst[i] = src0[i] * src1[i] + src2[i]; dst[i] = src0[i] * src1[i] + src2[i];
} }
static void vector_fmul_reverse_c(float *dst, const float *src0,
const float *src1, int len)
{
int i;
src1 += len-1;
for (i = 0; i < len; i++)
dst[i] = src0[i] * src1[-i];
}
void avpriv_float_dsp_init(AVFloatDSPContext *fdsp, int bit_exact) void avpriv_float_dsp_init(AVFloatDSPContext *fdsp, int bit_exact)
{ {
fdsp->vector_fmul = vector_fmul_c; fdsp->vector_fmul = vector_fmul_c;
...@@ -90,6 +100,7 @@ void avpriv_float_dsp_init(AVFloatDSPContext *fdsp, int bit_exact) ...@@ -90,6 +100,7 @@ void avpriv_float_dsp_init(AVFloatDSPContext *fdsp, int bit_exact)
fdsp->vector_dmul_scalar = vector_dmul_scalar_c; fdsp->vector_dmul_scalar = vector_dmul_scalar_c;
fdsp->vector_fmul_window = vector_fmul_window_c; fdsp->vector_fmul_window = vector_fmul_window_c;
fdsp->vector_fmul_add = vector_fmul_add_c; fdsp->vector_fmul_add = vector_fmul_add_c;
fdsp->vector_fmul_reverse = vector_fmul_reverse_c;
#if ARCH_ARM #if ARCH_ARM
ff_float_dsp_init_arm(fdsp); ff_float_dsp_init_arm(fdsp);
......
...@@ -118,6 +118,25 @@ typedef struct AVFloatDSPContext { ...@@ -118,6 +118,25 @@ typedef struct AVFloatDSPContext {
*/ */
void (*vector_fmul_add)(float *dst, const float *src0, const float *src1, void (*vector_fmul_add)(float *dst, const float *src0, const float *src1,
const float *src2, int len); const float *src2, int len);
/**
* Calculate the product of two vectors of floats, and store the result
* in a vector of floats. The second vector of floats is iterated over
* in reverse order.
*
* @param dst output vector
* constraints: 32-byte aligned
* @param src0 first input vector
* constraints: 32-byte aligned
* @param src1 second input vector
* constraints: 32-byte aligned
* @param src1 third input vector
* constraints: 32-byte aligned
* @param len number of elements in the input
* constraints: multiple of 16
*/
void (*vector_fmul_reverse)(float *dst, const float *src0,
const float *src1, int len);
} AVFloatDSPContext; } AVFloatDSPContext;
/** /**
......
...@@ -93,3 +93,32 @@ void ff_vector_fmul_add_altivec(float *dst, const float *src0, ...@@ -93,3 +93,32 @@ void ff_vector_fmul_add_altivec(float *dst, const float *src0,
vec_st(t0, 0, dst + i); vec_st(t0, 0, dst + i);
} }
} }
void ff_vector_fmul_reverse_altivec(float *dst, const float *src0,
const float *src1, int len)
{
int i;
vector float d, s0, s1, h0, l0,
s2, s3, zero = (vector float) vec_splat_u32(0);
src1 += len-4;
for(i = 0; i < len - 7; i += 8) {
s1 = vec_ld(0, src1 - i); // [a,b,c,d]
s0 = vec_ld(0, src0 + i);
l0 = vec_mergel(s1, s1); // [c,c,d,d]
s3 = vec_ld(-16, src1 - i);
h0 = vec_mergeh(s1, s1); // [a,a,b,b]
s2 = vec_ld(16, src0 + i);
s1 = vec_mergeh(vec_mergel(l0, h0), // [d,b,d,b]
vec_mergeh(l0, h0)); // [c,a,c,a]
// [d,c,b,a]
l0 = vec_mergel(s3, s3);
d = vec_madd(s0, s1, zero);
h0 = vec_mergeh(s3, s3);
vec_st(d, 0, dst + i);
s3 = vec_mergeh(vec_mergel(l0, h0),
vec_mergeh(l0, h0));
d = vec_madd(s2, s3, zero);
vec_st(d, 16, dst + i);
}
}
...@@ -32,4 +32,7 @@ extern void ff_vector_fmul_add_altivec(float *dst, const float *src0, ...@@ -32,4 +32,7 @@ extern void ff_vector_fmul_add_altivec(float *dst, const float *src0,
const float *src1, const float *src2, const float *src1, const float *src2,
int len); int len);
extern void ff_vector_fmul_reverse_altivec(float *dst, const float *src0,
const float *src1, int len);
#endif /* AVUTIL_PPC_FLOAT_DSP_ALTIVEC_H */ #endif /* AVUTIL_PPC_FLOAT_DSP_ALTIVEC_H */
...@@ -33,6 +33,7 @@ void ff_float_dsp_init_ppc(AVFloatDSPContext *fdsp, int bit_exact) ...@@ -33,6 +33,7 @@ void ff_float_dsp_init_ppc(AVFloatDSPContext *fdsp, int bit_exact)
fdsp->vector_fmul = ff_vector_fmul_altivec; fdsp->vector_fmul = ff_vector_fmul_altivec;
fdsp->vector_fmul_add = ff_vector_fmul_add_altivec; fdsp->vector_fmul_add = ff_vector_fmul_add_altivec;
fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_altivec;
if (!bit_exact) { if (!bit_exact) {
fdsp->vector_fmul_window = ff_vector_fmul_window_altivec; fdsp->vector_fmul_window = ff_vector_fmul_window_altivec;
......
...@@ -198,3 +198,42 @@ VECTOR_FMUL_ADD ...@@ -198,3 +198,42 @@ VECTOR_FMUL_ADD
INIT_YMM avx INIT_YMM avx
VECTOR_FMUL_ADD VECTOR_FMUL_ADD
%endif %endif
;-----------------------------------------------------------------------------
; void vector_fmul_reverse(float *dst, const float *src0, const float *src1,
; int len)
;-----------------------------------------------------------------------------
%macro VECTOR_FMUL_REVERSE 0
cglobal vector_fmul_reverse, 4,4,2, dst, src0, src1, len
lea lenq, [lend*4 - 2*mmsize]
ALIGN 16
.loop:
%if cpuflag(avx)
vmovaps xmm0, [src1q + 16]
vinsertf128 m0, m0, [src1q], 1
vshufps m0, m0, m0, q0123
vmovaps xmm1, [src1q + mmsize + 16]
vinsertf128 m1, m1, [src1q + mmsize], 1
vshufps m1, m1, m1, q0123
%else
mova m0, [src1q]
mova m1, [src1q + mmsize]
shufps m0, m0, q0123
shufps m1, m1, q0123
%endif
mulps m0, m0, [src0q + lenq + mmsize]
mulps m1, m1, [src0q + lenq]
mova [dstq + lenq + mmsize], m0
mova [dstq + lenq], m1
add src1q, 2*mmsize
sub lenq, 2*mmsize
jge .loop
REP_RET
%endmacro
INIT_XMM sse
VECTOR_FMUL_REVERSE
%if HAVE_AVX_EXTERNAL
INIT_YMM avx
VECTOR_FMUL_REVERSE
%endif
\ No newline at end of file
...@@ -46,6 +46,11 @@ void ff_vector_fmul_add_sse(float *dst, const float *src0, const float *src1, ...@@ -46,6 +46,11 @@ void ff_vector_fmul_add_sse(float *dst, const float *src0, const float *src1,
void ff_vector_fmul_add_avx(float *dst, const float *src0, const float *src1, void ff_vector_fmul_add_avx(float *dst, const float *src0, const float *src1,
const float *src2, int len); const float *src2, int len);
void ff_vector_fmul_reverse_sse(float *dst, const float *src0,
const float *src1, int len);
void ff_vector_fmul_reverse_avx(float *dst, const float *src0,
const float *src1, int len);
#if HAVE_6REGS && HAVE_INLINE_ASM #if HAVE_6REGS && HAVE_INLINE_ASM
static void vector_fmul_window_3dnowext(float *dst, const float *src0, static void vector_fmul_window_3dnowext(float *dst, const float *src0,
const float *src1, const float *win, const float *src1, const float *win,
...@@ -129,6 +134,7 @@ void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp) ...@@ -129,6 +134,7 @@ void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp)
fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_sse; fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_sse;
fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_sse; fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_sse;
fdsp->vector_fmul_add = ff_vector_fmul_add_sse; fdsp->vector_fmul_add = ff_vector_fmul_add_sse;
fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_sse;
} }
if (EXTERNAL_SSE2(mm_flags)) { if (EXTERNAL_SSE2(mm_flags)) {
fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_sse2; fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_sse2;
...@@ -138,5 +144,6 @@ void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp) ...@@ -138,5 +144,6 @@ void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp)
fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_avx; fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_avx;
fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_avx; fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_avx;
fdsp->vector_fmul_add = ff_vector_fmul_add_avx; fdsp->vector_fmul_add = ff_vector_fmul_add_avx;
fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_avx;
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment