Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
d3836b60
Commit
d3836b60
authored
Jun 29, 2015
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avfilter/af_astats: export metadata
Signed-off-by:
Paul B Mahol
<
onemda@gmail.com
>
parent
9f653e6d
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
113 additions
and
2 deletions
+113
-2
filters.texi
doc/filters.texi
+35
-0
af_astats.c
libavfilter/af_astats.c
+78
-2
No files found.
doc/filters.texi
View file @
d3836b60
...
@@ -941,6 +941,41 @@ It accepts the following option:
...
@@ -941,6 +941,41 @@ It accepts the following option:
@item length
@item length
Short window length in seconds, used for peak and trough RMS measurement.
Short window length in seconds, used for peak and trough RMS measurement.
Default is @code{0.05} (50 milliseconds). Allowed range is @code{[0.1 - 10]}.
Default is @code{0.05} (50 milliseconds). Allowed range is @code{[0.1 - 10]}.
@item metadata
Set metadata injection. All the metadata keys are prefixed with @code{lavfi.astats.X},
where @code{X} is channel number starting from 1 or string @code{Overall}. Default is
disabled.
Available keys for each channel are:
DC_offset
Min_level
Max_level
Peak_level
RMS_peak
RMS_trough
Crest_factor
Flat_factor
Peak_count
and for Overall:
DC_offset
Min_level
Max_level
Peak_level
RMS_level
RMS_peak
RMS_trough
Flat_factor
Peak_count
Number_of_samples
For example full key look like this @code{lavfi.astats.1.DC_offset} or
this @code{lavfi.astats.Overall.Peak_count}.
For description what each key means read bellow.
@end table
@end table
A description of each shown parameter follows:
A description of each shown parameter follows:
...
...
libavfilter/af_astats.c
View file @
d3836b60
...
@@ -44,6 +44,7 @@ typedef struct {
...
@@ -44,6 +44,7 @@ typedef struct {
uint64_t
tc_samples
;
uint64_t
tc_samples
;
double
time_constant
;
double
time_constant
;
double
mult
;
double
mult
;
int
metadata
;
}
AudioStatsContext
;
}
AudioStatsContext
;
#define OFFSET(x) offsetof(AudioStatsContext, x)
#define OFFSET(x) offsetof(AudioStatsContext, x)
...
@@ -51,6 +52,7 @@ typedef struct {
...
@@ -51,6 +52,7 @@ typedef struct {
static
const
AVOption
astats_options
[]
=
{
static
const
AVOption
astats_options
[]
=
{
{
"length"
,
"set the window length"
,
OFFSET
(
time_constant
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
.
05
},
.
01
,
10
,
FLAGS
},
{
"length"
,
"set the window length"
,
OFFSET
(
time_constant
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
.
05
},
.
01
,
10
,
FLAGS
},
{
"metadata"
,
"inject metadata in the filtergraph"
,
OFFSET
(
metadata
),
AV_OPT_TYPE_INT
,
{.
i64
=
0
},
0
,
1
,
FLAGS
},
{
NULL
}
{
NULL
}
};
};
...
@@ -146,9 +148,82 @@ static inline void update_stat(AudioStatsContext *s, ChannelStats *p, double d)
...
@@ -146,9 +148,82 @@ static inline void update_stat(AudioStatsContext *s, ChannelStats *p, double d)
p
->
nb_samples
++
;
p
->
nb_samples
++
;
}
}
static
void
set_meta
(
AVDictionary
**
metadata
,
int
chan
,
const
char
*
key
,
const
char
*
fmt
,
double
val
)
{
uint8_t
value
[
128
];
uint8_t
key2
[
128
];
snprintf
(
value
,
sizeof
(
value
),
fmt
,
val
);
if
(
chan
)
snprintf
(
key2
,
sizeof
(
key2
),
"lavfi.astats.%d.%s"
,
chan
,
key
);
else
snprintf
(
key2
,
sizeof
(
key2
),
"lavfi.astats.%s"
,
key
);
av_dict_set
(
metadata
,
key2
,
value
,
0
);
}
#define LINEAR_TO_DB(x) (log10(x) * 20)
static
void
set_metadata
(
AudioStatsContext
*
s
,
AVDictionary
**
metadata
)
{
uint64_t
min_count
=
0
,
max_count
=
0
,
nb_samples
=
0
;
double
min_runs
=
0
,
max_runs
=
0
,
min
=
DBL_MAX
,
max
=
DBL_MIN
,
max_sigma_x
=
0
,
sigma_x
=
0
,
sigma_x2
=
0
,
min_sigma_x2
=
DBL_MAX
,
max_sigma_x2
=
DBL_MIN
;
int
c
;
for
(
c
=
0
;
c
<
s
->
nb_channels
;
c
++
)
{
ChannelStats
*
p
=
&
s
->
chstats
[
c
];
if
(
p
->
nb_samples
<
s
->
tc_samples
)
p
->
min_sigma_x2
=
p
->
max_sigma_x2
=
p
->
sigma_x2
/
p
->
nb_samples
;
min
=
FFMIN
(
min
,
p
->
min
);
max
=
FFMAX
(
max
,
p
->
max
);
min_sigma_x2
=
FFMIN
(
min_sigma_x2
,
p
->
min_sigma_x2
);
max_sigma_x2
=
FFMAX
(
max_sigma_x2
,
p
->
max_sigma_x2
);
sigma_x
+=
p
->
sigma_x
;
sigma_x2
+=
p
->
sigma_x2
;
min_count
+=
p
->
min_count
;
max_count
+=
p
->
max_count
;
min_runs
+=
p
->
min_runs
;
max_runs
+=
p
->
max_runs
;
nb_samples
+=
p
->
nb_samples
;
if
(
fabs
(
p
->
sigma_x
)
>
fabs
(
max_sigma_x
))
max_sigma_x
=
p
->
sigma_x
;
set_meta
(
metadata
,
c
+
1
,
"DC_offset"
,
"%f"
,
p
->
sigma_x
/
p
->
nb_samples
);
set_meta
(
metadata
,
c
+
1
,
"Min_level"
,
"%f"
,
p
->
min
);
set_meta
(
metadata
,
c
+
1
,
"Max_level"
,
"%f"
,
p
->
max
);
set_meta
(
metadata
,
c
+
1
,
"Peak_level"
,
"%f"
,
LINEAR_TO_DB
(
FFMAX
(
-
p
->
min
,
p
->
max
)));
set_meta
(
metadata
,
c
+
1
,
"RMS_level"
,
"%f"
,
LINEAR_TO_DB
(
sqrt
(
p
->
sigma_x2
/
p
->
nb_samples
)));
set_meta
(
metadata
,
c
+
1
,
"RMS_peak"
,
"%f"
,
LINEAR_TO_DB
(
sqrt
(
p
->
max_sigma_x2
)));
set_meta
(
metadata
,
c
+
1
,
"RMS_trough"
,
"%f"
,
LINEAR_TO_DB
(
sqrt
(
p
->
min_sigma_x2
)));
set_meta
(
metadata
,
c
+
1
,
"Crest_factor"
,
"%f"
,
p
->
sigma_x2
?
FFMAX
(
-
p
->
min
,
p
->
max
)
/
sqrt
(
p
->
sigma_x2
/
p
->
nb_samples
)
:
1
);
set_meta
(
metadata
,
c
+
1
,
"Flat_factor"
,
"%f"
,
LINEAR_TO_DB
((
p
->
min_runs
+
p
->
max_runs
)
/
(
p
->
min_count
+
p
->
max_count
)));
set_meta
(
metadata
,
c
+
1
,
"Peak_count"
,
"%f"
,
(
float
)(
p
->
min_count
+
p
->
max_count
));
}
set_meta
(
metadata
,
0
,
"Overall.DC_offset"
,
"%f"
,
max_sigma_x
/
(
nb_samples
/
s
->
nb_channels
));
set_meta
(
metadata
,
0
,
"Overall.Min_level"
,
"%f"
,
min
);
set_meta
(
metadata
,
0
,
"Overall.Max_level"
,
"%f"
,
max
);
set_meta
(
metadata
,
0
,
"Overall.Peak_level"
,
"%f"
,
LINEAR_TO_DB
(
FFMAX
(
-
min
,
max
)));
set_meta
(
metadata
,
0
,
"Overall.RMS_level"
,
"%f"
,
LINEAR_TO_DB
(
sqrt
(
sigma_x2
/
nb_samples
)));
set_meta
(
metadata
,
0
,
"Overall.RMS_peak"
,
"%f"
,
LINEAR_TO_DB
(
sqrt
(
max_sigma_x2
)));
set_meta
(
metadata
,
0
,
"Overall.RMS_trough"
,
"%f"
,
LINEAR_TO_DB
(
sqrt
(
min_sigma_x2
)));
set_meta
(
metadata
,
0
,
"Overall.Flat_factor"
,
"%f"
,
LINEAR_TO_DB
((
min_runs
+
max_runs
)
/
(
min_count
+
max_count
)));
set_meta
(
metadata
,
0
,
"Overall.Peak_count"
,
"%f"
,
(
float
)(
min_count
+
max_count
)
/
(
double
)
s
->
nb_channels
);
set_meta
(
metadata
,
0
,
"Overall.Number_of_samples"
,
"%f"
,
nb_samples
/
s
->
nb_channels
);
}
static
int
filter_frame
(
AVFilterLink
*
inlink
,
AVFrame
*
buf
)
static
int
filter_frame
(
AVFilterLink
*
inlink
,
AVFrame
*
buf
)
{
{
AudioStatsContext
*
s
=
inlink
->
dst
->
priv
;
AudioStatsContext
*
s
=
inlink
->
dst
->
priv
;
AVDictionary
**
metadata
=
avpriv_frame_get_metadatap
(
buf
);
const
int
channels
=
s
->
nb_channels
;
const
int
channels
=
s
->
nb_channels
;
const
double
*
src
;
const
double
*
src
;
int
i
,
c
;
int
i
,
c
;
...
@@ -173,11 +248,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
...
@@ -173,11 +248,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
break
;
break
;
}
}
if
(
s
->
metadata
)
set_metadata
(
s
,
metadata
);
return
ff_filter_frame
(
inlink
->
dst
->
outputs
[
0
],
buf
);
return
ff_filter_frame
(
inlink
->
dst
->
outputs
[
0
],
buf
);
}
}
#define LINEAR_TO_DB(x) (log10(x) * 20)
static
void
print_stats
(
AVFilterContext
*
ctx
)
static
void
print_stats
(
AVFilterContext
*
ctx
)
{
{
AudioStatsContext
*
s
=
ctx
->
priv
;
AudioStatsContext
*
s
=
ctx
->
priv
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment