1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (C) 2012 Michael Niedermayer (michaelni@gmx.at) 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * This file is part of libswresample 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * libswresample is free software; you can redistribute it and/or 7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 10cabdff1aSopenharmony_ci * 11cabdff1aSopenharmony_ci * libswresample is distributed in the hope that it will be useful, 12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14cabdff1aSopenharmony_ci * Lesser General Public License for more details. 15cabdff1aSopenharmony_ci * 16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 17cabdff1aSopenharmony_ci * License along with libswresample; if not, write to the Free Software 18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19cabdff1aSopenharmony_ci */ 20cabdff1aSopenharmony_ci 21cabdff1aSopenharmony_ci#include "libavutil/attributes.h" 22cabdff1aSopenharmony_ci#include "libavutil/x86/cpu.h" 23cabdff1aSopenharmony_ci#include "libswresample/swresample_internal.h" 24cabdff1aSopenharmony_ci#include "libswresample/audioconvert.h" 25cabdff1aSopenharmony_ci 26cabdff1aSopenharmony_ci#define PROTO(pre, in, out, cap) void ff ## pre ## in## _to_ ##out## _a_ ##cap(uint8_t **dst, const uint8_t **src, int len); 27cabdff1aSopenharmony_ci#define PROTO2(pre, out, cap) PROTO(pre, int16, out, cap) PROTO(pre, int32, out, cap) PROTO(pre, float, out, cap) 28cabdff1aSopenharmony_ci#define PROTO3(pre, cap) PROTO2(pre, int16, cap) PROTO2(pre, int32, cap) PROTO2(pre, float, cap) 29cabdff1aSopenharmony_ci#define PROTO4(pre) PROTO3(pre, sse) PROTO3(pre, sse2) PROTO3(pre, ssse3) PROTO3(pre, sse4) PROTO3(pre, avx) PROTO3(pre, avx2) 30cabdff1aSopenharmony_ciPROTO4(_) 31cabdff1aSopenharmony_ciPROTO4(_pack_2ch_) 32cabdff1aSopenharmony_ciPROTO4(_pack_6ch_) 33cabdff1aSopenharmony_ciPROTO4(_pack_8ch_) 34cabdff1aSopenharmony_ciPROTO4(_unpack_2ch_) 35cabdff1aSopenharmony_ciPROTO4(_unpack_6ch_) 36cabdff1aSopenharmony_ci 37cabdff1aSopenharmony_ciav_cold void swri_audio_convert_init_x86(struct AudioConvert *ac, 38cabdff1aSopenharmony_ci enum AVSampleFormat out_fmt, 39cabdff1aSopenharmony_ci enum AVSampleFormat in_fmt, 40cabdff1aSopenharmony_ci int channels){ 41cabdff1aSopenharmony_ci int mm_flags = av_get_cpu_flags(); 42cabdff1aSopenharmony_ci 43cabdff1aSopenharmony_ci ac->simd_f= NULL; 44cabdff1aSopenharmony_ci 45cabdff1aSopenharmony_ci//FIXME add memcpy case 46cabdff1aSopenharmony_ci 47cabdff1aSopenharmony_ci#define MULTI_CAPS_FUNC(flag, cap) \ 48cabdff1aSopenharmony_ci if (EXTERNAL_##flag(mm_flags)) {\ 49cabdff1aSopenharmony_ci 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)\ 50cabdff1aSopenharmony_ci ac->simd_f = ff_int16_to_int32_a_ ## cap;\ 51cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_S32 || out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_S32P)\ 52cabdff1aSopenharmony_ci ac->simd_f = ff_int32_to_int16_a_ ## cap;\ 53cabdff1aSopenharmony_ci } 54cabdff1aSopenharmony_ci 55cabdff1aSopenharmony_ciMULTI_CAPS_FUNC(SSE2, sse2) 56cabdff1aSopenharmony_ci 57cabdff1aSopenharmony_ci if(EXTERNAL_SSE(mm_flags)) { 58cabdff1aSopenharmony_ci if(channels == 6) { 59cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P) 60cabdff1aSopenharmony_ci ac->simd_f = ff_pack_6ch_float_to_float_a_sse; 61cabdff1aSopenharmony_ci 62cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_S32) 63cabdff1aSopenharmony_ci ac->simd_f = ff_unpack_6ch_float_to_float_a_sse; 64cabdff1aSopenharmony_ci } 65cabdff1aSopenharmony_ci } 66cabdff1aSopenharmony_ci if(EXTERNAL_SSE2(mm_flags)) { 67cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32 || out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S32P) 68cabdff1aSopenharmony_ci ac->simd_f = ff_int32_to_float_a_sse2; 69cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S16 || out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S16P) 70cabdff1aSopenharmony_ci ac->simd_f = ff_int16_to_float_a_sse2; 71cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_FLTP) 72cabdff1aSopenharmony_ci ac->simd_f = ff_float_to_int32_a_sse2; 73cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_FLTP) 74cabdff1aSopenharmony_ci ac->simd_f = ff_float_to_int16_a_sse2; 75cabdff1aSopenharmony_ci 76cabdff1aSopenharmony_ci if(channels == 2) { 77cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P) 78cabdff1aSopenharmony_ci ac->simd_f = ff_pack_2ch_int32_to_int32_a_sse2; 79cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_S16P) 80cabdff1aSopenharmony_ci ac->simd_f = ff_pack_2ch_int16_to_int16_a_sse2; 81cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S16P) 82cabdff1aSopenharmony_ci ac->simd_f = ff_pack_2ch_int16_to_int32_a_sse2; 83cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_S32P) 84cabdff1aSopenharmony_ci ac->simd_f = ff_pack_2ch_int32_to_int16_a_sse2; 85cabdff1aSopenharmony_ci 86cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_S32) 87cabdff1aSopenharmony_ci ac->simd_f = ff_unpack_2ch_int32_to_int32_a_sse2; 88cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_S16) 89cabdff1aSopenharmony_ci ac->simd_f = ff_unpack_2ch_int16_to_int16_a_sse2; 90cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_S16) 91cabdff1aSopenharmony_ci ac->simd_f = ff_unpack_2ch_int16_to_int32_a_sse2; 92cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_S32) 93cabdff1aSopenharmony_ci ac->simd_f = ff_unpack_2ch_int32_to_int16_a_sse2; 94cabdff1aSopenharmony_ci 95cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32P) 96cabdff1aSopenharmony_ci ac->simd_f = ff_pack_2ch_int32_to_float_a_sse2; 97cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_FLTP) 98cabdff1aSopenharmony_ci ac->simd_f = ff_pack_2ch_float_to_int32_a_sse2; 99cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S16P) 100cabdff1aSopenharmony_ci ac->simd_f = ff_pack_2ch_int16_to_float_a_sse2; 101cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_FLTP) 102cabdff1aSopenharmony_ci ac->simd_f = ff_pack_2ch_float_to_int16_a_sse2; 103cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S32) 104cabdff1aSopenharmony_ci ac->simd_f = ff_unpack_2ch_int32_to_float_a_sse2; 105cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_FLT) 106cabdff1aSopenharmony_ci ac->simd_f = ff_unpack_2ch_float_to_int32_a_sse2; 107cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S16) 108cabdff1aSopenharmony_ci ac->simd_f = ff_unpack_2ch_int16_to_float_a_sse2; 109cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_FLT) 110cabdff1aSopenharmony_ci ac->simd_f = ff_unpack_2ch_float_to_int16_a_sse2; 111cabdff1aSopenharmony_ci } 112cabdff1aSopenharmony_ci if(channels == 6) { 113cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32P) 114cabdff1aSopenharmony_ci ac->simd_f = ff_pack_6ch_int32_to_float_a_sse2; 115cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_FLTP) 116cabdff1aSopenharmony_ci ac->simd_f = ff_pack_6ch_float_to_int32_a_sse2; 117cabdff1aSopenharmony_ci 118cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S32) 119cabdff1aSopenharmony_ci ac->simd_f = ff_unpack_6ch_int32_to_float_a_sse2; 120cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_FLT) 121cabdff1aSopenharmony_ci ac->simd_f = ff_unpack_6ch_float_to_int32_a_sse2; 122cabdff1aSopenharmony_ci } 123cabdff1aSopenharmony_ci if(channels == 8) { 124cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P) 125cabdff1aSopenharmony_ci ac->simd_f = ff_pack_8ch_float_to_float_a_sse2; 126cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32P) 127cabdff1aSopenharmony_ci ac->simd_f = ff_pack_8ch_int32_to_float_a_sse2; 128cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_FLTP) 129cabdff1aSopenharmony_ci ac->simd_f = ff_pack_8ch_float_to_int32_a_sse2; 130cabdff1aSopenharmony_ci } 131cabdff1aSopenharmony_ci } 132cabdff1aSopenharmony_ci if(EXTERNAL_SSSE3(mm_flags)) { 133cabdff1aSopenharmony_ci if(channels == 2) { 134cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_S16) 135cabdff1aSopenharmony_ci ac->simd_f = ff_unpack_2ch_int16_to_int16_a_ssse3; 136cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_S16) 137cabdff1aSopenharmony_ci ac->simd_f = ff_unpack_2ch_int16_to_int32_a_ssse3; 138cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S16) 139cabdff1aSopenharmony_ci ac->simd_f = ff_unpack_2ch_int16_to_float_a_ssse3; 140cabdff1aSopenharmony_ci } 141cabdff1aSopenharmony_ci } 142cabdff1aSopenharmony_ci if(EXTERNAL_AVX_FAST(mm_flags)) { 143cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32 || out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S32P) 144cabdff1aSopenharmony_ci ac->simd_f = ff_int32_to_float_a_avx; 145cabdff1aSopenharmony_ci } 146cabdff1aSopenharmony_ci if(EXTERNAL_AVX(mm_flags)) { 147cabdff1aSopenharmony_ci if(channels == 6) { 148cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P) 149cabdff1aSopenharmony_ci ac->simd_f = ff_pack_6ch_float_to_float_a_avx; 150cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32P) 151cabdff1aSopenharmony_ci ac->simd_f = ff_pack_6ch_int32_to_float_a_avx; 152cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_FLTP) 153cabdff1aSopenharmony_ci ac->simd_f = ff_pack_6ch_float_to_int32_a_avx; 154cabdff1aSopenharmony_ci 155cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_S32) 156cabdff1aSopenharmony_ci ac->simd_f = ff_unpack_6ch_float_to_float_a_avx; 157cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S32) 158cabdff1aSopenharmony_ci ac->simd_f = ff_unpack_6ch_int32_to_float_a_avx; 159cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_FLT) 160cabdff1aSopenharmony_ci ac->simd_f = ff_unpack_6ch_float_to_int32_a_avx; 161cabdff1aSopenharmony_ci } 162cabdff1aSopenharmony_ci if(channels == 8) { 163cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P) 164cabdff1aSopenharmony_ci ac->simd_f = ff_pack_8ch_float_to_float_a_avx; 165cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32P) 166cabdff1aSopenharmony_ci ac->simd_f = ff_pack_8ch_int32_to_float_a_avx; 167cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_FLTP) 168cabdff1aSopenharmony_ci ac->simd_f = ff_pack_8ch_float_to_int32_a_avx; 169cabdff1aSopenharmony_ci } 170cabdff1aSopenharmony_ci } 171cabdff1aSopenharmony_ci if(EXTERNAL_AVX2_FAST(mm_flags)) { 172cabdff1aSopenharmony_ci if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_FLTP) 173cabdff1aSopenharmony_ci ac->simd_f = ff_float_to_int32_a_avx2; 174cabdff1aSopenharmony_ci } 175cabdff1aSopenharmony_ci} 176