Unified · Split
| @@ -125,6 +125,9 @@ AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, · 124 unmodified lines | |||
| 125 | ctx->ch_map = ch_map; | 125 | ctx->ch_map = ch_map; |
| 126 | if (in_fmt == AV_SAMPLE_FMT_U8) | 126 | if (in_fmt == AV_SAMPLE_FMT_U8) |
| 127 | memset(ctx->silence, 0x80, sizeof(ctx->silence)); | 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 | return ctx; | 131 | return ctx; |
| 129 | } | 132 | } |
| 130 | 133 | ||
| @@ -136,21 +139,36 @@ void swri_audio_convert_free(AudioConvert **ctx) · 5 unmodified lines | |||
| 136 | int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len) | 139 | int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len) |
| 137 | { | 140 | { |
| 138 | int ch; | 141 | int ch; |
| 142 | int off=0; | ||
| 143 | const int os= (out->planar ? 1 :out->ch_count) *out->bps; | ||
| 139 | 144 | ||
| 140 | av_assert0(ctx->channels == out->ch_count); | 145 | av_assert0(ctx->channels == out->ch_count); |
| 141 | 146 | ||
| 142 | //FIXME optimize common cases | 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 | for(ch=0; ch<ctx->channels; ch++){ | 163 | for(ch=0; ch<ctx->channels; ch++){ |
| 145 | const int ich= ctx->ch_map ? ctx->ch_map[ch] : ch; | 164 | const int ich= ctx->ch_map ? ctx->ch_map[ch] : ch; |
| 146 | const int is= ich < 0 ? 0 : (in->planar ? 1 : in->ch_count) * in->bps; | 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 | const uint8_t *pi= ich < 0 ? ctx->silence : in->ch[ich]; | 166 | const uint8_t *pi= ich < 0 ? ctx->silence : in->ch[ich]; |
| 149 | uint8_t *po= out->ch[ch]; | 167 | uint8_t *po= out->ch[ch]; |
| 150 | uint8_t *end= po + os*len; | 168 | uint8_t *end= po + os*len; |
| 151 | if(!po) | 169 | if(!po) |
| 152 | continue; | 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 | return 0; | 173 | return 0; |
| 156 | } | 174 | } |
| @@ -35,10 +35,12 @@ · 34 unmodified lines | |||
| 35 | 35 | ||
| 36 | 36 | ||
| 37 | typedef void (conv_func_type)(uint8_t *po, const uint8_t *pi, int is, int os, uint8_t *end); | 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 | typedef struct AudioConvert { | 40 | typedef struct AudioConvert { |
| 40 | int channels; | 41 | int channels; |
| 41 | conv_func_type *conv_f; | 42 | conv_func_type *conv_f; |
| 43 | simd_func_type *simd_f; | ||
| 42 | const int *ch_map; | 44 | const int *ch_map; |
| 43 | uint8_t silence[8]; ///< silence input sample | 45 | uint8_t silence[8]; ///< silence input sample |
| 44 | }AudioConvert; | 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 | void swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt); | 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 | #endif | 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 | } | ||