2 * x86-optimized AC-3 DSP functions
3 * Copyright (c) 2011 Justin Ruggles
5 * This file is part of FFmpeg.
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.
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.
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
22 #include "libavutil/attributes.h"
23 #include "libavutil/mem.h"
24 #include "libavutil/x86/asm.h"
25 #include "libavutil/x86/cpu.h"
26 #include "libavcodec/ac3.h"
27 #include "libavcodec/ac3dsp.h"
29 void ff_ac3_exponent_min_mmx (uint8_t *exp, int num_reuse_blocks, int nb_coefs);
30 void ff_ac3_exponent_min_mmxext(uint8_t *exp, int num_reuse_blocks, int nb_coefs);
31 void ff_ac3_exponent_min_sse2 (uint8_t *exp, int num_reuse_blocks, int nb_coefs);
33 int ff_ac3_max_msb_abs_int16_mmx (const int16_t *src, int len);
34 int ff_ac3_max_msb_abs_int16_mmxext(const int16_t *src, int len);
35 int ff_ac3_max_msb_abs_int16_sse2 (const int16_t *src, int len);
36 int ff_ac3_max_msb_abs_int16_ssse3(const int16_t *src, int len);
38 void ff_ac3_lshift_int16_mmx (int16_t *src, unsigned int len, unsigned int shift);
39 void ff_ac3_lshift_int16_sse2(int16_t *src, unsigned int len, unsigned int shift);
41 void ff_ac3_rshift_int32_mmx (int32_t *src, unsigned int len, unsigned int shift);
42 void ff_ac3_rshift_int32_sse2(int32_t *src, unsigned int len, unsigned int shift);
44 void ff_float_to_fixed24_3dnow(int32_t *dst, const float *src, unsigned int len);
45 void ff_float_to_fixed24_sse (int32_t *dst, const float *src, unsigned int len);
46 void ff_float_to_fixed24_sse2 (int32_t *dst, const float *src, unsigned int len);
48 int ff_ac3_compute_mantissa_size_sse2(uint16_t mant_cnt[6][16]);
50 void ff_ac3_extract_exponents_sse2 (uint8_t *exp, int32_t *coef, int nb_coefs);
51 void ff_ac3_extract_exponents_ssse3(uint8_t *exp, int32_t *coef, int nb_coefs);
53 void ff_apply_window_int16_round_mmxext(int16_t *output, const int16_t *input,
54 const int16_t *window, unsigned int len);
55 void ff_apply_window_int16_round_sse2(int16_t *output, const int16_t *input,
56 const int16_t *window, unsigned int len);
57 void ff_apply_window_int16_mmxext(int16_t *output, const int16_t *input,
58 const int16_t *window, unsigned int len);
59 void ff_apply_window_int16_sse2(int16_t *output, const int16_t *input,
60 const int16_t *window, unsigned int len);
61 void ff_apply_window_int16_ssse3(int16_t *output, const int16_t *input,
62 const int16_t *window, unsigned int len);
63 void ff_apply_window_int16_ssse3_atom(int16_t *output, const int16_t *input,
64 const int16_t *window, unsigned int len);
66 av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact)
68 int cpu_flags = av_get_cpu_flags();
70 if (EXTERNAL_MMX(cpu_flags)) {
71 c->ac3_exponent_min = ff_ac3_exponent_min_mmx;
72 c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_mmx;
73 c->ac3_lshift_int16 = ff_ac3_lshift_int16_mmx;
74 c->ac3_rshift_int32 = ff_ac3_rshift_int32_mmx;
76 if (EXTERNAL_AMD3DNOW(cpu_flags)) {
78 c->float_to_fixed24 = ff_float_to_fixed24_3dnow;
81 if (EXTERNAL_MMXEXT(cpu_flags)) {
82 c->ac3_exponent_min = ff_ac3_exponent_min_mmxext;
83 c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_mmxext;
85 c->apply_window_int16 = ff_apply_window_int16_mmxext;
87 c->apply_window_int16 = ff_apply_window_int16_round_mmxext;
90 if (EXTERNAL_SSE(cpu_flags)) {
91 c->float_to_fixed24 = ff_float_to_fixed24_sse;
93 if (EXTERNAL_SSE2(cpu_flags)) {
94 c->ac3_exponent_min = ff_ac3_exponent_min_sse2;
95 c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_sse2;
96 c->float_to_fixed24 = ff_float_to_fixed24_sse2;
97 c->compute_mantissa_size = ff_ac3_compute_mantissa_size_sse2;
98 c->extract_exponents = ff_ac3_extract_exponents_sse2;
100 c->apply_window_int16 = ff_apply_window_int16_sse2;
104 if (EXTERNAL_SSE2_FAST(cpu_flags)) {
105 c->ac3_lshift_int16 = ff_ac3_lshift_int16_sse2;
106 c->ac3_rshift_int32 = ff_ac3_rshift_int32_sse2;
108 c->apply_window_int16 = ff_apply_window_int16_round_sse2;
112 if (EXTERNAL_SSSE3(cpu_flags)) {
113 c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_ssse3;
114 if (cpu_flags & AV_CPU_FLAG_ATOM) {
115 c->apply_window_int16 = ff_apply_window_int16_ssse3_atom;
117 c->extract_exponents = ff_ac3_extract_exponents_ssse3;
118 c->apply_window_int16 = ff_apply_window_int16_ssse3;
123 #define DOWNMIX_FUNC_OPT(ch, opt) \
124 void ff_ac3_downmix_ ## ch ## _to_1_ ## opt(float **samples, \
125 float **matrix, int len); \
126 void ff_ac3_downmix_ ## ch ## _to_2_ ## opt(float **samples, \
127 float **matrix, int len);
129 #define DOWNMIX_FUNCS(opt) \
130 DOWNMIX_FUNC_OPT(3, opt) \
131 DOWNMIX_FUNC_OPT(4, opt) \
132 DOWNMIX_FUNC_OPT(5, opt) \
133 DOWNMIX_FUNC_OPT(6, opt)
139 void ff_ac3dsp_set_downmix_x86(AC3DSPContext *c)
141 int cpu_flags = av_get_cpu_flags();
143 #define SET_DOWNMIX(ch, suf, SUF) \
144 if (ch == c->in_channels) { \
145 if (EXTERNAL_ ## SUF (cpu_flags)) { \
146 if (c->out_channels == 1) \
147 c->downmix = ff_ac3_downmix_ ## ch ## _to_1_ ## suf; \
149 c->downmix = ff_ac3_downmix_ ## ch ## _to_2_ ## suf; \
153 #define SET_DOWNMIX_ALL(suf, SUF) \
154 SET_DOWNMIX(3, suf, SUF) \
155 SET_DOWNMIX(4, suf, SUF) \
156 SET_DOWNMIX(5, suf, SUF) \
157 SET_DOWNMIX(6, suf, SUF)
159 SET_DOWNMIX_ALL(sse, SSE)
160 if (!(cpu_flags & AV_CPU_FLAG_AVXSLOW)) {
161 SET_DOWNMIX_ALL(avx, AVX)
162 SET_DOWNMIX_ALL(fma3, FMA3)