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
dc72d1dd
Commit
dc72d1dd
authored
May 19, 2017
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avfilter: add audio surround upmixer
Signed-off-by:
Paul B Mahol
<
onemda@gmail.com
>
parent
2934a10f
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
869 additions
and
1 deletion
+869
-1
Changelog
Changelog
+1
-0
filters.texi
doc/filters.texi
+30
-0
Makefile
libavfilter/Makefile
+1
-0
af_surround.c
libavfilter/af_surround.c
+835
-0
allfilters.c
libavfilter/allfilters.c
+1
-0
version.h
libavfilter/version.h
+1
-1
No files found.
Changelog
View file @
dc72d1dd
...
...
@@ -16,6 +16,7 @@ version <next>:
- spec compliant VP9 muxing support in MP4
- remove the libnut muxer/demuxer wrappers
- remove the libschroedinger encoder/decoder wrappers
- surround audio filter
version 3.3:
- CrystalHD decoder moved to new decode API
...
...
doc/filters.texi
View file @
dc72d1dd
...
...
@@ -3792,6 +3792,36 @@ channels. Default is 0.3.
Set level of input signal of original channel. Default is 0.8.
@end table
@section surround
Apply audio surround upmix filter.
This filter allows to produce multichannel output from stereo audio stream.
The filter accepts the following options:
@table @option
@item chl_out
Set output channel layout. By default, this is @var{5.1}.
See @ref{channel layout syntax,,the Channel Layout section in the ffmpeg-utils(1) manual,ffmpeg-utils}
for the required syntax.
@item level_in
Set input volume level. By default, this is @var{1}.
@item level_out
Set output volume level. By default, this is @var{1}.
@item lfe
Enable LFE channel output if output channel layout has it. By default, this is enabled.
@item lfe_low
Set LFE low cut off frequency. By default, this is @var{128} Hz.
@item lfe_high
Set LFE high cut off frequency. By default, this is @var{256} Hz.
@end table
@section treble
Boost or cut treble (upper) frequencies of the audio using a two-pole
...
...
libavfilter/Makefile
View file @
dc72d1dd
...
...
@@ -108,6 +108,7 @@ OBJS-$(CONFIG_SILENCEREMOVE_FILTER) += af_silenceremove.o
OBJS-$(CONFIG_SOFALIZER_FILTER)
+=
af_sofalizer.o
OBJS-$(CONFIG_STEREOTOOLS_FILTER)
+=
af_stereotools.o
OBJS-$(CONFIG_STEREOWIDEN_FILTER)
+=
af_stereowiden.o
OBJS-$(CONFIG_SURROUND_FILTER)
+=
af_surround.o
OBJS-$(CONFIG_TREBLE_FILTER)
+=
af_biquads.o
OBJS-$(CONFIG_TREMOLO_FILTER)
+=
af_tremolo.o
OBJS-$(CONFIG_VIBRATO_FILTER)
+=
af_vibrato.o
generate_wave_table.o
...
...
libavfilter/af_surround.c
0 → 100644
View file @
dc72d1dd
/*
* Copyright (c) 2017 Paul B Mahol
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/audio_fifo.h"
#include "libavutil/channel_layout.h"
#include "libavutil/opt.h"
#include "libavcodec/avfft.h"
#include "avfilter.h"
#include "audio.h"
#include "formats.h"
typedef
struct
AudioSurroundContext
{
const
AVClass
*
class
;
char
*
out_channel_layout_str
;
float
level_in
;
float
level_out
;
int
output_lfe
;
int
lowcutf
;
int
highcutf
;
float
lowcut
;
float
highcut
;
uint64_t
out_channel_layout
;
int
nb_in_channels
;
int
nb_out_channels
;
AVFrame
*
input
;
AVFrame
*
output
;
AVFrame
*
overlap_buffer
;
int
buf_size
;
int
hop_size
;
AVAudioFifo
*
fifo
;
RDFTContext
**
rdft
,
**
irdft
;
float
*
window_func_lut
;
int64_t
pts
;
void
(
*
upmix
)(
AVFilterContext
*
ctx
,
float
l_phase
,
float
r_phase
,
float
c_phase
,
float
mag_total
,
float
x
,
float
y
,
int
n
);
}
AudioSurroundContext
;
static
int
query_formats
(
AVFilterContext
*
ctx
)
{
AudioSurroundContext
*
s
=
ctx
->
priv
;
AVFilterFormats
*
formats
=
NULL
;
AVFilterChannelLayouts
*
layouts
=
NULL
;
int
ret
;
ret
=
ff_add_format
(
&
formats
,
AV_SAMPLE_FMT_FLTP
);
if
(
ret
)
return
ret
;
ret
=
ff_set_common_formats
(
ctx
,
formats
);
if
(
ret
)
return
ret
;
layouts
=
NULL
;
ret
=
ff_add_channel_layout
(
&
layouts
,
s
->
out_channel_layout
);
if
(
ret
)
return
ret
;
ret
=
ff_channel_layouts_ref
(
layouts
,
&
ctx
->
outputs
[
0
]
->
in_channel_layouts
);
if
(
ret
)
return
ret
;
layouts
=
NULL
;
ret
=
ff_add_channel_layout
(
&
layouts
,
AV_CH_LAYOUT_STEREO
);
if
(
ret
)
return
ret
;
ret
=
ff_channel_layouts_ref
(
layouts
,
&
ctx
->
inputs
[
0
]
->
out_channel_layouts
);
if
(
ret
)
return
ret
;
formats
=
ff_all_samplerates
();
if
(
!
formats
)
return
AVERROR
(
ENOMEM
);
return
ff_set_common_samplerates
(
ctx
,
formats
);
}
static
int
config_input
(
AVFilterLink
*
inlink
)
{
AVFilterContext
*
ctx
=
inlink
->
dst
;
AudioSurroundContext
*
s
=
ctx
->
priv
;
int
ch
;
s
->
rdft
=
av_calloc
(
inlink
->
channels
,
sizeof
(
*
s
->
rdft
));
if
(
!
s
->
rdft
)
return
AVERROR
(
ENOMEM
);
for
(
ch
=
0
;
ch
<
inlink
->
channels
;
ch
++
)
{
s
->
rdft
[
ch
]
=
av_rdft_init
(
ff_log2
(
s
->
buf_size
),
DFT_R2C
);
if
(
!
s
->
rdft
[
ch
])
return
AVERROR
(
ENOMEM
);
}
s
->
nb_in_channels
=
inlink
->
channels
;
s
->
input
=
ff_get_audio_buffer
(
inlink
,
s
->
buf_size
*
2
);
if
(
!
s
->
input
)
return
AVERROR
(
ENOMEM
);
s
->
fifo
=
av_audio_fifo_alloc
(
inlink
->
format
,
inlink
->
channels
,
s
->
buf_size
);
if
(
!
s
->
fifo
)
return
AVERROR
(
ENOMEM
);
s
->
lowcut
=
1
.
f
*
s
->
lowcutf
/
(
inlink
->
sample_rate
*
0
.
5
)
*
(
s
->
buf_size
/
2
);
s
->
highcut
=
1
.
f
*
s
->
highcutf
/
(
inlink
->
sample_rate
*
0
.
5
)
*
(
s
->
buf_size
/
2
);
return
0
;
}
static
int
config_output
(
AVFilterLink
*
outlink
)
{
AVFilterContext
*
ctx
=
outlink
->
src
;
AudioSurroundContext
*
s
=
ctx
->
priv
;
int
ch
;
s
->
irdft
=
av_calloc
(
outlink
->
channels
,
sizeof
(
*
s
->
irdft
));
if
(
!
s
->
irdft
)
return
AVERROR
(
ENOMEM
);
for
(
ch
=
0
;
ch
<
outlink
->
channels
;
ch
++
)
{
s
->
irdft
[
ch
]
=
av_rdft_init
(
ff_log2
(
s
->
buf_size
),
IDFT_C2R
);
if
(
!
s
->
irdft
[
ch
])
return
AVERROR
(
ENOMEM
);
}
s
->
nb_out_channels
=
outlink
->
channels
;
s
->
output
=
ff_get_audio_buffer
(
outlink
,
s
->
buf_size
*
2
);
s
->
overlap_buffer
=
ff_get_audio_buffer
(
outlink
,
s
->
buf_size
*
2
);
if
(
!
s
->
overlap_buffer
||
!
s
->
output
)
return
AVERROR
(
ENOMEM
);
return
0
;
}
static
void
stereo_position
(
float
a
,
float
p
,
float
*
x
,
float
*
y
)
{
*
x
=
av_clipf
(
a
+
FFMAX
(
0
,
sinf
(
p
-
M_PI_2
))
*
FFDIFFSIGN
(
a
,
0
),
-
1
,
1
);
*
y
=
av_clipf
(
cosf
(
a
*
M_PI_2
+
M_PI
)
*
cosf
(
M_PI_2
-
p
/
M_PI
)
*
M_LN10
+
1
,
-
1
,
1
);
}
static
inline
void
get_lfe
(
int
output_lfe
,
int
n
,
float
lowcut
,
float
highcut
,
float
*
lfe_mag
,
float
*
mag_total
)
{
if
(
output_lfe
&&
n
<
highcut
)
{
*
lfe_mag
=
n
<
lowcut
?
1
.
f
:
.
5
f
*
(
1
.
f
+
cosf
(
M_PI
*
(
lowcut
-
n
)
/
(
lowcut
-
highcut
)));
*
lfe_mag
*=
*
mag_total
;
*
mag_total
-=
*
lfe_mag
;
}
else
{
*
lfe_mag
=
0
.
f
;
}
}
static
void
upmix_1_0
(
AVFilterContext
*
ctx
,
float
l_phase
,
float
r_phase
,
float
c_phase
,
float
mag_total
,
float
x
,
float
y
,
int
n
)
{
AudioSurroundContext
*
s
=
ctx
->
priv
;
float
mag
,
*
dst
;
dst
=
(
float
*
)
s
->
output
->
extended_data
[
0
];
mag
=
sqrtf
(
1
.
f
-
fabsf
(
x
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
dst
[
2
*
n
]
=
mag
*
cosf
(
c_phase
);
dst
[
2
*
n
+
1
]
=
mag
*
sinf
(
c_phase
);
}
static
void
upmix_stereo
(
AVFilterContext
*
ctx
,
float
l_phase
,
float
r_phase
,
float
c_phase
,
float
mag_total
,
float
x
,
float
y
,
int
n
)
{
AudioSurroundContext
*
s
=
ctx
->
priv
;
float
l_mag
,
r_mag
,
*
dstl
,
*
dstr
;
dstl
=
(
float
*
)
s
->
output
->
extended_data
[
0
];
dstr
=
(
float
*
)
s
->
output
->
extended_data
[
1
];
l_mag
=
sqrtf
(.
5
f
*
(
x
+
1
.
f
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
r_mag
=
sqrtf
(.
5
f
*
(
-
x
+
1
.
f
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
dstl
[
2
*
n
]
=
l_mag
*
cosf
(
l_phase
);
dstl
[
2
*
n
+
1
]
=
l_mag
*
sinf
(
l_phase
);
dstr
[
2
*
n
]
=
r_mag
*
cosf
(
r_phase
);
dstr
[
2
*
n
+
1
]
=
r_mag
*
sinf
(
r_phase
);
}
static
void
upmix_2_1
(
AVFilterContext
*
ctx
,
float
l_phase
,
float
r_phase
,
float
c_phase
,
float
mag_total
,
float
x
,
float
y
,
int
n
)
{
AudioSurroundContext
*
s
=
ctx
->
priv
;
float
lfe_mag
,
l_mag
,
r_mag
,
*
dstl
,
*
dstr
,
*
dstlfe
;
dstl
=
(
float
*
)
s
->
output
->
extended_data
[
0
];
dstr
=
(
float
*
)
s
->
output
->
extended_data
[
1
];
dstlfe
=
(
float
*
)
s
->
output
->
extended_data
[
2
];
get_lfe
(
s
->
output_lfe
,
n
,
s
->
lowcut
,
s
->
highcut
,
&
lfe_mag
,
&
mag_total
);
l_mag
=
sqrtf
(.
5
f
*
(
x
+
1
.
f
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
r_mag
=
sqrtf
(.
5
f
*
(
-
x
+
1
.
f
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
dstl
[
2
*
n
]
=
l_mag
*
cosf
(
l_phase
);
dstl
[
2
*
n
+
1
]
=
l_mag
*
sinf
(
l_phase
);
dstr
[
2
*
n
]
=
r_mag
*
cosf
(
r_phase
);
dstr
[
2
*
n
+
1
]
=
r_mag
*
sinf
(
r_phase
);
dstlfe
[
2
*
n
]
=
lfe_mag
*
cosf
(
c_phase
);
dstlfe
[
2
*
n
+
1
]
=
lfe_mag
*
sinf
(
c_phase
);
}
static
void
upmix_3_0
(
AVFilterContext
*
ctx
,
float
l_phase
,
float
r_phase
,
float
c_phase
,
float
mag_total
,
float
x
,
float
y
,
int
n
)
{
AudioSurroundContext
*
s
=
ctx
->
priv
;
float
l_mag
,
r_mag
,
c_mag
,
*
dstc
,
*
dstl
,
*
dstr
;
dstl
=
(
float
*
)
s
->
output
->
extended_data
[
0
];
dstr
=
(
float
*
)
s
->
output
->
extended_data
[
1
];
dstc
=
(
float
*
)
s
->
output
->
extended_data
[
2
];
c_mag
=
sqrtf
(
1
.
f
-
fabsf
(
x
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
l_mag
=
sqrtf
(.
5
f
*
(
x
+
1
.
f
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
r_mag
=
sqrtf
(.
5
f
*
(
-
x
+
1
.
f
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
dstl
[
2
*
n
]
=
l_mag
*
cosf
(
l_phase
);
dstl
[
2
*
n
+
1
]
=
l_mag
*
sinf
(
l_phase
);
dstr
[
2
*
n
]
=
r_mag
*
cosf
(
r_phase
);
dstr
[
2
*
n
+
1
]
=
r_mag
*
sinf
(
r_phase
);
dstc
[
2
*
n
]
=
c_mag
*
cosf
(
c_phase
);
dstc
[
2
*
n
+
1
]
=
c_mag
*
sinf
(
c_phase
);
}
static
void
upmix_3_1
(
AVFilterContext
*
ctx
,
float
l_phase
,
float
r_phase
,
float
c_phase
,
float
mag_total
,
float
x
,
float
y
,
int
n
)
{
AudioSurroundContext
*
s
=
ctx
->
priv
;
float
lfe_mag
,
l_mag
,
r_mag
,
c_mag
,
*
dstc
,
*
dstl
,
*
dstr
,
*
dstlfe
;
dstl
=
(
float
*
)
s
->
output
->
extended_data
[
0
];
dstr
=
(
float
*
)
s
->
output
->
extended_data
[
1
];
dstc
=
(
float
*
)
s
->
output
->
extended_data
[
2
];
dstlfe
=
(
float
*
)
s
->
output
->
extended_data
[
3
];
get_lfe
(
s
->
output_lfe
,
n
,
s
->
lowcut
,
s
->
highcut
,
&
lfe_mag
,
&
mag_total
);
c_mag
=
sqrtf
(
1
.
f
-
fabsf
(
x
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
l_mag
=
sqrtf
(.
5
f
*
(
x
+
1
.
f
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
r_mag
=
sqrtf
(.
5
f
*
(
-
x
+
1
.
f
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
dstl
[
2
*
n
]
=
l_mag
*
cosf
(
l_phase
);
dstl
[
2
*
n
+
1
]
=
l_mag
*
sinf
(
l_phase
);
dstr
[
2
*
n
]
=
r_mag
*
cosf
(
r_phase
);
dstr
[
2
*
n
+
1
]
=
r_mag
*
sinf
(
r_phase
);
dstc
[
2
*
n
]
=
c_mag
*
cosf
(
c_phase
);
dstc
[
2
*
n
+
1
]
=
c_mag
*
sinf
(
c_phase
);
dstlfe
[
2
*
n
]
=
lfe_mag
*
cosf
(
c_phase
);
dstlfe
[
2
*
n
+
1
]
=
lfe_mag
*
sinf
(
c_phase
);
}
static
void
upmix_4_0
(
AVFilterContext
*
ctx
,
float
l_phase
,
float
r_phase
,
float
c_phase
,
float
mag_total
,
float
x
,
float
y
,
int
n
)
{
float
b_mag
,
l_mag
,
r_mag
,
c_mag
,
*
dstc
,
*
dstl
,
*
dstr
,
*
dstb
;
AudioSurroundContext
*
s
=
ctx
->
priv
;
dstl
=
(
float
*
)
s
->
output
->
extended_data
[
0
];
dstr
=
(
float
*
)
s
->
output
->
extended_data
[
1
];
dstc
=
(
float
*
)
s
->
output
->
extended_data
[
2
];
dstb
=
(
float
*
)
s
->
output
->
extended_data
[
3
];
c_mag
=
sqrtf
(
1
.
f
-
fabsf
(
x
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
b_mag
=
sqrtf
(
1
.
f
-
fabsf
(
x
))
*
((
1
.
f
-
y
)
*
.
5
f
)
*
mag_total
;
l_mag
=
sqrtf
(.
5
f
*
(
x
+
1
.
f
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
r_mag
=
sqrtf
(.
5
f
*
(
-
x
+
1
.
f
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
dstl
[
2
*
n
]
=
l_mag
*
cosf
(
l_phase
);
dstl
[
2
*
n
+
1
]
=
l_mag
*
sinf
(
l_phase
);
dstr
[
2
*
n
]
=
r_mag
*
cosf
(
r_phase
);
dstr
[
2
*
n
+
1
]
=
r_mag
*
sinf
(
r_phase
);
dstc
[
2
*
n
]
=
c_mag
*
cosf
(
c_phase
);
dstc
[
2
*
n
+
1
]
=
c_mag
*
sinf
(
c_phase
);
dstb
[
2
*
n
]
=
b_mag
*
cosf
(
c_phase
);
dstb
[
2
*
n
+
1
]
=
b_mag
*
sinf
(
c_phase
);
}
static
void
upmix_4_1
(
AVFilterContext
*
ctx
,
float
l_phase
,
float
r_phase
,
float
c_phase
,
float
mag_total
,
float
x
,
float
y
,
int
n
)
{
float
lfe_mag
,
b_mag
,
l_mag
,
r_mag
,
c_mag
,
*
dstc
,
*
dstl
,
*
dstr
,
*
dstb
,
*
dstlfe
;
AudioSurroundContext
*
s
=
ctx
->
priv
;
dstl
=
(
float
*
)
s
->
output
->
extended_data
[
0
];
dstr
=
(
float
*
)
s
->
output
->
extended_data
[
1
];
dstc
=
(
float
*
)
s
->
output
->
extended_data
[
2
];
dstlfe
=
(
float
*
)
s
->
output
->
extended_data
[
3
];
dstb
=
(
float
*
)
s
->
output
->
extended_data
[
4
];
get_lfe
(
s
->
output_lfe
,
n
,
s
->
lowcut
,
s
->
highcut
,
&
lfe_mag
,
&
mag_total
);
dstlfe
[
2
*
n
]
=
lfe_mag
*
cosf
(
c_phase
);
dstlfe
[
2
*
n
+
1
]
=
lfe_mag
*
sinf
(
c_phase
);
c_mag
=
sqrtf
(
1
.
f
-
fabsf
(
x
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
b_mag
=
sqrtf
(
1
.
f
-
fabsf
(
x
))
*
((
1
.
f
-
y
)
*
.
5
f
)
*
mag_total
;
l_mag
=
sqrtf
(.
5
f
*
(
x
+
1
.
f
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
r_mag
=
sqrtf
(.
5
f
*
(
-
x
+
1
.
f
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
dstl
[
2
*
n
]
=
l_mag
*
cosf
(
l_phase
);
dstl
[
2
*
n
+
1
]
=
l_mag
*
sinf
(
l_phase
);
dstr
[
2
*
n
]
=
r_mag
*
cosf
(
r_phase
);
dstr
[
2
*
n
+
1
]
=
r_mag
*
sinf
(
r_phase
);
dstc
[
2
*
n
]
=
c_mag
*
cosf
(
c_phase
);
dstc
[
2
*
n
+
1
]
=
c_mag
*
sinf
(
c_phase
);
dstb
[
2
*
n
]
=
b_mag
*
cosf
(
c_phase
);
dstb
[
2
*
n
+
1
]
=
b_mag
*
sinf
(
c_phase
);
}
static
void
upmix_5_0_back
(
AVFilterContext
*
ctx
,
float
l_phase
,
float
r_phase
,
float
c_phase
,
float
mag_total
,
float
x
,
float
y
,
int
n
)
{
float
l_mag
,
r_mag
,
ls_mag
,
rs_mag
,
c_mag
,
*
dstc
,
*
dstl
,
*
dstr
,
*
dstls
,
*
dstrs
;
AudioSurroundContext
*
s
=
ctx
->
priv
;
dstl
=
(
float
*
)
s
->
output
->
extended_data
[
0
];
dstr
=
(
float
*
)
s
->
output
->
extended_data
[
1
];
dstc
=
(
float
*
)
s
->
output
->
extended_data
[
2
];
dstls
=
(
float
*
)
s
->
output
->
extended_data
[
3
];
dstrs
=
(
float
*
)
s
->
output
->
extended_data
[
4
];
c_mag
=
sqrtf
(
1
.
f
-
fabsf
(
x
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
l_mag
=
sqrtf
(.
5
f
*
(
x
+
1
.
f
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
r_mag
=
sqrtf
(.
5
f
*
(
-
x
+
1
.
f
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
ls_mag
=
sqrtf
(.
5
f
*
(
x
+
1
.
f
))
*
(
1
.
f
-
((
y
+
1
.
f
)
*
.
5
f
))
*
mag_total
;
rs_mag
=
sqrtf
(.
5
f
*
(
-
x
+
1
.
f
))
*
(
1
.
f
-
((
y
+
1
.
f
)
*
.
5
f
))
*
mag_total
;
dstl
[
2
*
n
]
=
l_mag
*
cosf
(
l_phase
);
dstl
[
2
*
n
+
1
]
=
l_mag
*
sinf
(
l_phase
);
dstr
[
2
*
n
]
=
r_mag
*
cosf
(
r_phase
);
dstr
[
2
*
n
+
1
]
=
r_mag
*
sinf
(
r_phase
);
dstc
[
2
*
n
]
=
c_mag
*
cosf
(
c_phase
);
dstc
[
2
*
n
+
1
]
=
c_mag
*
sinf
(
c_phase
);
dstls
[
2
*
n
]
=
ls_mag
*
cosf
(
l_phase
);
dstls
[
2
*
n
+
1
]
=
ls_mag
*
sinf
(
l_phase
);
dstrs
[
2
*
n
]
=
rs_mag
*
cosf
(
r_phase
);
dstrs
[
2
*
n
+
1
]
=
rs_mag
*
sinf
(
r_phase
);
}
static
void
upmix_5_1_back
(
AVFilterContext
*
ctx
,
float
l_phase
,
float
r_phase
,
float
c_phase
,
float
mag_total
,
float
x
,
float
y
,
int
n
)
{
float
lfe_mag
,
l_mag
,
r_mag
,
ls_mag
,
rs_mag
,
c_mag
,
*
dstc
,
*
dstl
,
*
dstr
,
*
dstls
,
*
dstrs
,
*
dstlfe
;
AudioSurroundContext
*
s
=
ctx
->
priv
;
dstl
=
(
float
*
)
s
->
output
->
extended_data
[
0
];
dstr
=
(
float
*
)
s
->
output
->
extended_data
[
1
];
dstc
=
(
float
*
)
s
->
output
->
extended_data
[
2
];
dstlfe
=
(
float
*
)
s
->
output
->
extended_data
[
3
];
dstls
=
(
float
*
)
s
->
output
->
extended_data
[
4
];
dstrs
=
(
float
*
)
s
->
output
->
extended_data
[
5
];
get_lfe
(
s
->
output_lfe
,
n
,
s
->
lowcut
,
s
->
highcut
,
&
lfe_mag
,
&
mag_total
);
c_mag
=
sqrtf
(
1
.
f
-
fabsf
(
x
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
l_mag
=
sqrtf
(.
5
f
*
(
x
+
1
.
f
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
r_mag
=
sqrtf
(.
5
f
*
(
-
x
+
1
.
f
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
ls_mag
=
sqrtf
(.
5
f
*
(
x
+
1
.
f
))
*
(
1
.
f
-
((
y
+
1
.
f
)
*
.
5
f
))
*
mag_total
;
rs_mag
=
sqrtf
(.
5
f
*
(
-
x
+
1
.
f
))
*
(
1
.
f
-
((
y
+
1
.
f
)
*
.
5
f
))
*
mag_total
;
dstl
[
2
*
n
]
=
l_mag
*
cosf
(
l_phase
);
dstl
[
2
*
n
+
1
]
=
l_mag
*
sinf
(
l_phase
);
dstr
[
2
*
n
]
=
r_mag
*
cosf
(
r_phase
);
dstr
[
2
*
n
+
1
]
=
r_mag
*
sinf
(
r_phase
);
dstc
[
2
*
n
]
=
c_mag
*
cosf
(
c_phase
);
dstc
[
2
*
n
+
1
]
=
c_mag
*
sinf
(
c_phase
);
dstlfe
[
2
*
n
]
=
lfe_mag
*
cosf
(
c_phase
);
dstlfe
[
2
*
n
+
1
]
=
lfe_mag
*
sinf
(
c_phase
);
dstls
[
2
*
n
]
=
ls_mag
*
cosf
(
l_phase
);
dstls
[
2
*
n
+
1
]
=
ls_mag
*
sinf
(
l_phase
);
dstrs
[
2
*
n
]
=
rs_mag
*
cosf
(
r_phase
);
dstrs
[
2
*
n
+
1
]
=
rs_mag
*
sinf
(
r_phase
);
}
static
void
upmix_7_0
(
AVFilterContext
*
ctx
,
float
l_phase
,
float
r_phase
,
float
c_phase
,
float
mag_total
,
float
x
,
float
y
,
int
n
)
{
float
l_mag
,
r_mag
,
ls_mag
,
rs_mag
,
c_mag
,
lb_mag
,
rb_mag
;
float
*
dstc
,
*
dstl
,
*
dstr
,
*
dstls
,
*
dstrs
,
*
dstlb
,
*
dstrb
;
AudioSurroundContext
*
s
=
ctx
->
priv
;
dstl
=
(
float
*
)
s
->
output
->
extended_data
[
0
];
dstr
=
(
float
*
)
s
->
output
->
extended_data
[
1
];
dstc
=
(
float
*
)
s
->
output
->
extended_data
[
2
];
dstlb
=
(
float
*
)
s
->
output
->
extended_data
[
3
];
dstrb
=
(
float
*
)
s
->
output
->
extended_data
[
4
];
dstls
=
(
float
*
)
s
->
output
->
extended_data
[
5
];
dstrs
=
(
float
*
)
s
->
output
->
extended_data
[
6
];
c_mag
=
sqrtf
(
1
.
f
-
fabsf
(
x
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
l_mag
=
sqrtf
(.
5
f
*
(
x
+
1
.
f
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
r_mag
=
sqrtf
(.
5
f
*
(
-
x
+
1
.
f
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
lb_mag
=
sqrtf
(.
5
f
*
(
x
+
1
.
f
))
*
(
1
.
f
-
((
y
+
1
.
f
)
*
.
5
f
))
*
mag_total
;
rb_mag
=
sqrtf
(.
5
f
*
(
-
x
+
1
.
f
))
*
(
1
.
f
-
((
y
+
1
.
f
)
*
.
5
f
))
*
mag_total
;
ls_mag
=
sqrtf
(.
5
f
*
(
x
+
1
.
f
))
*
(
1
.
f
-
fabsf
(
y
))
*
mag_total
;
rs_mag
=
sqrtf
(.
5
f
*
(
-
x
+
1
.
f
))
*
(
1
.
f
-
fabsf
(
y
))
*
mag_total
;
dstl
[
2
*
n
]
=
l_mag
*
cosf
(
l_phase
);
dstl
[
2
*
n
+
1
]
=
l_mag
*
sinf
(
l_phase
);
dstr
[
2
*
n
]
=
r_mag
*
cosf
(
r_phase
);
dstr
[
2
*
n
+
1
]
=
r_mag
*
sinf
(
r_phase
);
dstc
[
2
*
n
]
=
c_mag
*
cosf
(
c_phase
);
dstc
[
2
*
n
+
1
]
=
c_mag
*
sinf
(
c_phase
);
dstlb
[
2
*
n
]
=
lb_mag
*
cosf
(
l_phase
);
dstlb
[
2
*
n
+
1
]
=
lb_mag
*
sinf
(
l_phase
);
dstrb
[
2
*
n
]
=
rb_mag
*
cosf
(
r_phase
);
dstrb
[
2
*
n
+
1
]
=
rb_mag
*
sinf
(
r_phase
);
dstls
[
2
*
n
]
=
ls_mag
*
cosf
(
l_phase
);
dstls
[
2
*
n
+
1
]
=
ls_mag
*
sinf
(
l_phase
);
dstrs
[
2
*
n
]
=
rs_mag
*
cosf
(
r_phase
);
dstrs
[
2
*
n
+
1
]
=
rs_mag
*
sinf
(
r_phase
);
}
static
void
upmix_7_1
(
AVFilterContext
*
ctx
,
float
l_phase
,
float
r_phase
,
float
c_phase
,
float
mag_total
,
float
x
,
float
y
,
int
n
)
{
float
lfe_mag
,
l_mag
,
r_mag
,
ls_mag
,
rs_mag
,
c_mag
,
lb_mag
,
rb_mag
;
float
*
dstc
,
*
dstl
,
*
dstr
,
*
dstls
,
*
dstrs
,
*
dstlb
,
*
dstrb
,
*
dstlfe
;
AudioSurroundContext
*
s
=
ctx
->
priv
;
dstl
=
(
float
*
)
s
->
output
->
extended_data
[
0
];
dstr
=
(
float
*
)
s
->
output
->
extended_data
[
1
];
dstc
=
(
float
*
)
s
->
output
->
extended_data
[
2
];
dstlfe
=
(
float
*
)
s
->
output
->
extended_data
[
3
];
dstlb
=
(
float
*
)
s
->
output
->
extended_data
[
4
];
dstrb
=
(
float
*
)
s
->
output
->
extended_data
[
5
];
dstls
=
(
float
*
)
s
->
output
->
extended_data
[
6
];
dstrs
=
(
float
*
)
s
->
output
->
extended_data
[
7
];
get_lfe
(
s
->
output_lfe
,
n
,
s
->
lowcut
,
s
->
highcut
,
&
lfe_mag
,
&
mag_total
);
c_mag
=
sqrtf
(
1
.
f
-
fabsf
(
x
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
l_mag
=
sqrtf
(.
5
f
*
(
x
+
1
.
f
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
r_mag
=
sqrtf
(.
5
f
*
(
-
x
+
1
.
f
))
*
((
y
+
1
.
f
)
*
.
5
f
)
*
mag_total
;
lb_mag
=
sqrtf
(.
5
f
*
(
x
+
1
.
f
))
*
(
1
.
f
-
((
y
+
1
.
f
)
*
.
5
f
))
*
mag_total
;
rb_mag
=
sqrtf
(.
5
f
*
(
-
x
+
1
.
f
))
*
(
1
.
f
-
((
y
+
1
.
f
)
*
.
5
f
))
*
mag_total
;
ls_mag
=
sqrtf
(.
5
f
*
(
x
+
1
.
f
))
*
(
1
.
f
-
fabsf
(
y
))
*
mag_total
;
rs_mag
=
sqrtf
(.
5
f
*
(
-
x
+
1
.
f
))
*
(
1
.
f
-
fabsf
(
y
))
*
mag_total
;
dstl
[
2
*
n
]
=
l_mag
*
cosf
(
l_phase
);
dstl
[
2
*
n
+
1
]
=
l_mag
*
sinf
(
l_phase
);
dstr
[
2
*
n
]
=
r_mag
*
cosf
(
r_phase
);
dstr
[
2
*
n
+
1
]
=
r_mag
*
sinf
(
r_phase
);
dstc
[
2
*
n
]
=
c_mag
*
cosf
(
c_phase
);
dstc
[
2
*
n
+
1
]
=
c_mag
*
sinf
(
c_phase
);
dstlfe
[
2
*
n
]
=
lfe_mag
*
cosf
(
c_phase
);
dstlfe
[
2
*
n
+
1
]
=
lfe_mag
*
sinf
(
c_phase
);
dstlb
[
2
*
n
]
=
lb_mag
*
cosf
(
l_phase
);
dstlb
[
2
*
n
+
1
]
=
lb_mag
*
sinf
(
l_phase
);
dstrb
[
2
*
n
]
=
rb_mag
*
cosf
(
r_phase
);
dstrb
[
2
*
n
+
1
]
=
rb_mag
*
sinf
(
r_phase
);
dstls
[
2
*
n
]
=
ls_mag
*
cosf
(
l_phase
);
dstls
[
2
*
n
+
1
]
=
ls_mag
*
sinf
(
l_phase
);
dstrs
[
2
*
n
]
=
rs_mag
*
cosf
(
r_phase
);
dstrs
[
2
*
n
+
1
]
=
rs_mag
*
sinf
(
r_phase
);
}
static
int
init
(
AVFilterContext
*
ctx
)
{
AudioSurroundContext
*
s
=
ctx
->
priv
;
float
overlap
;
int
i
;
if
(
!
(
s
->
out_channel_layout
=
av_get_channel_layout
(
s
->
out_channel_layout_str
)))
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Error parsing channel layout '%s'.
\n
"
,
s
->
out_channel_layout_str
);
return
AVERROR
(
EINVAL
);
}
if
(
s
->
lowcutf
>=
s
->
highcutf
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Low cut-off '%d' should be less than high cut-off '%d'.
\n
"
,
s
->
lowcutf
,
s
->
highcutf
);
return
AVERROR
(
EINVAL
);
}
switch
(
s
->
out_channel_layout
)
{
case
AV_CH_LAYOUT_MONO
:
s
->
upmix
=
upmix_1_0
;
break
;
case
AV_CH_LAYOUT_STEREO
:
s
->
upmix
=
upmix_stereo
;
break
;
case
AV_CH_LAYOUT_2POINT1
:
s
->
upmix
=
upmix_2_1
;
break
;
case
AV_CH_LAYOUT_SURROUND
:
s
->
upmix
=
upmix_3_0
;
break
;
case
AV_CH_LAYOUT_3POINT1
:
s
->
upmix
=
upmix_3_1
;
break
;
case
AV_CH_LAYOUT_4POINT0
:
s
->
upmix
=
upmix_4_0
;
break
;
case
AV_CH_LAYOUT_4POINT1
:
s
->
upmix
=
upmix_4_1
;
break
;
case
AV_CH_LAYOUT_5POINT0_BACK
:
s
->
upmix
=
upmix_5_0_back
;
break
;
case
AV_CH_LAYOUT_5POINT1_BACK
:
s
->
upmix
=
upmix_5_1_back
;
break
;
case
AV_CH_LAYOUT_7POINT0
:
s
->
upmix
=
upmix_7_0
;
break
;
case
AV_CH_LAYOUT_7POINT1
:
s
->
upmix
=
upmix_7_1
;
break
;
default:
av_log
(
ctx
,
AV_LOG_ERROR
,
"Unsupported output channel layout '%s'.
\n
"
,
s
->
out_channel_layout_str
);
return
AVERROR
(
EINVAL
);
}
s
->
buf_size
=
4096
;
s
->
pts
=
AV_NOPTS_VALUE
;
s
->
window_func_lut
=
av_calloc
(
s
->
buf_size
,
sizeof
(
*
s
->
window_func_lut
));
if
(
!
s
->
window_func_lut
)
return
AVERROR
(
ENOMEM
);
for
(
i
=
0
;
i
<
s
->
buf_size
;
i
++
)
s
->
window_func_lut
[
i
]
=
sqrtf
(
0
.
5
*
(
1
-
cosf
(
2
*
M_PI
*
i
/
s
->
buf_size
))
/
s
->
buf_size
);
overlap
=
.
5
;
s
->
hop_size
=
s
->
buf_size
*
(
1
.
-
overlap
);
return
0
;
}
static
int
fft_channel
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
ch
,
int
nb_jobs
)
{
AudioSurroundContext
*
s
=
ctx
->
priv
;
const
float
level_in
=
s
->
level_in
;
float
*
dst
;
int
n
;
memset
(
s
->
input
->
extended_data
[
ch
]
+
s
->
buf_size
*
sizeof
(
float
),
0
,
s
->
buf_size
*
sizeof
(
float
));
dst
=
(
float
*
)
s
->
input
->
extended_data
[
ch
];
for
(
n
=
0
;
n
<
s
->
buf_size
;
n
++
)
{
dst
[
n
]
*=
s
->
window_func_lut
[
n
]
*
level_in
;
}
av_rdft_calc
(
s
->
rdft
[
ch
],
(
float
*
)
s
->
input
->
extended_data
[
ch
]);
return
0
;
}
static
int
ifft_channel
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
ch
,
int
nb_jobs
)
{
AudioSurroundContext
*
s
=
ctx
->
priv
;
const
float
level_out
=
s
->
level_out
;
AVFrame
*
out
=
arg
;
float
*
dst
,
*
ptr
;
int
n
;
av_rdft_calc
(
s
->
irdft
[
ch
],
(
float
*
)
s
->
output
->
extended_data
[
ch
]);
dst
=
(
float
*
)
s
->
output
->
extended_data
[
ch
];
ptr
=
(
float
*
)
s
->
overlap_buffer
->
extended_data
[
ch
];
memmove
(
s
->
overlap_buffer
->
extended_data
[
ch
],
s
->
overlap_buffer
->
extended_data
[
ch
]
+
s
->
hop_size
*
sizeof
(
float
),
s
->
buf_size
*
sizeof
(
float
));
memset
(
s
->
overlap_buffer
->
extended_data
[
ch
]
+
s
->
buf_size
*
sizeof
(
float
),
0
,
s
->
hop_size
*
sizeof
(
float
));
for
(
n
=
0
;
n
<
s
->
buf_size
;
n
++
)
{
ptr
[
n
]
+=
dst
[
n
]
*
s
->
window_func_lut
[
n
]
*
level_out
;
}
ptr
=
(
float
*
)
s
->
overlap_buffer
->
extended_data
[
ch
];
dst
=
(
float
*
)
out
->
extended_data
[
ch
];
memcpy
(
dst
,
ptr
,
s
->
hop_size
*
sizeof
(
float
));
return
0
;
}
static
int
filter_frame
(
AVFilterLink
*
inlink
,
AVFrame
*
in
)
{
AVFilterContext
*
ctx
=
inlink
->
dst
;
AVFilterLink
*
outlink
=
ctx
->
outputs
[
0
];
AudioSurroundContext
*
s
=
ctx
->
priv
;
av_audio_fifo_write
(
s
->
fifo
,
(
void
**
)
in
->
extended_data
,
in
->
nb_samples
);
if
(
s
->
pts
==
AV_NOPTS_VALUE
)
s
->
pts
=
in
->
pts
;
av_frame_free
(
&
in
);
while
(
av_audio_fifo_size
(
s
->
fifo
)
>=
s
->
buf_size
)
{
float
*
srcl
,
*
srcr
;
AVFrame
*
out
;
int
n
,
ret
;
ret
=
av_audio_fifo_peek
(
s
->
fifo
,
(
void
**
)
s
->
input
->
extended_data
,
s
->
buf_size
);
if
(
ret
<
0
)
return
ret
;
ctx
->
internal
->
execute
(
ctx
,
fft_channel
,
NULL
,
NULL
,
inlink
->
channels
);
srcl
=
(
float
*
)
s
->
input
->
extended_data
[
0
];
srcr
=
(
float
*
)
s
->
input
->
extended_data
[
1
];
for
(
n
=
0
;
n
<
s
->
buf_size
;
n
++
)
{
float
l_re
=
srcl
[
2
*
n
],
r_re
=
srcr
[
2
*
n
];
float
l_im
=
srcl
[
2
*
n
+
1
],
r_im
=
srcr
[
2
*
n
+
1
];
float
c_phase
=
atan2f
(
l_im
+
r_im
,
l_re
+
r_re
);
float
l_mag
=
hypotf
(
l_re
,
l_im
);
float
r_mag
=
hypotf
(
r_re
,
r_im
);
float
l_phase
=
atan2f
(
l_im
,
l_re
);
float
r_phase
=
atan2f
(
r_im
,
r_re
);
float
phase_dif
=
fabsf
(
l_phase
-
r_phase
);
float
mag_dif
=
(
l_mag
-
r_mag
)
/
(
l_mag
+
r_mag
);
float
mag_total
=
hypotf
(
l_mag
,
r_mag
);
float
x
,
y
;
if
(
phase_dif
>
M_PI
)
phase_dif
=
2
*
M_PI
-
phase_dif
;
stereo_position
(
mag_dif
,
phase_dif
,
&
x
,
&
y
);
s
->
upmix
(
ctx
,
l_phase
,
r_phase
,
c_phase
,
mag_total
,
x
,
y
,
n
);
}
out
=
ff_get_audio_buffer
(
outlink
,
s
->
hop_size
);
if
(
!
out
)
return
AVERROR
(
ENOMEM
);
ctx
->
internal
->
execute
(
ctx
,
ifft_channel
,
out
,
NULL
,
outlink
->
channels
);
out
->
pts
=
s
->
pts
;
if
(
s
->
pts
!=
AV_NOPTS_VALUE
)
s
->
pts
+=
av_rescale_q
(
out
->
nb_samples
,
(
AVRational
){
1
,
outlink
->
sample_rate
},
outlink
->
time_base
);
av_audio_fifo_drain
(
s
->
fifo
,
s
->
hop_size
);
ret
=
ff_filter_frame
(
outlink
,
out
);
if
(
ret
<
0
)
return
ret
;
}
return
0
;
}
static
av_cold
void
uninit
(
AVFilterContext
*
ctx
)
{
AudioSurroundContext
*
s
=
ctx
->
priv
;
int
ch
;
av_frame_free
(
&
s
->
input
);
av_frame_free
(
&
s
->
output
);
av_frame_free
(
&
s
->
overlap_buffer
);
for
(
ch
=
0
;
ch
<
s
->
nb_in_channels
;
ch
++
)
{
av_rdft_end
(
s
->
rdft
[
ch
]);
}
for
(
ch
=
0
;
ch
<
s
->
nb_out_channels
;
ch
++
)
{
av_rdft_end
(
s
->
irdft
[
ch
]);
}
av_freep
(
&
s
->
rdft
);
av_freep
(
&
s
->
irdft
);
av_audio_fifo_free
(
s
->
fifo
);
av_freep
(
&
s
->
window_func_lut
);
}
#define OFFSET(x) offsetof(AudioSurroundContext, x)
#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
static
const
AVOption
surround_options
[]
=
{
{
"chl_out"
,
"set output channel layout"
,
OFFSET
(
out_channel_layout_str
),
AV_OPT_TYPE_STRING
,
{.
str
=
"5.1"
},
0
,
0
,
FLAGS
},
{
"level_in"
,
"set input level"
,
OFFSET
(
level_in
),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
1
},
0
,
10
,
FLAGS
},
{
"level_out"
,
"set output level"
,
OFFSET
(
level_out
),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
1
},
0
,
10
,
FLAGS
},
{
"lfe"
,
"output LFE"
,
OFFSET
(
output_lfe
),
AV_OPT_TYPE_BOOL
,
{.
i64
=
1
},
0
,
1
,
FLAGS
},
{
"lfe_low"
,
"LFE low cut off"
,
OFFSET
(
lowcutf
),
AV_OPT_TYPE_INT
,
{.
i64
=
128
},
0
,
256
,
FLAGS
},
{
"lfe_high"
,
"LFE high cut off"
,
OFFSET
(
highcutf
),
AV_OPT_TYPE_INT
,
{.
i64
=
256
},
0
,
512
,
FLAGS
},
{
NULL
}
};
AVFILTER_DEFINE_CLASS
(
surround
);
static
const
AVFilterPad
inputs
[]
=
{
{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_AUDIO
,
.
filter_frame
=
filter_frame
,
.
config_props
=
config_input
,
},
{
NULL
}
};
static
const
AVFilterPad
outputs
[]
=
{
{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_AUDIO
,
.
config_props
=
config_output
,
},
{
NULL
}
};
AVFilter
ff_af_surround
=
{
.
name
=
"surround"
,
.
description
=
NULL_IF_CONFIG_SMALL
(
"Apply audio surround upmix filter."
),
.
query_formats
=
query_formats
,
.
priv_size
=
sizeof
(
AudioSurroundContext
),
.
priv_class
=
&
surround_class
,
.
init
=
init
,
.
uninit
=
uninit
,
.
inputs
=
inputs
,
.
outputs
=
outputs
,
.
flags
=
AVFILTER_FLAG_SLICE_THREADS
,
};
libavfilter/allfilters.c
View file @
dc72d1dd
...
...
@@ -121,6 +121,7 @@ static void register_all(void)
REGISTER_FILTER
(
SOFALIZER
,
sofalizer
,
af
);
REGISTER_FILTER
(
STEREOTOOLS
,
stereotools
,
af
);
REGISTER_FILTER
(
STEREOWIDEN
,
stereowiden
,
af
);
REGISTER_FILTER
(
SURROUND
,
surround
,
af
);
REGISTER_FILTER
(
TREBLE
,
treble
,
af
);
REGISTER_FILTER
(
TREMOLO
,
tremolo
,
af
);
REGISTER_FILTER
(
VIBRATO
,
vibrato
,
af
);
...
...
libavfilter/version.h
View file @
dc72d1dd
...
...
@@ -30,7 +30,7 @@
#include "libavutil/version.h"
#define LIBAVFILTER_VERSION_MAJOR 6
#define LIBAVFILTER_VERSION_MINOR 9
0
#define LIBAVFILTER_VERSION_MINOR 9
1
#define LIBAVFILTER_VERSION_MICRO 100
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
...
...
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