DSP bits of swri_resample go into their own mini-DSP functions; DSP init goes from a per-call branch in multiple_resample to a proper DSP init routine; x86 bits go into x86/; swri_resample() moves out of resample_template.c into resample.c because it's independent of DSP code or sample type; multiple_resample() is simplified. Signed-off-by: Michael Niedermayer <michaelni@gmx.at>tags/n2.3
| @@ -10,6 +10,7 @@ OBJS = audioconvert.o \ | |||
| dither.o \ | |||
| rematrix.o \ | |||
| resample.o \ | |||
| resample_dsp.o \ | |||
| swresample.o \ | |||
| OBJS-$(CONFIG_LIBSOXR) += soxr_resample.o | |||
| @@ -25,32 +25,8 @@ | |||
| * @author Michael Niedermayer <michaelni@gmx.at> | |||
| */ | |||
| #include "libavutil/log.h" | |||
| #include "libavutil/avassert.h" | |||
| #include "swresample_internal.h" | |||
| typedef struct ResampleContext { | |||
| const AVClass *av_class; | |||
| uint8_t *filter_bank; | |||
| int filter_length; | |||
| int filter_alloc; | |||
| int ideal_dst_incr; | |||
| int dst_incr; | |||
| int index; | |||
| int frac; | |||
| int src_incr; | |||
| int compensation_distance; | |||
| int phase_shift; | |||
| int phase_mask; | |||
| int linear; | |||
| enum SwrFilterType filter_type; | |||
| int kaiser_beta; | |||
| double factor; | |||
| enum AVSampleFormat format; | |||
| int felem_size; | |||
| int filter_shift; | |||
| } ResampleContext; | |||
| #include "resample.h" | |||
| /** | |||
| * 0th order modified bessel function of the first kind. | |||
| @@ -197,7 +173,8 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap | |||
| static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_rate, int filter_size, int phase_shift, int linear, | |||
| double cutoff0, enum AVSampleFormat format, enum SwrFilterType filter_type, int kaiser_beta, | |||
| double precision, int cheby){ | |||
| double precision, int cheby) | |||
| { | |||
| double cutoff = cutoff0? cutoff0 : 0.97; | |||
| double factor= FFMIN(out_rate * cutoff / in_rate, 1.0); | |||
| int phase_count= 1<<phase_shift; | |||
| @@ -259,6 +236,8 @@ static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_r | |||
| c->index= -phase_count*((c->filter_length-1)/2); | |||
| c->frac= 0; | |||
| swresample_dsp_init(c); | |||
| return c; | |||
| error: | |||
| av_freep(&c->filter_bank); | |||
| @@ -282,59 +261,53 @@ static int set_compensation(ResampleContext *c, int sample_delta, int compensati | |||
| return 0; | |||
| } | |||
| #define TEMPLATE_RESAMPLE_S16 | |||
| #include "resample_template.c" | |||
| #undef TEMPLATE_RESAMPLE_S16 | |||
| #define TEMPLATE_RESAMPLE_S32 | |||
| #include "resample_template.c" | |||
| #undef TEMPLATE_RESAMPLE_S32 | |||
| #define TEMPLATE_RESAMPLE_FLT | |||
| #include "resample_template.c" | |||
| #undef TEMPLATE_RESAMPLE_FLT | |||
| #define TEMPLATE_RESAMPLE_DBL | |||
| #include "resample_template.c" | |||
| #undef TEMPLATE_RESAMPLE_DBL | |||
| // XXX FIXME the whole C loop should be written in asm so this x86 specific code here isnt needed | |||
| #if HAVE_MMXEXT_INLINE | |||
| #include "x86/resample_mmx.h" | |||
| #define TEMPLATE_RESAMPLE_S16_MMX2 | |||
| #include "resample_template.c" | |||
| #undef TEMPLATE_RESAMPLE_S16_MMX2 | |||
| #if HAVE_SSE_INLINE | |||
| #define TEMPLATE_RESAMPLE_FLT_SSE | |||
| #include "resample_template.c" | |||
| #undef TEMPLATE_RESAMPLE_FLT_SSE | |||
| #endif | |||
| #if HAVE_SSE2_INLINE | |||
| #define TEMPLATE_RESAMPLE_S16_SSE2 | |||
| #include "resample_template.c" | |||
| #undef TEMPLATE_RESAMPLE_S16_SSE2 | |||
| #define TEMPLATE_RESAMPLE_DBL_SSE2 | |||
| #include "resample_template.c" | |||
| #undef TEMPLATE_RESAMPLE_DBL_SSE2 | |||
| #endif | |||
| #if HAVE_AVX_INLINE | |||
| #define TEMPLATE_RESAMPLE_FLT_AVX | |||
| #include "resample_template.c" | |||
| #undef TEMPLATE_RESAMPLE_FLT_AVX | |||
| #endif | |||
| static int swri_resample(ResampleContext *c, | |||
| uint8_t *dst, const uint8_t *src, int *consumed, | |||
| int src_size, int dst_size, int update_ctx) | |||
| { | |||
| int fn_idx = c->format - AV_SAMPLE_FMT_S16P; | |||
| if (c->filter_length == 1 && c->phase_shift == 0) { | |||
| int index= c->index; | |||
| int frac= c->frac; | |||
| int dst_incr_frac= c->dst_incr % c->src_incr; | |||
| int dst_incr= c->dst_incr / c->src_incr; | |||
| int64_t index2= (1LL<<32)*c->frac/c->src_incr + (1LL<<32)*index; | |||
| int64_t incr= (1LL<<32) * c->dst_incr / c->src_incr; | |||
| int new_size = (src_size * (int64_t)c->src_incr - frac + c->dst_incr - 1) / c->dst_incr; | |||
| dst_size= FFMIN(dst_size, new_size); | |||
| c->dsp.resample_one[fn_idx](dst, src, dst_size, index2, incr); | |||
| index += dst_size * dst_incr; | |||
| index += (frac + dst_size * (int64_t)dst_incr_frac) / c->src_incr; | |||
| av_assert2(index >= 0); | |||
| *consumed= index; | |||
| if (update_ctx) { | |||
| c->frac = (frac + dst_size * (int64_t)dst_incr_frac) % c->src_incr; | |||
| c->index = 0; | |||
| } | |||
| } else { | |||
| int64_t end_index = (1LL + src_size - c->filter_length) << c->phase_shift; | |||
| int64_t delta_frac = (end_index - c->index) * c->src_incr - c->frac; | |||
| int delta_n = (delta_frac + c->dst_incr - 1) / c->dst_incr; | |||
| dst_size = FFMIN(dst_size, delta_n); | |||
| if (!c->linear) { | |||
| *consumed = c->dsp.resample_common[fn_idx](c, dst, src, dst_size, update_ctx); | |||
| } else { | |||
| *consumed = c->dsp.resample_linear[fn_idx](c, dst, src, dst_size, update_ctx); | |||
| } | |||
| } | |||
| #endif // HAVE_MMXEXT_INLINE | |||
| return dst_size; | |||
| } | |||
| static int multiple_resample(ResampleContext *c, AudioData *dst, int dst_size, AudioData *src, int src_size, int *consumed){ | |||
| int i, ret= -1; | |||
| int av_unused mm_flags = av_get_cpu_flags(); | |||
| int need_emms= 0; | |||
| int need_emms = c->format == AV_SAMPLE_FMT_S16P && ARCH_X86_32 && | |||
| (mm_flags & (AV_CPU_FLAG_MMX2 | AV_CPU_FLAG_SSE2)) == AV_CPU_FLAG_MMX2; | |||
| int64_t max_src_size = (INT64_MAX >> (c->phase_shift+1)) / c->src_incr; | |||
| if (c->compensation_distance) | |||
| @@ -342,32 +315,8 @@ static int multiple_resample(ResampleContext *c, AudioData *dst, int dst_size, A | |||
| src_size = FFMIN(src_size, max_src_size); | |||
| for(i=0; i<dst->ch_count; i++){ | |||
| #if HAVE_MMXEXT_INLINE | |||
| #if HAVE_SSE2_INLINE | |||
| if(c->format == AV_SAMPLE_FMT_S16P && (mm_flags&AV_CPU_FLAG_SSE2)) ret= swri_resample_int16_sse2 (c, (int16_t*)dst->ch[i], (const int16_t*)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count); | |||
| else | |||
| #endif | |||
| if(c->format == AV_SAMPLE_FMT_S16P && (mm_flags&AV_CPU_FLAG_MMX2 )){ | |||
| ret= swri_resample_int16_mmx2 (c, (int16_t*)dst->ch[i], (const int16_t*)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count); | |||
| need_emms= 1; | |||
| } else | |||
| #endif | |||
| if(c->format == AV_SAMPLE_FMT_S16P) ret= swri_resample_int16(c, (int16_t*)dst->ch[i], (const int16_t*)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count); | |||
| else if(c->format == AV_SAMPLE_FMT_S32P) ret= swri_resample_int32(c, (int32_t*)dst->ch[i], (const int32_t*)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count); | |||
| #if HAVE_AVX_INLINE | |||
| else if(c->format == AV_SAMPLE_FMT_FLTP && (mm_flags&AV_CPU_FLAG_AVX)) | |||
| ret= swri_resample_float_avx (c, (float*)dst->ch[i], (const float*)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count); | |||
| #endif | |||
| #if HAVE_SSE_INLINE | |||
| else if(c->format == AV_SAMPLE_FMT_FLTP && (mm_flags&AV_CPU_FLAG_SSE)) | |||
| ret= swri_resample_float_sse (c, (float*)dst->ch[i], (const float*)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count); | |||
| #endif | |||
| else if(c->format == AV_SAMPLE_FMT_FLTP) ret= swri_resample_float(c, (float *)dst->ch[i], (const float *)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count); | |||
| #if HAVE_SSE2_INLINE | |||
| else if(c->format == AV_SAMPLE_FMT_DBLP && (mm_flags&AV_CPU_FLAG_SSE2)) | |||
| ret= swri_resample_double_sse2(c,(double *)dst->ch[i], (const double *)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count); | |||
| #endif | |||
| else if(c->format == AV_SAMPLE_FMT_DBLP) ret= swri_resample_double(c,(double *)dst->ch[i], (const double *)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count); | |||
| ret= swri_resample(c, dst->ch[i], src->ch[i], | |||
| consumed, src_size, dst_size, i+1==dst->ch_count); | |||
| } | |||
| if(need_emms) | |||
| emms_c(); | |||
| @@ -0,0 +1,66 @@ | |||
| /* | |||
| * audio resampling | |||
| * Copyright (c) 2004-2012 Michael Niedermayer <michaelni@gmx.at> | |||
| * | |||
| * 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 | |||
| */ | |||
| #ifndef SWRESAMPLE_RESAMPLE_H | |||
| #define SWRESAMPLE_RESAMPLE_H | |||
| #include "libavutil/log.h" | |||
| #include "libavutil/samplefmt.h" | |||
| #include "swresample_internal.h" | |||
| typedef void (*resample_one_fn)(uint8_t *dst, const uint8_t *src, | |||
| int n, int64_t index, int64_t incr); | |||
| typedef int (*resample_fn)(struct ResampleContext *c, uint8_t *dst, | |||
| const uint8_t *src, int n, int update_ctx); | |||
| typedef struct ResampleContext { | |||
| const AVClass *av_class; | |||
| uint8_t *filter_bank; | |||
| int filter_length; | |||
| int filter_alloc; | |||
| int ideal_dst_incr; | |||
| int dst_incr; | |||
| int index; | |||
| int frac; | |||
| int src_incr; | |||
| int compensation_distance; | |||
| int phase_shift; | |||
| int phase_mask; | |||
| int linear; | |||
| enum SwrFilterType filter_type; | |||
| int kaiser_beta; | |||
| double factor; | |||
| enum AVSampleFormat format; | |||
| int felem_size; | |||
| int filter_shift; | |||
| struct { | |||
| resample_one_fn resample_one[AV_SAMPLE_FMT_NB - AV_SAMPLE_FMT_S16P]; | |||
| resample_fn resample_common[AV_SAMPLE_FMT_NB - AV_SAMPLE_FMT_S16P]; | |||
| resample_fn resample_linear[AV_SAMPLE_FMT_NB - AV_SAMPLE_FMT_S16P]; | |||
| } dsp; | |||
| } ResampleContext; | |||
| void swresample_dsp_init(ResampleContext *c); | |||
| void swresample_dsp_x86_init(ResampleContext *c); | |||
| #endif /* SWRESAMPLE_RESAMPLE_H */ | |||
| @@ -0,0 +1,69 @@ | |||
| /* | |||
| * audio resampling | |||
| * Copyright (c) 2004-2012 Michael Niedermayer <michaelni@gmx.at> | |||
| * | |||
| * 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 | |||
| */ | |||
| /** | |||
| * @file | |||
| * audio resampling | |||
| * @author Michael Niedermayer <michaelni@gmx.at> | |||
| */ | |||
| #include "resample.h" | |||
| #define DO_RESAMPLE_ONE 1 | |||
| #define TEMPLATE_RESAMPLE_S16 | |||
| #include "resample_template.c" | |||
| #undef TEMPLATE_RESAMPLE_S16 | |||
| #define TEMPLATE_RESAMPLE_S32 | |||
| #include "resample_template.c" | |||
| #undef TEMPLATE_RESAMPLE_S32 | |||
| #define TEMPLATE_RESAMPLE_FLT | |||
| #include "resample_template.c" | |||
| #undef TEMPLATE_RESAMPLE_FLT | |||
| #define TEMPLATE_RESAMPLE_DBL | |||
| #include "resample_template.c" | |||
| #undef TEMPLATE_RESAMPLE_DBL | |||
| #undef DO_RESAMPLE_ONE | |||
| void swresample_dsp_init(ResampleContext *c) | |||
| { | |||
| #define FNIDX(fmt) (AV_SAMPLE_FMT_##fmt - AV_SAMPLE_FMT_S16P) | |||
| c->dsp.resample_one[FNIDX(S16P)] = (resample_one_fn) resample_one_int16; | |||
| c->dsp.resample_one[FNIDX(S32P)] = (resample_one_fn) resample_one_int32; | |||
| c->dsp.resample_one[FNIDX(FLTP)] = (resample_one_fn) resample_one_float; | |||
| c->dsp.resample_one[FNIDX(DBLP)] = (resample_one_fn) resample_one_double; | |||
| c->dsp.resample_common[FNIDX(S16P)] = (resample_fn) resample_common_int16; | |||
| c->dsp.resample_common[FNIDX(S32P)] = (resample_fn) resample_common_int32; | |||
| c->dsp.resample_common[FNIDX(FLTP)] = (resample_fn) resample_common_float; | |||
| c->dsp.resample_common[FNIDX(DBLP)] = (resample_fn) resample_common_double; | |||
| c->dsp.resample_linear[FNIDX(S16P)] = (resample_fn) resample_linear_int16; | |||
| c->dsp.resample_linear[FNIDX(S32P)] = (resample_fn) resample_linear_int32; | |||
| c->dsp.resample_linear[FNIDX(FLTP)] = (resample_fn) resample_linear_float; | |||
| c->dsp.resample_linear[FNIDX(DBLP)] = (resample_fn) resample_linear_double; | |||
| if (ARCH_X86) swresample_dsp_x86_init(c); | |||
| } | |||
| @@ -106,45 +106,30 @@ | |||
| #endif | |||
| int RENAME(swri_resample)(ResampleContext *c, DELEM *dst, const DELEM *src, int *consumed, int src_size, int dst_size, int update_ctx){ | |||
| #if DO_RESAMPLE_ONE | |||
| static void RENAME(resample_one)(DELEM *dst, const DELEM *src, | |||
| int dst_size, int64_t index2, int64_t incr) | |||
| { | |||
| int dst_index; | |||
| #if !defined(COMMON_CORE) || !defined(LINEAR_CORE) | |||
| int i; | |||
| for (dst_index = 0; dst_index < dst_size; dst_index++) { | |||
| dst[dst_index] = src[index2 >> 32]; | |||
| index2 += incr; | |||
| } | |||
| } | |||
| #endif | |||
| int index= c->index; | |||
| int frac= c->frac; | |||
| int dst_incr_frac= c->dst_incr % c->src_incr; | |||
| int dst_incr= c->dst_incr / c->src_incr; | |||
| av_assert1(c->filter_shift == FILTER_SHIFT); | |||
| av_assert1(c->felem_size == sizeof(FELEM)); | |||
| if (c->filter_length == 1 && c->phase_shift == 0) { | |||
| int64_t index2= (1LL<<32)*c->frac/c->src_incr + (1LL<<32)*index; | |||
| int64_t incr= (1LL<<32) * c->dst_incr / c->src_incr; | |||
| int new_size = (src_size * (int64_t)c->src_incr - frac + c->dst_incr - 1) / c->dst_incr; | |||
| dst_size= FFMIN(dst_size, new_size); | |||
| for(dst_index=0; dst_index < dst_size; dst_index++){ | |||
| dst[dst_index] = src[index2>>32]; | |||
| index2 += incr; | |||
| } | |||
| index += dst_index * dst_incr; | |||
| index += (frac + dst_index * (int64_t)dst_incr_frac) / c->src_incr; | |||
| frac = (frac + dst_index * (int64_t)dst_incr_frac) % c->src_incr; | |||
| av_assert2(index >= 0); | |||
| *consumed= index; | |||
| index = 0; | |||
| } else { | |||
| int64_t end_index = (1LL + src_size - c->filter_length) << c->phase_shift; | |||
| int64_t delta_frac = (end_index - index) * c->src_incr - c->frac; | |||
| int delta_n = (delta_frac + c->dst_incr - 1) / c->dst_incr; | |||
| int n = FFMIN(dst_size, delta_n); | |||
| int sample_index; | |||
| if (!c->linear) { | |||
| sample_index = index >> c->phase_shift; | |||
| static int RENAME(resample_common)(ResampleContext *c, | |||
| DELEM *dst, const DELEM *src, | |||
| int n, int update_ctx) | |||
| { | |||
| int dst_index; | |||
| int index= c->index; | |||
| int frac= c->frac; | |||
| int dst_incr_frac= c->dst_incr % c->src_incr; | |||
| int dst_incr= c->dst_incr / c->src_incr; | |||
| int sample_index = index >> c->phase_shift; | |||
| index &= c->phase_mask; | |||
| for (dst_index = 0; dst_index < n; dst_index++) { | |||
| FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index; | |||
| @@ -153,6 +138,7 @@ int RENAME(swri_resample)(ResampleContext *c, DELEM *dst, const DELEM *src, int | |||
| COMMON_CORE | |||
| #else | |||
| FELEM2 val=0; | |||
| int i; | |||
| for (i = 0; i < c->filter_length; i++) { | |||
| val += src[sample_index + i] * (FELEM2)filter[i]; | |||
| } | |||
| @@ -168,8 +154,26 @@ int RENAME(swri_resample)(ResampleContext *c, DELEM *dst, const DELEM *src, int | |||
| sample_index += index >> c->phase_shift; | |||
| index &= c->phase_mask; | |||
| } | |||
| } else { | |||
| sample_index = index >> c->phase_shift; | |||
| if(update_ctx){ | |||
| c->frac= frac; | |||
| c->index= index; | |||
| } | |||
| return sample_index; | |||
| } | |||
| static int RENAME(resample_linear)(ResampleContext *c, | |||
| DELEM *dst, const DELEM *src, | |||
| int n, int update_ctx) | |||
| { | |||
| int dst_index; | |||
| int index= c->index; | |||
| int frac= c->frac; | |||
| int dst_incr_frac= c->dst_incr % c->src_incr; | |||
| int dst_incr= c->dst_incr / c->src_incr; | |||
| int sample_index = index >> c->phase_shift; | |||
| index &= c->phase_mask; | |||
| for (dst_index = 0; dst_index < n; dst_index++) { | |||
| FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index; | |||
| @@ -178,6 +182,7 @@ int RENAME(swri_resample)(ResampleContext *c, DELEM *dst, const DELEM *src, int | |||
| #ifdef LINEAR_CORE | |||
| LINEAR_CORE | |||
| #else | |||
| int i; | |||
| for (i = 0; i < c->filter_length; i++) { | |||
| val += src[sample_index + i] * (FELEM2)filter[i]; | |||
| v2 += src[sample_index + i] * (FELEM2)filter[i + c->filter_alloc]; | |||
| @@ -195,17 +200,13 @@ int RENAME(swri_resample)(ResampleContext *c, DELEM *dst, const DELEM *src, int | |||
| sample_index += index >> c->phase_shift; | |||
| index &= c->phase_mask; | |||
| } | |||
| } | |||
| *consumed = sample_index; | |||
| } | |||
| if(update_ctx){ | |||
| c->frac= frac; | |||
| c->index= index; | |||
| } | |||
| if(update_ctx){ | |||
| c->frac= frac; | |||
| c->index= index; | |||
| } | |||
| return dst_index; | |||
| return sample_index; | |||
| } | |||
| #undef COMMON_CORE | |||
| @@ -2,4 +2,6 @@ YASM-OBJS += x86/swresample_x86.o\ | |||
| x86/audio_convert.o\ | |||
| x86/rematrix.o\ | |||
| OBJS += x86/resample_x86_dsp.o\ | |||
| OBJS-$(CONFIG_XMM_CLOBBER_TEST) += x86/w64xmmtest.o | |||
| @@ -0,0 +1,89 @@ | |||
| /* | |||
| * audio resampling | |||
| * Copyright (c) 2004-2012 Michael Niedermayer <michaelni@gmx.at> | |||
| * | |||
| * 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 | |||
| */ | |||
| /** | |||
| * @file | |||
| * audio resampling | |||
| * @author Michael Niedermayer <michaelni@gmx.at> | |||
| */ | |||
| #include "libswresample/resample.h" | |||
| #if HAVE_MMXEXT_INLINE | |||
| #define DO_RESAMPLE_ONE 0 | |||
| #include "resample_mmx.h" | |||
| #define TEMPLATE_RESAMPLE_S16_MMX2 | |||
| #include "libswresample/resample_template.c" | |||
| #undef TEMPLATE_RESAMPLE_S16_MMX2 | |||
| #if HAVE_SSE_INLINE | |||
| #define TEMPLATE_RESAMPLE_FLT_SSE | |||
| #include "libswresample/resample_template.c" | |||
| #undef TEMPLATE_RESAMPLE_FLT_SSE | |||
| #endif | |||
| #if HAVE_SSE2_INLINE | |||
| #define TEMPLATE_RESAMPLE_S16_SSE2 | |||
| #include "libswresample/resample_template.c" | |||
| #undef TEMPLATE_RESAMPLE_S16_SSE2 | |||
| #define TEMPLATE_RESAMPLE_DBL_SSE2 | |||
| #include "libswresample/resample_template.c" | |||
| #undef TEMPLATE_RESAMPLE_DBL_SSE2 | |||
| #endif | |||
| #if HAVE_AVX_INLINE | |||
| #define TEMPLATE_RESAMPLE_FLT_AVX | |||
| #include "libswresample/resample_template.c" | |||
| #undef TEMPLATE_RESAMPLE_FLT_AVX | |||
| #endif | |||
| #undef DO_RESAMPLE_ONE | |||
| #endif // HAVE_MMXEXT_INLINE | |||
| void swresample_dsp_x86_init(ResampleContext *c) | |||
| { | |||
| int av_unused mm_flags = av_get_cpu_flags(); | |||
| #define FNIDX(fmt) (AV_SAMPLE_FMT_##fmt - AV_SAMPLE_FMT_S16P) | |||
| if (ARCH_X86_32 && HAVE_MMXEXT_INLINE && mm_flags & AV_CPU_FLAG_MMX2) { | |||
| c->dsp.resample_common[FNIDX(S16P)] = (resample_fn) resample_common_int16_mmx2; | |||
| c->dsp.resample_linear[FNIDX(S16P)] = (resample_fn) resample_linear_int16_mmx2; | |||
| } | |||
| if (HAVE_SSE_INLINE && mm_flags & AV_CPU_FLAG_SSE) { | |||
| c->dsp.resample_common[FNIDX(FLTP)] = (resample_fn) resample_common_float_sse; | |||
| c->dsp.resample_linear[FNIDX(FLTP)] = (resample_fn) resample_linear_float_sse; | |||
| } | |||
| if (HAVE_SSE2_INLINE && mm_flags & AV_CPU_FLAG_SSE2) { | |||
| c->dsp.resample_common[FNIDX(S16P)] = (resample_fn) resample_common_int16_sse2; | |||
| c->dsp.resample_linear[FNIDX(S16P)] = (resample_fn) resample_linear_int16_sse2; | |||
| c->dsp.resample_common[FNIDX(DBLP)] = (resample_fn) resample_common_double_sse2; | |||
| c->dsp.resample_linear[FNIDX(DBLP)] = (resample_fn) resample_linear_double_sse2; | |||
| } | |||
| if (HAVE_AVX_INLINE && mm_flags & AV_CPU_FLAG_AVX) { | |||
| c->dsp.resample_common[FNIDX(FLTP)] = (resample_fn) resample_common_float_avx; | |||
| c->dsp.resample_linear[FNIDX(FLTP)] = (resample_fn) resample_linear_float_avx; | |||
| } | |||
| } | |||