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 \ | dither.o \ | ||||
| rematrix.o \ | rematrix.o \ | ||||
| resample.o \ | resample.o \ | ||||
| resample_dsp.o \ | |||||
| swresample.o \ | swresample.o \ | ||||
| OBJS-$(CONFIG_LIBSOXR) += soxr_resample.o | OBJS-$(CONFIG_LIBSOXR) += soxr_resample.o | ||||
| @@ -25,32 +25,8 @@ | |||||
| * @author Michael Niedermayer <michaelni@gmx.at> | * @author Michael Niedermayer <michaelni@gmx.at> | ||||
| */ | */ | ||||
| #include "libavutil/log.h" | |||||
| #include "libavutil/avassert.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. | * 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, | 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 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 cutoff = cutoff0? cutoff0 : 0.97; | ||||
| double factor= FFMIN(out_rate * cutoff / in_rate, 1.0); | double factor= FFMIN(out_rate * cutoff / in_rate, 1.0); | ||||
| int phase_count= 1<<phase_shift; | 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->index= -phase_count*((c->filter_length-1)/2); | ||||
| c->frac= 0; | c->frac= 0; | ||||
| swresample_dsp_init(c); | |||||
| return c; | return c; | ||||
| error: | error: | ||||
| av_freep(&c->filter_bank); | av_freep(&c->filter_bank); | ||||
| @@ -282,59 +261,53 @@ static int set_compensation(ResampleContext *c, int sample_delta, int compensati | |||||
| return 0; | 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){ | static int multiple_resample(ResampleContext *c, AudioData *dst, int dst_size, AudioData *src, int src_size, int *consumed){ | ||||
| int i, ret= -1; | int i, ret= -1; | ||||
| int av_unused mm_flags = av_get_cpu_flags(); | 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; | int64_t max_src_size = (INT64_MAX >> (c->phase_shift+1)) / c->src_incr; | ||||
| if (c->compensation_distance) | 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); | src_size = FFMIN(src_size, max_src_size); | ||||
| for(i=0; i<dst->ch_count; i++){ | 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) | if(need_emms) | ||||
| emms_c(); | 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 | #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; | 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 | #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; | index &= c->phase_mask; | ||||
| for (dst_index = 0; dst_index < n; dst_index++) { | for (dst_index = 0; dst_index < n; dst_index++) { | ||||
| FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * 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 | COMMON_CORE | ||||
| #else | #else | ||||
| FELEM2 val=0; | FELEM2 val=0; | ||||
| int i; | |||||
| for (i = 0; i < c->filter_length; i++) { | for (i = 0; i < c->filter_length; i++) { | ||||
| val += src[sample_index + i] * (FELEM2)filter[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; | sample_index += index >> c->phase_shift; | ||||
| index &= c->phase_mask; | 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; | index &= c->phase_mask; | ||||
| for (dst_index = 0; dst_index < n; dst_index++) { | for (dst_index = 0; dst_index < n; dst_index++) { | ||||
| FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * 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 | #ifdef LINEAR_CORE | ||||
| LINEAR_CORE | LINEAR_CORE | ||||
| #else | #else | ||||
| int i; | |||||
| for (i = 0; i < c->filter_length; i++) { | for (i = 0; i < c->filter_length; i++) { | ||||
| val += src[sample_index + i] * (FELEM2)filter[i]; | val += src[sample_index + i] * (FELEM2)filter[i]; | ||||
| v2 += src[sample_index + i] * (FELEM2)filter[i + c->filter_alloc]; | 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; | sample_index += index >> c->phase_shift; | ||||
| index &= c->phase_mask; | 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 | #undef COMMON_CORE | ||||
| @@ -2,4 +2,6 @@ YASM-OBJS += x86/swresample_x86.o\ | |||||
| x86/audio_convert.o\ | x86/audio_convert.o\ | ||||
| x86/rematrix.o\ | x86/rematrix.o\ | ||||
| OBJS += x86/resample_x86_dsp.o\ | |||||
| OBJS-$(CONFIG_XMM_CLOBBER_TEST) += x86/w64xmmtest.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; | |||||
| } | |||||
| } | |||||