Mercurial > libavcodec.hg
annotate aacpsy.c @ 11352:6e0af2cfdcfe libavcodec
Do MC and IDCT in coding (hilbert) order
This increases the slice size to 64 pixels, due to having to decode an
entire chroma superblock row per slice.
This can be up to 6% slower depending on clip and CPU, but is necessary
for future optimizations that gain significantly more than was lost.
author | conrad |
---|---|
date | Wed, 03 Mar 2010 23:27:40 +0000 |
parents | c5ca5e520fe1 |
children | 7dd2a45249a9 |
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 /** | |
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
7606
diff
changeset
|
23 * @file libavcodec/aacpsy.c |
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; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
117 float barks[1024]; |
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 |
9936 | 124 for (i = 0; i < 1024; i++) |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
125 barks[i] = calc_bark(i * ctx->avctx->sample_rate / 2048.0); |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
126 minath = ath(3410, ATH_ADD); |
9936 | 127 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
|
128 Psy3gppCoeffs *coeffs = &pctx->psy_coef[j]; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
129 i = 0; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
130 prev = 0.0; |
9936 | 131 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
|
132 i += ctx->bands[j][g]; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
133 coeffs->barks[g] = (barks[i - 1] + prev) / 2.0; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
134 prev = barks[i - 1]; |
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++) { |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
142 minscale = ath(ctx->avctx->sample_rate * start / 1024.0, 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++) |
9944
c5ca5e520fe1
Change fminf/fmaxf to FFMIN/FFMAX to fix the build on broken operating systems.
alexc
parents:
9938
diff
changeset
|
144 minscale = FFMIN(minscale, ath(ctx->avctx->sample_rate * (start + i) / 1024.0 / 2.0, 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; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
188 FFPsyWindowInfo wi; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
189 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
190 memset(&wi, 0, sizeof(wi)); |
9936 | 191 if (la) { |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
192 float s[8], v; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
193 int switch_to_eight = 0; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
194 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
|
195 int attack_n = 0; |
9936 | 196 for (i = 0; i < 8; i++) { |
197 for (j = 0; j < 128; j++) { | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
198 v = iir_filter(audio[(i*128+j)*ctx->avctx->channels], pch->iir_state); |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
199 sum += v*v; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
200 } |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
201 s[i] = sum; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
202 sum2 += sum; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
203 } |
9936 | 204 for (i = 0; i < 8; i++) { |
205 if (s[i] > pch->win_energy * attack_ratio) { | |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
206 attack_n = i + 1; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
207 switch_to_eight = 1; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
208 break; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
209 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
210 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
211 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
|
212 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
213 wi.window_type[1] = prev_type; |
9936 | 214 switch (prev_type) { |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
215 case ONLY_LONG_SEQUENCE: |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
216 wi.window_type[0] = switch_to_eight ? LONG_START_SEQUENCE : ONLY_LONG_SEQUENCE; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
217 break; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
218 case LONG_START_SEQUENCE: |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
219 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
|
220 grouping = pch->next_grouping; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
221 break; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
222 case LONG_STOP_SEQUENCE: |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
223 wi.window_type[0] = ONLY_LONG_SEQUENCE; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
224 break; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
225 case EIGHT_SHORT_SEQUENCE: |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
226 wi.window_type[0] = switch_to_eight ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
227 grouping = switch_to_eight ? pch->next_grouping : 0; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
228 break; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
229 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
230 pch->next_grouping = window_grouping[attack_n]; |
9936 | 231 } else { |
232 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
|
233 wi.window_type[i] = prev_type; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
234 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
|
235 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
236 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
237 wi.window_shape = 1; |
9936 | 238 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
|
239 wi.num_windows = 1; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
240 wi.grouping[0] = 1; |
9936 | 241 } else { |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
242 int lastgrp = 0; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
243 wi.num_windows = 8; |
9936 | 244 for (i = 0; i < 8; i++) { |
245 if (!((grouping >> i) & 1)) | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
246 lastgrp = i; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
247 wi.grouping[lastgrp]++; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
248 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
249 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
250 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
251 return wi; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
252 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
253 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
254 /** |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
255 * 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
|
256 */ |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
257 static void psy_3gpp_analyze(FFPsyContext *ctx, int channel, |
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
258 const float *coefs, FFPsyWindowInfo *wi) |
9935
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 Psy3gppContext *pctx = (Psy3gppContext*) ctx->model_priv_data; |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
261 Psy3gppChannel *pch = &pctx->ch[channel]; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
262 int start = 0; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
263 int i, w, g; |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
264 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
|
265 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
|
266 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
|
267 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
268 //calculate energies, initial thresholds and related values - 5.4.2 "Threshold Calculation" |
9936 | 269 for (w = 0; w < wi->num_windows*16; w += 16) { |
270 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
|
271 Psy3gppBand *band = &pch->band[w+g]; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
272 band->energy = 0.0f; |
9936 | 273 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
|
274 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
|
275 band->energy *= 1.0f / (512*512); |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
276 band->thr = band->energy * 0.001258925f; |
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
277 start += band_sizes[g]; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
278 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
279 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
|
280 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
281 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
282 //modify thresholds - spread, threshold in quiet - 5.4.3 "Spreaded Energy Calculation" |
9936 | 283 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
|
284 Psy3gppBand *band = &pch->band[w]; |
9938
6c1ac45b3097
cosmetics: Remove unnecessary {} around if/for blocks;
diego
parents:
9937
diff
changeset
|
285 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
|
286 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
|
287 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
|
288 band[g].thr = FFMAX(band[g].thr, band[g+1].thr * coeffs->spread_hi [g]); |
9936 | 289 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
|
290 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
|
291 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
|
292 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
|
293 FFMIN(band[g].thr_quiet, |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
294 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
|
295 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
|
296 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
297 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
|
298 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
299 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
300 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
|
301 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
302 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
303 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
|
304 { |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
305 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
|
306 av_freep(&pctx->ch); |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
307 av_freep(&apc->model_priv_data); |
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 |
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 const FFPsyModel ff_aac_psy_model = |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
312 { |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
313 .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
|
314 .init = psy_3gpp_init, |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
315 .window = psy_3gpp_window, |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
316 .analyze = psy_3gpp_analyze, |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
317 .end = psy_3gpp_end, |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
318 }; |