FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/ebur128.c
Date: 2026-09-26 05:01:43
Exec Total Coverage
Lines: 0 334 0.0%
Functions: 0 22 0.0%
Branches: 0 197 0.0%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2011 Jan Kokemüller
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 * This file is based on libebur128 which is available at
21 * https://github.com/jiixyj/libebur128/
22 *
23 * Libebur128 has the following copyright:
24 *
25 * Permission is hereby granted, free of charge, to any person obtaining a copy
26 * of this software and associated documentation files (the "Software"), to deal
27 * in the Software without restriction, including without limitation the rights
28 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
29 * copies of the Software, and to permit persons to whom the Software is
30 * furnished to do so, subject to the following conditions:
31 *
32 * The above copyright notice and this permission notice shall be included in
33 * all copies or substantial portions of the Software.
34 *
35 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
36 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
37 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
38 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
39 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
40 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
41 * THE SOFTWARE.
42 */
43
44 #include "ebur128.h"
45
46 #include <float.h>
47 #include <limits.h>
48 #include <math.h> /* You may have to define _USE_MATH_DEFINES if you use MSVC */
49
50 #include "libavutil/error.h"
51 #include "libavutil/macros.h"
52 #include "libavutil/mem.h"
53 #include "libavutil/mem_internal.h"
54 #include "libavutil/thread.h"
55
56 #define CHECK_ERROR(condition, errorcode, goto_point) \
57 if ((condition)) { \
58 errcode = (errorcode); \
59 goto goto_point; \
60 }
61
62 #define ALMOST_ZERO 0.000001
63
64 #define RELATIVE_GATE (-10.0)
65 #define RELATIVE_GATE_FACTOR pow(10.0, RELATIVE_GATE / 10.0)
66 #define MINUS_20DB pow(10.0, -20.0 / 10.0)
67
68 struct FFEBUR128StateInternal {
69 /** Filtered audio data (used as ring buffer). */
70 double *audio_data;
71 /** Size of audio_data array. */
72 size_t audio_data_frames;
73 /** Current index for audio_data. */
74 size_t audio_data_index;
75 /** How many frames are needed for a gating block. Will correspond to 400ms
76 * of audio at initialization, and 100ms after the first block (75% overlap
77 * as specified in the 2011 revision of BS1770). */
78 unsigned long needed_frames;
79 /** The channel map. Has as many elements as there are channels. */
80 int *channel_map;
81 /** How many samples fit in 100ms (rounded). */
82 unsigned long samples_in_100ms;
83 /** BS.1770 filter coefficients (nominator). */
84 double b[5];
85 /** BS.1770 filter coefficients (denominator). */
86 double a[5];
87 /** BS.1770 filter state. */
88 double v[5][5];
89 /** Histograms, used to calculate LRA. */
90 unsigned long *block_energy_histogram;
91 unsigned long *short_term_block_energy_histogram;
92 /** Keeps track of when a new short term block is needed. */
93 size_t short_term_frame_counter;
94 /** Maximum sample peak, one per channel */
95 double *sample_peak;
96 /** The maximum window duration in ms. */
97 unsigned long window;
98 /** Data pointer array for interleaved data */
99 void **data_ptrs;
100 };
101
102 static AVOnce histogram_init = AV_ONCE_INIT;
103 static DECLARE_ALIGNED(32, double, histogram_energies)[1000];
104 static DECLARE_ALIGNED(32, double, histogram_energy_boundaries)[1001];
105
106 ✗ static void ebur128_init_filter(FFEBUR128State * st)
107 {
108 int i, j;
109
110 ✗ double f0 = 1681.974450955533;
111 ✗ double G = 3.999843853973347;
112 ✗ double Q = 0.7071752369554196;
113
114 ✗ double K = tan(M_PI * f0 / (double) st->samplerate);
115 ✗ double Vh = pow(10.0, G / 20.0);
116 ✗ double Vb = pow(Vh, 0.4996667741545416);
117
118 ✗ double pb[3] = { 0.0, 0.0, 0.0 };
119 ✗ double pa[3] = { 1.0, 0.0, 0.0 };
120 ✗ double rb[3] = { 1.0, -2.0, 1.0 };
121 ✗ double ra[3] = { 1.0, 0.0, 0.0 };
122
123 ✗ double a0 = 1.0 + K / Q + K * K;
124 ✗ pb[0] = (Vh + Vb * K / Q + K * K) / a0;
125 ✗ pb[1] = 2.0 * (K * K - Vh) / a0;
126 ✗ pb[2] = (Vh - Vb * K / Q + K * K) / a0;
127 ✗ pa[1] = 2.0 * (K * K - 1.0) / a0;
128 ✗ pa[2] = (1.0 - K / Q + K * K) / a0;
129
130 ✗ f0 = 38.13547087602444;
131 ✗ Q = 0.5003270373238773;
132 ✗ K = tan(M_PI * f0 / (double) st->samplerate);
133
134 ✗ ra[1] = 2.0 * (K * K - 1.0) / (1.0 + K / Q + K * K);
135 ✗ ra[2] = (1.0 - K / Q + K * K) / (1.0 + K / Q + K * K);
136
137 ✗ st->d->b[0] = pb[0] * rb[0];
138 ✗ st->d->b[1] = pb[0] * rb[1] + pb[1] * rb[0];
139 ✗ st->d->b[2] = pb[0] * rb[2] + pb[1] * rb[1] + pb[2] * rb[0];
140 ✗ st->d->b[3] = pb[1] * rb[2] + pb[2] * rb[1];
141 ✗ st->d->b[4] = pb[2] * rb[2];
142
143 ✗ st->d->a[0] = pa[0] * ra[0];
144 ✗ st->d->a[1] = pa[0] * ra[1] + pa[1] * ra[0];
145 ✗ st->d->a[2] = pa[0] * ra[2] + pa[1] * ra[1] + pa[2] * ra[0];
146 ✗ st->d->a[3] = pa[1] * ra[2] + pa[2] * ra[1];
147 ✗ st->d->a[4] = pa[2] * ra[2];
148
149 ✗ for (i = 0; i < 5; ++i) {
150 ✗ for (j = 0; j < 5; ++j) {
151 ✗ st->d->v[i][j] = 0.0;
152 }
153 }
154 ✗ }
155
156 ✗ static int ebur128_init_channel_map(FFEBUR128State * st)
157 {
158 size_t i;
159 ✗ st->d->channel_map =
160 ✗ (int *) av_malloc_array(st->channels, sizeof(*st->d->channel_map));
161 ✗ if (!st->d->channel_map)
162 ✗ return AVERROR(ENOMEM);
163 ✗ if (st->channels == 4) {
164 ✗ st->d->channel_map[0] = FF_EBUR128_LEFT;
165 ✗ st->d->channel_map[1] = FF_EBUR128_RIGHT;
166 ✗ st->d->channel_map[2] = FF_EBUR128_LEFT_SURROUND;
167 ✗ st->d->channel_map[3] = FF_EBUR128_RIGHT_SURROUND;
168 ✗ } else if (st->channels == 5) {
169 ✗ st->d->channel_map[0] = FF_EBUR128_LEFT;
170 ✗ st->d->channel_map[1] = FF_EBUR128_RIGHT;
171 ✗ st->d->channel_map[2] = FF_EBUR128_CENTER;
172 ✗ st->d->channel_map[3] = FF_EBUR128_LEFT_SURROUND;
173 ✗ st->d->channel_map[4] = FF_EBUR128_RIGHT_SURROUND;
174 } else {
175 ✗ for (i = 0; i < st->channels; ++i) {
176 ✗ switch (i) {
177 ✗ case 0:
178 ✗ st->d->channel_map[i] = FF_EBUR128_LEFT;
179 ✗ break;
180 ✗ case 1:
181 ✗ st->d->channel_map[i] = FF_EBUR128_RIGHT;
182 ✗ break;
183 ✗ case 2:
184 ✗ st->d->channel_map[i] = FF_EBUR128_CENTER;
185 ✗ break;
186 ✗ case 3:
187 ✗ st->d->channel_map[i] = FF_EBUR128_UNUSED;
188 ✗ break;
189 ✗ case 4:
190 ✗ st->d->channel_map[i] = FF_EBUR128_LEFT_SURROUND;
191 ✗ break;
192 ✗ case 5:
193 ✗ st->d->channel_map[i] = FF_EBUR128_RIGHT_SURROUND;
194 ✗ break;
195 ✗ default:
196 ✗ st->d->channel_map[i] = FF_EBUR128_UNUSED;
197 ✗ break;
198 }
199 }
200 }
201 ✗ return 0;
202 }
203
204 ✗ static inline void init_histogram(void)
205 {
206 int i;
207 /* initialize static constants */
208 ✗ histogram_energy_boundaries[0] = pow(10.0, (-70.0 + 0.691) / 10.0);
209 ✗ for (i = 0; i < 1000; ++i) {
210 ✗ histogram_energies[i] =
211 ✗ pow(10.0, ((double) i / 10.0 - 69.95 + 0.691) / 10.0);
212 }
213 ✗ for (i = 1; i < 1001; ++i) {
214 ✗ histogram_energy_boundaries[i] =
215 ✗ pow(10.0, ((double) i / 10.0 - 70.0 + 0.691) / 10.0);
216 }
217 ✗ }
218
219 ✗ FFEBUR128State *ff_ebur128_init(unsigned int channels,
220 unsigned long samplerate,
221 unsigned long window, int mode)
222 {
223 int errcode;
224 FFEBUR128State *st;
225
226 ✗ st = (FFEBUR128State *) av_malloc(sizeof(*st));
227 ✗ CHECK_ERROR(!st, 0, exit)
228 ✗ st->d = (struct FFEBUR128StateInternal *)
229 ✗ av_malloc(sizeof(*st->d));
230 ✗ CHECK_ERROR(!st->d, 0, free_state)
231 ✗ st->channels = channels;
232 ✗ errcode = ebur128_init_channel_map(st);
233 ✗ CHECK_ERROR(errcode, 0, free_internal)
234
235 ✗ st->d->sample_peak =
236 ✗ (double *) av_calloc(channels, sizeof(*st->d->sample_peak));
237 ✗ CHECK_ERROR(!st->d->sample_peak, 0, free_channel_map)
238
239 ✗ st->samplerate = samplerate;
240 ✗ st->d->samples_in_100ms = (st->samplerate + 5) / 10;
241 ✗ st->mode = mode;
242 ✗ if ((mode & FF_EBUR128_MODE_S) == FF_EBUR128_MODE_S) {
243 ✗ st->d->window = FFMAX(window, 3000);
244 ✗ } else if ((mode & FF_EBUR128_MODE_M) == FF_EBUR128_MODE_M) {
245 ✗ st->d->window = FFMAX(window, 400);
246 } else {
247 ✗ goto free_sample_peak;
248 }
249 ✗ st->d->audio_data_frames = st->samplerate * st->d->window / 1000;
250 ✗ if (st->d->audio_data_frames % st->d->samples_in_100ms) {
251 /* round up to multiple of samples_in_100ms */
252 ✗ st->d->audio_data_frames = st->d->audio_data_frames
253 ✗ + st->d->samples_in_100ms
254 ✗ - (st->d->audio_data_frames % st->d->samples_in_100ms);
255 }
256 ✗ st->d->audio_data =
257 ✗ (double *) av_calloc(st->d->audio_data_frames,
258 ✗ st->channels * sizeof(*st->d->audio_data));
259 ✗ CHECK_ERROR(!st->d->audio_data, 0, free_sample_peak)
260
261 ✗ ebur128_init_filter(st);
262
263 ✗ st->d->block_energy_histogram =
264 ✗ av_mallocz(1000 * sizeof(*st->d->block_energy_histogram));
265 ✗ CHECK_ERROR(!st->d->block_energy_histogram, 0, free_audio_data)
266 ✗ st->d->short_term_block_energy_histogram =
267 ✗ av_mallocz(1000 * sizeof(*st->d->short_term_block_energy_histogram));
268 ✗ CHECK_ERROR(!st->d->short_term_block_energy_histogram, 0,
269 free_block_energy_histogram)
270 ✗ st->d->short_term_frame_counter = 0;
271
272 /* the first block needs 400ms of audio data */
273 ✗ st->d->needed_frames = st->d->samples_in_100ms * 4;
274 /* start at the beginning of the buffer */
275 ✗ st->d->audio_data_index = 0;
276
277 ✗ if (ff_thread_once(&histogram_init, &init_histogram) != 0)
278 ✗ goto free_short_term_block_energy_histogram;
279
280 ✗ st->d->data_ptrs = av_malloc_array(channels, sizeof(*st->d->data_ptrs));
281 ✗ CHECK_ERROR(!st->d->data_ptrs, 0,
282 free_short_term_block_energy_histogram);
283
284 ✗ return st;
285
286 ✗ free_short_term_block_energy_histogram:
287 ✗ av_free(st->d->short_term_block_energy_histogram);
288 ✗ free_block_energy_histogram:
289 ✗ av_free(st->d->block_energy_histogram);
290 ✗ free_audio_data:
291 ✗ av_free(st->d->audio_data);
292 ✗ free_sample_peak:
293 ✗ av_free(st->d->sample_peak);
294 ✗ free_channel_map:
295 ✗ av_free(st->d->channel_map);
296 ✗ free_internal:
297 ✗ av_free(st->d);
298 ✗ free_state:
299 ✗ av_free(st);
300 ✗ exit:
301 ✗ return NULL;
302 }
303
304 ✗ void ff_ebur128_destroy(FFEBUR128State ** st)
305 {
306 ✗ av_free((*st)->d->block_energy_histogram);
307 ✗ av_free((*st)->d->short_term_block_energy_histogram);
308 ✗ av_free((*st)->d->audio_data);
309 ✗ av_free((*st)->d->channel_map);
310 ✗ av_free((*st)->d->sample_peak);
311 ✗ av_free((*st)->d->data_ptrs);
312 ✗ av_free((*st)->d);
313 ✗ av_free(*st);
314 ✗ *st = NULL;
315 ✗ }
316
317 #define EBUR128_FILTER(type, scaling_factor) \
318 static void ebur128_filter_##type(FFEBUR128State* st, const type** srcs, \
319 size_t src_index, size_t frames, \
320 int stride) { \
321 double* audio_data = st->d->audio_data + st->d->audio_data_index; \
322 size_t i, c; \
323 \
324 if ((st->mode & FF_EBUR128_MODE_SAMPLE_PEAK) == FF_EBUR128_MODE_SAMPLE_PEAK) { \
325 for (c = 0; c < st->channels; ++c) { \
326 double max = 0.0; \
327 for (i = 0; i < frames; ++i) { \
328 type v = srcs[c][src_index + i * stride]; \
329 if (v > max) { \
330 max = v; \
331 } else if (-v > max) { \
332 max = -1.0 * v; \
333 } \
334 } \
335 max /= scaling_factor; \
336 if (max > st->d->sample_peak[c]) st->d->sample_peak[c] = max; \
337 } \
338 } \
339 for (c = 0; c < st->channels; ++c) { \
340 int ci = st->d->channel_map[c] - 1; \
341 if (ci < 0) continue; \
342 else if (ci == FF_EBUR128_DUAL_MONO - 1) ci = 0; /*dual mono */ \
343 for (i = 0; i < frames; ++i) { \
344 st->d->v[ci][0] = (double) (srcs[c][src_index + i * stride] / scaling_factor) \
345 - st->d->a[1] * st->d->v[ci][1] \
346 - st->d->a[2] * st->d->v[ci][2] \
347 - st->d->a[3] * st->d->v[ci][3] \
348 - st->d->a[4] * st->d->v[ci][4]; \
349 audio_data[i * st->channels + c] = \
350 st->d->b[0] * st->d->v[ci][0] \
351 + st->d->b[1] * st->d->v[ci][1] \
352 + st->d->b[2] * st->d->v[ci][2] \
353 + st->d->b[3] * st->d->v[ci][3] \
354 + st->d->b[4] * st->d->v[ci][4]; \
355 st->d->v[ci][4] = st->d->v[ci][3]; \
356 st->d->v[ci][3] = st->d->v[ci][2]; \
357 st->d->v[ci][2] = st->d->v[ci][1]; \
358 st->d->v[ci][1] = st->d->v[ci][0]; \
359 } \
360 st->d->v[ci][4] = fabs(st->d->v[ci][4]) < DBL_MIN ? 0.0 : st->d->v[ci][4]; \
361 st->d->v[ci][3] = fabs(st->d->v[ci][3]) < DBL_MIN ? 0.0 : st->d->v[ci][3]; \
362 st->d->v[ci][2] = fabs(st->d->v[ci][2]) < DBL_MIN ? 0.0 : st->d->v[ci][2]; \
363 st->d->v[ci][1] = fabs(st->d->v[ci][1]) < DBL_MIN ? 0.0 : st->d->v[ci][1]; \
364 } \
365 }
366 ✗ EBUR128_FILTER(double, 1.0)
367
368 ✗ static double ebur128_energy_to_loudness(double energy)
369 {
370 ✗ return 10 * log10(energy) - 0.691;
371 }
372
373 ✗ static size_t find_histogram_index(double energy)
374 {
375 ✗ size_t index_min = 0;
376 ✗ size_t index_max = 1000;
377 size_t index_mid;
378
379 do {
380 ✗ index_mid = (index_min + index_max) / 2;
381 ✗ if (energy >= histogram_energy_boundaries[index_mid]) {
382 ✗ index_min = index_mid;
383 } else {
384 ✗ index_max = index_mid;
385 }
386 ✗ } while (index_max - index_min != 1);
387
388 ✗ return index_min;
389 }
390
391 ✗ static void ebur128_calc_gating_block(FFEBUR128State * st,
392 size_t frames_per_block,
393 double *optional_output)
394 {
395 size_t i, c;
396 ✗ double sum = 0.0;
397 double channel_sum;
398 ✗ for (c = 0; c < st->channels; ++c) {
399 ✗ if (st->d->channel_map[c] == FF_EBUR128_UNUSED)
400 ✗ continue;
401 ✗ channel_sum = 0.0;
402 ✗ if (st->d->audio_data_index < frames_per_block * st->channels) {
403 ✗ for (i = 0; i < st->d->audio_data_index / st->channels; ++i) {
404 ✗ channel_sum += st->d->audio_data[i * st->channels + c] *
405 ✗ st->d->audio_data[i * st->channels + c];
406 }
407 ✗ for (i = st->d->audio_data_frames -
408 (frames_per_block -
409 ✗ st->d->audio_data_index / st->channels);
410 ✗ i < st->d->audio_data_frames; ++i) {
411 ✗ channel_sum += st->d->audio_data[i * st->channels + c] *
412 ✗ st->d->audio_data[i * st->channels + c];
413 }
414 } else {
415 ✗ for (i =
416 ✗ st->d->audio_data_index / st->channels - frames_per_block;
417 ✗ i < st->d->audio_data_index / st->channels; ++i) {
418 ✗ channel_sum +=
419 ✗ st->d->audio_data[i * st->channels +
420 ✗ c] * st->d->audio_data[i *
421 ✗ st->channels +
422 c];
423 }
424 }
425 ✗ if (st->d->channel_map[c] == FF_EBUR128_Mp110 ||
426 ✗ st->d->channel_map[c] == FF_EBUR128_Mm110 ||
427 ✗ st->d->channel_map[c] == FF_EBUR128_Mp060 ||
428 ✗ st->d->channel_map[c] == FF_EBUR128_Mm060 ||
429 ✗ st->d->channel_map[c] == FF_EBUR128_Mp090 ||
430 ✗ st->d->channel_map[c] == FF_EBUR128_Mm090) {
431 ✗ channel_sum *= 1.41;
432 ✗ } else if (st->d->channel_map[c] == FF_EBUR128_DUAL_MONO) {
433 ✗ channel_sum *= 2.0;
434 }
435 ✗ sum += channel_sum;
436 }
437 ✗ sum /= (double) frames_per_block;
438 ✗ if (optional_output) {
439 ✗ *optional_output = sum;
440 ✗ } else if (sum >= histogram_energy_boundaries[0]) {
441 ✗ ++st->d->block_energy_histogram[find_histogram_index(sum)];
442 }
443 ✗ }
444
445 ✗ int ff_ebur128_set_channel(FFEBUR128State * st,
446 unsigned int channel_number, int value)
447 {
448 ✗ if (channel_number >= st->channels) {
449 ✗ return 1;
450 }
451 ✗ if (value == FF_EBUR128_DUAL_MONO &&
452 ✗ (st->channels != 1 || channel_number != 0)) {
453 ✗ return 1;
454 }
455 ✗ st->d->channel_map[channel_number] = value;
456 ✗ return 0;
457 }
458
459 static int ebur128_energy_shortterm(FFEBUR128State * st, double *out);
460 #define EBUR128_ADD_FRAMES_PLANAR(type) \
461 static void ebur128_add_frames_planar_##type(FFEBUR128State* st, const type** srcs, \
462 size_t frames, int stride) { \
463 size_t src_index = 0; \
464 while (frames > 0) { \
465 if (frames >= st->d->needed_frames) { \
466 ebur128_filter_##type(st, srcs, src_index, st->d->needed_frames, stride); \
467 src_index += st->d->needed_frames * stride; \
468 frames -= st->d->needed_frames; \
469 st->d->audio_data_index += st->d->needed_frames * st->channels; \
470 /* calculate the new gating block */ \
471 if ((st->mode & FF_EBUR128_MODE_I) == FF_EBUR128_MODE_I) { \
472 ebur128_calc_gating_block(st, st->d->samples_in_100ms * 4, NULL); \
473 } \
474 if ((st->mode & FF_EBUR128_MODE_LRA) == FF_EBUR128_MODE_LRA) { \
475 st->d->short_term_frame_counter += st->d->needed_frames; \
476 if (st->d->short_term_frame_counter == st->d->samples_in_100ms * 30) { \
477 double st_energy; \
478 ebur128_energy_shortterm(st, &st_energy); \
479 if (st_energy >= histogram_energy_boundaries[0]) { \
480 ++st->d->short_term_block_energy_histogram[ \
481 find_histogram_index(st_energy)]; \
482 } \
483 st->d->short_term_frame_counter = st->d->samples_in_100ms * 20; \
484 } \
485 } \
486 /* 100ms are needed for all blocks besides the first one */ \
487 st->d->needed_frames = st->d->samples_in_100ms; \
488 /* reset audio_data_index when buffer full */ \
489 if (st->d->audio_data_index == st->d->audio_data_frames * st->channels) { \
490 st->d->audio_data_index = 0; \
491 } \
492 } else { \
493 ebur128_filter_##type(st, srcs, src_index, frames, stride); \
494 st->d->audio_data_index += frames * st->channels; \
495 if ((st->mode & FF_EBUR128_MODE_LRA) == FF_EBUR128_MODE_LRA) { \
496 st->d->short_term_frame_counter += frames; \
497 } \
498 st->d->needed_frames -= frames; \
499 frames = 0; \
500 } \
501 } \
502 }
503 ✗ EBUR128_ADD_FRAMES_PLANAR(double)
504 #define FF_EBUR128_ADD_FRAMES(type) \
505 void ff_ebur128_add_frames_##type(FFEBUR128State* st, const type* src, \
506 size_t frames) { \
507 int i; \
508 const type **buf = (const type**)st->d->data_ptrs; \
509 for (i = 0; i < st->channels; i++) \
510 buf[i] = src + i; \
511 ebur128_add_frames_planar_##type(st, buf, frames, st->channels); \
512 }
513 ✗ FF_EBUR128_ADD_FRAMES(double)
514
515 ✗ static int ebur128_calc_relative_threshold(FFEBUR128State **sts, size_t size,
516 double *relative_threshold)
517 {
518 size_t i, j;
519 ✗ int above_thresh_counter = 0;
520 ✗ *relative_threshold = 0.0;
521
522 ✗ for (i = 0; i < size; i++) {
523 ✗ unsigned long *block_energy_histogram = sts[i]->d->block_energy_histogram;
524 ✗ for (j = 0; j < 1000; ++j) {
525 ✗ *relative_threshold += block_energy_histogram[j] * histogram_energies[j];
526 ✗ above_thresh_counter += block_energy_histogram[j];
527 }
528 }
529
530 ✗ if (above_thresh_counter != 0) {
531 ✗ *relative_threshold /= (double)above_thresh_counter;
532 ✗ *relative_threshold *= RELATIVE_GATE_FACTOR;
533 }
534
535 ✗ return above_thresh_counter;
536 }
537
538 ✗ static int ebur128_gated_loudness(FFEBUR128State ** sts, size_t size,
539 double *out)
540 {
541 ✗ double gated_loudness = 0.0;
542 double relative_threshold;
543 size_t above_thresh_counter;
544 size_t i, j, start_index;
545
546 ✗ for (i = 0; i < size; i++)
547 ✗ if ((sts[i]->mode & FF_EBUR128_MODE_I) != FF_EBUR128_MODE_I)
548 ✗ return AVERROR(EINVAL);
549
550 ✗ if (!ebur128_calc_relative_threshold(sts, size, &relative_threshold)) {
551 ✗ *out = -HUGE_VAL;
552 ✗ return 0;
553 }
554
555 ✗ above_thresh_counter = 0;
556 ✗ if (relative_threshold < histogram_energy_boundaries[0]) {
557 ✗ start_index = 0;
558 } else {
559 ✗ start_index = find_histogram_index(relative_threshold);
560 ✗ if (relative_threshold > histogram_energies[start_index]) {
561 ✗ ++start_index;
562 }
563 }
564 ✗ for (i = 0; i < size; i++) {
565 ✗ for (j = start_index; j < 1000; ++j) {
566 ✗ gated_loudness += sts[i]->d->block_energy_histogram[j] *
567 ✗ histogram_energies[j];
568 ✗ above_thresh_counter += sts[i]->d->block_energy_histogram[j];
569 }
570 }
571 ✗ if (!above_thresh_counter) {
572 ✗ *out = -HUGE_VAL;
573 ✗ return 0;
574 }
575 ✗ gated_loudness /= (double) above_thresh_counter;
576 ✗ *out = ebur128_energy_to_loudness(gated_loudness);
577 ✗ return 0;
578 }
579
580 ✗ int ff_ebur128_relative_threshold(FFEBUR128State * st, double *out)
581 {
582 double relative_threshold;
583
584 ✗ if ((st->mode & FF_EBUR128_MODE_I) != FF_EBUR128_MODE_I)
585 ✗ return AVERROR(EINVAL);
586
587 ✗ if (!ebur128_calc_relative_threshold(&st, 1, &relative_threshold)) {
588 ✗ *out = -70.0;
589 ✗ return 0;
590 }
591
592 ✗ *out = ebur128_energy_to_loudness(relative_threshold);
593 ✗ return 0;
594 }
595
596 ✗ int ff_ebur128_loudness_global(FFEBUR128State * st, double *out)
597 {
598 ✗ return ebur128_gated_loudness(&st, 1, out);
599 }
600
601 ✗ static int ebur128_energy_in_interval(FFEBUR128State * st,
602 size_t interval_frames, double *out)
603 {
604 ✗ if (interval_frames > st->d->audio_data_frames) {
605 ✗ return AVERROR(EINVAL);
606 }
607 ✗ ebur128_calc_gating_block(st, interval_frames, out);
608 ✗ return 0;
609 }
610
611 ✗ static int ebur128_energy_shortterm(FFEBUR128State * st, double *out)
612 {
613 ✗ return ebur128_energy_in_interval(st, st->d->samples_in_100ms * 30,
614 out);
615 }
616
617 ✗ int ff_ebur128_loudness_shortterm(FFEBUR128State * st, double *out)
618 {
619 double energy;
620 ✗ int error = ebur128_energy_shortterm(st, &energy);
621 ✗ if (error) {
622 ✗ return error;
623 ✗ } else if (energy <= 0.0) {
624 ✗ *out = -HUGE_VAL;
625 ✗ return 0;
626 }
627 ✗ *out = ebur128_energy_to_loudness(energy);
628 ✗ return 0;
629 }
630
631 /* EBU - TECH 3342 */
632 ✗ int ff_ebur128_loudness_range_multiple(FFEBUR128State ** sts, size_t size,
633 double *out)
634 {
635 size_t i, j;
636 size_t stl_size;
637 double stl_power, stl_integrated;
638 /* High and low percentile energy */
639 double h_en, l_en;
640 ✗ unsigned long hist[1000] = { 0 };
641 size_t percentile_low, percentile_high;
642 size_t index;
643
644 ✗ for (i = 0; i < size; ++i) {
645 ✗ if (sts[i]) {
646 ✗ if ((sts[i]->mode & FF_EBUR128_MODE_LRA) !=
647 FF_EBUR128_MODE_LRA) {
648 ✗ return AVERROR(EINVAL);
649 }
650 }
651 }
652
653 ✗ stl_size = 0;
654 ✗ stl_power = 0.0;
655 ✗ for (i = 0; i < size; ++i) {
656 ✗ if (!sts[i])
657 ✗ continue;
658 ✗ for (j = 0; j < 1000; ++j) {
659 ✗ hist[j] += sts[i]->d->short_term_block_energy_histogram[j];
660 ✗ stl_size += sts[i]->d->short_term_block_energy_histogram[j];
661 ✗ stl_power += sts[i]->d->short_term_block_energy_histogram[j]
662 ✗ * histogram_energies[j];
663 }
664 }
665 ✗ if (!stl_size) {
666 ✗ *out = 0.0;
667 ✗ return 0;
668 }
669
670 ✗ stl_power /= stl_size;
671 ✗ stl_integrated = MINUS_20DB * stl_power;
672
673 ✗ if (stl_integrated < histogram_energy_boundaries[0]) {
674 ✗ index = 0;
675 } else {
676 ✗ index = find_histogram_index(stl_integrated);
677 ✗ if (stl_integrated > histogram_energies[index]) {
678 ✗ ++index;
679 }
680 }
681 ✗ stl_size = 0;
682 ✗ for (j = index; j < 1000; ++j) {
683 ✗ stl_size += hist[j];
684 }
685 ✗ if (!stl_size) {
686 ✗ *out = 0.0;
687 ✗ return 0;
688 }
689
690 ✗ percentile_low = (size_t) ((stl_size - 1) * 0.1 + 0.5);
691 ✗ percentile_high = (size_t) ((stl_size - 1) * 0.95 + 0.5);
692
693 ✗ stl_size = 0;
694 ✗ j = index;
695 ✗ while (stl_size <= percentile_low) {
696 ✗ stl_size += hist[j++];
697 }
698 ✗ l_en = histogram_energies[j - 1];
699 ✗ while (stl_size <= percentile_high) {
700 ✗ stl_size += hist[j++];
701 }
702 ✗ h_en = histogram_energies[j - 1];
703 ✗ *out =
704 ✗ ebur128_energy_to_loudness(h_en) -
705 ✗ ebur128_energy_to_loudness(l_en);
706 ✗ return 0;
707 }
708
709 ✗ int ff_ebur128_loudness_range(FFEBUR128State * st, double *out)
710 {
711 ✗ return ff_ebur128_loudness_range_multiple(&st, 1, out);
712 }
713
714 ✗ int ff_ebur128_sample_peak(FFEBUR128State * st,
715 unsigned int channel_number, double *out)
716 {
717 ✗ if ((st->mode & FF_EBUR128_MODE_SAMPLE_PEAK) !=
718 FF_EBUR128_MODE_SAMPLE_PEAK) {
719 ✗ return AVERROR(EINVAL);
720 ✗ } else if (channel_number >= st->channels) {
721 ✗ return AVERROR(EINVAL);
722 }
723 ✗ *out = st->d->sample_peak[channel_number];
724 ✗ return 0;
725 }
726