* commit '42d324694883cdf1fff1612ac70fa403692a1ad4': 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: Michael Niedermayer <michaelni@gmx.at>tags/n1.2
| @@ -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) | |||||
| 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) | |||||
| } | } | ||||
| #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) | |||||
| 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); | |||||
| dsp->vector_fmul_reverse(out + 1024, audio + 1024, pwindow, 1024); | |||||
| fdsp->vector_fmul (out, audio, lwindow, 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) | |||||
| 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) | |||||
| 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) | |||||
| 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, | |||||
| 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) | |||||
| { | { | ||||
| 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 { | |||||
| 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) | |||||
| * @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, | |||||
| } | } | ||||
| 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 \ | |||||
| 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) | |||||
| 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); | |||||
| 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) | |||||
| 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; | ||||
| @@ -1,30 +0,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 "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] | |||||
| 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] | ||||
| @@ -1,106 +0,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) | |||||
| 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) | |||||
| 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 { | |||||
| 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 @@ | |||||
| 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) | |||||
| 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->dsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in1, ff_sine_128, NELLY_BUF_LEN); | |||||
| s->fdsp.vector_fmul (s->in_buff, in0, 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->dsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in2, ff_sine_128, NELLY_BUF_LEN); | |||||
| s->fdsp.vector_fmul (s->in_buff, in1, 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) | |||||
| 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 | |||||
| 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) | |||||
| 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; | ||||
| @@ -1,57 +0,0 @@ | |||||
| /* | |||||
| * 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) | |||||
| 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) | |||||
| 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) | |||||
| 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 { | |||||
| /* 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) | |||||
| 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 | |||||
| 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, | |||||
| 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) | |||||
| #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) | |||||
| 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, | |||||
| 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) | |||||
| 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 @@ | |||||
| 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 | |||||
| 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 | |||||
| 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, | |||||
| 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) | |||||
| 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 { | |||||
| */ | */ | ||||
| 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, | |||||
| 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, | |||||
| 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) | |||||
| 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 | |||||
| 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 | |||||
| @@ -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) | |||||
| 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) | |||||
| 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; | |||||
| } | } | ||||
| } | } | ||||