Mercurial > libavcodec.hg
annotate aacpsy.c @ 12197:fbf4d5b1b664 libavcodec
Remove FF_MM_SSE2/3 flags for CPUs where this is generally not faster than
regular MMX code. Examples of this are the Core1 CPU. Instead, set a new flag,
FF_MM_SSE2/3SLOW, which can be checked for particular SSE2/3 functions that
have been checked specifically on such CPUs and are actually faster than
their MMX counterparts.
In addition, use this flag to enable particular VP8 and LPC SSE2 functions
that are faster than their MMX counterparts.
Based on a patch by Loren Merritt <lorenm AT u washington edu>.
author | rbultje |
---|---|
date | Mon, 19 Jul 2010 22:38:23 +0000 |
parents | f948f8cf97db |
children | b25537518e40 |
rev | line source |
---|---|
7606 | 1 /* |
2 * AAC encoder psychoacoustic model | |
3 * Copyright (C) 2008 Konstantin Shishkov | |
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 /** | |
11644
7dd2a45249a9
Remove explicit filename from Doxygen @file commands.
diego
parents:
9944
diff
changeset
|
23 * @file |
7606 | 24 * AAC encoder psychoacoustic model |
25 */ | |
26 | |
27 #include "avcodec.h" | |
28 #include "aactab.h" | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
29 #include "psymodel.h" |
7606 | 30 |
31 /*********************************** | |
32 * TODOs: | |
33 * thresholds linearization after their modifications for attaining given bitrate | |
34 * try other bitrate controlling mechanism (maybe use ratecontrol.c?) | |
35 * control quality for quality-based output | |
36 **********************************/ | |
37 | |
38 /** | |
39 * constants for 3GPP AAC psychoacoustic model | |
40 * @{ | |
41 */ | |
42 #define PSY_3GPP_SPREAD_LOW 1.5f // spreading factor for ascending threshold spreading (15 dB/Bark) | |
43 #define PSY_3GPP_SPREAD_HI 3.0f // spreading factor for descending threshold spreading (30 dB/Bark) | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
44 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
45 #define PSY_3GPP_RPEMIN 0.01f |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
46 #define PSY_3GPP_RPELEV 2.0f |
7606 | 47 /** |
48 * @} | |
49 */ | |
50 | |
51 /** | |
52 * information for single band used by 3GPP TS26.403-inspired psychoacoustic model | |
53 */ | |
54 typedef struct Psy3gppBand{ | |
55 float energy; ///< band energy | |
56 float ffac; ///< form factor | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
57 float thr; ///< energy threshold |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
58 float min_snr; ///< minimal SNR |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
59 float thr_quiet; ///< threshold in quiet |
7606 | 60 }Psy3gppBand; |
61 | |
62 /** | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
63 * single/pair channel context for psychoacoustic model |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
64 */ |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
65 typedef struct Psy3gppChannel{ |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
66 Psy3gppBand band[128]; ///< bands information |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
67 Psy3gppBand prev_band[128]; ///< bands information from the previous frame |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
68 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
69 float win_energy; ///< sliding average of channel energy |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
70 float iir_state[2]; ///< hi-pass IIR filter state |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
71 uint8_t next_grouping; ///< stored grouping scheme for the next frame (in case of 8 short window sequence) |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
72 enum WindowSequence next_window_seq; ///< window sequence to be used in the next frame |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
73 }Psy3gppChannel; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
74 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
75 /** |
7606 | 76 * psychoacoustic model frame type-dependent coefficients |
77 */ | |
78 typedef struct Psy3gppCoeffs{ | |
79 float ath [64]; ///< absolute threshold of hearing per bands | |
80 float barks [64]; ///< Bark value for each spectral band in long frame | |
81 float spread_low[64]; ///< spreading factor for low-to-high threshold spreading in long frame | |
82 float spread_hi [64]; ///< spreading factor for high-to-low threshold spreading in long frame | |
83 }Psy3gppCoeffs; | |
84 | |
85 /** | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
86 * 3GPP TS26.403-inspired psychoacoustic model specific data |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
87 */ |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
88 typedef struct Psy3gppContext{ |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
89 Psy3gppCoeffs psy_coef[2]; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
90 Psy3gppChannel *ch; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
91 }Psy3gppContext; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
92 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
93 /** |
7606 | 94 * Calculate Bark value for given line. |
95 */ | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
96 static av_cold float calc_bark(float f) |
7606 | 97 { |
98 return 13.3f * atanf(0.00076f * f) + 3.5f * atanf((f / 7500.0f) * (f / 7500.0f)); | |
99 } | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
100 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
101 #define ATH_ADD 4 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
102 /** |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
103 * Calculate ATH value for given frequency. |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
104 * Borrowed from Lame. |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
105 */ |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
106 static av_cold float ath(float f, float add) |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
107 { |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
108 f /= 1000.0f; |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
109 return 3.64 * pow(f, -0.8) |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
110 - 6.8 * exp(-0.6 * (f - 3.4) * (f - 3.4)) |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
111 + 6.0 * exp(-0.15 * (f - 8.7) * (f - 8.7)) |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
112 + (0.6 + 0.04 * add) * 0.001 * f * f * f * f; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
113 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
114 |
9936 | 115 static av_cold int psy_3gpp_init(FFPsyContext *ctx) { |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
116 Psy3gppContext *pctx; |
12159
25ac974ce96d
aacenc: psy_3gpp_init(): Calculate barks on demand.
alexc
parents:
11998
diff
changeset
|
117 float bark; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
118 int i, j, g, start; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
119 float prev, minscale, minath; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
120 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
121 ctx->model_priv_data = av_mallocz(sizeof(Psy3gppContext)); |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
122 pctx = (Psy3gppContext*) ctx->model_priv_data; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
123 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
124 minath = ath(3410, ATH_ADD); |
9936 | 125 for (j = 0; j < 2; j++) { |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
126 Psy3gppCoeffs *coeffs = &pctx->psy_coef[j]; |
12162
f948f8cf97db
aacenc: psy_3gpp_init(): Fix line_to_frequency for short windows.
alexc
parents:
12161
diff
changeset
|
127 float line_to_frequency = ctx->avctx->sample_rate / (j ? 256.f : 2048.0f); |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
128 i = 0; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
129 prev = 0.0; |
9936 | 130 for (g = 0; g < ctx->num_bands[j]; g++) { |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
131 i += ctx->bands[j][g]; |
12161
d34f0f3ac678
aacenc: aac_psy_init(): Factorize line_to_frequency.
alexc
parents:
12160
diff
changeset
|
132 bark = calc_bark((i-1) * line_to_frequency); |
12159
25ac974ce96d
aacenc: psy_3gpp_init(): Calculate barks on demand.
alexc
parents:
11998
diff
changeset
|
133 coeffs->barks[g] = (bark + prev) / 2.0; |
25ac974ce96d
aacenc: psy_3gpp_init(): Calculate barks on demand.
alexc
parents:
11998
diff
changeset
|
134 prev = bark; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
135 } |
9936 | 136 for (g = 0; g < ctx->num_bands[j] - 1; g++) { |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
137 coeffs->spread_low[g] = pow(10.0, -(coeffs->barks[g+1] - coeffs->barks[g]) * PSY_3GPP_SPREAD_LOW); |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
138 coeffs->spread_hi [g] = pow(10.0, -(coeffs->barks[g+1] - coeffs->barks[g]) * PSY_3GPP_SPREAD_HI); |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
139 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
140 start = 0; |
9936 | 141 for (g = 0; g < ctx->num_bands[j]; g++) { |
12161
d34f0f3ac678
aacenc: aac_psy_init(): Factorize line_to_frequency.
alexc
parents:
12160
diff
changeset
|
142 minscale = ath(start * line_to_frequency, ATH_ADD); |
9938
6c1ac45b3097
cosmetics: Remove unnecessary {} around if/for blocks;
diego
parents:
9937
diff
changeset
|
143 for (i = 1; i < ctx->bands[j][g]; i++) |
12161
d34f0f3ac678
aacenc: aac_psy_init(): Factorize line_to_frequency.
alexc
parents:
12160
diff
changeset
|
144 minscale = FFMIN(minscale, ath((start + i) * line_to_frequency, ATH_ADD)); |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
145 coeffs->ath[g] = minscale - minath; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
146 start += ctx->bands[j][g]; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
147 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
148 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
149 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
150 pctx->ch = av_mallocz(sizeof(Psy3gppChannel) * ctx->avctx->channels); |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
151 return 0; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
152 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
153 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
154 /** |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
155 * IIR filter used in block switching decision |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
156 */ |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
157 static float iir_filter(int in, float state[2]) |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
158 { |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
159 float ret; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
160 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
161 ret = 0.7548f * (in - state[0]) + 0.5095f * state[1]; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
162 state[0] = in; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
163 state[1] = ret; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
164 return ret; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
165 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
166 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
167 /** |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
168 * window grouping information stored as bits (0 - new group, 1 - group continues) |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
169 */ |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
170 static const uint8_t window_grouping[9] = { |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
171 0xB6, 0x6C, 0xD8, 0xB2, 0x66, 0xC6, 0x96, 0x36, 0x36 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
172 }; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
173 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
174 /** |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
175 * Tell encoder which window types to use. |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
176 * @see 3GPP TS26.403 5.4.1 "Blockswitching" |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
177 */ |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
178 static FFPsyWindowInfo psy_3gpp_window(FFPsyContext *ctx, |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
179 const int16_t *audio, const int16_t *la, |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
180 int channel, int prev_type) |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
181 { |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
182 int i, j; |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
183 int br = ctx->avctx->bit_rate / ctx->avctx->channels; |
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
184 int attack_ratio = br <= 16000 ? 18 : 10; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
185 Psy3gppContext *pctx = (Psy3gppContext*) ctx->model_priv_data; |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
186 Psy3gppChannel *pch = &pctx->ch[channel]; |
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
187 uint8_t grouping = 0; |
11998 | 188 int next_type = pch->next_window_seq; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
189 FFPsyWindowInfo wi; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
190 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
191 memset(&wi, 0, sizeof(wi)); |
9936 | 192 if (la) { |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
193 float s[8], v; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
194 int switch_to_eight = 0; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
195 float sum = 0.0, sum2 = 0.0; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
196 int attack_n = 0; |
11998 | 197 int stay_short = 0; |
9936 | 198 for (i = 0; i < 8; i++) { |
199 for (j = 0; j < 128; j++) { | |
11728 | 200 v = iir_filter(la[(i*128+j)*ctx->avctx->channels], pch->iir_state); |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
201 sum += v*v; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
202 } |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
203 s[i] = sum; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
204 sum2 += sum; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
205 } |
9936 | 206 for (i = 0; i < 8; i++) { |
207 if (s[i] > pch->win_energy * attack_ratio) { | |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
208 attack_n = i + 1; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
209 switch_to_eight = 1; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
210 break; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
211 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
212 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
213 pch->win_energy = pch->win_energy*7/8 + sum2/64; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
214 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
215 wi.window_type[1] = prev_type; |
9936 | 216 switch (prev_type) { |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
217 case ONLY_LONG_SEQUENCE: |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
218 wi.window_type[0] = switch_to_eight ? LONG_START_SEQUENCE : ONLY_LONG_SEQUENCE; |
11998 | 219 next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : ONLY_LONG_SEQUENCE; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
220 break; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
221 case LONG_START_SEQUENCE: |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
222 wi.window_type[0] = EIGHT_SHORT_SEQUENCE; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
223 grouping = pch->next_grouping; |
11998 | 224 next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
225 break; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
226 case LONG_STOP_SEQUENCE: |
11998 | 227 wi.window_type[0] = switch_to_eight ? LONG_START_SEQUENCE : ONLY_LONG_SEQUENCE; |
228 next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : ONLY_LONG_SEQUENCE; | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
229 break; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
230 case EIGHT_SHORT_SEQUENCE: |
11998 | 231 stay_short = next_type == EIGHT_SHORT_SEQUENCE || switch_to_eight; |
232 wi.window_type[0] = stay_short ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE; | |
233 grouping = next_type == EIGHT_SHORT_SEQUENCE ? pch->next_grouping : 0; | |
234 next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE; | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
235 break; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
236 } |
11998 | 237 |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
238 pch->next_grouping = window_grouping[attack_n]; |
11998 | 239 pch->next_window_seq = next_type; |
9936 | 240 } else { |
241 for (i = 0; i < 3; i++) | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
242 wi.window_type[i] = prev_type; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
243 grouping = (prev_type == EIGHT_SHORT_SEQUENCE) ? window_grouping[0] : 0; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
244 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
245 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
246 wi.window_shape = 1; |
9936 | 247 if (wi.window_type[0] != EIGHT_SHORT_SEQUENCE) { |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
248 wi.num_windows = 1; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
249 wi.grouping[0] = 1; |
9936 | 250 } else { |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
251 int lastgrp = 0; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
252 wi.num_windows = 8; |
9936 | 253 for (i = 0; i < 8; i++) { |
254 if (!((grouping >> i) & 1)) | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
255 lastgrp = i; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
256 wi.grouping[lastgrp]++; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
257 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
258 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
259 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
260 return wi; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
261 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
262 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
263 /** |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
264 * Calculate band thresholds as suggested in 3GPP TS26.403 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
265 */ |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
266 static void psy_3gpp_analyze(FFPsyContext *ctx, int channel, |
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
267 const float *coefs, FFPsyWindowInfo *wi) |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
268 { |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
269 Psy3gppContext *pctx = (Psy3gppContext*) ctx->model_priv_data; |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
270 Psy3gppChannel *pch = &pctx->ch[channel]; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
271 int start = 0; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
272 int i, w, g; |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
273 const int num_bands = ctx->num_bands[wi->num_windows == 8]; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
274 const uint8_t* band_sizes = ctx->bands[wi->num_windows == 8]; |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
275 Psy3gppCoeffs *coeffs = &pctx->psy_coef[wi->num_windows == 8]; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
276 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
277 //calculate energies, initial thresholds and related values - 5.4.2 "Threshold Calculation" |
9936 | 278 for (w = 0; w < wi->num_windows*16; w += 16) { |
279 for (g = 0; g < num_bands; g++) { | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
280 Psy3gppBand *band = &pch->band[w+g]; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
281 band->energy = 0.0f; |
9936 | 282 for (i = 0; i < band_sizes[g]; i++) |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
283 band->energy += coefs[start+i] * coefs[start+i]; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
284 band->energy *= 1.0f / (512*512); |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
285 band->thr = band->energy * 0.001258925f; |
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
286 start += band_sizes[g]; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
287 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
288 ctx->psy_bands[channel*PSY_MAX_BANDS+w+g].energy = band->energy; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
289 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
290 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
291 //modify thresholds - spread, threshold in quiet - 5.4.3 "Spreaded Energy Calculation" |
9936 | 292 for (w = 0; w < wi->num_windows*16; w += 16) { |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
293 Psy3gppBand *band = &pch->band[w]; |
9938
6c1ac45b3097
cosmetics: Remove unnecessary {} around if/for blocks;
diego
parents:
9937
diff
changeset
|
294 for (g = 1; g < num_bands; g++) |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
295 band[g].thr = FFMAX(band[g].thr, band[g-1].thr * coeffs->spread_low[g-1]); |
9938
6c1ac45b3097
cosmetics: Remove unnecessary {} around if/for blocks;
diego
parents:
9937
diff
changeset
|
296 for (g = num_bands - 2; g >= 0; g--) |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
297 band[g].thr = FFMAX(band[g].thr, band[g+1].thr * coeffs->spread_hi [g]); |
9936 | 298 for (g = 0; g < num_bands; g++) { |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
299 band[g].thr_quiet = FFMAX(band[g].thr, coeffs->ath[g]); |
9938
6c1ac45b3097
cosmetics: Remove unnecessary {} around if/for blocks;
diego
parents:
9937
diff
changeset
|
300 if (wi->num_windows != 8 && wi->window_type[1] != EIGHT_SHORT_SEQUENCE) |
9944
c5ca5e520fe1
Change fminf/fmaxf to FFMIN/FFMAX to fix the build on broken operating systems.
alexc
parents:
9938
diff
changeset
|
301 band[g].thr_quiet = FFMAX(PSY_3GPP_RPEMIN*band[g].thr_quiet, |
c5ca5e520fe1
Change fminf/fmaxf to FFMIN/FFMAX to fix the build on broken operating systems.
alexc
parents:
9938
diff
changeset
|
302 FFMIN(band[g].thr_quiet, |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
303 PSY_3GPP_RPELEV*pch->prev_band[w+g].thr_quiet)); |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
304 band[g].thr = FFMAX(band[g].thr, band[g].thr_quiet * 0.25); |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
305 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
306 ctx->psy_bands[channel*PSY_MAX_BANDS+w+g].threshold = band[g].thr; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
307 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
308 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
309 memcpy(pch->prev_band, pch->band, sizeof(pch->band)); |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
310 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
311 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
312 static av_cold void psy_3gpp_end(FFPsyContext *apc) |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
313 { |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
314 Psy3gppContext *pctx = (Psy3gppContext*) apc->model_priv_data; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
315 av_freep(&pctx->ch); |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
316 av_freep(&apc->model_priv_data); |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
317 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
318 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
319 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
320 const FFPsyModel ff_aac_psy_model = |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
321 { |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
322 .name = "3GPP TS 26.403-inspired model", |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
323 .init = psy_3gpp_init, |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
324 .window = psy_3gpp_window, |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
325 .analyze = psy_3gpp_analyze, |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
326 .end = psy_3gpp_end, |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
327 }; |