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
9665217a
Commit
9665217a
authored
Oct 04, 2013
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avfilter/af_silencedetect: support more sample formats
Signed-off-by:
Paul B Mahol
<
onemda@gmail.com
>
parent
922596e3
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
81 additions
and
33 deletions
+81
-33
af_silencedetect.c
libavfilter/af_silencedetect.c
+81
-33
No files found.
libavfilter/af_silencedetect.c
View file @
9665217a
...
...
@@ -32,13 +32,17 @@
#include "avfilter.h"
#include "internal.h"
typedef
struct
{
typedef
struct
SilenceDetectContext
{
const
AVClass
*
class
;
double
noise
;
///< noise amplitude ratio
double
duration
;
///< minimum duration of silence until notification
int64_t
nb_null_samples
;
///< current number of continuous zero samples
int64_t
start
;
///< if silence is detected, this value contains the time of the first zero sample
int
last_sample_rate
;
///< last sample rate to check for sample rate changes
void
(
*
silencedetect
)(
struct
SilenceDetectContext
*
s
,
AVFrame
*
insamples
,
int
nb_samples
,
int64_t
nb_samples_notify
,
AVRational
time_base
);
}
SilenceDetectContext
;
#define OFFSET(x) offsetof(SilenceDetectContext, x)
...
...
@@ -59,9 +63,78 @@ static char *get_metadata_val(AVFrame *insamples, const char *key)
return
e
&&
e
->
value
?
e
->
value
:
NULL
;
}
static
av_always_inline
void
update
(
SilenceDetectContext
*
s
,
AVFrame
*
insamples
,
int
is_silence
,
int64_t
nb_samples_notify
,
AVRational
time_base
)
{
if
(
is_silence
)
{
if
(
!
s
->
start
)
{
s
->
nb_null_samples
++
;
if
(
s
->
nb_null_samples
>=
nb_samples_notify
)
{
s
->
start
=
insamples
->
pts
-
(
int64_t
)(
s
->
duration
/
av_q2d
(
time_base
)
+
.
5
);
av_dict_set
(
&
insamples
->
metadata
,
"lavfi.silence_start"
,
av_ts2timestr
(
s
->
start
,
&
time_base
),
0
);
av_log
(
s
,
AV_LOG_INFO
,
"silence_start: %s
\n
"
,
get_metadata_val
(
insamples
,
"lavfi.silence_start"
));
}
}
}
else
{
if
(
s
->
start
)
{
av_dict_set
(
&
insamples
->
metadata
,
"lavfi.silence_end"
,
av_ts2timestr
(
insamples
->
pts
,
&
time_base
),
0
);
av_dict_set
(
&
insamples
->
metadata
,
"lavfi.silence_duration"
,
av_ts2timestr
(
insamples
->
pts
-
s
->
start
,
&
time_base
),
0
);
av_log
(
s
,
AV_LOG_INFO
,
"silence_end: %s | silence_duration: %s
\n
"
,
get_metadata_val
(
insamples
,
"lavfi.silence_end"
),
get_metadata_val
(
insamples
,
"lavfi.silence_duration"
));
}
s
->
nb_null_samples
=
s
->
start
=
0
;
}
}
#define SILENCE_DETECT(name, type) \
static void silencedetect_##name(SilenceDetectContext *s, AVFrame *insamples, \
int nb_samples, int64_t nb_samples_notify, \
AVRational time_base) \
{ \
const type *p = (const type *)insamples->data[0]; \
const type noise = s->noise; \
int i; \
\
for (i = 0; i < nb_samples; i++, p++) \
update(s, insamples, *p < noise && *p > -noise, \
nb_samples_notify, time_base); \
}
SILENCE_DETECT
(
dbl
,
double
)
SILENCE_DETECT
(
flt
,
float
)
SILENCE_DETECT
(
s32
,
int32_t
)
SILENCE_DETECT
(
s16
,
int16_t
)
static
int
config_input
(
AVFilterLink
*
inlink
)
{
AVFilterContext
*
ctx
=
inlink
->
dst
;
SilenceDetectContext
*
s
=
ctx
->
priv
;
switch
(
inlink
->
format
)
{
case
AV_SAMPLE_FMT_DBL
:
s
->
silencedetect
=
silencedetect_dbl
;
break
;
case
AV_SAMPLE_FMT_FLT
:
s
->
silencedetect
=
silencedetect_flt
;
break
;
case
AV_SAMPLE_FMT_S32
:
s
->
noise
*=
INT32_MAX
;
s
->
silencedetect
=
silencedetect_s32
;
break
;
case
AV_SAMPLE_FMT_S16
:
s
->
noise
*=
INT16_MAX
;
s
->
silencedetect
=
silencedetect_s16
;
break
;
}
return
0
;
}
static
int
filter_frame
(
AVFilterLink
*
inlink
,
AVFrame
*
insamples
)
{
int
i
;
SilenceDetectContext
*
s
=
inlink
->
dst
->
priv
;
const
int
nb_channels
=
inlink
->
channels
;
const
int
srate
=
inlink
->
sample_rate
;
...
...
@@ -73,38 +146,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
s
->
nb_null_samples
=
srate
*
s
->
nb_null_samples
/
s
->
last_sample_rate
;
s
->
last_sample_rate
=
srate
;
// TODO: support more sample formats
// TODO: document metadata
if
(
insamples
->
format
==
AV_SAMPLE_FMT_DBL
)
{
double
*
p
=
(
double
*
)
insamples
->
data
[
0
];
for
(
i
=
0
;
i
<
nb_samples
;
i
++
,
p
++
)
{
if
(
*
p
<
s
->
noise
&&
*
p
>
-
s
->
noise
)
{
if
(
!
s
->
start
)
{
s
->
nb_null_samples
++
;
if
(
s
->
nb_null_samples
>=
nb_samples_notify
)
{
s
->
start
=
insamples
->
pts
-
(
int64_t
)(
s
->
duration
/
av_q2d
(
inlink
->
time_base
)
+
.
5
);
av_dict_set
(
&
insamples
->
metadata
,
"lavfi.silence_start"
,
av_ts2timestr
(
s
->
start
,
&
inlink
->
time_base
),
0
);
av_log
(
s
,
AV_LOG_INFO
,
"silence_start: %s
\n
"
,
get_metadata_val
(
insamples
,
"lavfi.silence_start"
));
}
}
}
else
{
if
(
s
->
start
)
{
av_dict_set
(
&
insamples
->
metadata
,
"lavfi.silence_end"
,
av_ts2timestr
(
insamples
->
pts
,
&
inlink
->
time_base
),
0
);
av_dict_set
(
&
insamples
->
metadata
,
"lavfi.silence_duration"
,
av_ts2timestr
(
insamples
->
pts
-
s
->
start
,
&
inlink
->
time_base
),
0
);
av_log
(
s
,
AV_LOG_INFO
,
"silence_end: %s | silence_duration: %s
\n
"
,
get_metadata_val
(
insamples
,
"lavfi.silence_end"
),
get_metadata_val
(
insamples
,
"lavfi.silence_duration"
));
}
s
->
nb_null_samples
=
s
->
start
=
0
;
}
}
}
s
->
silencedetect
(
s
,
insamples
,
nb_samples
,
nb_samples_notify
,
inlink
->
time_base
);
return
ff_filter_frame
(
inlink
->
dst
->
outputs
[
0
],
insamples
);
}
...
...
@@ -115,6 +159,9 @@ static int query_formats(AVFilterContext *ctx)
AVFilterChannelLayouts
*
layouts
=
NULL
;
static
const
enum
AVSampleFormat
sample_fmts
[]
=
{
AV_SAMPLE_FMT_DBL
,
AV_SAMPLE_FMT_FLT
,
AV_SAMPLE_FMT_S32
,
AV_SAMPLE_FMT_S16
,
AV_SAMPLE_FMT_NONE
};
...
...
@@ -140,6 +187,7 @@ static const AVFilterPad silencedetect_inputs[] = {
{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_AUDIO
,
.
config_props
=
config_input
,
.
filter_frame
=
filter_frame
,
},
{
NULL
}
...
...
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