FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/aaccoder_nmr.h
Date: 2026-09-22 02:45:01
Exec Total Coverage
Lines: 485 529 91.7%
Functions: 10 10 100.0%
Branches: 399 498 80.1%

Line Branch Exec Source
1 /*
2 * AAC encoder NMR (noise-to-mask ratio) scalefactor coder
3 * Copyright (c) 2026 Lynne <dev@lynne.ee>
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 * AAC encoder NMR scalefactor coder.
24 *
25 * Optimizes the same noise-to-mask objective as the two-loop coder, but with an
26 * optimal Viterbi search over scalefactors instead of a heuristic loop. For each
27 * coded band the per-scalefactor distortion/bits curve is precomputed, then a
28 * trellis over the (window-group, band) coding sequence minimizes
29 * sum_g = dist_g(sf_g)/threshold_g +
30 * lambda * (spectral_bits_g(sf_g) + scalefactor_differential_bits)
31 * with |sf_g - sf_{g-1}| <= SCALE_MAX_DIFF as a constraint, and lambda
32 * binary-searched so the coded size meets the per-frame bit budget
33 *
34 * Perceptual noise substitution (PNS) is integrated into the same objective: once
35 * the trellis settles on its operating lambda, each noise-like band (flagged by
36 * mark_pns) is offered a terminal "code as noise" candidate whose cost is
37 * nmr_pns + lambda*NMR_PNS_BITS. Because NMR_PNS_BITS is far below a band's spectral bit
38 * count, this candidate only wins when lambda is large, i.e. when the encoder is
39 * struggling to hold the bitrate. The bits freed by the chosen PNS bands are
40 * then re-spent by a second trellis pass over the remaining bands.
41 */
42
43 #ifndef AVCODEC_AACCODER_NMR_H
44 #define AVCODEC_AACCODER_NMR_H
45
46 #include <float.h>
47 #include <string.h>
48 #include "libavutil/mathematics.h"
49 #include "mathops.h"
50 #include "avcodec.h"
51 #include "put_bits.h"
52 #include "aac.h"
53 #include "aacenc.h"
54 #include "aactab.h"
55 #include "aacenctab.h"
56
57 /* differential scalefactor coding cost, clamped to the legal delta range */
58 #define NMR_SFBITS(d) ff_aac_scalefactor_bits[av_clip((d) + SCALE_DIFF_ZERO, 0, 2*SCALE_MAX_DIFF)]
59
60 #define NMR_ITERS 14 /* lambda binary-search iters */
61 #define NMR_IFINE 9 /* fine-pass lambda iters */
62 #define NMR_CITERS 7 /* coarse-pass lambda iters */
63 #define NMR_CWARM 5 /* coarse-pass iters when warm-started off the previous frame's
64 * lambda: the bracket spans 10 octaves instead of ~43, so fewer
65 * bisection steps reach the same resolution */
66 #define NMR_COARSE 8 /* two-pass coarse->fine grid step, cuts the Viterbi ncand^2 with no
67 * quality loss, 0 disables it (single full-resolution pass) */
68 #define NMR_STEP 1 /* fine-pass scalefactor candidate granularity */
69
70 #define NMR_PNS_BITS 9 /* approx cost in bits of signalling PNS */
71
72 /* Spectral-hole fill: noise-like bands the trellis left mostly empty are filled with
73 * energy-matched noise (PNS); an audible hole sounds worse than matched noise. */
74 #define NMR_PNS_HOLE_FRAC 0.5f
75 #define NMR_PNS_HOLE_SPREAD 0.5f
76
77 /* RC servo gain: scale the corridor centre by exp2(-K*fill/R) each frame to hold
78 * the long-run mean rate; without it a bad centre drifts for dozens of frames. */
79 #define NMR_RC_K_CBR 0.5f
80
81 #define NMR_RC_ITERS 8 /* lambda bisection iters when clamping an over-cap frame */
82 /* Corridor: bisect within [lam_rc/NMR_RC_CORR, lam_rc*NMR_RC_CORR] so quality stays
83 * smooth while per-frame demand is tracked; 1.5 cuts lambda jitter ~25%. */
84 #define NMR_RC_CORR 1.5f
85
86 /* Reservoir half-window (bits/ch); swept 512/1536/3072, 1536 optimal. */
87 #define NMR_CBR_BUF 1536
88 /* Slew limit on the FINAL operating lambda per frame; bits deviate instead,
89 * the reservoir absorbs. See memory: aac-castanets-transient-rc. */
90 #define NMR_SLEW 1.6f
91 #define NMR_SLEW_RUN 1.15f /* within short runs */
92 #define NMR_RC_CITERS 3 /* corridor coarse-pass iters */
93
94 /* Transition premask: an attack cannot mask backwards; clamp a START frame's
95 * thresholds toward the previous long frame's. */
96 #define NMR_TRANS_PM 2.0f
97
98 /* Zero-decision hysteresis: previously-coded bands need this margin below
99 * threshold to zero (marginal bands flicker audibly otherwise). */
100 #define NMR_ZERO_STICKY 0.5f
101
102 /* Transient bit-burst: an isolated onset (preceded by >= NMR_BURST_GAP long frames)
103 * is coded NMR_BURST_GAIN x finer, held uniform across the run, repaid from steady stretches. */
104 #define NMR_BURST_GAP 10
105 #define NMR_BURST_GAIN 8.0f
106 /* Dense-beat boost: short runs with gap < NMR_BURST_GAP get a budget factor
107 * ramping with the gap (starvation-scaled at the use site). */
108 #define NMR_SHORT_BOOST 2.0f
109 #define NMR_RC_FITERS 4 /* corridor fine-pass iters */
110 #define NMR_RC_TRACK 0.1f /* per-frame pull of the corridor centre toward the realized lambda */
111
112 /* PNS noise-distortion gate: only bands coded well above the masking floor become noise. */
113 #define NMR_PNS_NDGATE 4.0f
114
115 /* Energy/threshold cap for PNS: loud bands (energy >> mask) yield clipping random peaks;
116 * only near-masked bands are safe substitution targets. */
117 #define NMR_PNS_MAX_ET 8.0f
118
119 /* Operating-lambda floor for PNS: below it the encoder is not struggling, so
120 * substituting real texture for 9 signalling bits is net-negative. */
121 #define NMR_PNS_LAM 100.0f
122
123 /* PNS decision hysteresis: enter and leave both cost a margin. */
124 #define NMR_PNS_ENTER 0.7f
125 #define NMR_PNS_STAY 1.4f
126 /* PNS debounce: enter after NMR_PNS_ON consecutive wants, leave after
127 * NMR_PNS_OFF (chronically marginal bands never qualify). */
128 #define NMR_PNS_ON 8
129 #define NMR_PNS_OFF 4
130
131 /**
132 * Viterbi over the coding sequence act[0..nact-1] (indices into the per-band
133 * curves nd/nb), with lambda binary-searched so the coded size ~ destbits.
134 * Fills chosen[band] for every band referenced by act. Returns the operating
135 * lambda. node cost = dist/threshold + lambda*spectral_bits;
136 * edge cost = lambda*sf_differential_bits; |delta sf| <= SCALE_MAX_DIFF hard.
137 */
138 11624 static float nmr_solve(AACEncContext *s,
139 const float (*nd)[NMR_NCAND], const int (*nb)[NMR_NCAND],
140 const int *blo, const int *bnc, int step,
141 const int *act, int nact, int destbits, int *chosen,
142 float lo_l, float hi_l, int iters)
143 {
144 float dp[NMR_NCAND], dpp[NMR_NCAND], node[NMR_NCAND];
145 float lamsf[2*SCALE_MAX_DIFF + 1]; /* lam*sfdiff bit cost, per lambda */
146 uint8_t bp[128][NMR_NCAND];
147 11624 float lam = 1.0f;
148
149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11624 times.
11624 if (nact <= 0)
150 return lam;
151
152
1/2
✓ Branch 0 taken 11624 times.
✗ Branch 1 not taken.
11624 for (int it = 0; it < iters; it++) {
153 11624 lam = sqrtf(lo_l * hi_l);
154
2/2
✓ Branch 0 taken 1406504 times.
✓ Branch 1 taken 11624 times.
1418128 for (int i = 0; i <= 2*SCALE_MAX_DIFF; i++)
155 1406504 lamsf[i] = lam * ff_aac_scalefactor_bits[i]; /* edge cost for this lambda */
156
157 11624 int b0 = act[0];
158
2/2
✓ Branch 0 taken 146908 times.
✓ Branch 1 taken 11624 times.
158532 for (int o = 0; o < bnc[b0]; o++)
159 146908 dp[o] = nd[b0][o] + lam * nb[b0][o]; /* anchor band node cost */
160
161
2/2
✓ Branch 0 taken 494392 times.
✓ Branch 1 taken 11624 times.
506016 for (int k = 1; k < nact; k++) {
162 494392 int b = act[k], pb = act[k-1];
163 494392 memcpy(dpp, dp, sizeof(dp));
164
2/2
✓ Branch 0 taken 6281306 times.
✓ Branch 1 taken 494392 times.
6775698 for (int o = 0; o < bnc[b]; o++)
165 6281306 node[o] = nd[b][o] + lam * nb[b][o];
166 /* dp[o] = node[o] + min_op(dpp[op] + edge cost) */
167 494392 s->aacdsp.nmr_trellis_step(dp, bp[k], dpp, node, lamsf,
168 494392 bnc[b], bnc[pb], blo[b] - blo[pb], step,
169 SCALE_MAX_DIFF);
170 }
171
172 /* backtrack */
173 11624 int beo = 0, b = act[nact-1];
174 11624 float bec = FLT_MAX;
175
2/2
✓ Branch 0 taken 149683 times.
✓ Branch 1 taken 11624 times.
161307 for (int o = 0; o < bnc[b]; o++)
176
2/2
✓ Branch 0 taken 117111 times.
✓ Branch 1 taken 32572 times.
149683 if (dp[o] < bec) { bec = dp[o]; beo = o; }
177 11624 chosen[b] = beo;
178
2/2
✓ Branch 0 taken 494392 times.
✓ Branch 1 taken 11624 times.
506016 for (int k = nact-1; k > 0; k--)
179 494392 chosen[act[k-1]] = bp[k][chosen[act[k]]];
180
181 /* calc cost */
182 11624 int total = 0;
183
2/2
✓ Branch 0 taken 506016 times.
✓ Branch 1 taken 11624 times.
517640 for (int k = 0; k < nact; k++)
184 506016 total += nb[act[k]][chosen[act[k]]];
185
2/2
✓ Branch 0 taken 494392 times.
✓ Branch 1 taken 11624 times.
506016 for (int k = 1; k < nact; k++)
186 494392 total += NMR_SFBITS((blo[act[k]]+chosen[act[k]]*step) - (blo[act[k-1]]+chosen[act[k-1]]*step));
187
188
1/2
✓ Branch 0 taken 11624 times.
✗ Branch 1 not taken.
11624 if (it == iters - 1)
189 11624 break;
190
191 /* check if we went over budget, go coarser if we did */
192 if (total > destbits)
193 lo_l = lam;
194 else
195 hi_l = lam;
196 }
197 11624 return lam;
198 }
199
200 /* Build one coded band's (dist/threshold, bits) cost curve, candidates sf = lo + o*step
201 * for o in [0,maxn), stopping when the band would drop (cb <= 0). Returns the bit count. */
202 124244 static int nmr_band_curve(AACEncContext *s, SingleChannelElement *sce, int w, int g,
203 int start, int lo, int step, int maxn, float invthr,
204 float maxval, float *nd_row, int *nb_row)
205 {
206 124244 int ncand = 0;
207
3/4
✓ Branch 0 taken 1652144 times.
✓ Branch 1 taken 11489 times.
✓ Branch 2 taken 1652144 times.
✗ Branch 3 not taken.
1663633 for (int o = 0; o < maxn && lo + o*step <= SCALE_MAX_POS; o++) {
208 1652144 int sf = lo + o*step, btot = 0, cb = find_min_book(maxval, sf);
209 1652144 float dist = 0.0f;
210
2/2
✓ Branch 0 taken 112755 times.
✓ Branch 1 taken 1539389 times.
1652144 if (cb <= 0)
211 112755 break;
212
2/2
✓ Branch 0 taken 1603630 times.
✓ Branch 1 taken 1539389 times.
3143019 for (int w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
213 int bb;
214 3207260 dist += quantize_band_cost_cached(s, w + w2, g, sce->coeffs + start + w2*128,
215 1603630 s->scoefs + start + w2*128, sce->ics.swb_sizes[g],
216 sf, cb, 1.0f, INFINITY, &bb, NULL, 0);
217 1603630 btot += bb;
218 }
219 1539389 nd_row[ncand] = (dist - btot) * invthr;
220 1539389 nb_row[ncand] = btot;
221 1539389 ncand++;
222 }
223 124244 return ncand;
224 }
225
226 /* Zero a channel with nothing codeable; stale band_types would resurrect
227 * bands with chain-illegal scalefactors. */
228 113 static void nmr_bail_channel(SingleChannelElement *sce)
229 {
230
2/2
✓ Branch 0 taken 14464 times.
✓ Branch 1 taken 113 times.
14577 for (int i = 0; i < 128; i++) {
231
3/4
✓ Branch 0 taken 13911 times.
✓ Branch 1 taken 553 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13911 times.
14464 if (sce->band_type[i] == INTENSITY_BT || sce->band_type[i] == INTENSITY_BT2)
232 553 continue;
233 13911 sce->zeroes[i] = 1;
234 13911 sce->band_type[i] = 0;
235 }
236 113 }
237
238 /* Per-channel setup into slot t: short-block threshold shaping, the
239 * allocation law, zero decisions, and the PASS 1 coarse candidate curves.
240 * Returns the coded-band count; 0 = nothing codeable (caller bails). */
241 1530 static int nmr_setup_channel(AVCodecContext *avctx, AACEncContext *s,
242 SingleChannelElement *sce, NMRSlot *t)
243 {
244 1530 float (*nd)[NMR_NCAND] = s->nmr->nd[t->si];
245 1530 int (*nb)[NMR_NCAND] = s->nmr->nb[t->si];
246 1530 const int cstep = NMR_COARSE > 0 ? NMR_COARSE : NMR_STEP;
247 1530 int allz = 0, cutoff = 1024, nbnd = 0;
248
249 1530 uint8_t *zprev = s->nmr->zero_prev[s->cur_channel & 15];
250
2/2
✓ Branch 0 taken 273 times.
✓ Branch 1 taken 1257 times.
1530 if (s->nmr->zero_nw[s->cur_channel & 15] != sce->ics.num_windows) {
251 273 memset(zprev, 1, 128);
252 273 s->nmr->zero_nw[s->cur_channel & 15] = sce->ics.num_windows;
253 }
254
255 1530 t->sce = sce;
256 1530 t->cur_ch = s->cur_channel;
257 1530 t->is8 = sce->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE;
258 1530 t->nbnd = t->nact = 0;
259
260 /* band cutoff index for this frame's window size; the bandwidth is fixed
261 * at init and shared with the psy model */
262 1530 cutoff = s->bandwidth * 2 * (1024 / sce->ics.num_windows) / avctx->sample_rate;
263
264 /* Short-block shaping: temporal premask + per-window threshold flatten. */
265
2/2
✓ Branch 0 taken 89 times.
✓ Branch 1 taken 1441 times.
1530 if (sce->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
266 89 const float pm_p1 = 0.1f, pm_p2 = 2.0f, pm_p3 = 4.0f;
267
2/2
✓ Branch 0 taken 1246 times.
✓ Branch 1 taken 89 times.
1335 for (int g = 0; g < sce->ics.num_swb; g++) {
268 1246 float t1 = FLT_MAX, t2 = FLT_MAX; /* original thr of w-1, w-2 */
269
2/2
✓ Branch 0 taken 9968 times.
✓ Branch 1 taken 1246 times.
11214 for (int w = 0; w < sce->ics.num_windows; w++) {
270 9968 FFPsyBand *b = &s->psy.ch[s->cur_channel].psy_bands[w*16+g];
271 9968 float th = b->threshold;
272
6/6
✓ Branch 0 taken 856 times.
✓ Branch 1 taken 9112 times.
✓ Branch 2 taken 1197 times.
✓ Branch 3 taken 8771 times.
✓ Branch 4 taken 71 times.
✓ Branch 5 taken 1126 times.
9968 float c = FFMIN(th, FFMIN(t1*pm_p2, t2*pm_p3));
273
2/2
✓ Branch 0 taken 9890 times.
✓ Branch 1 taken 78 times.
9968 b->threshold = FFMAX(c, th*pm_p1);
274 9968 t2 = t1; t1 = th;
275 }
276 }
277 {
278
2/2
✓ Branch 0 taken 712 times.
✓ Branch 1 taken 89 times.
801 for (int w = 0; w < sce->ics.num_windows; w++) {
279 712 float sum = 0.0f, esum = 0.0f; int n = 0;
280
2/2
✓ Branch 0 taken 9968 times.
✓ Branch 1 taken 712 times.
10680 for (int g = 0; g < sce->ics.num_swb; g++) {
281 9968 FFPsyBand *b = &s->psy.ch[s->cur_channel].psy_bands[w*16+g];
282
3/4
✓ Branch 0 taken 9776 times.
✓ Branch 1 taken 192 times.
✓ Branch 2 taken 9776 times.
✗ Branch 3 not taken.
9968 if (b->energy > b->threshold && b->threshold > 0.0f) { sum += b->threshold; esum += b->energy; n++; }
283 }
284
2/2
✓ Branch 0 taken 704 times.
✓ Branch 1 taken 8 times.
712 if (n > 0) {
285 /* keep each window codeable: cap the mean 12dB under the
286 * window's mean audible energy */
287
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 684 times.
704 float mean = FFMIN(sum / n, (esum / n) * expf(-12.0f * (float)M_LN10 / 10.0f));
288
2/2
✓ Branch 0 taken 9856 times.
✓ Branch 1 taken 704 times.
10560 for (int g = 0; g < sce->ics.num_swb; g++) {
289 9856 FFPsyBand *b = &s->psy.ch[s->cur_channel].psy_bands[w*16+g];
290
3/4
✓ Branch 0 taken 9776 times.
✓ Branch 1 taken 80 times.
✓ Branch 2 taken 9776 times.
✗ Branch 3 not taken.
9856 if (b->energy > b->threshold && b->threshold > 0.0f)
291
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9776 times.
9776 b->threshold = FFMIN(mean, b->threshold * 1e9f);
292 }
293 }
294 }
295 }
296 }
297
298 /* Allocation law; short frames blend to softer energy exponents under
299 * pressure (roll anti-starvation, see memory). */
300 1530 float a_ae = 0.443f, a_at = 0.111f;
301
3/4
✓ Branch 0 taken 89 times.
✓ Branch 1 taken 1441 times.
✓ Branch 2 taken 89 times.
✗ Branch 3 not taken.
1530 if (sce->ics.num_windows == 8 && s->nmr) {
302 /* blend to mask-weighted exponents under rate pressure */
303 89 a_ae += (0.35f - a_ae) * s->nmr->press;
304 89 a_at += (0.3f - a_at) * s->nmr->press;
305 }
306
2/2
✓ Branch 0 taken 1796 times.
✓ Branch 1 taken 1530 times.
3326 for (int w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
307 1796 int start = 0;
308
2/2
✓ Branch 0 taken 72267 times.
✓ Branch 1 taken 1796 times.
74063 for (int g = 0; g < sce->ics.num_swb; start += sce->ics.swb_sizes[g++]) {
309 72267 float uplim = 0.0f, ener = 0.0f, spread = 2.0f;
310 72267 int nz = 0;
311
2/2
✓ Branch 0 taken 71567 times.
✓ Branch 1 taken 700 times.
72267 if (sce->band_type[w*16+g] == INTENSITY_BT ||
312
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71567 times.
71567 sce->band_type[w*16+g] == INTENSITY_BT2) {
313 /* pre-decided intensity band (right channel): keep its
314 * signalling, it is not trellis-coded */
315
2/2
✓ Branch 0 taken 728 times.
✓ Branch 1 taken 700 times.
1428 for (int w2 = 0; w2 < sce->ics.group_len[w]; w2++)
316 728 sce->zeroes[(w+w2)*16+g] = 0;
317 700 continue;
318 }
319
2/2
✓ Branch 0 taken 19765 times.
✓ Branch 1 taken 51802 times.
71567 float zthr_mul = zprev[w*16+g] ? 1.0f : NMR_ZERO_STICKY;
320 /* M/S side bands: zero-reluctance scaled by side/mid ratio (a tiny
321 * side IS the image; zeroing it flickers). */
322
5/6
✓ Branch 0 taken 21623 times.
✓ Branch 1 taken 49944 times.
✓ Branch 2 taken 21623 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20986 times.
✓ Branch 5 taken 637 times.
71567 if ((t->cur_ch & 1) && s->nmr && s->nmr->pair &&
323
2/2
✓ Branch 0 taken 5113 times.
✓ Branch 1 taken 15873 times.
20986 s->nmr->smode_band[(t->cur_ch >> 1) & 7][w*16+g] == 1) {
324 5113 const FFPsyBand *mb = &s->psy.ch[s->cur_channel - 1].psy_bands[w*16+g];
325 5113 float ratio = 0.0f;
326 5113 float eside = 0.0f;
327
2/2
✓ Branch 0 taken 5211 times.
✓ Branch 1 taken 5113 times.
10324 for (int w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
328 5211 const FFPsyBand *bb = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g];
329 5211 eside += bb->energy;
330 }
331
1/2
✓ Branch 0 taken 5113 times.
✗ Branch 1 not taken.
5113 ratio = eside / FFMAX(mb->energy * sce->ics.group_len[w], 1e-9f);
332 5113 zthr_mul *= 0.25f + 0.75f * av_clipf(ratio / 0.3f, 0.0f, 1.0f);
333 }
334
2/2
✓ Branch 0 taken 76537 times.
✓ Branch 1 taken 71567 times.
148104 for (int w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
335 76537 FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g];
336 76537 ener += band->energy;
337
2/2
✓ Branch 0 taken 73621 times.
✓ Branch 1 taken 2916 times.
76537 spread = FFMIN(spread, band->spread);
338
4/4
✓ Branch 0 taken 75635 times.
✓ Branch 1 taken 902 times.
✓ Branch 2 taken 64377 times.
✓ Branch 3 taken 11258 times.
76537 if (start >= cutoff || band->energy <= band->threshold * zthr_mul ||
339
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 64377 times.
64377 band->threshold == 0.0f) {
340 12160 sce->zeroes[(w+w2)*16+g] = 1;
341 12160 continue;
342 }
343 64377 uplim += band->threshold;
344 64377 nz = 1;
345 }
346 71567 zprev[w*16+g] = !nz;
347 71567 sce->zeroes[w*16+g] = !nz;
348 71567 t->thr_real[w*16+g] = uplim; /* real mask, before the allocation law (PNS gate) */
349
4/6
✓ Branch 0 taken 62122 times.
✓ Branch 1 taken 9445 times.
✓ Branch 2 taken 62122 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 62122 times.
✗ Branch 5 not taken.
71567 if (nz && ener > 0.0f && uplim > 0.0f) /* allocation law */
350 62122 uplim = expf(a_ae * logf(ener) + a_at * logf(uplim));
351 71567 t->thr[w*16+g] = uplim;
352 71567 t->pener[w*16+g] = ener;
353 71567 t->pspread[w*16+g] = spread;
354 71567 allz |= nz;
355 }
356 }
357
2/2
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 1417 times.
1530 if (!allz)
358 113 return 0;
359
360 /* transition premask (see NMR_TRANS_PM) */
361
2/2
✓ Branch 0 taken 1329 times.
✓ Branch 1 taken 88 times.
1417 if (sce->ics.num_windows == 1) {
362 1329 int ci = t->cur_ch & 15;
363
2/2
✓ Branch 0 taken 87 times.
✓ Branch 1 taken 1242 times.
1329 if (sce->ics.window_sequence[0] == LONG_START_SEQUENCE &&
364
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 86 times.
87 s->nmr->thr_prev_ok[ci]) {
365
3/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
50 for (int g = 0; g < sce->ics.num_swb && g < 64; g++)
366
2/4
✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
49 if (t->thr[g] > 0.0f && s->nmr->thr_prev[ci][g] > 0.0f)
367
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 48 times.
49 t->thr[g] = FFMIN(t->thr[g], s->nmr->thr_prev[ci][g] * NMR_TRANS_PM);
368 }
369
3/4
✓ Branch 0 taken 61809 times.
✓ Branch 1 taken 1329 times.
✓ Branch 2 taken 61809 times.
✗ Branch 3 not taken.
63138 for (int g = 0; g < sce->ics.num_swb && g < 64; g++)
370 61809 s->nmr->thr_prev[ci][g] = t->thr[g];
371 1329 s->nmr->thr_prev_ok[ci] = 1;
372 } else {
373 88 s->nmr->thr_prev_ok[t->cur_ch & 15] = 0;
374 }
375
376 1417 s->aacdsp.abs_pow34(s->scoefs, sce->coeffs, 1024);
377 1417 ff_quantize_band_cost_cache_init(s);
378
379 /* TNS synthesis gain per band: the decoder re-amplifies residual-domain
380 * quantization noise by the whitening gain (shorts only). */
381
2/2
✓ Branch 0 taken 181376 times.
✓ Branch 1 taken 1417 times.
182793 for (int i = 0; i < 128; i++)
382 181376 t->tnsg[i] = 1.0f;
383
3/4
✓ Branch 0 taken 88 times.
✓ Branch 1 taken 1329 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 88 times.
1417 if (sce->ics.num_windows == 8 && sce->tns.present) {
384 const int mmm2 = FFMIN(sce->ics.tns_max_bands, sce->ics.max_sfb ? sce->ics.max_sfb : sce->ics.num_swb);
385 for (int w = 0; w < 8; w++) {
386 int bottom2 = sce->ics.num_swb;
387 for (int filt = 0; filt < sce->tns.n_filt[w]; filt++) {
388 int top2 = bottom2;
389 bottom2 = FFMAX(0, top2 - sce->tns.length[w][filt]);
390 if (!sce->tns.order[w][filt])
391 continue;
392 for (int g = FFMIN(bottom2, mmm2); g < FFMIN(top2, mmm2); g++) {
393 int s0 = sce->ics.swb_offset[g] + w*128;
394 int s1 = sce->ics.swb_offset[g+1] + w*128;
395 float eres = 0.0f;
396 const FFPsyBand *pb = &s->psy.ch[s->cur_channel].psy_bands[w*16+g];
397 for (int k = s0; k < s1; k++)
398 eres += sce->coeffs[k]*sce->coeffs[k];
399 t->tnsg[w*16+g] = av_clipf(pb->energy / FFMAX(eres, 1e-12f), 1.0f, 64.0f);
400 }
401 }
402 }
403 }
404
405 /* finest codeable scalefactor and max value per band */
406
2/2
✓ Branch 0 taken 1680 times.
✓ Branch 1 taken 1417 times.
3097 for (int w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
407 1680 int start = w*128;
408
2/2
✓ Branch 0 taken 66723 times.
✓ Branch 1 taken 1680 times.
68403 for (int g = 0; g < sce->ics.num_swb; g++) {
409 66723 t->maxvals[w*16+g] = find_max_val(sce->ics.group_len[w], sce->ics.swb_sizes[g], s->scoefs + start);
410
2/2
✓ Branch 0 taken 66576 times.
✓ Branch 1 taken 147 times.
66723 t->minsf[w*16+g] = t->maxvals[w*16+g] > 0 ? coef2minsf(t->maxvals[w*16+g]) : 0;
411 66723 start += sce->ics.swb_sizes[g];
412 }
413 }
414
415 /* PASS 1: coarse candidate curves per coded band
416 * (the lambda search runs on this cheap grid, PASS 2 refines the winner) */
417 {
418
2/2
✓ Branch 0 taken 1680 times.
✓ Branch 1 taken 1417 times.
3097 for (int w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
419 1680 int start = w*128;
420
2/2
✓ Branch 0 taken 66723 times.
✓ Branch 1 taken 1680 times.
68403 for (int g = 0; g < sce->ics.num_swb; g++) {
421
5/6
✓ Branch 0 taken 62269 times.
✓ Branch 1 taken 4454 times.
✓ Branch 2 taken 62122 times.
✓ Branch 3 taken 147 times.
✓ Branch 4 taken 62122 times.
✗ Branch 5 not taken.
66723 if (!sce->zeroes[w*16+g] && t->maxvals[w*16+g] > 0 && nbnd < 128) {
422 62122 int lo = av_clip(t->minsf[w*16+g], 0, SCALE_MAX_POS);
423
1/2
✓ Branch 0 taken 62122 times.
✗ Branch 1 not taken.
62122 float invthr = 1.0f / FFMAX(t->thr[w*16+g], 1e-9f);
424 62122 int ncand = nmr_band_curve(s, sce, w, g, start, lo, cstep, NMR_NCAND,
425 62122 invthr, t->maxvals[w*16+g], nd[nbnd], nb[nbnd]);
426
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62122 times.
62122 if (t->tnsg[w*16+g] > 1.0f)
427 for (int o = 0; o < ncand; o++)
428 nd[nbnd][o] *= t->tnsg[w*16+g];
429
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62122 times.
62122 if (ncand == 0) {
430 /* nothing codeable: drop the group band incl. subwindow
431 * flags (group flag is re-derived by ANDing) */
432 for (int w2 = 0; w2 < sce->ics.group_len[w]; w2++)
433 sce->zeroes[(w+w2)*16+g] = 1;
434 } else {
435 62122 t->bidx[nbnd] = w*16+g;
436 62122 t->bw[nbnd] = w;
437 62122 t->bg[nbnd] = g;
438 62122 t->bst[nbnd] = start;
439 62122 t->blo[nbnd] = lo;
440 62122 t->bnc[nbnd] = ncand;
441 62122 nbnd++;
442 }
443 }
444 66723 start += sce->ics.swb_sizes[g];
445 }
446 }
447 }
448 1417 t->nbnd = nbnd;
449
2/2
✓ Branch 0 taken 62122 times.
✓ Branch 1 taken 1417 times.
63539 for (int b = 0; b < nbnd; b++) {
450 62122 t->act[b] = b;
451 62122 t->is_pns[b] = 0;
452 }
453 1417 t->nact = nbnd;
454 1417 return nbnd;
455 }
456
457 /* total bits of a slot's current chosen[] on grid `step`, incl. sf deltas */
458 14270 static int nmr_slot_bits(const NMRSlot *t, const int (*nb)[NMR_NCAND], int step)
459 {
460 14270 int tot = 0;
461
2/2
✓ Branch 0 taken 622234 times.
✓ Branch 1 taken 14270 times.
636504 for (int k = 0; k < t->nact; k++)
462 622234 tot += nb[t->act[k]][t->chosen[t->act[k]]];
463
2/2
✓ Branch 0 taken 607964 times.
✓ Branch 1 taken 14270 times.
622234 for (int k = 1; k < t->nact; k++)
464 607964 tot += NMR_SFBITS((t->blo[t->act[k]]+t->chosen[t->act[k]]*step) -
465 (t->blo[t->act[k-1]]+t->chosen[t->act[k-1]]*step));
466 14270 return tot;
467 }
468
469 /* Run every slot's trellis at one fixed lambda; returns the pooled bits. */
470 9540 static int nmr_eval_slots(AACEncContext *s, NMRSlot *const *sl, int nsl, int step, float lam)
471 {
472 9540 int total = 0;
473
2/2
✓ Branch 0 taken 11624 times.
✓ Branch 1 taken 9540 times.
21164 for (int k = 0; k < nsl; k++) {
474 11624 NMRSlot *t = sl[k];
475
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11624 times.
11624 if (!t->nact)
476 continue;
477 11624 nmr_solve(s, s->nmr->nd[t->si], s->nmr->nb[t->si], t->blo, t->bnc, step,
478 11624 t->act, t->nact, 0, t->chosen, lam, lam, 1);
479 11624 total += nmr_slot_bits(t, s->nmr->nb[t->si], step);
480 }
481 9540 return total;
482 }
483
484 /* Bisect ONE shared lambda across the slots so the POOLED bits meet destbits.
485 * This is the CPE budget pool: bits flow to whichever channel of the pair has
486 * demand at the common operating point, instead of an equal per-channel split. */
487 2301 static float nmr_solve_slots(AACEncContext *s, NMRSlot *const *sl, int nsl, int step,
488 int destbits, float lo_l, float hi_l, int iters)
489 {
490 2301 float lam = 1.0f;
491
1/2
✓ Branch 0 taken 9129 times.
✗ Branch 1 not taken.
9129 for (int it = 0; it < iters; it++) {
492 9129 lam = sqrtf(lo_l * hi_l);
493 9129 int total = nmr_eval_slots(s, sl, nsl, step, lam);
494
2/2
✓ Branch 0 taken 2301 times.
✓ Branch 1 taken 6828 times.
9129 if (it == iters - 1)
495 2301 break;
496 /* over budget -> go coarser */
497
2/2
✓ Branch 0 taken 2569 times.
✓ Branch 1 taken 4259 times.
6828 if (total > destbits)
498 2569 lo_l = lam;
499 else
500 4259 hi_l = lam;
501 }
502 2301 return lam;
503 }
504
505 /* Write a solved slot back into its channel: band types, scalefactors, and the
506 * SCALE_MAX_DIFF legality fixups. Verbatim from the pre-pool single-channel tail. */
507 1417 static void nmr_commit_channel(AACEncContext *s, NMRSlot *t)
508 {
509 1417 SingleChannelElement *sce = t->sce;
510 1417 const int (*nb)[NMR_NCAND] = (const int (*)[NMR_NCAND])s->nmr->nb[t->si];
511
512
2/2
✓ Branch 0 taken 62122 times.
✓ Branch 1 taken 1417 times.
63539 for (int b = 0; b < t->nbnd; b++) {
513 62122 int bi = t->bidx[b];
514
2/2
✓ Branch 0 taken 2679 times.
✓ Branch 1 taken 59443 times.
62122 if (t->is_pns[b]) {
515 2679 sce->band_type[bi] = NOISE_BT;
516 2679 sce->zeroes[bi] = 0;
517
2/2
✓ Branch 0 taken 2442 times.
✓ Branch 1 taken 237 times.
2679 sce->pns_ener[bi] = t->pener[bi] * FFMIN(1.0f, t->pspread[bi]*t->pspread[bi]);
518 } else {
519 59443 sce->sf_idx[bi] = av_clip(t->blo[b] + t->chosen[b]*NMR_STEP, 0, SCALE_MAX_POS);
520 }
521 }
522
523
524 { /* record the bits this solve accounted for; the encoder compares them
525 * against the channel's real output to keep the budget honest */
526 1417 int tot = 0, prevb = -1;
527
2/2
✓ Branch 0 taken 62122 times.
✓ Branch 1 taken 1417 times.
63539 for (int b = 0; b < t->nbnd; b++) {
528
2/2
✓ Branch 0 taken 2679 times.
✓ Branch 1 taken 59443 times.
62122 if (t->is_pns[b])
529 2679 continue;
530 59443 tot += nb[b][t->chosen[b]];
531
2/2
✓ Branch 0 taken 58026 times.
✓ Branch 1 taken 1417 times.
59443 if (prevb >= 0)
532 58026 tot += NMR_SFBITS((t->blo[b]+t->chosen[b]*NMR_STEP) - (t->blo[prevb]+t->chosen[prevb]*NMR_STEP));
533 59443 prevb = b;
534 }
535 1417 s->nmr->counted[t->cur_ch] = tot;
536 }
537
538 /* SCALE_MAX_DIFF condition:
539 * re-clamp, codebook fixup, drop uncodeable, set global gain
540 * NOISE_BT bands keep their own scalefactor chain via set_special_band_scalefactors) */
541 {
542 uint8_t nextband[128];
543 1417 int prev = -1;
544 1417 ff_init_nextband_map(sce, nextband);
545
2/2
✓ Branch 0 taken 1680 times.
✓ Branch 1 taken 1417 times.
3097 for (int w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
546
2/2
✓ Branch 0 taken 66723 times.
✓ Branch 1 taken 1680 times.
68403 for (int g = 0; g < sce->ics.num_swb; g++) {
547
2/2
✓ Branch 0 taken 64044 times.
✓ Branch 1 taken 2679 times.
66723 if (sce->band_type[w*16+g] == NOISE_BT ||
548
2/2
✓ Branch 0 taken 63897 times.
✓ Branch 1 taken 147 times.
64044 sce->band_type[w*16+g] == INTENSITY_BT ||
549
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63897 times.
63897 sce->band_type[w*16+g] == INTENSITY_BT2)
550 2826 continue;
551
2/2
✓ Branch 0 taken 4454 times.
✓ Branch 1 taken 59443 times.
63897 if (sce->zeroes[w*16+g]) {
552 4454 sce->band_type[w*16+g] = 0;
553 4454 continue;
554 }
555
556
2/2
✓ Branch 0 taken 58026 times.
✓ Branch 1 taken 1417 times.
59443 if (prev != -1)
557 58026 sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], prev - SCALE_MAX_DIFF, prev + SCALE_MAX_DIFF);
558 59443 sce->band_type[w*16+g] = find_min_book(t->maxvals[w*16+g], sce->sf_idx[w*16+g]);
559
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59443 times.
59443 if (sce->band_type[w*16+g] <= 0) {
560 if (!ff_sfdelta_can_remove_band(sce, nextband, prev, w*16+g)) {
561 sce->band_type[w*16+g] = 1;
562 } else {
563 /* drop subwindow flags too, see the PASS 1 drop above */
564 for (int w2 = 0; w2 < sce->ics.group_len[w]; w2++)
565 sce->zeroes[(w+w2)*16+g] = 1;
566 sce->band_type[w*16+g] = 0;
567 continue;
568 }
569 }
570
2/2
✓ Branch 0 taken 1417 times.
✓ Branch 1 taken 58026 times.
59443 if (prev == -1)
571 1417 sce->sf_idx[0] = sce->sf_idx[w*16+g]; /* global gain */
572 59443 prev = sce->sf_idx[w*16+g];
573 }
574 }
575
576 /* every band must carry a chain-legal scalefactor (re-clamp, codebook
577 * fixup, global gain) */
578
1/2
✓ Branch 0 taken 1417 times.
✗ Branch 1 not taken.
1417 if (prev != -1) {
579 1417 int last = sce->sf_idx[0];
580
2/2
✓ Branch 0 taken 1680 times.
✓ Branch 1 taken 1417 times.
3097 for (int w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
581
2/2
✓ Branch 0 taken 66723 times.
✓ Branch 1 taken 1680 times.
68403 for (int g = 0; g < sce->ics.num_swb; g++) {
582
4/4
✓ Branch 0 taken 62269 times.
✓ Branch 1 taken 4454 times.
✓ Branch 2 taken 59590 times.
✓ Branch 3 taken 2679 times.
66723 if (!sce->zeroes[w*16+g] && sce->band_type[w*16+g] != NOISE_BT &&
583
2/2
✓ Branch 0 taken 59443 times.
✓ Branch 1 taken 147 times.
59590 sce->band_type[w*16+g] < RESERVED_BT)
584 59443 last = sce->sf_idx[w*16+g];
585
4/4
✓ Branch 0 taken 4454 times.
✓ Branch 1 taken 2826 times.
✓ Branch 2 taken 4350 times.
✓ Branch 3 taken 104 times.
7280 else if (sce->band_type[w*16+g] < RESERVED_BT && (w*16+g) > 0)
586 4350 sce->sf_idx[w*16+g] = last;
587 }
588 }
589 }
590 }
591 1417 }
592
593 /* Solve one element group (a solo channel, or a CPE pair pooled under one
594 * shared lambda and one pooled budget), then PNS and commit. */
595 1128 static void nmr_solve_group(AVCodecContext *avctx, AACEncContext *s,
596 const float lambda, NMRSlot *const *sl, int nsl,
597 int chans, int rc_eligible, int rc_global,
598 int rc_rate_frame, int rc_bmax)
599 {
600 1128 const int cstep = NMR_COARSE > 0 ? NMR_COARSE : NMR_STEP;
601
1/2
✓ Branch 0 taken 1128 times.
✗ Branch 1 not taken.
1128 int bch = ((avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : avctx->ch_layout.nb_channels);
602 1128 int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / bch * (lambda / 120.f) * chans;
603 1128 int is8_any = 0;
604 float lam;
605 1128 float rc_off = 1.0f, lam_dem = 0.0f;
606
607
2/2
✓ Branch 0 taken 1417 times.
✓ Branch 1 taken 1128 times.
2545 for (int k = 0; k < nsl; k++)
608 1417 is8_any |= sl[k]->is8;
609
610
1/2
✓ Branch 0 taken 1128 times.
✗ Branch 1 not taken.
1128 if (s->psy.bitres.alloc >= 0)
611 2256 destbits = s->psy.bitres.alloc *
612
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1128 times.
1128 (lambda / (avctx->global_quality ? avctx->global_quality : 120)) * chans;
613
3/4
✓ Branch 0 taken 1034 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 1034 times.
✗ Branch 3 not taken.
1128 if (rc_global && s->psy.bitres.alloc >= 0) {
614 /* CBR target: nominal + repayment, bounded +-30%/frame */
615 1034 double rr = avctx->bit_rate * 1024.0 / avctx->sample_rate;
616 1034 destbits = (rr + av_clipd(s->nmr->rc_fill / 2.0, -0.3 * rr, 0.3 * rr)) * chans / s->channels;
617
2/4
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 94 times.
✗ Branch 3 not taken.
94 } else if (rc_eligible && s->psy.bitres.alloc >= 0) {
618 /* pre-bootstrap CBR frames: target nominal (psy bitres is cold) */
619 94 destbits = (avctx->bit_rate * 1024.0 / avctx->sample_rate) * chans / s->channels;
620 }
621 1128 destbits = FFMIN(destbits, 5800 * chans);
622 /* honest budget: subtract the measured non-trellis overhead (section data, ICS,
623 * sf/PNS signalling), which is rate-dependent hence adaptive. */
624
2/2
✓ Branch 0 taken 1034 times.
✓ Branch 1 taken 94 times.
1128 if (s->nmr->side_inited)
625 1034 destbits = av_clip(destbits - (int)(s->nmr->side_ema * chans / s->channels), 64, 5800 * chans);
626
627 /* Held transient burst, bank-aware: spend banked bits, never borrow deep
628 * (payback troughs starve the next transient). */
629
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1125 times.
1128 if (s->nmr->run_burst > 1.0f) {
630 3 int extra = destbits * (s->nmr->run_burst - 1.0f);
631 3 int avail = FFMAX(0, (int)((s->nmr->rc_fill + rc_bmax / 2) * (int64_t)chans / s->channels));
632 3 destbits = av_clip(destbits + FFMIN(extra, avail), 64, 6800 * chans);
633 }
634
635
2/2
✓ Branch 0 taken 1034 times.
✓ Branch 1 taken 94 times.
1128 if (rc_global) {
636 /* corridor bisect around the servoed centre; pressure = stateless
637 * rc_off multiplier (folding it into lam_rc winds up) */
638 1034 float R = avctx->bit_rate * 1024.0 / avctx->sample_rate;
639 float cen;
640 int tot, hardcap, rc_cap;
641 float lo;
642 1034 rc_off = exp2f(-NMR_RC_K_CBR * s->nmr->rc_fill / R);
643 1034 cen = s->nmr->lam_rc * rc_off;
644 1034 lo = cen / NMR_RC_CORR;
645 /* transient burst: widen the lower bound so the boosted destbits can
646 * actually pour into the onset frame */
647
4/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 984 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 48 times.
1034 if (is8_any && s->nmr->run_burst > 1.0f)
648 2 lo /= s->nmr->run_burst;
649 1034 lam = nmr_solve_slots(s, sl, nsl, cstep, destbits,
650 lo, cen * NMR_RC_CORR, NMR_RC_CITERS);
651
652 1034 tot = 0;
653
2/2
✓ Branch 0 taken 1323 times.
✓ Branch 1 taken 1034 times.
2357 for (int k = 0; k < nsl; k++)
654 1323 tot += nmr_slot_bits(sl[k], s->nmr->nb[sl[k]->si], cstep);
655
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1034 times.
1034 hardcap = av_clip((int)(5800.f * FFMIN(1.f, lambda / 120.f)), 256, 5800) * chans;
656 /* legality cap only; no spend-floor (rc_off spends the bank) */
657 1034 rc_cap = FFMIN(hardcap, (s->nmr->rc_fill + rc_rate_frame + rc_bmax) * chans / s->channels);
658
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 1007 times.
1034 if (tot > rc_cap) {
659 27 lam = nmr_solve_slots(s, sl, nsl, cstep, rc_cap, lam, 1e4f, NMR_CITERS);
660 }
661 } else {
662 /* per-frame bisection, warm-started off the previous frame's lambda;
663 * a result at the bracket edge means redo the full search */
664 94 float lam0 = s->nmr->lam[sl[0]->cur_ch];
665 94 lam = 1.0f;
666
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 94 times.
94 if (NMR_COARSE > 0 && lam0 > 0.0f) {
667 lam = nmr_solve_slots(s, sl, nsl, cstep, destbits, lam0/32.0f, lam0*32.0f, NMR_CWARM);
668 if (lam < lam0/16.0f || lam > lam0*16.0f)
669 lam0 = 0.0f;
670 }
671
1/2
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
94 if (lam0 <= 0.0f)
672 94 lam = nmr_solve_slots(s, sl, nsl, cstep, destbits,
673 1e-9f, 1e4f, NMR_COARSE > 0 ? NMR_CITERS : NMR_ITERS);
674 }
675
676 /* PASS 2:
677 * refine each band at full granularity (NMR_STEP) in a +/-cstep window
678 * around the coarse pick, then re-solve. Recovers single-pass quality while the
679 * lambda search stayed cheap on the coarse grid. */
680 if (NMR_COARSE > 0) {
681 /* nmr_speed, 0 = slowest/best, higher = faster; see the option docs. */
682 1128 int win = NMR_COARSE - av_clip(s->options.nmr_speed, 0, 4);
683
2/2
✓ Branch 0 taken 1417 times.
✓ Branch 1 taken 1128 times.
2545 for (int k = 0; k < nsl; k++) {
684 1417 NMRSlot *t = sl[k];
685 1417 float (*ndk)[NMR_NCAND] = s->nmr->nd[t->si];
686 1417 int (*nbk)[NMR_NCAND] = s->nmr->nb[t->si];
687
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1417 times.
1417 if (!t->nact)
688 continue;
689 /* the pow34 spectrum and the quantize cache are per-channel state */
690 1417 s->aacdsp.abs_pow34(s->scoefs, t->sce->coeffs, 1024);
691 1417 ff_quantize_band_cost_cache_init(s);
692
2/2
✓ Branch 0 taken 62122 times.
✓ Branch 1 taken 1417 times.
63539 for (int b = 0; b < t->nbnd; b++) {
693 62122 int center = t->blo[b] + t->chosen[b]*cstep;
694 62122 int flo = av_clip(center - win, av_clip(t->minsf[t->bidx[b]], 0, SCALE_MAX_POS), SCALE_MAX_POS);
695 62122 int maxn = FFMIN(NMR_NCAND, 2*win/NMR_STEP + 1);
696
1/2
✓ Branch 0 taken 62122 times.
✗ Branch 1 not taken.
62122 float invthr = 1.0f / FFMAX(t->thr[t->bidx[b]], 1e-9f);
697 62122 int ncand = nmr_band_curve(s, t->sce, t->bw[b], t->bg[b], t->bst[b], flo, NMR_STEP, maxn,
698 62122 invthr, t->maxvals[t->bidx[b]], ndk[b], nbk[b]);
699
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62122 times.
62122 if (t->tnsg[t->bidx[b]] > 1.0f)
700 for (int o = 0; o < ncand; o++)
701 ndk[b][o] *= t->tnsg[t->bidx[b]];
702 62122 t->blo[b] = flo;
703 62122 t->bnc[b] = FFMAX(1, ncand);
704 }
705 }
706 /* fine pass: narrow corridor around the coarse solve */
707
2/2
✓ Branch 0 taken 1034 times.
✓ Branch 1 taken 94 times.
1128 if (rc_global)
708 1034 lam = nmr_solve_slots(s, sl, nsl, NMR_STEP, destbits, lam/2.0f, lam*2.0f, NMR_RC_FITERS);
709 else
710 94 lam = nmr_solve_slots(s, sl, nsl, NMR_STEP, destbits, lam/16.0f, lam*16.0f, NMR_IFINE);
711 }
712
713 1128 lam_dem = lam; /* demand-solved lambda, pre bucket clamp: what content wants */
714
715
2/2
✓ Branch 0 taken 1034 times.
✓ Branch 1 taken 94 times.
1128 if (rc_global) {
716 /* legality clamp, then the quality slew limiter */
717
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1034 times.
1034 int hardcap = av_clip((int)(5800.f * FFMIN(1.f, lambda / 120.f)), 256, 5800) * chans;
718 1034 int tot = 0, rc_cap;
719
2/2
✓ Branch 0 taken 1323 times.
✓ Branch 1 taken 1034 times.
2357 for (int k = 0; k < nsl; k++)
720 1323 tot += nmr_slot_bits(sl[k], s->nmr->nb[sl[k]->si], NMR_STEP);
721 1034 rc_cap = FFMIN(hardcap, (s->nmr->rc_fill + rc_rate_frame + rc_bmax) * chans / s->channels);
722
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1034 times.
1034 if (tot > rc_cap) {
723 lam = nmr_solve_slots(s, sl, nsl, NMR_STEP, rc_cap, lam, 1e4f, NMR_RC_ITERS);
724 }
725
1/2
✓ Branch 0 taken 1034 times.
✗ Branch 1 not taken.
1034 if (s->nmr->lam_slew > 0.0f) {
726 float kup, kdn;
727 /* hold lambda near-constant within short runs; bits follow content */
728
3/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 984 times.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
1034 kup = (is8_any && s->nmr->prev_was_short) ? NMR_SLEW_RUN : NMR_SLEW;
729 /* a deliberate onset burst may dive as far as its widened corridor
730 * allows; the RECOVERY back up is what must stay gradual */
731
4/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 984 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 48 times.
2066 kdn = (is8_any && s->nmr->run_burst > 1.0f) ? NMR_SLEW * s->nmr->run_burst :
732
3/4
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 984 times.
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
1032 (is8_any && s->nmr->prev_was_short) ? NMR_SLEW_RUN : NMR_SLEW;
733
4/4
✓ Branch 0 taken 978 times.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 100 times.
✓ Branch 3 taken 878 times.
1034 if (lam > s->nmr->lam_slew * kup || lam < s->nmr->lam_slew / kdn) {
734 156 lam = av_clipf(lam, s->nmr->lam_slew / kdn, s->nmr->lam_slew * kup);
735 156 tot = nmr_eval_slots(s, sl, nsl, NMR_STEP, lam);
736 /* never at the price of an illegal reservoir excursion */
737
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 147 times.
156 if (tot > rc_cap) {
738 9 lam = nmr_solve_slots(s, sl, nsl, NMR_STEP, rc_cap, lam, 1e4f, NMR_RC_ITERS);
739 }
740 }
741 }
742 1034 s->nmr->lam_slew = lam;
743 }
744
745
2/2
✓ Branch 0 taken 1417 times.
✓ Branch 1 taken 1128 times.
2545 for (int k = 0; k < nsl; k++)
746 1417 s->nmr->lam[sl[k]->cur_ch] = lam; /* warm start for the next frame */
747 { /* nd: mean achieved dist/real-mask (dimensionless starvation +
748 * noise-class signal) */
749 1128 float ndsum = 0.0f; int ndn = 0;
750
2/2
✓ Branch 0 taken 1417 times.
✓ Branch 1 taken 1128 times.
2545 for (int k = 0; k < nsl; k++) {
751 1417 NMRSlot *t = sl[k];
752 1417 float (*ndk)[NMR_NCAND] = s->nmr->nd[t->si];
753
2/2
✓ Branch 0 taken 62122 times.
✓ Branch 1 taken 1417 times.
63539 for (int b_ = 0; b_ < t->nact; b_++) {
754 62122 int b = t->act[b_], bi = t->bidx[b];
755
2/4
✓ Branch 0 taken 62122 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 62122 times.
✗ Branch 3 not taken.
62122 if (t->thr_real[bi] > 0.0f && t->thr[bi] > 0.0f) {
756 62122 ndsum += ndk[b][t->chosen[b]] * t->thr[bi] / t->thr_real[bi];
757 62122 ndn++;
758 }
759 }
760 }
761 /* long frames only (short groups inflate the ratio) */
762
4/4
✓ Branch 0 taken 1056 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 1006 times.
✓ Branch 3 taken 50 times.
1128 if (ndn >= 8 && !is8_any) {
763 1006 float nd = ndsum / ndn;
764 1006 s->nmr->nd_ema = s->nmr->nd_ema > 0.0f ?
765
2/2
✓ Branch 0 taken 992 times.
✓ Branch 1 taken 14 times.
1006 0.95f * s->nmr->nd_ema + 0.05f * nd : nd;
766 }
767 }
768 { /* track short vs long operating lambda (dense-beat boost scaling) */
769
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 1078 times.
1128 float *ema = is8_any ? &s->nmr->lam_short_ema : &s->nmr->lam_long_ema;
770
2/2
✓ Branch 0 taken 1100 times.
✓ Branch 1 taken 28 times.
1128 *ema = *ema > 0.0f ? 0.9f * *ema + 0.1f * lam : lam;
771 /* sustained-strain floor: snaps down at any comfortable moment,
772 * recovers only slowly, so bursty content cannot bank pressure
773 * credit between its lambda valleys. */
774 2256 s->nmr->lam_floor = s->nmr->lam_floor > 0.0f ?
775
2/2
✓ Branch 0 taken 1114 times.
✓ Branch 1 taken 14 times.
1128 fminf(s->nmr->lam_floor * 1.02f, lam) : lam;
776 }
777 { /* shared rate-pressure ramp: lambda vs nd-scaled anchors */
778 float scale, ramp;
779 1128 scale = 1.0f + av_clipf(s->nmr->nd_ema / 50.0f, 0.0f, 8.0f);
780 2256 ramp = s->nmr->lam_long_ema > 0.0f ?
781 1128 av_clipf((s->nmr->lam_long_ema - 120.0f * scale) /
782
1/2
✓ Branch 0 taken 1128 times.
✗ Branch 1 not taken.
1128 (350.0f * scale - 120.0f * scale), 0.0f, 1.0f) : 0.0f;
783 /* transparency veto: lambda*nd below ~74 = comfortable */
784
1/2
✓ Branch 0 taken 1128 times.
✗ Branch 1 not taken.
1128 if (s->nmr->nd_ema > 0.0f)
785 1128 ramp *= av_clipf((s->nmr->lam_long_ema * s->nmr->nd_ema - 60.0f) /
786 (120.0f - 60.0f), 0.0f, 1.0f);
787 1128 s->nmr->press = ramp;
788 }
789
2/2
✓ Branch 0 taken 1034 times.
✓ Branch 1 taken 94 times.
1128 if (rc_global) {
790 /* track the centre toward the CONTENT lambda (demand-solved, pressure
791 * divided out); clamped lambda is rate noise, not content */
792 1034 float c = s->nmr->lam_rc * powf(lam_dem / rc_off / s->nmr->lam_rc, NMR_RC_TRACK);
793 1034 s->nmr->lam_rc = av_clipf(c, 1e-6f, 1e4f);
794
1/2
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
94 } else if (rc_eligible) {
795 /* bootstrap the servo off the first substantive frame (silent lead-ins
796 * have degenerate budgets) */
797 94 int nbnd_max = 0;
798
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 94 times.
188 for (int k = 0; k < nsl; k++)
799 94 nbnd_max = FFMAX(nbnd_max, sl[k]->nbnd);
800
2/2
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 8 times.
94 if (nbnd_max >= 8) {
801 86 s->nmr->lam_rc = av_clipf(lam, 1e-4f, 1e4f);
802 86 s->nmr->lam_slew = s->nmr->lam_rc;
803 }
804 }
805
806 { /* PNS, per channel at the group's operating lambda */
807 1128 const float pns_lam = NMR_PNS_LAM;
808 1128 int pns_total = 0;
809
2/2
✓ Branch 0 taken 1417 times.
✓ Branch 1 taken 1128 times.
2545 for (int k = 0; k < nsl; k++) {
810 1417 NMRSlot *t = sl[k];
811 1417 const float (*ndk)[NMR_NCAND] = (const float (*)[NMR_NCAND])s->nmr->nd[t->si];
812 1417 const int (*nbk)[NMR_NCAND] = (const int (*)[NMR_NCAND])s->nmr->nb[t->si];
813 1417 int pns_count = 0;
814 /* band 0 (lowest freq) is kept as the global-gain / sf-chain anchor */
815
2/2
✓ Branch 0 taken 60705 times.
✓ Branch 1 taken 1417 times.
62122 for (int b = 1; b < t->nbnd; b++) {
816 60705 int bi = t->bidx[b];
817 60705 float spread = t->pspread[bi];
818 float nmr_pns, cost_keep, cost_pns, frac;
819
2/2
✓ Branch 0 taken 46031 times.
✓ Branch 1 taken 14674 times.
60705 if (!t->sce->can_pns[bi])
820 46031 continue;
821
822 14674 int was = s->nmr->pns_prev[t->cur_ch & 15][bi];
823
2/2
✓ Branch 0 taken 2419 times.
✓ Branch 1 taken 12255 times.
14674 float bias = was ? NMR_PNS_STAY : NMR_PNS_ENTER;
824 14674 int want = 0, force_exit = 0;
825
826 /* (can_pns was already checked above; gates below fill `want`) */
827
2/2
✓ Branch 0 taken 1916 times.
✓ Branch 1 taken 12758 times.
14674 if (t->pener[bi] > NMR_PNS_MAX_ET * t->thr_real[bi]) {
828 1916 force_exit = 1; /* loud-band guard */
829
2/2
✓ Branch 0 taken 4109 times.
✓ Branch 1 taken 8649 times.
12758 } else if (lam > pns_lam) {
830 /* Spectral-hole fill: a noise-like band left mostly empty */
831
1/2
✓ Branch 0 taken 4109 times.
✗ Branch 1 not taken.
4109 frac = ndk[b][t->chosen[b]] * t->thr[bi] / FFMAX(t->pener[bi], 1e-9f);
832
1/2
✓ Branch 0 taken 4109 times.
✗ Branch 1 not taken.
4109 if (spread > NMR_PNS_HOLE_SPREAD &&
833
4/4
✓ Branch 0 taken 1872 times.
✓ Branch 1 taken 2237 times.
✓ Branch 2 taken 2526 times.
✓ Branch 3 taken 1583 times.
4109 frac > NMR_PNS_HOLE_FRAC * (was ? 0.7f : 1.0f)) {
834 2526 want = 1;
835 3166 } else if (ndk[b][t->chosen[b]] * t->thr[bi] >
836
3/4
✓ Branch 0 taken 206 times.
✓ Branch 1 taken 1377 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1583 times.
1583 NMR_PNS_NDGATE * t->thr_real[bi] * (was ? 0.5f : 1.0f)) {
837 /* replace only a band coded audibly badly; cost of
838 * energy-matched noise = its non-noise-like fraction */
839 nmr_pns = FFMAX(0.0f, t->pener[bi] * (1.0f - spread*spread))
840 / FFMAX(t->thr[bi], 1e-9f);
841 cost_keep = ndk[b][t->chosen[b]] + lam * nbk[b][t->chosen[b]];
842 cost_pns = nmr_pns + lam * NMR_PNS_BITS;
843 want = cost_pns < cost_keep * bias;
844 }
845 }
846 { /* debounce; near-mask deletion candidates skip entry
847 * (noise beats the ~silent rendition they'd get) */
848 14674 uint8_t *ron = &s->nmr->pns_run_on [t->cur_ch & 15][bi];
849 14674 uint8_t *roff = &s->nmr->pns_run_off[t->cur_ch & 15][bi];
850 14674 int near = t->pener[bi] < 2.0f * t->thr_real[bi];
851
3/4
✓ Branch 0 taken 2526 times.
✓ Branch 1 taken 12148 times.
✓ Branch 2 taken 2526 times.
✗ Branch 3 not taken.
14674 if (want) { if (*ron < 255) (*ron)++; *roff = 0; }
852
2/2
✓ Branch 0 taken 12145 times.
✓ Branch 1 taken 3 times.
12148 else { if (*roff < 255) (*roff)++; *ron = 0; }
853
2/2
✓ Branch 0 taken 1916 times.
✓ Branch 1 taken 12758 times.
14674 if (force_exit)
854 1916 want = 0;
855
2/2
✓ Branch 0 taken 10356 times.
✓ Branch 1 taken 2402 times.
12758 else if (!was)
856
2/2
✓ Branch 0 taken 5973 times.
✓ Branch 1 taken 4383 times.
10356 want = near ? want : *ron >= NMR_PNS_ON;
857
2/2
✓ Branch 0 taken 1000 times.
✓ Branch 1 taken 1402 times.
2402 else if (near)
858 1000 want = 1; /* physics-hysteresis: noise until audible */
859 else
860 1402 want = !(*roff >= NMR_PNS_OFF);
861 }
862
2/2
✓ Branch 0 taken 2679 times.
✓ Branch 1 taken 11995 times.
14674 if (want) {
863 2679 t->is_pns[b] = 1;
864 2679 pns_count++;
865 }
866 }
867
2/2
✓ Branch 0 taken 264 times.
✓ Branch 1 taken 1153 times.
1417 if (pns_count) {
868 264 t->nact = 0;
869
2/2
✓ Branch 0 taken 12872 times.
✓ Branch 1 taken 264 times.
13136 for (int b = 0; b < t->nbnd; b++)
870
2/2
✓ Branch 0 taken 10193 times.
✓ Branch 1 taken 2679 times.
12872 if (!t->is_pns[b])
871 10193 t->act[t->nact++] = b;
872 }
873 1417 pns_total += pns_count;
874 }
875
2/2
✓ Branch 0 taken 264 times.
✓ Branch 1 taken 864 times.
1128 if (pns_total) {
876 /* re-solve over the survivors: at fixed lambda the allocation is
877 * the same except for the repaired sf-delta chain; in bisection
878 * mode re-spend the freed budget */
879
2/2
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 9 times.
264 if (rc_global)
880 255 nmr_eval_slots(s, sl, nsl, NMR_STEP, lam);
881 else
882 9 nmr_solve_slots(s, sl, nsl, NMR_STEP, destbits - pns_total * NMR_PNS_BITS,
883 1e-9f, 1e4f, NMR_ITERS);
884 }
885 }
886
887
2/2
✓ Branch 0 taken 1417 times.
✓ Branch 1 taken 1128 times.
2545 for (int k = 0; k < nsl; k++) {
888 1417 NMRSlot *t = sl[k];
889 1417 uint8_t *pp = s->nmr->pns_prev[t->cur_ch & 15];
890 1417 uint8_t now[128] = {0};
891
2/2
✓ Branch 0 taken 62122 times.
✓ Branch 1 taken 1417 times.
63539 for (int b = 0; b < t->nbnd; b++)
892
2/2
✓ Branch 0 taken 2679 times.
✓ Branch 1 taken 59443 times.
62122 if (t->is_pns[b])
893 2679 now[t->bidx[b]] = 1;
894 1417 memcpy(pp, now, 128);
895 }
896
2/2
✓ Branch 0 taken 1417 times.
✓ Branch 1 taken 1128 times.
2545 for (int k = 0; k < nsl; k++)
897 1417 nmr_commit_channel(s, sl[k]);
898
899 1128 }
900
901 1530 static void search_for_quantizers_nmr(AVCodecContext *avctx,
902 AACEncContext *s,
903 SingleChannelElement *sce,
904 const float lambda)
905 {
906 1530 AACNMRCurves *n = s->nmr;
907 /* Global-lambda RC: one solve per frame at a servoed centre lambda; the reservoir
908 * holds the long-run mean rate. Bypassed for VBR (-q:a) and the bootstrap frame. */
909
2/4
✓ Branch 0 taken 1530 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1530 times.
✗ Branch 3 not taken.
3060 int rc_eligible = !(avctx->flags & AV_CODEC_FLAG_QSCALE) && avctx->bit_rate > 0 &&
910
1/2
✓ Branch 0 taken 1530 times.
✗ Branch 1 not taken.
1530 avctx->bit_rate_tolerance != 0;
911 /* Signed reservoir; soft steering (bounded repay + rc_off), hard cap =
912 * legality only. */
913 1530 int rc_rate_frame = avctx->bit_rate * 1024.0 / avctx->sample_rate;
914 1530 int rc_bmax = FFMIN(FFMAX(6144 * s->channels - rc_rate_frame, 256), NMR_CBR_BUF * s->channels);
915
916 int rc_global, defer;
917 NMRSlot *t;
918
919 1530 s->nmr->counted[s->cur_channel] = 0;
920
921
3/4
✓ Branch 0 taken 1530 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 1515 times.
1530 if (rc_eligible && !n->rc_fill_seeded) {
922 /* the decoder bit reservoir starts FULL: seed it so the head may frontload */
923 15 n->rc_fill = rc_bmax;
924 15 n->rc_fill_seeded = 1;
925 }
926
3/4
✓ Branch 0 taken 1530 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 718 times.
✓ Branch 3 taken 812 times.
1530 if (rc_eligible && avctx->frame_num != n->rc_frame_num) {
927
4/4
✓ Branch 0 taken 703 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 698 times.
✓ Branch 3 taken 5 times.
718 if (n->rc_frame_num > 0 && n->lam_rc > 0.0f)
928 698 n->rc_fill = av_clip(n->rc_fill + rc_rate_frame - s->last_frame_pb_count,
929 -rc_bmax, rc_bmax);
930 718 n->rc_frame_num = avctx->frame_num;
931 718 n->pending = 0; /* a deferred first channel never crosses a frame */
932 /* latch the RC mode per frame: a mid-frame bootstrap must not flip
933 * the CPE defer logic between channels */
934
3/4
✓ Branch 0 taken 718 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 698 times.
✓ Branch 3 taken 20 times.
718 n->rc_gl = rc_eligible && n->lam_rc > 0.0f;
935
936 /* Transient burst run state: set at run start and held across the run so
937 * coding stays uniform; repaid from the reservoir's steady stretches. */
938 718 int is_short = sce->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE;
939
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 702 times.
718 if (is_short) {
940
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 1 times.
16 if (!n->prev_was_short) { /* run start */
941
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 14 times.
15 if (n->frames_since_short >= NMR_BURST_GAP) {
942 1 n->run_burst = NMR_BURST_GAIN;
943 } else {
944 /* dense-beat boost, scaled by measured short-frame starvation */
945 14 float imb = 0.0f;
946
2/4
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
14 if (n->lam_long_ema > 0.0f && n->lam_short_ema > 0.0f)
947 imb = av_clipf(n->lam_short_ema / n->lam_long_ema - 1.0f,
948 0.0f, 1.0f);
949 14 n->run_burst = 1.0f + (NMR_SHORT_BOOST - 1.0f) * imb *
950 14 n->frames_since_short / (float)NMR_BURST_GAP;
951 }
952 }
953 16 n->frames_since_short = 0;
954 } else {
955 /* the frame closing a run (the STOP) absorbs the corridor recoil
956 * of the boosted shorts; give it half the run's factor so the
957 * repayment spreads into the steady stretch instead */
958
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 687 times.
702 n->run_burst = n->prev_was_short ? sqrtf(n->run_burst) : 1.0f;
959 702 n->frames_since_short++;
960 }
961 718 n->prev_was_short = is_short;
962 }
963
3/4
✓ Branch 0 taken 1530 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1423 times.
✓ Branch 3 taken 107 times.
1530 rc_global = rc_eligible && n->rc_gl;
964
965 /* CPE budget pool: under global-lambda RC, defer the pair's first channel
966 * and solve both against one pooled budget when the second one arrives. */
967
4/4
✓ Branch 0 taken 868 times.
✓ Branch 1 taken 662 times.
✓ Branch 2 taken 778 times.
✓ Branch 3 taken 90 times.
1530 defer = n->pair && rc_global;
968
969
4/4
✓ Branch 0 taken 778 times.
✓ Branch 1 taken 752 times.
✓ Branch 2 taken 389 times.
✓ Branch 3 taken 389 times.
1530 t = &n->slot[(defer && n->pending) ? 1 : 0];
970
4/4
✓ Branch 0 taken 778 times.
✓ Branch 1 taken 752 times.
✓ Branch 2 taken 389 times.
✓ Branch 3 taken 389 times.
1530 t->si = (defer && n->pending) ? 1 : 0;
971
972
2/2
✓ Branch 1 taken 113 times.
✓ Branch 2 taken 1417 times.
1530 if (!nmr_setup_channel(avctx, s, sce, t)) {
973 113 nmr_bail_channel(sce);
974 113 t->nbnd = t->nact = 0;
975 }
976
977
4/4
✓ Branch 0 taken 778 times.
✓ Branch 1 taken 752 times.
✓ Branch 2 taken 389 times.
✓ Branch 3 taken 389 times.
1530 if (defer && !n->pending) {
978 389 n->pending = 1; /* wait for the partner channel */
979 389 return;
980 }
981
982 {
983 NMRSlot *sl[2];
984 1141 int nsl = 0, chans = 1;
985
2/2
✓ Branch 0 taken 389 times.
✓ Branch 1 taken 752 times.
1141 if (defer) {
986 389 n->pending = 0;
987 389 chans = 2;
988
1/2
✓ Branch 0 taken 389 times.
✗ Branch 1 not taken.
389 if (n->slot[0].nact)
989 389 sl[nsl++] = &n->slot[0];
990
2/2
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 100 times.
389 if (n->slot[1].nact)
991 289 sl[nsl++] = &n->slot[1];
992
2/2
✓ Branch 0 taken 739 times.
✓ Branch 1 taken 13 times.
752 } else if (t->nact) {
993 739 sl[nsl++] = t;
994 }
995
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 1128 times.
1141 if (!nsl)
996 13 return; /* nothing codeable in the group */
997 1128 nmr_solve_group(avctx, s, lambda, sl, nsl, chans,
998 rc_eligible, rc_global, rc_rate_frame, rc_bmax);
999 }
1000 }
1001
1002 #endif /* AVCODEC_AACCODER_NMR_H */
1003