31#define HISTOGRAM_SIZE 8192
32#define HISTOGRAM_MAX (HISTOGRAM_SIZE-1)
34#define MEASURE_ALL UINT_MAX
37#define MEASURE_DC_OFFSET (1 << 0)
38#define MEASURE_MIN_LEVEL (1 << 1)
39#define MEASURE_MAX_LEVEL (1 << 2)
40#define MEASURE_MIN_DIFFERENCE (1 << 3)
41#define MEASURE_MAX_DIFFERENCE (1 << 4)
42#define MEASURE_MEAN_DIFFERENCE (1 << 5)
43#define MEASURE_RMS_DIFFERENCE (1 << 6)
44#define MEASURE_PEAK_LEVEL (1 << 7)
45#define MEASURE_RMS_LEVEL (1 << 8)
46#define MEASURE_RMS_PEAK (1 << 9)
47#define MEASURE_RMS_TROUGH (1 << 10)
48#define MEASURE_CREST_FACTOR (1 << 11)
49#define MEASURE_FLAT_FACTOR (1 << 12)
50#define MEASURE_PEAK_COUNT (1 << 13)
51#define MEASURE_BIT_DEPTH (1 << 14)
52#define MEASURE_DYNAMIC_RANGE (1 << 15)
53#define MEASURE_ZERO_CROSSINGS (1 << 16)
54#define MEASURE_ZERO_CROSSINGS_RATE (1 << 17)
55#define MEASURE_NUMBER_OF_SAMPLES (1 << 18)
56#define MEASURE_NUMBER_OF_NANS (1 << 19)
57#define MEASURE_NUMBER_OF_INFS (1 << 20)
58#define MEASURE_NUMBER_OF_DENORMALS (1 << 21)
59#define MEASURE_NOISE_FLOOR (1 << 22)
60#define MEASURE_NOISE_FLOOR_COUNT (1 << 23)
61#define MEASURE_ENTROPY (1 << 24)
62#define MEASURE_ABS_PEAK_COUNT (1 << 25)
64#define MEASURE_MINMAXPEAK (MEASURE_MIN_LEVEL | MEASURE_MAX_LEVEL | MEASURE_PEAK_LEVEL)
119#define OFFSET(x) offsetof(AudioStatsContext, x)
120#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
125 {
"reset",
"Set the number of frames over which cumulative stats are calculated before being reset",
OFFSET(reset_count),
AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX,
FLAGS },
165 for (
c = 0;
c <
s->nb_channels;
c++) {
168 p->min = p->nmin = p->min_sigma_x2 = DBL_MAX;
169 p->max = p->nmax = p->max_sigma_x2 =-DBL_MAX;
171 p->min_non_zero = DBL_MAX;
172 p->min_diff = DBL_MAX;
189 p->abs_peak_count = 0;
196 p->noise_floor =
NAN;
197 p->noise_floor_count = 0;
202 memset(p->win_samples, 0,
s->tc_samples *
sizeof(*p->win_samples));
203 memset(p->ehistogram, 0,
sizeof(p->ehistogram));
204 for (
int n = 0; n <
s->tc_samples; n++)
205 p->sorted_samples[n] = -1.0;
220 for (
int i = 0;
i <
s->nb_channels;
i++) {
223 p->win_samples =
av_calloc(
s->tc_samples,
sizeof(*p->win_samples));
227 p->sorted_samples =
av_calloc(
s->tc_samples,
sizeof(*p->sorted_samples));
228 if (!p->sorted_samples)
248 unsigned result =
s->maxbitdepth;
252 for (
int i = 0;
i < result;
i++)
253 depth[0] += !!(
mask[0] & (1ULL <<
i));
256 for (
int i = 0;
i < result;
i++)
257 depth[1] += !!(
mask[1] & (1ULL <<
i));
260 for (
int i = 0;
i < result && !(amask & 1);
i++) {
266 for (
int i = 0;
i < result;
i++)
267 depth[3] += !!(
mask[3] & (1ULL <<
i));
275 double entry = p->ehistogram[
i] / ((
double)p->nb_samples);
285 int n,
int *ffront,
int *bback)
287 double r, ax =
fabs(x);
290 int empty = front == back &&
ss[front] == -1.0;
292 if (!empty &&
fabs(px) ==
ss[front]) {
299 empty = front == back;
302 if (!empty && ax >=
ss[front]) {
315 while (!empty && ax >=
ss[back]) {
351 double abs_d =
FFABS(d);
352 double drop, noise_floor;
355 if (p->abs_peak < abs_d) {
357 p->abs_peak_count = 1;
358 }
else if (p->abs_peak == abs_d) {
367 }
else if (d == p->min) {
369 p->min_run = d == p->last ? p->min_run + 1 : 1;
370 }
else if (p->last == p->min) {
371 p->min_runs += p->min_run * p->min_run;
374 if (d != 0 &&
FFABS(d) < p->min_non_zero)
375 p->min_non_zero =
FFABS(d);
383 }
else if (d == p->max) {
385 p->max_run = d == p->last ? p->max_run + 1 : 1;
386 }
else if (p->last == p->max) {
387 p->max_runs += p->max_run * p->max_run;
392 p->last_non_zero = d;
396 p->sigma_x2 += nd * nd;
397 p->avg_sigma_x2 = p->avg_sigma_x2 *
s->mult + (1.0 -
s->mult) * nd * nd;
398 if (!
isnan(p->last)) {
399 p->min_diff =
FFMIN(p->min_diff,
fabs(d - p->last));
400 p->max_diff =
FFMAX(p->max_diff,
fabs(d - p->last));
401 p->diff1_sum +=
fabs(d - p->last);
402 p->diff1_sum_x2 += (d - p->last) * (d - p->last);
404 p->mask[0] |= (
i < 0) ? -
i :
i;
408 p->mask[3] |=
i ^ p->lasti;
412 drop = p->win_samples[p->win_pos];
413 p->win_samples[p->win_pos] = nd;
416 p->ehistogram[
index]++;
419 if (p->win_pos >=
s->tc_samples)
422 if (p->nb_samples >=
s->tc_samples) {
423 p->max_sigma_x2 =
FFMAX(p->max_sigma_x2, p->avg_sigma_x2);
424 p->min_sigma_x2 =
FFMIN(p->min_sigma_x2, p->avg_sigma_x2);
429 s->tc_samples, &p->sorted_front, &p->sorted_back);
430 if (p->nb_samples >=
s->tc_samples) {
431 if (
isnan(p->noise_floor)) {
432 p->noise_floor = noise_floor;
433 p->noise_floor_count = 1;
435 if (noise_floor < p->noise_floor) {
436 p->noise_floor = noise_floor;
437 p->noise_floor_count = 1;
438 }
else if (noise_floor == p->noise_floor) {
439 p->noise_floor_count++;
447 int type = fpclassify(d);
449 p->nb_nans +=
type == FP_NAN;
450 p->nb_infs +=
type == FP_INFINITE;
451 p->nb_denormals +=
type == FP_SUBNORMAL;
456 int type = fpclassify(d);
458 p->nb_nans +=
type == FP_NAN;
459 p->nb_infs +=
type == FP_INFINITE;
460 p->nb_denormals +=
type == FP_SUBNORMAL;
464 const char *fmt,
double val)
471 snprintf(key2,
sizeof(key2),
"lavfi.astats.%d.%s", chan,
key);
473 snprintf(key2,
sizeof(key2),
"lavfi.astats.%s",
key);
477#define LINEAR_TO_DB(x) (log10(x) * 20)
481 uint64_t
mask[4], min_count = 0, max_count = 0, nb_samples = 0, noise_floor_count = 0;
482 uint64_t nb_nans = 0, nb_infs = 0, nb_denormals = 0;
483 uint64_t abs_peak_count = 0;
484 double min_runs = 0, max_runs = 0,
485 min = DBL_MAX,
max =-DBL_MAX, min_diff = DBL_MAX, max_diff = 0,
486 nmin = DBL_MAX, nmax =-DBL_MAX,
493 min_sigma_x2 = DBL_MAX,
494 max_sigma_x2 =-DBL_MAX;
503 for (
c = 0;
c <
s->nb_channels;
c++) {
506 if (p->nb_samples <
s->tc_samples)
507 p->min_sigma_x2 = p->max_sigma_x2 = p->sigma_x2 / p->nb_samples;
511 nmin =
FFMIN(nmin, p->nmin);
512 nmax =
FFMAX(nmax, p->nmax);
513 min_diff =
FFMIN(min_diff, p->min_diff);
514 max_diff =
FFMAX(max_diff, p->max_diff);
515 diff1_sum += p->diff1_sum;
516 diff1_sum_x2 += p->diff1_sum_x2;
517 min_sigma_x2 =
FFMIN(min_sigma_x2, p->min_sigma_x2);
518 max_sigma_x2 =
FFMAX(max_sigma_x2, p->max_sigma_x2);
519 sigma_x2 += p->sigma_x2;
520 noise_floor =
FFMAX(noise_floor, p->noise_floor);
521 noise_floor_count += p->noise_floor_count;
523 entropy += p->entropy;
524 min_count += p->min_count;
525 max_count += p->max_count;
526 abs_peak_count += p->abs_peak_count;
527 min_runs += p->min_runs;
528 max_runs += p->max_runs;
529 mask[0] |= p->mask[0];
530 mask[1] |= p->mask[1];
531 mask[2] &= p->mask[2];
532 mask[3] |= p->mask[3];
533 nb_samples += p->nb_samples;
534 nb_nans += p->nb_nans;
535 nb_infs += p->nb_infs;
536 nb_denormals += p->nb_denormals;
537 if (
fabs(p->sigma_x) >
fabs(max_sigma_x))
538 max_sigma_x = p->sigma_x;
551 set_meta(
metadata,
c + 1,
"Mean_difference",
"%f", p->diff1_sum / (p->nb_samples - 1));
553 set_meta(
metadata,
c + 1,
"RMS_difference",
"%f", sqrt(p->diff1_sum_x2 / (p->nb_samples - 1)));
563 set_meta(
metadata,
c + 1,
"Crest_factor",
"%f", p->sigma_x2 ?
FFMAX(-p->min, p->max) / sqrt(p->sigma_x2 / p->nb_samples) : 1);
567 set_meta(
metadata,
c + 1,
"Peak_count",
"%f", (
float)(p->min_count + p->max_count));
588 set_meta(
metadata,
c + 1,
"Zero_crossings_rate",
"%f", p->zero_runs/(
double)p->nb_samples);
598 set_meta(
metadata, 0,
"Overall.DC_offset",
"%f", max_sigma_x / (nb_samples /
s->nb_channels));
608 set_meta(
metadata, 0,
"Overall.Mean_difference",
"%f", diff1_sum / (nb_samples -
s->nb_channels));
610 set_meta(
metadata, 0,
"Overall.RMS_difference",
"%f", sqrt(diff1_sum_x2 / (nb_samples -
s->nb_channels)));
622 set_meta(
metadata, 0,
"Overall.Peak_count",
"%f", (
float)(min_count + max_count) / (
double)
s->nb_channels);
624 set_meta(
metadata, 0,
"Overall.Abs_Peak_count",
"%f", (
float)(abs_peak_count) / (
double)
s->nb_channels);
628 set_meta(
metadata, 0,
"Overall.Noise_floor_count",
"%f", noise_floor_count / (
double)
s->nb_channels);
630 set_meta(
metadata, 0,
"Overall.Entropy",
"%f", entropy / (
double)
s->nb_channels);
639 set_meta(
metadata, 0,
"Overall.Number_of_samples",
"%f", nb_samples /
s->nb_channels);
645 set_meta(
metadata, 0,
"Number of denormals",
"%f", nb_denormals / (
float)
s->nb_channels);
648#define UPDATE_STATS_P(type, update_func, update_float, channel_func) \
649 for (int c = start; c < end; c++) { \
650 ChannelStats *p = &s->chstats[c]; \
651 const type *src = (const type *)data[c]; \
652 const type * const srcend = src + samples; \
653 for (; src < srcend; src++) { \
660#define UPDATE_STATS_I(type, update_func, update_float, channel_func) \
661 for (int c = start; c < end; c++) { \
662 ChannelStats *p = &s->chstats[c]; \
663 const type *src = (const type *)data[0]; \
664 const type * const srcend = src + samples * channels; \
665 for (src += c; src < srcend; src += channels) { \
672#define UPDATE_STATS(planar, type, sample, normalizer_suffix, int_sample) \
673 if ((s->measure_overall | s->measure_perchannel) & ~MEASURE_MINMAXPEAK) { \
674 UPDATE_STATS_##planar(type, update_stat(s, p, sample, sample normalizer_suffix, int_sample), s->is_float ? update_float_stat(s, p, sample) : s->is_double ? update_double_stat(s, p, sample) : (void)NULL, ); \
676 UPDATE_STATS_##planar(type, update_minmax(s, p, sample), , p->nmin = p->min normalizer_suffix; p->nmax = p->max normalizer_suffix;); \
684 const uint8_t *
const *
const data = (
const uint8_t *
const *)buf->
extended_data;
732 if (
s->reset_count > 0) {
733 if (
s->nb_frames >=
s->reset_count) {
754 uint64_t
mask[4], min_count = 0, max_count = 0, nb_samples = 0, noise_floor_count = 0;
755 uint64_t nb_nans = 0, nb_infs = 0, nb_denormals = 0, abs_peak_count = 0;
756 double min_runs = 0, max_runs = 0,
757 min = DBL_MAX,
max =-DBL_MAX, min_diff = DBL_MAX, max_diff = 0,
758 nmin = DBL_MAX, nmax =-DBL_MAX,
765 min_sigma_x2 = DBL_MAX,
766 max_sigma_x2 =-DBL_MAX;
775 for (
c = 0;
c <
s->nb_channels;
c++) {
778 if (p->nb_samples == 0 && !
s->used)
781 if (p->nb_samples <
s->tc_samples)
782 p->min_sigma_x2 = p->max_sigma_x2 = p->sigma_x2 / p->nb_samples;
786 nmin =
FFMIN(nmin, p->nmin);
787 nmax =
FFMAX(nmax, p->nmax);
788 min_diff =
FFMIN(min_diff, p->min_diff);
789 max_diff =
FFMAX(max_diff, p->max_diff);
790 diff1_sum_x2 += p->diff1_sum_x2;
791 diff1_sum += p->diff1_sum;
792 min_sigma_x2 =
FFMIN(min_sigma_x2, p->min_sigma_x2);
793 max_sigma_x2 =
FFMAX(max_sigma_x2, p->max_sigma_x2);
794 sigma_x2 += p->sigma_x2;
795 noise_floor =
FFMAX(noise_floor, p->noise_floor);
797 entropy += p->entropy;
798 min_count += p->min_count;
799 max_count += p->max_count;
800 abs_peak_count += p->abs_peak_count;
801 noise_floor_count += p->noise_floor_count;
802 min_runs += p->min_runs;
803 max_runs += p->max_runs;
804 mask[0] |= p->mask[0];
805 mask[1] |= p->mask[1];
806 mask[2] &= p->mask[2];
807 mask[3] |= p->mask[3];
808 nb_samples += p->nb_samples;
809 nb_nans += p->nb_nans;
810 nb_infs += p->nb_infs;
811 nb_denormals += p->nb_denormals;
812 if (
fabs(p->sigma_x) >
fabs(max_sigma_x))
813 max_sigma_x = p->sigma_x;
838 if (p->min_sigma_x2 != 1)
841 av_log(
ctx,
AV_LOG_INFO,
"Crest factor: %f\n", p->sigma_x2 ?
FFMAX(-p->nmin, p->nmax) / sqrt(p->sigma_x2 / p->nb_samples) : 1);
872 if (nb_samples == 0 && !
s->used)
890 av_log(
ctx,
AV_LOG_INFO,
"RMS difference: %f\n", sqrt(diff1_sum_x2 / (nb_samples -
s->nb_channels)));
898 if (min_sigma_x2 != 1)
933 for (
int i = 0;
i <
s->nb_channels;
i++) {
962 .p.priv_class = &astats_class,
static double val(void *priv, double ch)
#define MEASURE_MAX_LEVEL
#define UPDATE_STATS(planar, type, sample, normalizer_suffix, int_sample)
static void update_stat(AudioStatsContext *s, ChannelStats *p, double d, double nd, int64_t i)
#define MEASURE_FLAT_FACTOR
#define MEASURE_MAX_DIFFERENCE
static void set_metadata(AudioStatsContext *s, AVDictionary **metadata)
#define MEASURE_BIT_DEPTH
static void update_float_stat(AudioStatsContext *s, ChannelStats *p, float d)
#define MEASURE_NUMBER_OF_SAMPLES
#define MEASURE_RMS_DIFFERENCE
#define MEASURE_NOISE_FLOOR
#define MEASURE_DYNAMIC_RANGE
static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
#define MEASURE_PEAK_LEVEL
#define MEASURE_MEAN_DIFFERENCE
#define MEASURE_DC_OFFSET
static const AVOption astats_options[]
#define MEASURE_NOISE_FLOOR_COUNT
#define MEASURE_PEAK_COUNT
#define MEASURE_NUMBER_OF_DENORMALS
#define MEASURE_NUMBER_OF_INFS
#define MEASURE_RMS_LEVEL
static const AVFilterPad astats_outputs[]
#define MEASURE_ZERO_CROSSINGS_RATE
#define MEASURE_MIN_LEVEL
#define MEASURE_MIN_DIFFERENCE
static double calc_entropy(AudioStatsContext *s, ChannelStats *p)
static av_cold void uninit(AVFilterContext *ctx)
static void update_double_stat(AudioStatsContext *s, ChannelStats *p, double d)
#define MEASURE_ABS_PEAK_COUNT
static double calc_noise_floor(double *ss, double x, double px, int n, int *ffront, int *bback)
static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static const AVFilterPad astats_inputs[]
static int config_output(AVFilterLink *outlink)
#define MEASURE_RMS_TROUGH
static void bit_depth(AudioStatsContext *s, const uint64_t *const mask, uint8_t *depth)
#define MEASURE_NUMBER_OF_NANS
#define MEASURE_ZERO_CROSSINGS
static void reset_stats(AudioStatsContext *s)
const FFFilter ff_af_astats
static void set_meta(AVDictionary **metadata, int chan, const char *key, const char *fmt, double val)
static void update_minmax(AudioStatsContext *s, ChannelStats *p, double d)
#define MEASURE_CREST_FACTOR
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Main libavfilter public API header.
static int FUNC metadata(CodedBitstreamContext *ctx, RWContext *rw, APVRawMetadata *current)
#define i(width, name, range_min, range_max)
#define ss(width, name, subs,...)
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
static __device__ float fabs(float a)
static int filter_frame(DBEDecodeContext *s, AVFrame *frame)
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
@ AV_OPT_TYPE_FLAGS
Underlying C type is unsigned int.
@ AV_OPT_TYPE_INT
Underlying C type is int.
@ AV_OPT_TYPE_DOUBLE
Underlying C type is double.
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
#define AVFILTER_FLAG_METADATA_ONLY
The filter is a "metadata" filter - it does not modify the frame data in any way.
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
#define AV_LOG_INFO
Standard information.
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
@ AV_SAMPLE_FMT_FLTP
float, planar
@ AV_SAMPLE_FMT_S16P
signed 16 bits, planar
@ AV_SAMPLE_FMT_S64
signed 64 bits
@ AV_SAMPLE_FMT_S32P
signed 32 bits, planar
@ AV_SAMPLE_FMT_S32
signed 32 bits
@ AV_SAMPLE_FMT_DBLP
double, planar
@ AV_SAMPLE_FMT_DBL
double
@ AV_SAMPLE_FMT_S64P
signed 64 bits, planar
@ AV_SAMPLE_FMT_S16
signed 16 bits
static av_cold void uninit(AVBitStreamFilterContext *ctx)
static int config_output(AVBitStreamFilterLink *outlink)
static void filter_channel(MLPDecodeContext *m, unsigned int substr, unsigned int channel)
Generate PCM samples using the prediction filters and residual values read from the data stream,...
#define FILTER_INPUTS(array)
#define FILTER_OUTPUTS(array)
#define FILTER_SAMPLEFMTS(...)
static int ff_slice_pos(int total, int jobnr, int nb_jobs)
Compute the boundary index for a slice when work of size total is split into nb_jobs slices.
#define AVFILTER_DEFINE_CLASS(fname)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static const uint16_t mask[17]
void * av_calloc(size_t nmemb, size_t size)
Memory handling functions.
int nb_channels
Number of channels in this layout.
Describe the class of an AVClass context structure.
void * priv
private data for use by the filter
AVFilterLink ** outputs
array of pointers to output links
A link between two filters.
AVFilterContext * src
source filter
int sample_rate
samples per second
AVChannelLayout ch_layout
channel layout of current buffer (see libavutil/channel_layout.h)
AVFilterContext * dst
dest filter
int format
agreed upon media format
A filter pad used for either input or output.
This structure describes decoded (raw) audio or video data.
int nb_samples
number of audio samples (per channel) described by this frame
AVDictionary * metadata
metadata.
AVChannelLayout ch_layout
Channel layout of the audio data.
uint8_t ** extended_data
pointers to the data planes/channels.
uint64_t ehistogram[HISTOGRAM_SIZE]
uint64_t noise_floor_count
static AVFormatContext * ctx