Unified · Split
| @@ -125,6 +125,9 @@ AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, · 124 unmodified lines | ||
| 125 | 125 | ctx->ch_map = ch_map; |
| 126 | 126 | if (in_fmt == AV_SAMPLE_FMT_U8) |
| 127 | 127 | memset(ctx->silence, 0x80, sizeof(ctx->silence)); |
| 128 | + | |
| 129 | + if(HAVE_YASM && HAVE_MMX) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels); | |
| 130 | + | |
| 128 | 131 | return ctx; |
| 129 | 132 | } |
| 130 | 133 | |
| @@ -136,21 +139,36 @@ void swri_audio_convert_free(AudioConvert **ctx) · 5 unmodified lines | ||
| 136 | 139 | int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len) |
| 137 | 140 | { |
| 138 | 141 | int ch; |
| 142 | + int off=0; | |
| 143 | + const int os= (out->planar ? 1 :out->ch_count) *out->bps; | |
| 139 | 144 | |
| 140 | 145 | av_assert0(ctx->channels == out->ch_count); |
| 141 | 146 | |
| 142 | 147 | //FIXME optimize common cases |
| 143 | 148 | |
| 149 | + if(ctx->simd_f && !ctx->ch_map){ | |
| 150 | + int planes = out->planar ? out->ch_count : 1; | |
| 151 | + off = len/16 * 16; | |
| 152 | + av_assert1(out->planar == in->planar); | |
| 153 | + av_assert1(off>=0); | |
| 154 | + if(off>0) | |
| 155 | + for(ch=0; ch<planes; ch++){ | |
| 156 | + ctx->simd_f(out->ch+ch, in->ch+ch, off*os); | |
| 157 | + } | |
| 158 | + av_assert1(off<=len); | |
| 159 | + if(off == len) | |
| 160 | + return 0; | |
| 161 | + } | |
| 162 | + | |
| 144 | 163 | for(ch=0; ch<ctx->channels; ch++){ |
| 145 | 164 | const int ich= ctx->ch_map ? ctx->ch_map[ch] : ch; |
| 146 | 165 | const int is= ich < 0 ? 0 : (in->planar ? 1 : in->ch_count) * in->bps; |
| 147 | − const int os= (out->planar ? 1 :out->ch_count) *out->bps; | |
| 148 | 166 | const uint8_t *pi= ich < 0 ? ctx->silence : in->ch[ich]; |
| 149 | 167 | uint8_t *po= out->ch[ch]; |
| 150 | 168 | uint8_t *end= po + os*len; |
| 151 | 169 | if(!po) |
| 152 | 170 | continue; |
| 153 | − ctx->conv_f(po, pi, is, os, end); | |
| 171 | + ctx->conv_f(po+off*os, pi+off*is, is, os, end); | |
| 154 | 172 | } |
| 155 | 173 | return 0; |
| 156 | 174 | } |
| @@ -35,10 +35,12 @@ · 34 unmodified lines | ||
| 35 | 35 | |
| 36 | 36 | |
| 37 | 37 | typedef void (conv_func_type)(uint8_t *po, const uint8_t *pi, int is, int os, uint8_t *end); |
| 38 | +typedef void (simd_func_type)(uint8_t **dst, const uint8_t **src, int len); | |
| 38 | 39 | |
| 39 | 40 | typedef struct AudioConvert { |
| 40 | 41 | int channels; |
| 41 | 42 | conv_func_type *conv_f; |
| 43 | + simd_func_type *simd_f; | |
| 42 | 44 | const int *ch_map; |
| 43 | 45 | uint8_t silence[8]; ///< silence input sample |
| 44 | 46 | }AudioConvert; |
| @@ -101,4 +101,8 @@ void swri_sum2(enum AVSampleFormat format, void *dst, const void *src0, const vo · 100 unmodified lines | ||
| 101 | 101 | |
| 102 | 102 | void swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt); |
| 103 | 103 | |
| 104 | +void swri_audio_convert_init_x86(struct AudioConvert *ac, | |
| 105 | + enum AVSampleFormat out_fmt, | |
| 106 | + enum AVSampleFormat in_fmt, | |
| 107 | + int channels); | |
| 104 | 108 | #endif |
| @@ -0,0 +1,2 @@ | ||
| 1 | +YASM-OBJS += x86/swresample_x86.o\ | |
| 2 | + x86/audio_convert.o\ | |
| @@ -0,0 +1,52 @@ | ||
| 1 | +;****************************************************************************** | |
| 2 | +;* Copyright (c) 2012 Michael Niedermayer | |
| 3 | +;* | |
| 4 | +;* This file is part of FFmpeg. | |
| 5 | +;* | |
| 6 | +;* FFmpeg is free software; you can redistribute it and/or | |
| 7 | +;* modify it under the terms of the GNU Lesser General Public | |
| 8 | +;* License as published by the Free Software Foundation; either | |
| 9 | +;* version 2.1 of the License, or (at your option) any later version. | |
| 10 | +;* | |
| 11 | +;* FFmpeg is distributed in the hope that it will be useful, | |
| 12 | +;* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | +;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 14 | +;* Lesser General Public License for more details. | |
| 15 | +;* | |
| 16 | +;* You should have received a copy of the GNU Lesser General Public | |
| 17 | +;* License along with FFmpeg; if not, write to the Free Software | |
| 18 | +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 19 | +;****************************************************************************** | |
| 20 | + | |
| 21 | +%include "libavutil/x86/x86inc.asm" | |
| 22 | +%include "libavutil/x86/x86util.asm" | |
| 23 | + | |
| 24 | +SECTION .text | |
| 25 | + | |
| 26 | +%macro INT16_TO_INT32 0 | |
| 27 | +cglobal int16_to_int32_%1, 3, 3, 0, dst, src, len | |
| 28 | + mov srcq, [srcq] | |
| 29 | + mov dstq, [dstq] | |
| 30 | +.next | |
| 31 | + movu m4, [srcq] | |
| 32 | + pxor m0, m0 | |
| 33 | + pxor m1, m1 | |
| 34 | + punpcklwd m0, m4 | |
| 35 | + punpckhwd m1, m4 | |
| 36 | + movu [ dstq], m0 | |
| 37 | + movu [mmsize + dstq], m1 | |
| 38 | + add srcq, mmsize | |
| 39 | + add dstq, 2*mmsize | |
| 40 | + sub lenq, 2*mmsize | |
| 41 | + jg .next | |
| 42 | +%if mmsize == 8 | |
| 43 | + emms | |
| 44 | +%endif | |
| 45 | + REP_RET | |
| 46 | +%endmacro | |
| 47 | + | |
| 48 | +INIT_MMX mmx | |
| 49 | +INT16_TO_INT32 | |
| 50 | + | |
| 51 | +INIT_XMM sse | |
| 52 | +INT16_TO_INT32 | |
| @@ -0,0 +1,47 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2012 Michael Niedermayer (michaelni@gmx.at) | |
| 3 | + * | |
| 4 | + * This file is part of libswresample | |
| 5 | + * | |
| 6 | + * libswresample is free software; you can redistribute it and/or | |
| 7 | + * modify it under the terms of the GNU Lesser General Public | |
| 8 | + * License as published by the Free Software Foundation; either | |
| 9 | + * version 2.1 of the License, or (at your option) any later version. | |
| 10 | + * | |
| 11 | + * libswresample is distributed in the hope that it will be useful, | |
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 14 | + * Lesser General Public License for more details. | |
| 15 | + * | |
| 16 | + * You should have received a copy of the GNU Lesser General Public | |
| 17 | + * License along with libswresample; if not, write to the Free Software | |
| 18 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 19 | + */ | |
| 20 | + | |
| 21 | +#include "libswresample/swresample_internal.h" | |
| 22 | +#include "libswresample/audioconvert.h" | |
| 23 | + | |
| 24 | +#define MULTI_CAPS_FUNC_DECL(cap) \ | |
| 25 | + void ff_int16_to_int32_ ## cap(uint8_t **dst, const uint8_t **src, int len); | |
| 26 | +MULTI_CAPS_FUNC_DECL(mmx) | |
| 27 | +MULTI_CAPS_FUNC_DECL(sse) | |
| 28 | + | |
| 29 | +void swri_audio_convert_init_x86(struct AudioConvert *ac, | |
| 30 | + enum AVSampleFormat out_fmt, | |
| 31 | + enum AVSampleFormat in_fmt, | |
| 32 | + int channels){ | |
| 33 | + int mm_flags = av_get_cpu_flags(); | |
| 34 | + | |
| 35 | + ac->simd_f= NULL; | |
| 36 | + | |
| 37 | +//FIXME add memcpy case | |
| 38 | + | |
| 39 | +#define MULTI_CAPS_FUNC(flag, cap) \ | |
| 40 | + if (mm_flags & flag) {\ | |
| 41 | + if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S16 || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_S16P)\ | |
| 42 | + ac->simd_f = ff_int16_to_int32_ ## cap;\ | |
| 43 | + } | |
| 44 | + | |
| 45 | +MULTI_CAPS_FUNC(AV_CPU_FLAG_MMX, mmx) | |
| 46 | +MULTI_CAPS_FUNC(AV_CPU_FLAG_SSE, sse) | |
| 47 | +} | |