1/* 2 * x86-optimized AC-3 DSP functions 3 * Copyright (c) 2011 Justin Ruggles 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22#include "libavutil/attributes.h" 23#include "libavutil/x86/asm.h" 24#include "libavutil/x86/cpu.h" 25#include "libavcodec/ac3dsp.h" 26 27void ff_ac3_exponent_min_sse2 (uint8_t *exp, int num_reuse_blocks, int nb_coefs); 28 29void ff_float_to_fixed24_sse2 (int32_t *dst, const float *src, unsigned int len); 30 31int ff_ac3_compute_mantissa_size_sse2(uint16_t mant_cnt[6][16]); 32 33void ff_ac3_extract_exponents_sse2 (uint8_t *exp, int32_t *coef, int nb_coefs); 34void ff_ac3_extract_exponents_ssse3(uint8_t *exp, int32_t *coef, int nb_coefs); 35 36av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact) 37{ 38 int cpu_flags = av_get_cpu_flags(); 39 40 if (EXTERNAL_SSE2(cpu_flags)) { 41 c->ac3_exponent_min = ff_ac3_exponent_min_sse2; 42 c->float_to_fixed24 = ff_float_to_fixed24_sse2; 43 c->compute_mantissa_size = ff_ac3_compute_mantissa_size_sse2; 44 c->extract_exponents = ff_ac3_extract_exponents_sse2; 45 } 46 47 if (EXTERNAL_SSSE3(cpu_flags)) { 48 if (!(cpu_flags & AV_CPU_FLAG_ATOM)) 49 c->extract_exponents = ff_ac3_extract_exponents_ssse3; 50 } 51} 52 53#define DOWNMIX_FUNC_OPT(ch, opt) \ 54void ff_ac3_downmix_ ## ch ## _to_1_ ## opt(float **samples, \ 55 float **matrix, int len); \ 56void ff_ac3_downmix_ ## ch ## _to_2_ ## opt(float **samples, \ 57 float **matrix, int len); 58 59#define DOWNMIX_FUNCS(opt) \ 60 DOWNMIX_FUNC_OPT(3, opt) \ 61 DOWNMIX_FUNC_OPT(4, opt) \ 62 DOWNMIX_FUNC_OPT(5, opt) \ 63 DOWNMIX_FUNC_OPT(6, opt) 64 65DOWNMIX_FUNCS(sse) 66DOWNMIX_FUNCS(avx) 67DOWNMIX_FUNCS(fma3) 68 69void ff_ac3dsp_set_downmix_x86(AC3DSPContext *c) 70{ 71 int cpu_flags = av_get_cpu_flags(); 72 73#define SET_DOWNMIX(ch, suf, SUF) \ 74 if (ch == c->in_channels) { \ 75 if (EXTERNAL_ ## SUF (cpu_flags)) { \ 76 if (c->out_channels == 1) \ 77 c->downmix = ff_ac3_downmix_ ## ch ## _to_1_ ## suf; \ 78 else \ 79 c->downmix = ff_ac3_downmix_ ## ch ## _to_2_ ## suf; \ 80 } \ 81 } 82 83#define SET_DOWNMIX_ALL(suf, SUF) \ 84 SET_DOWNMIX(3, suf, SUF) \ 85 SET_DOWNMIX(4, suf, SUF) \ 86 SET_DOWNMIX(5, suf, SUF) \ 87 SET_DOWNMIX(6, suf, SUF) 88 89 SET_DOWNMIX_ALL(sse, SSE) 90 if (!(cpu_flags & AV_CPU_FLAG_AVXSLOW)) { 91 SET_DOWNMIX_ALL(avx, AVX) 92 SET_DOWNMIX_ALL(fma3, FMA3) 93 } 94} 95