FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/aacpsy.c
Date: 2026-07-21 08:37:06
Exec Total Coverage
Lines: 457 542 84.3%
Functions: 19 21 90.5%
Branches: 328 425 77.2%

Line Branch Exec Source
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 /**
23 * @file
24 * AAC encoder psychoacoustic model
25 */
26
27 #include "libavutil/attributes.h"
28 #include "libavutil/ffmath.h"
29 #include "libavutil/mem.h"
30
31 #include "avcodec.h"
32 #include "aac.h"
33 #include "psymodel.h"
34
35 /***********************************
36 * TODOs:
37 * try other bitrate controlling mechanism (maybe use ratecontrol.c?)
38 * control quality for quality-based output
39 **********************************/
40
41 /**
42 * constants for 3GPP AAC psychoacoustic model
43 * @{
44 */
45 #define PSY_3GPP_THR_SPREAD_HI 1.5f // spreading factor for low-to-hi threshold spreading (15 dB/Bark)
46 #define PSY_3GPP_THR_SPREAD_LOW 3.0f // spreading factor for hi-to-low threshold spreading (30 dB/Bark)
47 /* spreading factor for low-to-hi energy spreading, long block, > 22kbps/channel (20dB/Bark) */
48 #define PSY_3GPP_EN_SPREAD_HI_L1 2.0f
49 /* spreading factor for low-to-hi energy spreading, long block, <= 22kbps/channel (15dB/Bark) */
50 #define PSY_3GPP_EN_SPREAD_HI_L2 1.5f
51 /* spreading factor for low-to-hi energy spreading, short block (15 dB/Bark) */
52 #define PSY_3GPP_EN_SPREAD_HI_S 1.5f
53 /* spreading factor for hi-to-low energy spreading, long block (30dB/Bark) */
54 #define PSY_3GPP_EN_SPREAD_LOW_L 3.0f
55 /* spreading factor for hi-to-low energy spreading, short block (20dB/Bark) */
56 #define PSY_3GPP_EN_SPREAD_LOW_S 2.0f
57
58 #define PSY_3GPP_RPEMIN 0.01f
59 #define PSY_3GPP_RPELEV 2.0f
60
61 #define PSY_3GPP_C1 3.0f /* log2(8) */
62 #define PSY_3GPP_C2 1.3219281f /* log2(2.5) */
63 #define PSY_3GPP_C3 0.55935729f /* 1 - C2 / C1 */
64
65 #define PSY_SNR_1DB 7.9432821e-1f /* -1dB */
66 #define PSY_SNR_25DB 3.1622776e-3f /* -25dB */
67
68 #define PSY_3GPP_SAVE_SLOPE_L -0.46666667f
69 #define PSY_3GPP_SAVE_SLOPE_S -0.36363637f
70 #define PSY_3GPP_SAVE_ADD_L -0.84285712f
71 #define PSY_3GPP_SAVE_ADD_S -0.75f
72 #define PSY_3GPP_SPEND_SLOPE_L 0.66666669f
73 #define PSY_3GPP_SPEND_SLOPE_S 0.81818181f
74 #define PSY_3GPP_SPEND_ADD_L -0.35f
75 #define PSY_3GPP_SPEND_ADD_S -0.26111111f
76 #define PSY_3GPP_CLIP_LO_L 0.2f
77 #define PSY_3GPP_CLIP_LO_S 0.2f
78 #define PSY_3GPP_CLIP_HI_L 0.95f
79 #define PSY_3GPP_CLIP_HI_S 0.75f
80
81 #define PSY_3GPP_AH_THR_LONG 0.5f
82 #define PSY_3GPP_AH_THR_SHORT 0.63f
83
84 #define PSY_PE_FORGET_SLOPE 511
85
86 enum {
87 PSY_3GPP_AH_NONE,
88 PSY_3GPP_AH_INACTIVE,
89 PSY_3GPP_AH_ACTIVE
90 };
91
92 #define PSY_3GPP_BITS_TO_PE(bits) ((bits) * 1.18f)
93 #define PSY_3GPP_PE_TO_BITS(bits) ((bits) / 1.18f)
94
95 /* LAME psy model constants */
96 #define PSY_LAME_FIR_LEN 21 ///< LAME psy model FIR order
97 #define AAC_BLOCK_SIZE_LONG 1024 ///< long block size
98 #define AAC_BLOCK_SIZE_SHORT 128 ///< short block size
99 #define AAC_NUM_BLOCKS_SHORT 8 ///< number of blocks in a short sequence
100 #define PSY_LAME_NUM_SUBBLOCKS 2 ///< Number of sub-blocks in each short block
101
102 /* Pre-echo-aware attack detection: the LAME ratio test misses gentler attacks after a quiet
103 * gap, which then stay long and pre-echo. For an isolated onset (long for PSY_LAME_PE_GAP
104 * frames) whose pre-onset is below PSY_LAME_PE_QUIET of the frame peak, scale the threshold by
105 * PSY_LAME_PE_RED so it switches short; dense-transient content never qualifies. */
106 #define PSY_LAME_PE_GAP 12 ///< min consecutive long frames before the relaxation applies
107 #define PSY_LAME_PE_QUIET 0.4f ///< pre-onset must be below this fraction of the frame peak
108 #define PSY_LAME_PE_RED 0.45f ///< attack-threshold multiplier for a qualifying isolated onset
109
110 /* The novelty check must see at least one full period of a pulse train to
111 * recognize its pulses as repeats; 30 sub-blocks reaches down to ~23Hz. */
112 #define PSY_LAME_HIST 32 ///< HP sub-block peak history depth
113 #define PSY_LAME_NOV_BACK 30 ///< novelty look-back in sub-blocks
114
115 /**
116 * @}
117 */
118
119 /**
120 * information for single band used by 3GPP TS26.403-inspired psychoacoustic model
121 */
122 typedef struct AacPsyBand{
123 float energy; ///< band energy
124 float thr; ///< energy threshold
125 float thr_quiet; ///< threshold in quiet
126 float nz_lines; ///< number of non-zero spectral lines
127 float active_lines; ///< number of active spectral lines
128 float pe; ///< perceptual entropy
129 float pe_const; ///< constant part of the PE calculation
130 float norm_fac; ///< normalization factor for linearization
131 int avoid_holes; ///< hole avoidance flag
132 }AacPsyBand;
133
134 /**
135 * single/pair channel context for psychoacoustic model
136 */
137 typedef struct AacPsyChannel{
138 AacPsyBand band[128]; ///< bands information
139 AacPsyBand prev_band[128]; ///< bands information from the previous frame
140
141 float win_energy; ///< sliding average of channel energy
142 float iir_state[2]; ///< hi-pass IIR filter state
143 uint8_t next_grouping; ///< stored grouping scheme for the next frame (in case of 8 short window sequence)
144 enum WindowSequence next_window_seq; ///< window sequence to be used in the next frame
145 /* LAME psy model specific members */
146 float attack_threshold; ///< attack threshold for this channel
147 float prev_energy_subshort[AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS];
148 float hp_env_hist[PSY_LAME_HIST]; ///< rolling HP sub-block peak envelope
149 int prev_attack; ///< attack value for the last short block in the previous sequence
150 int next_attack0_zero; ///< whether attack[0] of the next frame is zero
151 int frames_since_short; ///< consecutive long frames (pre-echo-aware isolated-onset gate)
152 float prev_frame_energy; ///< previous frame's full-band lookahead energy (attack veto)
153 int64_t win_count; ///< window() calls so far (frame counter for pair sync)
154 int64_t last_att; ///< win_count value of this channel's last own attack
155
156 /* rate-loop re-analysis rewind state, see psy_3gpp_analyze() */
157 int64_t rc_frame_num; ///< frame this channel last saved rewind state for
158 AacPsyBand rc_prev_band[128]; ///< prev_band as it was entering the frame
159 }AacPsyChannel;
160
161 /**
162 * psychoacoustic model frame type-dependent coefficients
163 */
164 typedef struct AacPsyCoeffs{
165 float ath; ///< absolute threshold of hearing per bands
166 float barks; ///< Bark value for each spectral band in long frame
167 float spread_low[2]; ///< spreading factor for low-to-high threshold spreading in long frame
168 float spread_hi [2]; ///< spreading factor for high-to-low threshold spreading in long frame
169 float min_snr; ///< minimal SNR
170 }AacPsyCoeffs;
171
172 /**
173 * 3GPP TS26.403-inspired psychoacoustic model specific data
174 */
175 typedef struct AacPsyContext{
176 int chan_bitrate; ///< bitrate per channel
177 int frame_bits; ///< average bits per frame
178 int fill_level; ///< bit reservoir fill level
179 struct {
180 float min; ///< minimum allowed PE for bit factor calculation
181 float max; ///< maximum allowed PE for bit factor calculation
182 float previous; ///< allowed PE of the previous frame
183 float correction; ///< PE correction factor
184 } pe;
185 AacPsyCoeffs psy_coef[2][64];
186 AacPsyChannel *ch;
187 float global_quality; ///< normalized global quality taken from avctx
188
189 /* rate-loop re-analysis rewind state, see psy_3gpp_analyze() */
190 int64_t rc_frame_num; ///< frame the rewind state was saved for
191 int rc_first_ch; ///< first channel analyzed in that frame
192 int rc_fill_level;
193 float rc_pe_min, rc_pe_max, rc_pe_previous;
194 }AacPsyContext;
195
196 /**
197 * LAME psy model preset struct
198 */
199 typedef struct PsyLamePreset {
200 int quality; ///< Quality to map the rest of the values to.
201 /* This is overloaded to be both kbps per channel in ABR mode, and
202 * requested quality in constant quality mode.
203 */
204 float st_lrm; ///< short threshold for L, R, and M channels
205 } PsyLamePreset;
206
207 /**
208 * LAME psy model preset table for ABR
209 */
210 static const PsyLamePreset psy_abr_map[] = {
211 /* TODO: Tuning. These were taken from LAME. */
212 /* kbps/ch st_lrm */
213 { 8, 7.60},
214 { 16, 7.60},
215 { 24, 7.60},
216 { 32, 7.60},
217 { 40, 7.60},
218 { 48, 7.60},
219 { 56, 7.60},
220 { 64, 7.40},
221 { 80, 7.00},
222 { 96, 6.60},
223 {112, 6.20},
224 {128, 6.20},
225 {160, 6.20}
226 };
227
228 /**
229 * LAME psy model preset table for constant quality
230 */
231 static const PsyLamePreset psy_vbr_map[] = {
232 /* vbr_q st_lrm */
233 { 0, 4.20},
234 { 1, 4.20},
235 { 2, 4.20},
236 { 3, 4.20},
237 { 4, 4.20},
238 { 5, 4.20},
239 { 6, 4.20},
240 { 7, 4.20},
241 { 8, 4.20},
242 { 9, 4.20},
243 {10, 4.20}
244 };
245
246 /**
247 * LAME psy model FIR coefficient table
248 */
249 static const float psy_fir_coeffs[] = {
250 -8.65163e-18 * 2, -0.00851586 * 2, -6.74764e-18 * 2, 0.0209036 * 2,
251 -3.36639e-17 * 2, -0.0438162 * 2, -1.54175e-17 * 2, 0.0931738 * 2,
252 -5.52212e-17 * 2, -0.313819 * 2
253 };
254
255 /**
256 * Calculate the ABR attack threshold from the above LAME psymodel table.
257 */
258 35 static float lame_calc_attack_threshold(int bitrate)
259 {
260 /* Assume max bitrate to start with */
261 35 int lower_range = 12, upper_range = 12;
262 35 int lower_range_kbps = psy_abr_map[12].quality;
263 35 int upper_range_kbps = psy_abr_map[12].quality;
264 int i;
265
266 /* Determine which bitrates the value specified falls between.
267 * If the loop ends without breaking our above assumption of 320kbps was correct.
268 */
269
2/2
✓ Branch 0 taken 290 times.
✓ Branch 1 taken 4 times.
294 for (i = 1; i < 13; i++) {
270
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 259 times.
290 if (FFMAX(bitrate, psy_abr_map[i].quality) != bitrate) {
271 31 upper_range = i;
272 31 upper_range_kbps = psy_abr_map[i ].quality;
273 31 lower_range = i - 1;
274 31 lower_range_kbps = psy_abr_map[i - 1].quality;
275 31 break; /* Upper range found */
276 }
277 }
278
279 /* Determine which range the value specified is closer to */
280
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 4 times.
35 if ((upper_range_kbps - bitrate) > (bitrate - lower_range_kbps))
281 31 return psy_abr_map[lower_range].st_lrm;
282 4 return psy_abr_map[upper_range].st_lrm;
283 }
284
285 /**
286 * LAME psy model specific initialization
287 */
288 16 static av_cold void lame_window_init(AacPsyContext *ctx, AVCodecContext *avctx)
289 {
290 int i, j;
291
292
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 16 times.
51 for (i = 0; i < avctx->ch_layout.nb_channels; i++) {
293 35 AacPsyChannel *pch = &ctx->ch[i];
294
295
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35 times.
35 if (avctx->flags & AV_CODEC_FLAG_QSCALE)
296 pch->attack_threshold = psy_vbr_map[av_clip(avctx->global_quality / FF_QP2LAMBDA, 0, 10)].st_lrm;
297 else
298 35 pch->attack_threshold = lame_calc_attack_threshold(avctx->bit_rate / avctx->ch_layout.nb_channels / 1000);
299
300
2/2
✓ Branch 0 taken 560 times.
✓ Branch 1 taken 35 times.
595 for (j = 0; j < AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS; j++)
301 560 pch->prev_energy_subshort[j] = 10.0f;
302
2/2
✓ Branch 0 taken 1120 times.
✓ Branch 1 taken 35 times.
1155 for (j = 0; j < PSY_LAME_HIST; j++)
303 1120 pch->hp_env_hist[j] = 10.0f;
304 }
305 16 }
306
307 /**
308 * Calculate Bark value for given line.
309 */
310 1024 static av_cold float calc_bark(float f)
311 {
312 1024 return 13.3f * atanf(0.00076f * f) + 3.5f * atanf((f / 7500.0f) * (f / 7500.0f));
313 }
314
315 #define ATH_ADD 4
316 /**
317 * Calculate ATH value for given frequency.
318 * Borrowed from Lame.
319 */
320 20866 static av_cold float ath(float f, float add)
321 {
322 20866 f /= 1000.0f;
323 20866 return 3.64 * pow(f, -0.8)
324 20866 - 6.8 * exp(-0.6 * (f - 3.4) * (f - 3.4))
325 20866 + 6.0 * exp(-0.15 * (f - 8.7) * (f - 8.7))
326 20866 + (0.6 + 0.04 * add) * 0.001 * f * f * f * f;
327 }
328
329 16 static av_cold int psy_3gpp_init(FFPsyContext *ctx) {
330 AacPsyContext *pctx;
331 float bark;
332 int i, j, g, start;
333 float prev, minscale, minath, minsnr, pe_min;
334
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 int chan_bitrate = ctx->avctx->bit_rate / ((ctx->avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : ctx->avctx->ch_layout.nb_channels);
335
336
1/8
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
16 const int bandwidth = ctx->cutoff ? ctx->cutoff : AAC_CUTOFF(ctx->avctx);
337 16 const float num_bark = calc_bark((float)bandwidth);
338
339
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (bandwidth <= 0)
340 return AVERROR(EINVAL);
341
342 16 ctx->model_priv_data = av_mallocz(sizeof(AacPsyContext));
343
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (!ctx->model_priv_data)
344 return AVERROR(ENOMEM);
345 16 pctx = ctx->model_priv_data;
346
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 pctx->global_quality = (ctx->avctx->global_quality ? ctx->avctx->global_quality : 120) * 0.01f;
347
348
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (ctx->avctx->flags & AV_CODEC_FLAG_QSCALE) {
349 /* Use the target average bitrate to compute spread parameters */
350 chan_bitrate = (int)(chan_bitrate / 120.0 * (ctx->avctx->global_quality ? ctx->avctx->global_quality : 120));
351 }
352
353 16 pctx->chan_bitrate = chan_bitrate;
354 16 pctx->frame_bits = FFMIN(2560, chan_bitrate * AAC_BLOCK_SIZE_LONG / ctx->avctx->sample_rate);
355 16 pctx->pe.min = 8.0f * AAC_BLOCK_SIZE_LONG * bandwidth / (ctx->avctx->sample_rate * 2.0f);
356 16 pctx->pe.max = 12.0f * AAC_BLOCK_SIZE_LONG * bandwidth / (ctx->avctx->sample_rate * 2.0f);
357 16 ctx->bitres.size = 6144 - pctx->frame_bits;
358 16 ctx->bitres.size -= ctx->bitres.size % 8;
359 16 pctx->fill_level = ctx->bitres.size;
360 16 minath = ath(3410 - 0.733 * ATH_ADD, ATH_ADD);
361
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 16 times.
48 for (j = 0; j < 2; j++) {
362 32 AacPsyCoeffs *coeffs = pctx->psy_coef[j];
363 32 const uint8_t *band_sizes = ctx->bands[j];
364
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 float line_to_frequency = ctx->avctx->sample_rate / (j ? 256.f : 2048.0f);
365
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 float avg_chan_bits = chan_bitrate * (j ? 128.0f : 1024.0f) / ctx->avctx->sample_rate;
366 /* reference encoder uses 2.4% here instead of 60% like the spec says */
367 32 float bark_pe = 0.024f * PSY_3GPP_BITS_TO_PE(avg_chan_bits) / num_bark;
368
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 float en_spread_low = j ? PSY_3GPP_EN_SPREAD_LOW_S : PSY_3GPP_EN_SPREAD_LOW_L;
369 /* High energy spreading for long blocks <= 22kbps/channel and short blocks are the same. */
370
3/4
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
32 float en_spread_hi = (j || (chan_bitrate <= 22.0f)) ? PSY_3GPP_EN_SPREAD_HI_S : PSY_3GPP_EN_SPREAD_HI_L1;
371
372 32 i = 0;
373 32 prev = 0.0;
374
2/2
✓ Branch 0 taken 1008 times.
✓ Branch 1 taken 32 times.
1040 for (g = 0; g < ctx->num_bands[j]; g++) {
375 1008 i += band_sizes[g];
376 1008 bark = calc_bark((i-1) * line_to_frequency);
377 1008 coeffs[g].barks = (bark + prev) / 2.0;
378 1008 prev = bark;
379 }
380
2/2
✓ Branch 0 taken 976 times.
✓ Branch 1 taken 32 times.
1008 for (g = 0; g < ctx->num_bands[j] - 1; g++) {
381 976 AacPsyCoeffs *coeff = &coeffs[g];
382 976 float bark_width = coeffs[g+1].barks - coeffs->barks;
383 976 coeff->spread_low[0] = ff_exp10(-bark_width * PSY_3GPP_THR_SPREAD_LOW);
384 976 coeff->spread_hi [0] = ff_exp10(-bark_width * PSY_3GPP_THR_SPREAD_HI);
385 976 coeff->spread_low[1] = ff_exp10(-bark_width * en_spread_low);
386 976 coeff->spread_hi [1] = ff_exp10(-bark_width * en_spread_hi);
387 976 pe_min = bark_pe * bark_width;
388 976 minsnr = exp2(pe_min / band_sizes[g]) - 1.5f;
389 976 coeff->min_snr = av_clipf(1.0f / minsnr, PSY_SNR_25DB, PSY_SNR_1DB);
390 }
391 32 start = 0;
392
2/2
✓ Branch 0 taken 1008 times.
✓ Branch 1 taken 32 times.
1040 for (g = 0; g < ctx->num_bands[j]; g++) {
393 1008 minscale = ath(start * line_to_frequency, ATH_ADD);
394
2/2
✓ Branch 0 taken 17424 times.
✓ Branch 1 taken 1008 times.
18432 for (i = 1; i < band_sizes[g]; i++)
395
2/2
✓ Branch 1 taken 2418 times.
✓ Branch 2 taken 15006 times.
17424 minscale = FFMIN(minscale, ath((start + i) * line_to_frequency, ATH_ADD));
396 1008 coeffs[g].ath = minscale - minath;
397 1008 start += band_sizes[g];
398 }
399 }
400
401 16 pctx->ch = av_calloc(ctx->avctx->ch_layout.nb_channels, sizeof(*pctx->ch));
402
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (!pctx->ch) {
403 av_freep(&ctx->model_priv_data);
404 return AVERROR(ENOMEM);
405 }
406
407 16 pctx->rc_frame_num = -1;
408
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 16 times.
51 for (i = 0; i < ctx->avctx->ch_layout.nb_channels; i++)
409 35 pctx->ch[i].rc_frame_num = -1;
410
411 16 lame_window_init(pctx, ctx->avctx);
412
413 16 return 0;
414 }
415
416 /**
417 * IIR filter used in block switching decision
418 */
419 static float iir_filter(int in, float state[2])
420 {
421 float ret;
422
423 ret = 0.7548f * (in - state[0]) + 0.5095f * state[1];
424 state[0] = in;
425 state[1] = ret;
426 return ret;
427 }
428
429 /**
430 * window grouping information stored as bits (0 - new group, 1 - group continues)
431 */
432 static const uint8_t window_grouping[9] = {
433 0xB6, 0x6C, 0xD8, 0xB2, 0x66, 0xC6, 0x96, 0x36, 0x36
434 };
435
436 /**
437 * Tell encoder which window types to use.
438 * @see 3GPP TS26.403 5.4.1 "Blockswitching"
439 */
440 av_unused static FFPsyWindowInfo psy_3gpp_window(FFPsyContext *ctx,
441 const int16_t *audio,
442 const int16_t *la,
443 int channel, int prev_type)
444 {
445 int i, j;
446 int br = ((AacPsyContext*)ctx->model_priv_data)->chan_bitrate;
447 int attack_ratio = br <= 16000 ? 18 : 10;
448 AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data;
449 AacPsyChannel *pch = &pctx->ch[channel];
450 uint8_t grouping = 0;
451 int next_type = pch->next_window_seq;
452 FFPsyWindowInfo wi = { { 0 } };
453
454 if (la) {
455 float s[8], v;
456 int switch_to_eight = 0;
457 float sum = 0.0, sum2 = 0.0;
458 int attack_n = 0;
459 int stay_short = 0;
460 for (i = 0; i < 8; i++) {
461 for (j = 0; j < 128; j++) {
462 v = iir_filter(la[i*128+j], pch->iir_state);
463 sum += v*v;
464 }
465 s[i] = sum;
466 sum2 += sum;
467 }
468 for (i = 0; i < 8; i++) {
469 if (s[i] > pch->win_energy * attack_ratio) {
470 attack_n = i + 1;
471 switch_to_eight = 1;
472 break;
473 }
474 }
475 pch->win_energy = pch->win_energy*7/8 + sum2/64;
476
477 wi.window_type[1] = prev_type;
478 switch (prev_type) {
479 case ONLY_LONG_SEQUENCE:
480 wi.window_type[0] = switch_to_eight ? LONG_START_SEQUENCE : ONLY_LONG_SEQUENCE;
481 next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : ONLY_LONG_SEQUENCE;
482 break;
483 case LONG_START_SEQUENCE:
484 wi.window_type[0] = EIGHT_SHORT_SEQUENCE;
485 grouping = pch->next_grouping;
486 next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE;
487 break;
488 case LONG_STOP_SEQUENCE:
489 wi.window_type[0] = switch_to_eight ? LONG_START_SEQUENCE : ONLY_LONG_SEQUENCE;
490 next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : ONLY_LONG_SEQUENCE;
491 break;
492 case EIGHT_SHORT_SEQUENCE:
493 stay_short = next_type == EIGHT_SHORT_SEQUENCE || switch_to_eight;
494 wi.window_type[0] = stay_short ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE;
495 grouping = next_type == EIGHT_SHORT_SEQUENCE ? pch->next_grouping : 0;
496 next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE;
497 break;
498 }
499
500 pch->next_grouping = window_grouping[attack_n];
501 pch->next_window_seq = next_type;
502 } else {
503 for (i = 0; i < 3; i++)
504 wi.window_type[i] = prev_type;
505 grouping = (prev_type == EIGHT_SHORT_SEQUENCE) ? window_grouping[0] : 0;
506 }
507
508 wi.window_shape = 1;
509 if (wi.window_type[0] != EIGHT_SHORT_SEQUENCE) {
510 wi.num_windows = 1;
511 wi.grouping[0] = 1;
512 } else {
513 int lastgrp = 0;
514 wi.num_windows = 8;
515 for (i = 0; i < 8; i++) {
516 if (!((grouping >> i) & 1))
517 lastgrp = i;
518 wi.grouping[lastgrp]++;
519 }
520 }
521
522 return wi;
523 }
524
525 /* 5.6.1.2 "Calculation of Bit Demand" */
526 9458 static int calc_bit_demand(AacPsyContext *ctx, float pe, int bits, int size,
527 int short_window)
528 {
529
2/2
✓ Branch 0 taken 241 times.
✓ Branch 1 taken 9217 times.
9458 const float bitsave_slope = short_window ? PSY_3GPP_SAVE_SLOPE_S : PSY_3GPP_SAVE_SLOPE_L;
530
2/2
✓ Branch 0 taken 241 times.
✓ Branch 1 taken 9217 times.
9458 const float bitsave_add = short_window ? PSY_3GPP_SAVE_ADD_S : PSY_3GPP_SAVE_ADD_L;
531
2/2
✓ Branch 0 taken 241 times.
✓ Branch 1 taken 9217 times.
9458 const float bitspend_slope = short_window ? PSY_3GPP_SPEND_SLOPE_S : PSY_3GPP_SPEND_SLOPE_L;
532
2/2
✓ Branch 0 taken 241 times.
✓ Branch 1 taken 9217 times.
9458 const float bitspend_add = short_window ? PSY_3GPP_SPEND_ADD_S : PSY_3GPP_SPEND_ADD_L;
533 9458 const float clip_low = short_window ? PSY_3GPP_CLIP_LO_S : PSY_3GPP_CLIP_LO_L;
534
2/2
✓ Branch 0 taken 241 times.
✓ Branch 1 taken 9217 times.
9458 const float clip_high = short_window ? PSY_3GPP_CLIP_HI_S : PSY_3GPP_CLIP_HI_L;
535 float clipped_pe, bit_save, bit_spend, bit_factor, fill_level, forgetful_min_pe;
536
537 9458 ctx->fill_level += ctx->frame_bits - bits;
538 9458 ctx->fill_level = av_clip(ctx->fill_level, 0, size);
539 9458 fill_level = av_clipf((float)ctx->fill_level / size, clip_low, clip_high);
540 9458 clipped_pe = av_clipf(pe, ctx->pe.min, ctx->pe.max);
541 9458 bit_save = (fill_level + bitsave_add) * bitsave_slope;
542 assert(bit_save <= 0.3f && bit_save >= -0.05000001f);
543 9458 bit_spend = (fill_level + bitspend_add) * bitspend_slope;
544 assert(bit_spend <= 0.5f && bit_spend >= -0.1f);
545 /* The bit factor graph in the spec is obviously incorrect.
546 * bit_spend + ((bit_spend - bit_spend))...
547 * The reference encoder subtracts everything from 1, but also seems incorrect.
548 * 1 - bit_save + ((bit_spend + bit_save))...
549 * Hopefully below is correct.
550 */
551 9458 bit_factor = 1.0f - bit_save + ((bit_spend - bit_save) / (ctx->pe.max - ctx->pe.min)) * (clipped_pe - ctx->pe.min);
552 /* NOTE: The reference encoder attempts to center pe max/min around the current pe.
553 * Here we do that by slowly forgetting pe.min when pe stays in a range that makes
554 * it unlikely (ie: above the mean)
555 */
556
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 9412 times.
9458 ctx->pe.max = FFMAX(pe, ctx->pe.max);
557 18916 forgetful_min_pe = ((ctx->pe.min * PSY_PE_FORGET_SLOPE)
558
2/2
✓ Branch 0 taken 2911 times.
✓ Branch 1 taken 6547 times.
9458 + FFMAX(ctx->pe.min, pe * (pe / ctx->pe.max))) / (PSY_PE_FORGET_SLOPE + 1);
559
2/2
✓ Branch 0 taken 9434 times.
✓ Branch 1 taken 24 times.
9458 ctx->pe.min = FFMIN(pe, forgetful_min_pe);
560
561 /* NOTE: allocate a minimum of 1/8th average frame bits, to avoid
562 * reservoir starvation from producing zero-bit frames
563 */
564
6/6
✓ Branch 0 taken 9444 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 1156 times.
✓ Branch 3 taken 8302 times.
✓ Branch 4 taken 1142 times.
✓ Branch 5 taken 14 times.
9458 return FFMIN(
565 ctx->frame_bits * bit_factor,
566 FFMAX(ctx->frame_bits + size - bits, ctx->frame_bits / 8));
567 }
568
569 1606052 static float calc_pe_3gpp(AacPsyBand *band)
570 {
571 float pe, a;
572
573 1606052 band->pe = 0.0f;
574 1606052 band->pe_const = 0.0f;
575 1606052 band->active_lines = 0.0f;
576
2/2
✓ Branch 0 taken 1581663 times.
✓ Branch 1 taken 24389 times.
1606052 if (band->energy > band->thr) {
577 1581663 a = log2f(band->energy);
578 1581663 pe = a - log2f(band->thr);
579 1581663 band->active_lines = band->nz_lines;
580
2/2
✓ Branch 0 taken 751811 times.
✓ Branch 1 taken 829852 times.
1581663 if (pe < PSY_3GPP_C1) {
581 751811 pe = pe * PSY_3GPP_C3 + PSY_3GPP_C2;
582 751811 a = a * PSY_3GPP_C3 + PSY_3GPP_C2;
583 751811 band->active_lines *= PSY_3GPP_C3;
584 }
585 1581663 band->pe = pe * band->nz_lines;
586 1581663 band->pe_const = a * band->nz_lines;
587 }
588
589 1606052 return band->pe;
590 }
591
592 24076 static float calc_reduction_3gpp(float a, float desired_pe, float pe,
593 float active_lines)
594 {
595 float thr_avg, reduction;
596
597
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 24072 times.
24076 if(active_lines == 0.0)
598 4 return 0;
599
600 24072 thr_avg = exp2f((a - pe) / (4.0f * active_lines));
601 24072 reduction = exp2f((a - desired_pe) / (4.0f * active_lines)) - thr_avg;
602
603
2/2
✓ Branch 0 taken 21377 times.
✓ Branch 1 taken 2695 times.
24072 return FFMAX(reduction, 0.0f);
604 }
605
606 1127427 static float calc_reduced_thr_3gpp(AacPsyBand *band, float min_snr,
607 float reduction)
608 {
609 1127427 float thr = band->thr;
610
611
2/2
✓ Branch 0 taken 1110895 times.
✓ Branch 1 taken 16532 times.
1127427 if (band->energy > thr) {
612 1110895 thr = sqrtf(thr);
613 1110895 thr = sqrtf(thr) + reduction;
614 1110895 thr *= thr;
615 1110895 thr *= thr;
616
617 /* This deviates from the 3GPP spec to match the reference encoder.
618 * It performs min(thr_reduced, max(thr, energy/min_snr)) only for bands
619 * that have hole avoidance on (active or inactive). It always reduces the
620 * threshold of bands with hole avoidance off.
621 */
622
4/4
✓ Branch 0 taken 342617 times.
✓ Branch 1 taken 768278 times.
✓ Branch 2 taken 342549 times.
✓ Branch 3 taken 68 times.
1110895 if (thr > band->energy * min_snr && band->avoid_holes != PSY_3GPP_AH_NONE) {
623
2/2
✓ Branch 0 taken 5585 times.
✓ Branch 1 taken 336964 times.
342549 thr = FFMAX(band->thr, band->energy * min_snr);
624 342549 band->avoid_holes = PSY_3GPP_AH_ACTIVE;
625 }
626 }
627
628 1127427 return thr;
629 }
630
631 9458 static void calc_thr_3gpp(const FFPsyWindowInfo *wi, const int num_bands, AacPsyChannel *pch,
632 const uint8_t *band_sizes, const float *coefs, const int cutoff)
633 {
634 int i, w, g;
635 9458 int start = 0, wstart = 0;
636
2/2
✓ Branch 0 taken 11145 times.
✓ Branch 1 taken 9458 times.
20603 for (w = 0; w < wi->num_windows*16; w += 16) {
637 11145 wstart = 0;
638
2/2
✓ Branch 0 taken 478625 times.
✓ Branch 1 taken 11145 times.
489770 for (g = 0; g < num_bands; g++) {
639 478625 AacPsyBand *band = &pch->band[w+g];
640
641 478625 float form_factor = 0.0f;
642 float Temp;
643 478625 band->energy = 0.0f;
644
2/2
✓ Branch 0 taken 474385 times.
✓ Branch 1 taken 4240 times.
478625 if (wstart < cutoff) {
645
2/2
✓ Branch 0 taken 9501696 times.
✓ Branch 1 taken 474385 times.
9976081 for (i = 0; i < band_sizes[g]; i++) {
646 9501696 band->energy += coefs[start+i] * coefs[start+i];
647 9501696 form_factor += sqrtf(fabs(coefs[start+i]));
648 }
649 }
650
2/2
✓ Branch 0 taken 473269 times.
✓ Branch 1 taken 5356 times.
478625 Temp = band->energy > 0 ? sqrtf((float)band_sizes[g] / band->energy) : 0;
651 478625 band->thr = band->energy * 0.001258925f;
652 478625 band->nz_lines = form_factor * sqrtf(Temp);
653
654 478625 start += band_sizes[g];
655 478625 wstart += band_sizes[g];
656 }
657 }
658 9458 }
659
660 6416 static void psy_hp_filter(const float *firbuf, float *hpfsmpl, const float *psy_fir_coeffs)
661 {
662 int i, j;
663
2/2
✓ Branch 0 taken 6569984 times.
✓ Branch 1 taken 6416 times.
6576400 for (i = 0; i < AAC_BLOCK_SIZE_LONG; i++) {
664 float sum1, sum2;
665 6569984 sum1 = firbuf[i + (PSY_LAME_FIR_LEN - 1) / 2];
666 6569984 sum2 = 0.0;
667
2/2
✓ Branch 0 taken 32849920 times.
✓ Branch 1 taken 6569984 times.
39419904 for (j = 0; j < ((PSY_LAME_FIR_LEN - 1) / 2) - 1; j += 2) {
668 32849920 sum1 += psy_fir_coeffs[j] * (firbuf[i + j] + firbuf[i + PSY_LAME_FIR_LEN - j]);
669 32849920 sum2 += psy_fir_coeffs[j + 1] * (firbuf[i + j + 1] + firbuf[i + PSY_LAME_FIR_LEN - j - 1]);
670 }
671 /* NOTE: The LAME psymodel expects it's input in the range -32768 to 32768.
672 * Tuning this for normalized floats would be difficult. */
673 6569984 hpfsmpl[i] = (sum1 + sum2) * 32768.0f;
674 }
675 6416 }
676
677 /**
678 * Calculate band thresholds as suggested in 3GPP TS26.403
679 */
680 9458 static void psy_3gpp_analyze_channel(FFPsyContext *ctx, int channel,
681 const float *coefs, const FFPsyWindowInfo *wi)
682 {
683 9458 AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data;
684 9458 AacPsyChannel *pch = &pctx->ch[channel];
685 int i, w, g;
686 9458 float desired_bits, desired_pe, delta_pe, reduction= NAN, spread_en[128] = {0};
687 9458 float a = 0.0f, active_lines = 0.0f, norm_fac = 0.0f;
688
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9458 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
9458 float pe = pctx->chan_bitrate > 32000 ? 0.0f : FFMAX(50.0f, 100.0f - pctx->chan_bitrate * 100.0f / 32000.0f);
689
2/2
✓ Branch 0 taken 241 times.
✓ Branch 1 taken 9217 times.
9458 const int num_bands = ctx->num_bands[wi->num_windows == 8];
690
2/2
✓ Branch 0 taken 241 times.
✓ Branch 1 taken 9217 times.
9458 const uint8_t *band_sizes = ctx->bands[wi->num_windows == 8];
691 9458 uint8_t s2l[16] = {0};
692
2/2
✓ Branch 0 taken 241 times.
✓ Branch 1 taken 9217 times.
9699 int start_after_long = wi->num_windows == 8 &&
693
2/2
✓ Branch 0 taken 206 times.
✓ Branch 1 taken 35 times.
241 wi->window_type[1] == LONG_START_SEQUENCE;
694 { /* short->long grid band map for cross-transition pre-echo control */
695
2/2
✓ Branch 0 taken 206 times.
✓ Branch 1 taken 9252 times.
9458 if (start_after_long) {
696 206 const uint8_t *ls = ctx->bands[0];
697 206 const int ln = ctx->num_bands[0];
698 206 const uint8_t *ss = ctx->bands[1];
699 206 int lacc = 0, sacc = 0, gl = 0;
700
3/4
✓ Branch 0 taken 2884 times.
✓ Branch 1 taken 206 times.
✓ Branch 2 taken 2884 times.
✗ Branch 3 not taken.
3090 for (int gs = 0; gs < num_bands && gs < 16; gs++) {
701 2884 int center8 = (sacc + ss[gs] / 2) * 8;
702
4/4
✓ Branch 0 taken 12566 times.
✓ Branch 1 taken 206 times.
✓ Branch 2 taken 9888 times.
✓ Branch 3 taken 2678 times.
12772 while (gl < ln - 1 && lacc + ls[gl] <= center8) { lacc += ls[gl]; gl++; }
703 2884 s2l[gs] = gl;
704 2884 sacc += ss[gs];
705 }
706 }
707 }
708 9458 AacPsyCoeffs *coeffs = pctx->psy_coef[wi->num_windows == 8];
709
2/2
✓ Branch 0 taken 241 times.
✓ Branch 1 taken 9217 times.
9458 const float avoid_hole_thr = wi->num_windows == 8 ? PSY_3GPP_AH_THR_SHORT : PSY_3GPP_AH_THR_LONG;
710
1/8
✓ Branch 0 taken 9458 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
9458 const int bandwidth = ctx->cutoff ? ctx->cutoff : AAC_CUTOFF(ctx->avctx);
711 9458 const int cutoff = bandwidth * 2048 / wi->num_windows / ctx->avctx->sample_rate;
712
713 //calculate energies, initial thresholds and related values - 5.4.2 "Threshold Calculation"
714 9458 calc_thr_3gpp(wi, num_bands, pch, band_sizes, coefs, cutoff);
715
716 //modify thresholds and energies - spread, threshold in quiet, pre-echo control
717
2/2
✓ Branch 0 taken 11145 times.
✓ Branch 1 taken 9458 times.
20603 for (w = 0; w < wi->num_windows*16; w += 16) {
718 11145 AacPsyBand *bands = &pch->band[w];
719
720 /* 5.4.2.3 "Spreading" & 5.4.3 "Spread Energy Calculation" */
721 11145 spread_en[0] = bands[0].energy;
722
2/2
✓ Branch 0 taken 467480 times.
✓ Branch 1 taken 11145 times.
478625 for (g = 1; g < num_bands; g++) {
723
2/2
✓ Branch 0 taken 461546 times.
✓ Branch 1 taken 5934 times.
467480 bands[g].thr = FFMAX(bands[g].thr, bands[g-1].thr * coeffs[g].spread_hi[0]);
724
2/2
✓ Branch 0 taken 462041 times.
✓ Branch 1 taken 5439 times.
467480 spread_en[w+g] = FFMAX(bands[g].energy, spread_en[w+g-1] * coeffs[g].spread_hi[1]);
725 }
726
2/2
✓ Branch 0 taken 467480 times.
✓ Branch 1 taken 11145 times.
478625 for (g = num_bands - 2; g >= 0; g--) {
727
2/2
✓ Branch 0 taken 463387 times.
✓ Branch 1 taken 4093 times.
467480 bands[g].thr = FFMAX(bands[g].thr, bands[g+1].thr * coeffs[g].spread_low[0]);
728
2/2
✓ Branch 0 taken 461224 times.
✓ Branch 1 taken 6256 times.
467480 spread_en[w+g] = FFMAX(spread_en[w+g], spread_en[w+g+1] * coeffs[g].spread_low[1]);
729 }
730 //5.4.2.4 "Threshold in quiet"
731
2/2
✓ Branch 0 taken 478625 times.
✓ Branch 1 taken 11145 times.
489770 for (g = 0; g < num_bands; g++) {
732 478625 AacPsyBand *band = &bands[g];
733
734
2/2
✓ Branch 0 taken 356961 times.
✓ Branch 1 taken 121664 times.
478625 band->thr_quiet = band->thr = FFMAX(band->thr, coeffs[g].ath);
735 //5.4.2.5 "Pre-echo control"
736
6/6
✓ Branch 0 taken 467061 times.
✓ Branch 1 taken 11564 times.
✓ Branch 2 taken 443443 times.
✓ Branch 3 taken 23618 times.
✓ Branch 4 taken 440559 times.
✓ Branch 5 taken 2884 times.
478625 if (!(wi->window_type[0] == LONG_STOP_SEQUENCE || (!w && wi->window_type[1] == LONG_START_SEQUENCE)))
737
6/6
✓ Branch 0 taken 69712 times.
✓ Branch 1 taken 394465 times.
✓ Branch 2 taken 10241 times.
✓ Branch 3 taken 453936 times.
✓ Branch 4 taken 59471 times.
✓ Branch 5 taken 394465 times.
464177 band->thr = FFMAX(PSY_3GPP_RPEMIN*band->thr, FFMIN(band->thr,
738 PSY_3GPP_RPELEV*pch->prev_band[w+g].thr_quiet));
739
3/4
✓ Branch 0 taken 14448 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2884 times.
✓ Branch 3 taken 11564 times.
14448 else if (!w && start_after_long)
740 /* w0 after a START frame: grid-mapped, scaled continuity
741 * clamp instead of the spec's skip (cannot bind on noise
742 * content - see memory - but correct for tonal) */
743
6/6
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 2801 times.
✓ Branch 2 taken 69 times.
✓ Branch 3 taken 2815 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 2801 times.
2884 band->thr = FFMAX(PSY_3GPP_RPEMIN*band->thr, FFMIN(band->thr,
744 PSY_3GPP_RPELEV*pch->prev_band[s2l[FFMIN(g,15)]].thr / 8.0f));
745
746 /* 5.6.1.3.1 "Preparatory steps of the perceptual entropy calculation" */
747 478625 pe += calc_pe_3gpp(band);
748 478625 a += band->pe_const;
749 478625 active_lines += band->active_lines;
750
751 /* 5.6.1.3.3 "Selection of the bands for avoidance of holes" */
752
3/4
✓ Branch 0 taken 478519 times.
✓ Branch 1 taken 106 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 478519 times.
478625 if (spread_en[w+g] * avoid_hole_thr > band->energy || coeffs[g].min_snr > 1.0f)
753 106 band->avoid_holes = PSY_3GPP_AH_NONE;
754 else
755 478519 band->avoid_holes = PSY_3GPP_AH_INACTIVE;
756 }
757 }
758
759 /* 5.6.1.3.2 "Calculation of the desired perceptual entropy" */
760 9458 ctx->ch[channel].entropy = pe;
761
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9458 times.
9458 if (ctx->avctx->flags & AV_CODEC_FLAG_QSCALE) {
762 /* (2.5 * 120) achieves almost transparent rate, and we want to give
763 * ample room downwards, so we make that equivalent to QSCALE=2.4
764 */
765 desired_pe = pe * (ctx->avctx->global_quality ? ctx->avctx->global_quality : 120) / (2 * 2.5f * 120.0f);
766 desired_bits = FFMIN(2560, PSY_3GPP_PE_TO_BITS(desired_pe));
767 desired_pe = PSY_3GPP_BITS_TO_PE(desired_bits); // reflect clipping
768
769 /* PE slope smoothing */
770 if (ctx->bitres.bits > 0) {
771 desired_bits = FFMIN(2560, PSY_3GPP_PE_TO_BITS(desired_pe));
772 desired_pe = PSY_3GPP_BITS_TO_PE(desired_bits); // reflect clipping
773 }
774
775 pctx->pe.max = FFMAX(pe, pctx->pe.max);
776 pctx->pe.min = FFMIN(pe, pctx->pe.min);
777 } else {
778 9458 desired_bits = calc_bit_demand(pctx, pe, ctx->bitres.bits, ctx->bitres.size, wi->num_windows == 8);
779 9458 desired_pe = PSY_3GPP_BITS_TO_PE(desired_bits);
780
781 /* NOTE: PE correction is kept simple. During initial testing it had very
782 * little effect on the final bitrate. Probably a good idea to come
783 * back and do more testing later.
784 */
785
2/2
✓ Branch 0 taken 9393 times.
✓ Branch 1 taken 65 times.
9458 if (ctx->bitres.bits > 0)
786 9393 desired_pe *= av_clipf(pctx->pe.previous / PSY_3GPP_BITS_TO_PE(ctx->bitres.bits),
787 0.85f, 1.15f);
788 }
789 9458 pctx->pe.previous = PSY_3GPP_BITS_TO_PE(desired_bits);
790 9458 ctx->bitres.alloc = desired_bits;
791
792
2/2
✓ Branch 0 taken 9434 times.
✓ Branch 1 taken 24 times.
9458 if (desired_pe < pe) {
793 /* 5.6.1.3.4 "First Estimation of the reduction value" */
794
2/2
✓ Branch 0 taken 11121 times.
✓ Branch 1 taken 9434 times.
20555 for (w = 0; w < wi->num_windows*16; w += 16) {
795 11121 reduction = calc_reduction_3gpp(a, desired_pe, pe, active_lines);
796 11121 pe = 0.0f;
797 11121 a = 0.0f;
798 11121 active_lines = 0.0f;
799
2/2
✓ Branch 0 taken 477449 times.
✓ Branch 1 taken 11121 times.
488570 for (g = 0; g < num_bands; g++) {
800 477449 AacPsyBand *band = &pch->band[w+g];
801
802 477449 band->thr = calc_reduced_thr_3gpp(band, coeffs[g].min_snr, reduction);
803 /* recalculate PE */
804 477449 pe += calc_pe_3gpp(band);
805 477449 a += band->pe_const;
806 477449 active_lines += band->active_lines;
807 }
808 }
809
810 /* 5.6.1.3.5 "Second Estimation of the reduction value" */
811
2/2
✓ Branch 0 taken 12955 times.
✓ Branch 1 taken 3521 times.
16476 for (i = 0; i < 2; i++) {
812 12955 float pe_no_ah = 0.0f, desired_pe_no_ah;
813 12955 active_lines = a = 0.0f;
814
2/2
✓ Branch 0 taken 14642 times.
✓ Branch 1 taken 12955 times.
27597 for (w = 0; w < wi->num_windows*16; w += 16) {
815
2/2
✓ Branch 0 taken 649978 times.
✓ Branch 1 taken 14642 times.
664620 for (g = 0; g < num_bands; g++) {
816 649978 AacPsyBand *band = &pch->band[w+g];
817
818
2/2
✓ Branch 0 taken 517217 times.
✓ Branch 1 taken 132761 times.
649978 if (band->avoid_holes != PSY_3GPP_AH_ACTIVE) {
819 517217 pe_no_ah += band->pe;
820 517217 a += band->pe_const;
821 517217 active_lines += band->active_lines;
822 }
823 }
824 }
825
2/2
✓ Branch 0 taken 12890 times.
✓ Branch 1 taken 65 times.
12955 desired_pe_no_ah = FFMAX(desired_pe - (pe - pe_no_ah), 0.0f);
826
1/2
✓ Branch 0 taken 12955 times.
✗ Branch 1 not taken.
12955 if (active_lines > 0.0f)
827 12955 reduction = calc_reduction_3gpp(a, desired_pe_no_ah, pe_no_ah, active_lines);
828
829 12955 pe = 0.0f;
830
2/2
✓ Branch 0 taken 14642 times.
✓ Branch 1 taken 12955 times.
27597 for (w = 0; w < wi->num_windows*16; w += 16) {
831
2/2
✓ Branch 0 taken 649978 times.
✓ Branch 1 taken 14642 times.
664620 for (g = 0; g < num_bands; g++) {
832 649978 AacPsyBand *band = &pch->band[w+g];
833
834
1/2
✓ Branch 0 taken 649978 times.
✗ Branch 1 not taken.
649978 if (active_lines > 0.0f)
835 649978 band->thr = calc_reduced_thr_3gpp(band, coeffs[g].min_snr, reduction);
836 649978 pe += calc_pe_3gpp(band);
837
1/2
✓ Branch 0 taken 649978 times.
✗ Branch 1 not taken.
649978 if (band->thr > 0.0f)
838 649978 band->norm_fac = band->active_lines / band->thr;
839 else
840 band->norm_fac = 0.0f;
841 649978 norm_fac += band->norm_fac;
842 }
843 }
844 12955 delta_pe = desired_pe - pe;
845
2/2
✓ Branch 0 taken 5913 times.
✓ Branch 1 taken 7042 times.
12955 if (fabs(delta_pe) > 0.05f * desired_pe)
846 5913 break;
847 }
848
849
2/2
✓ Branch 0 taken 5194 times.
✓ Branch 1 taken 4240 times.
9434 if (pe < 1.15f * desired_pe) {
850 /* 6.6.1.3.6 "Final threshold modification by linearization" */
851
1/2
✓ Branch 0 taken 5194 times.
✗ Branch 1 not taken.
5194 norm_fac = norm_fac ? 1.0f / norm_fac : 0;
852
2/2
✓ Branch 0 taken 5194 times.
✓ Branch 1 taken 5194 times.
10388 for (w = 0; w < wi->num_windows*16; w += 16) {
853
2/2
✓ Branch 0 taken 254506 times.
✓ Branch 1 taken 5194 times.
259700 for (g = 0; g < num_bands; g++) {
854 254506 AacPsyBand *band = &pch->band[w+g];
855
856
2/2
✓ Branch 0 taken 251236 times.
✓ Branch 1 taken 3270 times.
254506 if (band->active_lines > 0.5f) {
857 251236 float delta_sfb_pe = band->norm_fac * norm_fac * delta_pe;
858 251236 float thr = band->thr;
859
860 251236 thr *= exp2f(delta_sfb_pe / band->active_lines);
861
4/4
✓ Branch 0 taken 25292 times.
✓ Branch 1 taken 225944 times.
✓ Branch 2 taken 89 times.
✓ Branch 3 taken 25203 times.
251236 if (thr > coeffs[g].min_snr * band->energy && band->avoid_holes == PSY_3GPP_AH_INACTIVE)
862
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 89 times.
89 thr = FFMAX(band->thr, coeffs[g].min_snr * band->energy);
863 251236 band->thr = thr;
864 }
865 }
866 }
867 } else {
868 /* 5.6.1.3.7 "Further perceptual entropy reduction" */
869 4240 g = num_bands;
870
4/4
✓ Branch 0 taken 203129 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 198903 times.
✓ Branch 3 taken 4226 times.
203143 while (pe > desired_pe && g--) {
871
2/2
✓ Branch 0 taken 222521 times.
✓ Branch 1 taken 198903 times.
421424 for (w = 0; w < wi->num_windows*16; w+= 16) {
872 222521 AacPsyBand *band = &pch->band[w+g];
873
4/4
✓ Branch 0 taken 222469 times.
✓ Branch 1 taken 52 times.
✓ Branch 2 taken 366 times.
✓ Branch 3 taken 222103 times.
222521 if (band->avoid_holes != PSY_3GPP_AH_NONE && coeffs[g].min_snr < PSY_SNR_1DB) {
874 366 coeffs[g].min_snr = PSY_SNR_1DB;
875 366 band->thr = band->energy * PSY_SNR_1DB;
876 366 pe += band->active_lines * 1.5f - band->pe;
877 }
878 }
879 }
880 /* TODO: allow more holes (unused without mid/side) */
881 }
882 }
883
884
2/2
✓ Branch 0 taken 11145 times.
✓ Branch 1 taken 9458 times.
20603 for (w = 0; w < wi->num_windows*16; w += 16) {
885
2/2
✓ Branch 0 taken 478625 times.
✓ Branch 1 taken 11145 times.
489770 for (g = 0; g < num_bands; g++) {
886 478625 AacPsyBand *band = &pch->band[w+g];
887 478625 FFPsyBand *psy_band = &ctx->ch[channel].psy_bands[w+g];
888
889 478625 psy_band->threshold = band->thr;
890 478625 psy_band->energy = band->energy;
891 478625 psy_band->spread = band->active_lines * 2.0f / band_sizes[g];
892 478625 psy_band->bits = PSY_3GPP_PE_TO_BITS(band->pe);
893 }
894 }
895
896 9458 memcpy(pch->prev_band, pch->band, sizeof(pch->band));
897 9458 }
898
899 5070 static void psy_3gpp_analyze(FFPsyContext *ctx, int channel,
900 const float **coeffs, const FFPsyWindowInfo *wi)
901 {
902 int ch;
903 5070 FFPsyChannelGroup *group = ff_psy_find_group(ctx, channel);
904 5070 AacPsyContext *pctx = ctx->model_priv_data;
905
906 /* The encoder's rate-control loop may re-run the analysis for the same
907 * frame; carried state (bit reservoir, PE history, previous-frame
908 * thresholds) must advance exactly once per frame, so save it on the
909 * frame's first run and rewind on re-runs. */
910
2/2
✓ Branch 0 taken 3429 times.
✓ Branch 1 taken 1641 times.
5070 if (ctx->avctx->frame_num != pctx->rc_frame_num) {
911 3429 pctx->rc_frame_num = ctx->avctx->frame_num;
912 3429 pctx->rc_first_ch = channel;
913 3429 pctx->rc_fill_level = pctx->fill_level;
914 3429 pctx->rc_pe_min = pctx->pe.min;
915 3429 pctx->rc_pe_max = pctx->pe.max;
916 3429 pctx->rc_pe_previous = pctx->pe.previous;
917
2/2
✓ Branch 0 taken 1395 times.
✓ Branch 1 taken 246 times.
1641 } else if (channel == pctx->rc_first_ch) {
918 1395 pctx->fill_level = pctx->rc_fill_level;
919 1395 pctx->pe.min = pctx->rc_pe_min;
920 1395 pctx->pe.max = pctx->rc_pe_max;
921 1395 pctx->pe.previous = pctx->rc_pe_previous;
922 }
923
924
2/2
✓ Branch 0 taken 9458 times.
✓ Branch 1 taken 5070 times.
14528 for (ch = 0; ch < group->num_ch; ch++) {
925 9458 AacPsyChannel *pch = &pctx->ch[channel + ch];
926
2/2
✓ Branch 0 taken 6532 times.
✓ Branch 1 taken 2926 times.
9458 if (ctx->avctx->frame_num != pch->rc_frame_num) {
927 6532 pch->rc_frame_num = ctx->avctx->frame_num;
928 6532 memcpy(pch->rc_prev_band, pch->prev_band, sizeof(pch->prev_band));
929 } else {
930 2926 memcpy(pch->prev_band, pch->rc_prev_band, sizeof(pch->prev_band));
931 }
932 9458 psy_3gpp_analyze_channel(ctx, channel + ch, coeffs[ch], &wi[ch]);
933 }
934 5070 }
935
936 16 static av_cold void psy_3gpp_end(FFPsyContext *apc)
937 {
938 16 AacPsyContext *pctx = (AacPsyContext*) apc->model_priv_data;
939
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if (pctx)
940 16 av_freep(&pctx->ch);
941 16 av_freep(&apc->model_priv_data);
942 16 }
943
944 6484 static void lame_apply_block_type(AacPsyChannel *ctx, FFPsyWindowInfo *wi, int uselongblock)
945 {
946 6484 int blocktype = ONLY_LONG_SEQUENCE;
947
2/2
✓ Branch 0 taken 6255 times.
✓ Branch 1 taken 229 times.
6484 if (uselongblock) {
948
2/2
✓ Branch 0 taken 194 times.
✓ Branch 1 taken 6061 times.
6255 if (ctx->next_window_seq == EIGHT_SHORT_SEQUENCE)
949 194 blocktype = LONG_STOP_SEQUENCE;
950 } else {
951 229 blocktype = EIGHT_SHORT_SEQUENCE;
952
2/2
✓ Branch 0 taken 194 times.
✓ Branch 1 taken 35 times.
229 if (ctx->next_window_seq == ONLY_LONG_SEQUENCE)
953 194 ctx->next_window_seq = LONG_START_SEQUENCE;
954
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 229 times.
229 if (ctx->next_window_seq == LONG_STOP_SEQUENCE)
955 ctx->next_window_seq = EIGHT_SHORT_SEQUENCE;
956 }
957
958 6484 wi->window_type[0] = ctx->next_window_seq;
959 6484 ctx->next_window_seq = blocktype;
960 6484 }
961
962 /* Attack detection half of the LAME window decision: everything up to (and
963 * excluding) the block-type state machine. Fills attacks[] and returns the raw
964 * uselongblock; mutates only the detection history. Split out so a channel
965 * pair can be detected first and DECIDED together (synced block switching). */
966 6484 static int psy_lame_detect(AacPsyContext *pctx, AacPsyChannel *pch,
967 const float *la, int channel, int prev_type,
968 int attacks[AAC_NUM_BLOCKS_SHORT + 1])
969 {
970 6484 int uselongblock = 1;
971 int i;
972
973
2/2
✓ Branch 0 taken 6416 times.
✓ Branch 1 taken 68 times.
6484 if (la) {
974 float hpfsmpl[AAC_BLOCK_SIZE_LONG];
975 6416 const float *pf = hpfsmpl;
976 float attack_intensity[(AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS];
977 float energy_subshort[(AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS];
978 6416 float energy_short[AAC_NUM_BLOCKS_SHORT + 1] = { 0 };
979 6416 const float *firbuf = la + (AAC_BLOCK_SIZE_SHORT/4 - PSY_LAME_FIR_LEN);
980 6416 int att_sum = 0;
981
982 /* LAME comment: apply high pass filter of fs/4 */
983 6416 psy_hp_filter(firbuf, hpfsmpl, psy_fir_coeffs);
984
985 /* Calculate the energies of each sub-shortblock */
986
2/2
✓ Branch 0 taken 12832 times.
✓ Branch 1 taken 6416 times.
19248 for (i = 0; i < PSY_LAME_NUM_SUBBLOCKS; i++) {
987 12832 energy_subshort[i] = pch->prev_energy_subshort[i + ((AAC_NUM_BLOCKS_SHORT - 1) * PSY_LAME_NUM_SUBBLOCKS)];
988 assert(pch->prev_energy_subshort[i + ((AAC_NUM_BLOCKS_SHORT - 1) * PSY_LAME_NUM_SUBBLOCKS - 2)] > 0);
989 12832 attack_intensity[i] = energy_subshort[i] / pch->prev_energy_subshort[i + ((AAC_NUM_BLOCKS_SHORT - 1) * PSY_LAME_NUM_SUBBLOCKS - 2)];
990 12832 energy_short[0] += energy_subshort[i];
991 }
992
993
2/2
✓ Branch 0 taken 102656 times.
✓ Branch 1 taken 6416 times.
109072 for (i = 0; i < AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS; i++) {
994 102656 const float *const pfe = pf + AAC_BLOCK_SIZE_LONG / (AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS);
995 102656 float p = 1.0f;
996
2/2
✓ Branch 0 taken 6569984 times.
✓ Branch 1 taken 102656 times.
6672640 for (; pf < pfe; pf++)
997
2/2
✓ Branch 0 taken 6007214 times.
✓ Branch 1 taken 562770 times.
6569984 p = FFMAX(p, fabsf(*pf));
998 102656 pch->prev_energy_subshort[i] = energy_subshort[i + PSY_LAME_NUM_SUBBLOCKS] = p;
999 102656 energy_short[1 + i / PSY_LAME_NUM_SUBBLOCKS] += p;
1000
1001 /* NOTE: The indexes below are [i + 3 - 2] in the LAME source. Compare each sub-block to sub-block - 2 */
1002
2/2
✓ Branch 0 taken 51265 times.
✓ Branch 1 taken 51391 times.
102656 if (p > energy_subshort[i + PSY_LAME_NUM_SUBBLOCKS - 2])
1003 51265 p = p / energy_subshort[i + PSY_LAME_NUM_SUBBLOCKS - 2];
1004
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 51335 times.
51391 else if (energy_subshort[i + PSY_LAME_NUM_SUBBLOCKS - 2] > p * 10.0f)
1005 56 p = energy_subshort[i + PSY_LAME_NUM_SUBBLOCKS - 2] / (p * 10.0f);
1006 else
1007 51335 p = 0.0;
1008
1009 102656 attack_intensity[i + PSY_LAME_NUM_SUBBLOCKS] = p;
1010 }
1011
1012 { /* pre-echo-aware threshold relaxation + periodicity/novelty check
1013 * (a pulse train repeats its peak; a real onset towers) */
1014 6416 float frame_peak = 1.0f;
1015 float env[PSY_LAME_HIST + AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS];
1016 6416 const float nov_gate = 1.25f;
1017 6416 memcpy(env, pch->hp_env_hist, sizeof(pch->hp_env_hist));
1018 6416 memcpy(env + PSY_LAME_HIST, energy_subshort + PSY_LAME_NUM_SUBBLOCKS,
1019 AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS * sizeof(*env));
1020
2/2
✓ Branch 0 taken 102656 times.
✓ Branch 1 taken 6416 times.
109072 for (i = PSY_LAME_NUM_SUBBLOCKS; i < (AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS; i++)
1021
2/2
✓ Branch 0 taken 77134 times.
✓ Branch 1 taken 25522 times.
102656 frame_peak = FFMAX(frame_peak, energy_subshort[i]);
1022
2/2
✓ Branch 0 taken 115488 times.
✓ Branch 1 taken 6416 times.
121904 for (i = 0; i < (AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS; i++)
1023
2/2
✓ Branch 0 taken 115357 times.
✓ Branch 1 taken 131 times.
115488 if (!attacks[i / PSY_LAME_NUM_SUBBLOCKS]) {
1024 115357 float thr = pch->attack_threshold;
1025
2/2
✓ Branch 0 taken 102540 times.
✓ Branch 1 taken 12817 times.
115357 if (i >= PSY_LAME_NUM_SUBBLOCKS &&
1026
2/2
✓ Branch 0 taken 64255 times.
✓ Branch 1 taken 38285 times.
102540 pch->frames_since_short >= PSY_LAME_PE_GAP &&
1027
2/2
✓ Branch 0 taken 4999 times.
✓ Branch 1 taken 59256 times.
64255 energy_subshort[i - PSY_LAME_NUM_SUBBLOCKS] < PSY_LAME_PE_QUIET * frame_peak)
1028 4999 thr *= PSY_LAME_PE_RED;
1029
2/2
✓ Branch 0 taken 335 times.
✓ Branch 1 taken 115022 times.
115357 if (attack_intensity[i] > thr) {
1030 /* An attack must tower over the recent HP envelope:
1031 * within ~12ms always (pitch-rate trains), within
1032 * ~44ms only from steady long-window state (slow
1033 * pulse trains, where an isolated short excursion
1034 * is an audible click). */
1035
3/4
✓ Branch 0 taken 335 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 309 times.
✓ Branch 3 taken 26 times.
335 if (nov_gate > 0.0f && i >= PSY_LAME_NUM_SUBBLOCKS) {
1036 309 const int pos = PSY_LAME_HIST + i - PSY_LAME_NUM_SUBBLOCKS;
1037 309 float nearmax = 1.0f, deepmax = 1.0f;
1038
2/2
✓ Branch 0 taken 1854 times.
✓ Branch 1 taken 309 times.
2163 for (int k = 3; k <= 8; k++)
1039
2/2
✓ Branch 0 taken 1090 times.
✓ Branch 1 taken 764 times.
1854 nearmax = FFMAX(nearmax, env[pos - k]);
1040
2/2
✓ Branch 0 taken 8652 times.
✓ Branch 1 taken 309 times.
8961 for (int k = 3; k <= PSY_LAME_NOV_BACK; k++)
1041
2/2
✓ Branch 0 taken 7174 times.
✓ Branch 1 taken 1478 times.
8652 deepmax = FFMAX(deepmax, env[pos - k]);
1042
2/2
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 120 times.
309 if (energy_subshort[i] < nov_gate * nearmax ||
1043
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 168 times.
189 (energy_subshort[i] < nov_gate * deepmax &&
1044
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 pch->frames_since_short >= PSY_LAME_PE_GAP))
1045 141 continue; /* periodic, not an onset */
1046 }
1047 194 attacks[i / PSY_LAME_NUM_SUBBLOCKS] = (i % PSY_LAME_NUM_SUBBLOCKS) + 1;
1048 }
1049 }
1050 }
1051
1052 /* should have energy change between short blocks, in order to avoid periodic signals */
1053 /* Good samples to show the effect are Trumpet test songs */
1054 /* GB: tuned (1) to avoid too many short blocks for test sample TRUMPET */
1055 /* RH: tuned (2) to let enough short blocks through for test sample FSOL and SNAPS */
1056
2/2
✓ Branch 0 taken 51328 times.
✓ Branch 1 taken 6416 times.
57744 for (i = 1; i < AAC_NUM_BLOCKS_SHORT + 1; i++) {
1057 51328 const float u = energy_short[i - 1];
1058 51328 const float v = energy_short[i];
1059
2/2
✓ Branch 0 taken 25914 times.
✓ Branch 1 taken 25414 times.
51328 const float m = FFMAX(u, v);
1060
2/2
✓ Branch 0 taken 48948 times.
✓ Branch 1 taken 2380 times.
51328 if (m < 40000) { /* (2) */
1061
4/4
✓ Branch 0 taken 48628 times.
✓ Branch 1 taken 320 times.
✓ Branch 2 taken 48121 times.
✓ Branch 3 taken 507 times.
48948 if (u < 2.3f * v && v < 2.3f * u) { /* (1) */
1062
3/4
✓ Branch 0 taken 5964 times.
✓ Branch 1 taken 42157 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5964 times.
48121 if (i == 1 && attacks[0] < attacks[i])
1063 attacks[0] = 0;
1064 48121 attacks[i] = 0;
1065 }
1066 }
1067 51328 att_sum += attacks[i];
1068 }
1069
1070 /* roll the HP sub-block peak history */
1071 6416 memmove(pch->hp_env_hist,
1072 6416 pch->hp_env_hist + AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS,
1073 (PSY_LAME_HIST - AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS) *
1074 sizeof(*pch->hp_env_hist));
1075 6416 memcpy(pch->hp_env_hist + PSY_LAME_HIST - AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS,
1076 energy_subshort + PSY_LAME_NUM_SUBBLOCKS,
1077 AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS * sizeof(*pch->hp_env_hist));
1078
1079
2/2
✓ Branch 0 taken 6340 times.
✓ Branch 1 taken 76 times.
6416 if (pch->next_attack0_zero)
1080 6340 attacks[0] = 0;
1081 6416 pch->next_attack0_zero = !attacks[AAC_NUM_BLOCKS_SHORT];
1082
1083
2/2
✓ Branch 0 taken 6392 times.
✓ Branch 1 taken 24 times.
6416 if (attacks[0] <= pch->prev_attack)
1084 6392 attacks[0] = 0;
1085
1086 6416 att_sum += attacks[0];
1087
1088 /* If the previous attack happened in the last sub-block of the previous sequence,
1089 * or if there's a new attack, use short window */
1090
4/4
✓ Branch 0 taken 6415 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 139 times.
✓ Branch 3 taken 6276 times.
6416 if (pch->prev_attack == PSY_LAME_NUM_SUBBLOCKS || att_sum) {
1091 140 uselongblock = 0;
1092
1093
2/2
✓ Branch 0 taken 1120 times.
✓ Branch 1 taken 140 times.
1260 for (i = 1; i < AAC_NUM_BLOCKS_SHORT + 1; i++)
1094
3/4
✓ Branch 0 taken 122 times.
✓ Branch 1 taken 998 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 122 times.
1120 if (attacks[i] && attacks[i-1])
1095 attacks[i] = 0;
1096 }
1097
1098 } else {
1099 /* We have no lookahead info, so just use same type as the previous sequence. */
1100 68 uselongblock = !(prev_type == EIGHT_SHORT_SEQUENCE);
1101 }
1102 6484 return uselongblock;
1103 }
1104
1105 /* Decision half: the block-type state machine and window/grouping fill,
1106 * given the (possibly pair-synced) final uselongblock. */
1107 6484 static FFPsyWindowInfo psy_lame_apply(AacPsyContext *pctx, AacPsyChannel *pch,
1108 int uselongblock,
1109 const int attacks[AAC_NUM_BLOCKS_SHORT + 1],
1110 int prev_type, int have_la)
1111 {
1112 6484 int grouping = 0;
1113 int i;
1114 6484 FFPsyWindowInfo wi = { { 0 } };
1115
1116
2/2
✓ Branch 0 taken 6416 times.
✓ Branch 1 taken 68 times.
6484 if (have_la)
1117
2/2
✓ Branch 0 taken 6187 times.
✓ Branch 1 taken 229 times.
6416 pch->frames_since_short = uselongblock ? pch->frames_since_short + 1 : 0;
1118
1119 6484 lame_apply_block_type(pch, &wi, uselongblock);
1120
1121 6484 wi.window_type[1] = prev_type;
1122
2/2
✓ Branch 0 taken 6255 times.
✓ Branch 1 taken 229 times.
6484 if (wi.window_type[0] != EIGHT_SHORT_SEQUENCE) {
1123
1124 6255 wi.num_windows = 1;
1125 6255 wi.grouping[0] = 1;
1126
2/2
✓ Branch 0 taken 194 times.
✓ Branch 1 taken 6061 times.
6255 if (wi.window_type[0] == LONG_START_SEQUENCE)
1127 194 wi.window_shape = 0;
1128 else
1129 6061 wi.window_shape = 1;
1130
1131 } else {
1132 229 int lastgrp = 0;
1133
1134 229 wi.num_windows = 8;
1135 229 wi.window_shape = 0;
1136
2/2
✓ Branch 0 taken 1832 times.
✓ Branch 1 taken 229 times.
2061 for (i = 0; i < 8; i++) {
1137
2/2
✓ Branch 0 taken 881 times.
✓ Branch 1 taken 951 times.
1832 if (!((pch->next_grouping >> i) & 1))
1138 881 lastgrp = i;
1139 1832 wi.grouping[lastgrp]++;
1140 }
1141 }
1142
1143 /* Determine grouping, based on the location of the first attack, and save for
1144 * the next frame.
1145 * FIXME: Move this to analysis.
1146 * TODO: Tune groupings depending on attack location
1147 * TODO: Handle more than one attack in a group
1148 */
1149
2/2
✓ Branch 0 taken 57322 times.
✓ Branch 1 taken 6256 times.
63578 for (i = 0; i < 9; i++) {
1150
2/2
✓ Branch 0 taken 228 times.
✓ Branch 1 taken 57094 times.
57322 if (attacks[i]) {
1151 228 grouping = i;
1152 228 break;
1153 }
1154 }
1155 6484 pch->next_grouping = window_grouping[grouping];
1156
1157 6484 pch->prev_attack = attacks[AAC_NUM_BLOCKS_SHORT - 1];
1158
1159 6484 return wi;
1160 }
1161
1162 630 static FFPsyWindowInfo psy_lame_window(FFPsyContext *ctx, const float *audio,
1163 const float *la, int channel, int prev_type)
1164 {
1165 630 AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data;
1166 630 AacPsyChannel *pch = &pctx->ch[channel];
1167 630 int attacks[AAC_NUM_BLOCKS_SHORT + 1] = { 0 };
1168 630 int uselongblock = psy_lame_detect(pctx, pch, la, channel, prev_type, attacks);
1169
1170 630 return psy_lame_apply(pctx, pch, uselongblock, attacks, prev_type, !!la);
1171 }
1172
1173 /* Pair-synced block switching: either channel's attack switches both. */
1174 2927 static void psy_lame_window_pair(FFPsyContext *ctx,
1175 const float *audio0, const float *la0,
1176 const float *audio1, const float *la1,
1177 int channel0, int channel1,
1178 int prev_type0, int prev_type1,
1179 FFPsyWindowInfo wi[2])
1180 {
1181 2927 AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data;
1182 2927 AacPsyChannel *pch0 = &pctx->ch[channel0];
1183 2927 AacPsyChannel *pch1 = &pctx->ch[channel1];
1184 2927 int att0[AAC_NUM_BLOCKS_SHORT + 1] = { 0 };
1185 2927 int att1[AAC_NUM_BLOCKS_SHORT + 1] = { 0 };
1186 int merged[AAC_NUM_BLOCKS_SHORT + 1];
1187 2927 int u0 = psy_lame_detect(pctx, pch0, la0, channel0, prev_type0, att0);
1188 2927 int u1 = psy_lame_detect(pctx, pch1, la1, channel1, prev_type1, att1);
1189
4/4
✓ Branch 0 taken 2848 times.
✓ Branch 1 taken 79 times.
✓ Branch 2 taken 2814 times.
✓ Branch 3 taken 34 times.
2927 int u = u0 && u1;
1190
1191
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2924 times.
2927 if (ctx->pair_decoupled[(channel0 >> 1) & 15]) {
1192 /* Joint tools are dead on this pair (encoder-fed state): each channel
1193 * windows for ITS transients - divergence costs nothing there, while
1194 * union-syncing forces the steady channel short at every event in
1195 * the other. Correlated content keeps the sync. */
1196 3 wi[0] = psy_lame_apply(pctx, pch0, u0, att0, prev_type0, !!la0);
1197 3 wi[1] = psy_lame_apply(pctx, pch1, u1, att1, prev_type1, !!la1);
1198 3 return;
1199 }
1200
1201 /* One merged attack map for both channels: the grouping (and with it
1202 * common_window) must match across the pair, and the group boundary
1203 * should isolate the first attack heard in EITHER channel. */
1204
2/2
✓ Branch 0 taken 26316 times.
✓ Branch 1 taken 2924 times.
29240 for (int i = 0; i < AAC_NUM_BLOCKS_SHORT + 1; i++)
1205
2/2
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 26230 times.
26316 merged[i] = att0[i] ? att0[i] : att1[i];
1206
1207 2924 wi[0] = psy_lame_apply(pctx, pch0, u, merged, prev_type0, !!la0);
1208 2924 wi[1] = psy_lame_apply(pctx, pch1, u, merged, prev_type1, !!la1);
1209 }
1210
1211 const FFPsyModel ff_aac_psy_model =
1212 {
1213 .name = "3GPP TS 26.403-inspired model",
1214 .init = psy_3gpp_init,
1215 .window = psy_lame_window,
1216 .analyze = psy_3gpp_analyze,
1217 .end = psy_3gpp_end,
1218 .window_pair = psy_lame_window_pair,
1219 };
1220