History

libavresample: Remove deprecated library

Deprecated in c29038f3041a4080342b2e333c1967d136749c0f. The resample filter based upon this library has been removed as well.

Andreas Rheinhardt committed 5 years ago

Commit 420cedd1 parent d40bb5159 files · +5 −10167Browse files

Unified · Split

59 files
  1. Makefile +0 −1
  2. configure +3 −13
  3. doc/APIchanges +0 −1
  4. ffbuild/common.mak +1 −1
  5. fftools/cmdutils.c +0 −12
  6. fftools/ffmpeg_filter.c +0 −2
  7. libavfilter/Makefile +0 −1
  8. libavfilter/af_resample.c +0 −369
  9. libavfilter/allfilters.c +0 −1
  10. libavresample/Makefile +0 −19
  11. libavresample/aarch64/Makefile +0 −7
  12. libavresample/aarch64/asm-offsets.h +0 −28
  13. libavresample/aarch64/audio_convert_init.c +0 −49
  14. libavresample/aarch64/audio_convert_neon.S +0 −363
  15. libavresample/aarch64/neontest.c +0 −31
  16. libavresample/aarch64/resample_init.c +0 −71
  17. libavresample/aarch64/resample_neon.S +0 −233
  18. libavresample/arm/Makefile +0 −7
  19. libavresample/arm/asm-offsets.h +0 −29
  20. libavresample/arm/audio_convert_init.c +0 −49
  21. libavresample/arm/audio_convert_neon.S +0 −363
  22. libavresample/arm/neontest.c +0 −31
  23. libavresample/arm/resample_init.c +0 −74
  24. libavresample/arm/resample_neon.S +0 −358
  25. libavresample/audio_convert.c +0 −416
  26. libavresample/audio_convert.h +0 −103
  27. libavresample/audio_data.c +0 −381
  28. libavresample/audio_data.h +0 −178
  29. libavresample/audio_mix.c +0 −742
  30. libavresample/audio_mix.h +0 −94
  31. libavresample/audio_mix_matrix.c +0 −294
  32. libavresample/avresample.h +0 −595
  33. libavresample/avresampleres.rc +0 −55
  34. libavresample/dither.c +0 −440
  35. libavresample/dither.h +0 −93
  36. libavresample/internal.h +0 −116
  37. libavresample/libavresample.v +0 −6
  38. libavresample/options.c +0 −113
  39. libavresample/resample.c +0 −446
  40. libavresample/resample.h +0 −96
  41. libavresample/resample_template.c +0 −118
  42. libavresample/tests/.gitignore +0 −1
  43. libavresample/tests/avresample.c +0 −342
  44. libavresample/utils.c +0 −793
  45. libavresample/version.h +0 −50
  46. libavresample/x86/Makefile +0 −9
  47. libavresample/x86/audio_convert.asm +0 −1261
  48. libavresample/x86/audio_convert_init.c +0 −265
  49. libavresample/x86/audio_mix.asm +0 −511
  50. libavresample/x86/audio_mix_init.c +0 −215
  51. libavresample/x86/dither.asm +0 −117
  52. libavresample/x86/dither_init.c +0 −60
  53. libavresample/x86/util.asm +0 −41
  54. libavresample/x86/w64xmmtest.c +0 −31
  55. tests/Makefile +0 −1
  56. tests/fate.sh +0 −1
  57. tests/fate/libavresample.mak +0 −68
  58. tools/gen-rc +0 −1
  59. tools/target_dec_fuzzer.c +1 −1
Makefile+0−1
@@ -23,7 +23,6 @@ FFLIBS-$(CONFIG_AVDEVICE) += avdevice · 22 unmodified lines
2323 FFLIBS-$(CONFIG_AVFILTER) += avfilter
2424 FFLIBS-$(CONFIG_AVFORMAT) += avformat
2525 FFLIBS-$(CONFIG_AVCODEC) += avcodec
26−FFLIBS-$(CONFIG_AVRESAMPLE) += avresample
2726 FFLIBS-$(CONFIG_POSTPROC) += postproc
2827 FFLIBS-$(CONFIG_SWRESAMPLE) += swresample
2928 FFLIBS-$(CONFIG_SWSCALE) += swscale
configure+3−13
@@ -132,7 +132,6 @@ Component options: · 131 unmodified lines
132132 --disable-swscale disable libswscale build
133133 --disable-postproc disable libpostproc build
134134 --disable-avfilter disable libavfilter build
135− --enable-avresample enable libavresample build (deprecated) [no]
136135 --disable-pthreads disable pthreads [autodetect]
137136 --disable-w32threads disable Win32 threads [autodetect]
138137 --disable-os2threads disable OS/2 threads [autodetect]
@@ -1901,7 +1900,6 @@ LIBRARY_LIST=" · 1762 unmodified lines
19011900 avformat
19021901 avcodec
19031902 swresample
1904− avresample
19051903 avutil
19061904 "
19071905
@@ -3609,7 +3607,6 @@ program_opencl_filter_deps="opencl" · 1701 unmodified lines
36093607 pullup_filter_deps="gpl"
36103608 removelogo_filter_deps="avcodec avformat swscale"
36113609 repeatfields_filter_deps="gpl"
3612−resample_filter_deps="avresample"
36133610 roberts_opencl_filter_deps="opencl"
36143611 rubberband_filter_deps="librubberband"
36153612 sab_filter_deps="gpl swscale"
@@ -3711,8 +3708,6 @@ avfilter_deps="avutil" · 95 unmodified lines
37113708 avfilter_suggest="libm"
37123709 avformat_deps="avcodec avutil"
37133710 avformat_suggest="libm network zlib"
3714−avresample_deps="avutil"
3715−avresample_suggest="libm"
37163711 avutil_suggest="clock_gettime ffnvcodec libm libdrm libmfx opencl user32 vaapi vulkan videotoolbox corefoundation corevideo coremedia bcrypt"
37173712 postproc_deps="avutil gpl"
37183713 postproc_suggest="libm"
@@ -3795,7 +3790,7 @@ intrinsics="none" · 76 unmodified lines
37953790 enable $PROGRAM_LIST
37963791 enable $DOCUMENT_LIST
37973792 enable $EXAMPLE_LIST
3798−enable $(filter_out avresample $LIBRARY_LIST)
3793+enable $LIBRARY_LIST
37993794 enable stripping
38003795
38013796 enable asm
@@ -6845,7 +6840,7 @@ EOF · 3043 unmodified lines
68456840
68466841 # add some linker flags
68476842 check_ldflags -Wl,--warn-common
6848−check_ldflags -Wl,-rpath-link=:libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil:libavresample
6843+check_ldflags -Wl,-rpath-link=:libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil
68496844 enabled rpath && add_ldexeflags -Wl,-rpath,$libdir && add_ldsoflags -Wl,-rpath,$libdir
68506845 test_ldflags -Wl,-Bsymbolic && append SHFLAGS -Wl,-Bsymbolic
68516846
@@ -6860,8 +6855,7 @@ enabled neon_clobber_test && · 8 unmodified lines
68606855 -Wl,--wrap,avcodec_receive_packet \
68616856 -Wl,--wrap,avcodec_send_frame \
68626857 -Wl,--wrap,avcodec_receive_frame \
6863− -Wl,--wrap,swr_convert \
6864− -Wl,--wrap,avresample_convert ||
6858+ -Wl,--wrap,swr_convert ||
68656859 disable neon_clobber_test
68666860
68676861 enabled xmm_clobber_test &&
@@ -6873,7 +6867,6 @@ enabled xmm_clobber_test && · 5 unmodified lines
68736867 -Wl,--wrap,avcodec_send_frame \
68746868 -Wl,--wrap,avcodec_receive_frame \
68756869 -Wl,--wrap,swr_convert \
6876− -Wl,--wrap,avresample_convert \
68776870 -Wl,--wrap,sws_scale ||
68786871 disable xmm_clobber_test
68796872
@@ -7098,7 +7091,6 @@ check_deps $CONFIG_LIST \ · 218 unmodified lines
70987091 $ALL_COMPONENTS \
70997092
71007093 enabled threads && ! enabled pthreads && ! enabled atomics_native && die "non pthread threading without atomics not supported, try adding --enable-pthreads or --cpu=i486 or higher if you are on x86"
7101−enabled avresample && warn "Building with deprecated library libavresample"
71027094
71037095 case $target_os in
71047096 haiku)
@@ -7214,7 +7206,6 @@ enabled movie_filter && prepend avfilter_deps "avformat avcodec" · 109 unmodified lines
72147206 enabled pan_filter && prepend avfilter_deps "swresample"
72157207 enabled pp_filter && prepend avfilter_deps "postproc"
72167208 enabled removelogo_filter && prepend avfilter_deps "avformat avcodec swscale"
7217−enabled resample_filter && prepend avfilter_deps "avresample"
72187209 enabled sab_filter && prepend avfilter_deps "swscale"
72197210 enabled scale_filter && prepend avfilter_deps "swscale"
72207211 enabled scale2ref_filter && prepend avfilter_deps "swscale"
@@ -7707,7 +7698,6 @@ extralibs_avcodec="$avcodec_extralibs" · 486 unmodified lines
77077698 extralibs_avformat="$avformat_extralibs"
77087699 extralibs_avdevice="$avdevice_extralibs"
77097700 extralibs_avfilter="$avfilter_extralibs"
7710−extralibs_avresample="$avresample_extralibs"
77117701 extralibs_postproc="$postproc_extralibs"
77127702 extralibs_swscale="$swscale_extralibs"
77137703 extralibs_swresample="$swresample_extralibs"
doc/APIchanges+0−1
@@ -6,7 +6,6 @@ libavcodec: 2017-10-21 · 5 unmodified lines
66 libavdevice: 2017-10-21
77 libavfilter: 2017-10-21
88 libavformat: 2017-10-21
9−libavresample: 2017-10-21
109 libpostproc: 2017-10-21
1110 libswresample: 2017-10-21
1211 libswscale: 2017-10-21
ffbuild/common.mak+1−1
@@ -26,7 +26,7 @@ $(foreach VAR,$(SILENT),$(eval override $(VAR) = @$($(VAR)))) · 25 unmodified lines
2626 $(eval INSTALL = @$(call ECHO,INSTALL,$$(^:$(SRC_DIR)/%=%)); $(INSTALL))
2727 endif
2828
29−ALLFFLIBS = avcodec avdevice avfilter avformat avresample avutil postproc swscale swresample
29+ALLFFLIBS = avcodec avdevice avfilter avformat avutil postproc swscale swresample
3030
3131 # NASM requires -I path terminated with /
3232 IFLAGS := -I. -I$(SRC_LINK)/
fftools/cmdutils.c+0−12
@@ -34,7 +34,6 @@ · 33 unmodified lines
3434 #include "libavformat/avformat.h"
3535 #include "libavfilter/avfilter.h"
3636 #include "libavdevice/avdevice.h"
37−#include "libavresample/avresample.h"
3837 #include "libswscale/swscale.h"
3938 #include "libswresample/swresample.h"
4039 #include "libpostproc/postprocess.h"
@@ -545,9 +544,6 @@ int opt_default(void *optctx, const char *opt, const char *arg) · 504 unmodified lines
545544 char opt_stripped[128];
546545 const char *p;
547546 const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class();
548−#if CONFIG_AVRESAMPLE
549− const AVClass *rc = avresample_get_class();
550−#endif
551547 #if CONFIG_SWSCALE
552548 const AVClass *sc = sws_get_class();
553549 #endif
@@ -617,13 +613,6 @@ int opt_default(void *optctx, const char *opt, const char *arg) · 63 unmodified lines
617613 consumed = 1;
618614 }
619615 #endif
620−#if CONFIG_AVRESAMPLE
621− if ((o=opt_find(&rc, opt, NULL, 0,
622− AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
623− av_dict_set(&resample_opts, opt, arg, FLAGS);
624− consumed = 1;
625− }
626−#endif
627616
628617 if (consumed)
629618 return 0;
@@ -1134,7 +1123,6 @@ static void print_all_libs_info(int flags, int level) · 504 unmodified lines
11341123 PRINT_LIB_INFO(avformat, AVFORMAT, flags, level);
11351124 PRINT_LIB_INFO(avdevice, AVDEVICE, flags, level);
11361125 PRINT_LIB_INFO(avfilter, AVFILTER, flags, level);
1137− PRINT_LIB_INFO(avresample, AVRESAMPLE, flags, level);
11381126 PRINT_LIB_INFO(swscale, SWSCALE, flags, level);
11391127 PRINT_LIB_INFO(swresample, SWRESAMPLE, flags, level);
11401128 PRINT_LIB_INFO(postproc, POSTPROC, flags, level);
fftools/ffmpeg_filter.c+0−2
@@ -26,8 +26,6 @@ · 25 unmodified lines
2626 #include "libavfilter/buffersink.h"
2727 #include "libavfilter/buffersrc.h"
2828
29−#include "libavresample/avresample.h"
30−
3129 #include "libavutil/avassert.h"
3230 #include "libavutil/avstring.h"
3331 #include "libavutil/bprint.h"
libavfilter/Makefile+0−1
@@ -135,7 +135,6 @@ OBJS-$(CONFIG_LV2_FILTER) += af_lv2.o · 134 unmodified lines
135135 OBJS-$(CONFIG_MCOMPAND_FILTER) += af_mcompand.o
136136 OBJS-$(CONFIG_PAN_FILTER) += af_pan.o
137137 OBJS-$(CONFIG_REPLAYGAIN_FILTER) += af_replaygain.o
138−OBJS-$(CONFIG_RESAMPLE_FILTER) += af_resample.o
139138 OBJS-$(CONFIG_RUBBERBAND_FILTER) += af_rubberband.o
140139 OBJS-$(CONFIG_SIDECHAINCOMPRESS_FILTER) += af_sidechaincompress.o
141140 OBJS-$(CONFIG_SIDECHAINGATE_FILTER) += af_agate.o
libavfilter/af_resample.c+0−369
@@ -1,369 +0,0 @@
1−/*
2− * This file is part of FFmpeg.
3− *
4− * FFmpeg is free software; you can redistribute it and/or
5− * modify it under the terms of the GNU Lesser General Public
6− * License as published by the Free Software Foundation; either
7− * version 2.1 of the License, or (at your option) any later version.
8− *
9− * FFmpeg is distributed in the hope that it will be useful,
10− * but WITHOUT ANY WARRANTY; without even the implied warranty of
11− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12− * Lesser General Public License for more details.
13− *
14− * You should have received a copy of the GNU Lesser General Public
15− * License along with FFmpeg; if not, write to the Free Software
16− * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17− */
18−
19−/**
20− * @file
21− * sample format and channel layout conversion audio filter
22− */
23−
24−#include "libavutil/avassert.h"
25−#include "libavutil/avstring.h"
26−#include "libavutil/common.h"
27−#include "libavutil/dict.h"
28−#include "libavutil/mathematics.h"
29−#include "libavutil/opt.h"
30−
31−#include "libavresample/avresample.h"
32−
33−#include "audio.h"
34−#include "avfilter.h"
35−#include "formats.h"
36−#include "internal.h"
37−
38−typedef struct ResampleContext {
39− const AVClass *class;
40− AVAudioResampleContext *avr;
41− AVDictionary *options;
42−
43− int resampling;
44− int64_t next_pts;
45− int64_t next_in_pts;
46−
47− /* set by filter_frame() to signal an output frame to request_frame() */
48− int got_output;
49−} ResampleContext;
50−
51−static av_cold int init(AVFilterContext *ctx, AVDictionary **opts)
52−{
53− ResampleContext *s = ctx->priv;
54− const AVClass *avr_class = avresample_get_class();
55− AVDictionaryEntry *e = NULL;
56−
57− while ((e = av_dict_get(*opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
58− if (av_opt_find(&avr_class, e->key, NULL, 0,
59− AV_OPT_SEARCH_FAKE_OBJ | AV_OPT_SEARCH_CHILDREN))
60− av_dict_set(&s->options, e->key, e->value, 0);
61− }
62−
63− e = NULL;
64− while ((e = av_dict_get(s->options, "", e, AV_DICT_IGNORE_SUFFIX)))
65− av_dict_set(opts, e->key, NULL, 0);
66−
67− /* do not allow the user to override basic format options */
68− av_dict_set(&s->options, "in_channel_layout", NULL, 0);
69− av_dict_set(&s->options, "out_channel_layout", NULL, 0);
70− av_dict_set(&s->options, "in_sample_fmt", NULL, 0);
71− av_dict_set(&s->options, "out_sample_fmt", NULL, 0);
72− av_dict_set(&s->options, "in_sample_rate", NULL, 0);
73− av_dict_set(&s->options, "out_sample_rate", NULL, 0);
74−
75− return 0;
76−}
77−
78−static av_cold void uninit(AVFilterContext *ctx)
79−{
80− ResampleContext *s = ctx->priv;
81−
82− if (s->avr) {
83− avresample_close(s->avr);
84− avresample_free(&s->avr);
85− }
86− av_dict_free(&s->options);
87−}
88−
89−static int query_formats(AVFilterContext *ctx)
90−{
91− AVFilterLink *inlink = ctx->inputs[0];
92− AVFilterLink *outlink = ctx->outputs[0];
93− AVFilterFormats *in_formats, *out_formats, *in_samplerates, *out_samplerates;
94− AVFilterChannelLayouts *in_layouts, *out_layouts;
95− int ret;
96−
97− if (!(in_formats = ff_all_formats (AVMEDIA_TYPE_AUDIO)) ||
98− !(out_formats = ff_all_formats (AVMEDIA_TYPE_AUDIO)) ||
99− !(in_samplerates = ff_all_samplerates ( )) ||
100− !(out_samplerates = ff_all_samplerates ( )) ||
101− !(in_layouts = ff_all_channel_layouts ( )) ||
102− !(out_layouts = ff_all_channel_layouts ( )))
103− return AVERROR(ENOMEM);
104−
105− if ((ret = ff_formats_ref (in_formats, &inlink->outcfg.formats )) < 0 ||
106− (ret = ff_formats_ref (out_formats, &outlink->incfg.formats )) < 0 ||
107− (ret = ff_formats_ref (in_samplerates, &inlink->outcfg.samplerates )) < 0 ||
108− (ret = ff_formats_ref (out_samplerates, &outlink->incfg.samplerates )) < 0 ||
109− (ret = ff_channel_layouts_ref (in_layouts, &inlink->outcfg.channel_layouts)) < 0 ||
110− (ret = ff_channel_layouts_ref (out_layouts, &outlink->incfg.channel_layouts)) < 0)
111− return ret;
112−
113− return 0;
114−}
115−
116−static int config_output(AVFilterLink *outlink)
117−{
118− AVFilterContext *ctx = outlink->src;
119− AVFilterLink *inlink = ctx->inputs[0];
120− ResampleContext *s = ctx->priv;
121− char buf1[64], buf2[64];
122− int ret;
123−
124− int64_t resampling_forced;
125−
126− if (s->avr) {
127− avresample_close(s->avr);
128− avresample_free(&s->avr);
129− }
130−
131− if (inlink->channel_layout == outlink->channel_layout &&
132− inlink->sample_rate == outlink->sample_rate &&
133− (inlink->format == outlink->format ||
134− (av_get_channel_layout_nb_channels(inlink->channel_layout) == 1 &&
135− av_get_channel_layout_nb_channels(outlink->channel_layout) == 1 &&
136− av_get_planar_sample_fmt(inlink->format) ==
137− av_get_planar_sample_fmt(outlink->format))))
138− return 0;
139−
140− if (!(s->avr = avresample_alloc_context()))
141− return AVERROR(ENOMEM);
142−
143− if (s->options) {
144− int ret;
145− AVDictionaryEntry *e = NULL;
146− while ((e = av_dict_get(s->options, "", e, AV_DICT_IGNORE_SUFFIX)))
147− av_log(ctx, AV_LOG_VERBOSE, "lavr option: %s=%s\n", e->key, e->value);
148−
149− ret = av_opt_set_dict(s->avr, &s->options);
150− if (ret < 0)
151− return ret;
152− }
153−
154− av_opt_set_int(s->avr, "in_channel_layout", inlink ->channel_layout, 0);
155− av_opt_set_int(s->avr, "out_channel_layout", outlink->channel_layout, 0);
156− av_opt_set_int(s->avr, "in_sample_fmt", inlink ->format, 0);
157− av_opt_set_int(s->avr, "out_sample_fmt", outlink->format, 0);
158− av_opt_set_int(s->avr, "in_sample_rate", inlink ->sample_rate, 0);
159− av_opt_set_int(s->avr, "out_sample_rate", outlink->sample_rate, 0);
160−
161− if ((ret = avresample_open(s->avr)) < 0)
162− return ret;
163−
164− av_opt_get_int(s->avr, "force_resampling", 0, &resampling_forced);
165− s->resampling = resampling_forced || (inlink->sample_rate != outlink->sample_rate);
166−
167− if (s->resampling) {
168− outlink->time_base = (AVRational){ 1, outlink->sample_rate };
169− s->next_pts = AV_NOPTS_VALUE;
170− s->next_in_pts = AV_NOPTS_VALUE;
171− } else
172− outlink->time_base = inlink->time_base;
173−
174− av_get_channel_layout_string(buf1, sizeof(buf1),
175− -1, inlink ->channel_layout);
176− av_get_channel_layout_string(buf2, sizeof(buf2),
177− -1, outlink->channel_layout);
178− av_log(ctx, AV_LOG_VERBOSE,
179− "fmt:%s srate:%d cl:%s -> fmt:%s srate:%d cl:%s\n",
180− av_get_sample_fmt_name(inlink ->format), inlink ->sample_rate, buf1,
181− av_get_sample_fmt_name(outlink->format), outlink->sample_rate, buf2);
182−
183− return 0;
184−}
185−
186−static int request_frame(AVFilterLink *outlink)
187−{
188− AVFilterContext *ctx = outlink->src;
189− ResampleContext *s = ctx->priv;
190− int ret = 0;
191−
192− s->got_output = 0;
193− while (ret >= 0 && !s->got_output)
194− ret = ff_request_frame(ctx->inputs[0]);
195−
196− /* flush the lavr delay buffer */
197− if (ret == AVERROR_EOF && s->avr) {
198− AVFrame *frame;
199− int nb_samples = avresample_get_out_samples(s->avr, 0);
200−
201− if (!nb_samples)
202− return ret;
203−
204− frame = ff_get_audio_buffer(outlink, nb_samples);
205− if (!frame)
206− return AVERROR(ENOMEM);
207−
208− ret = avresample_convert(s->avr, frame->extended_data,
209− frame->linesize[0], nb_samples,
210− NULL, 0, 0);
211− if (ret <= 0) {
212− av_frame_free(&frame);
213− return (ret == 0) ? AVERROR_EOF : ret;
214− }
215−
216− frame->nb_samples = ret;
217− frame->pts = s->next_pts;
218− return ff_filter_frame(outlink, frame);
219− }
220− return ret;
221−}
222−
223−static int filter_frame(AVFilterLink *inlink, AVFrame *in)
224−{
225− AVFilterContext *ctx = inlink->dst;
226− ResampleContext *s = ctx->priv;
227− AVFilterLink *outlink = ctx->outputs[0];
228− int ret;
229−
230− if (s->avr) {
231− AVFrame *out;
232− int delay, nb_samples;
233−
234− /* maximum possible samples lavr can output */
235− delay = avresample_get_delay(s->avr);
236− nb_samples = avresample_get_out_samples(s->avr, in->nb_samples);
237−
238− out = ff_get_audio_buffer(outlink, nb_samples);
239− if (!out) {
240− ret = AVERROR(ENOMEM);
241− goto fail;
242− }
243−
244− ret = avresample_convert(s->avr, out->extended_data, out->linesize[0],
245− nb_samples, in->extended_data, in->linesize[0],
246− in->nb_samples);
247− if (ret <= 0) {
248− av_frame_free(&out);
249− if (ret < 0)
250− goto fail;
251− }
252−
253− av_assert0(!avresample_available(s->avr));
254−
255− if (s->resampling && s->next_pts == AV_NOPTS_VALUE) {
256− if (in->pts == AV_NOPTS_VALUE) {
257− av_log(ctx, AV_LOG_WARNING, "First timestamp is missing, "
258− "assuming 0.\n");
259− s->next_pts = 0;
260− } else
261− s->next_pts = av_rescale_q(in->pts, inlink->time_base,
262− outlink->time_base);
263− }
264−
265− if (ret > 0) {
266− out->nb_samples = ret;
267−
268− ret = av_frame_copy_props(out, in);
269− if (ret < 0) {
270− av_frame_free(&out);
271− goto fail;
272− }
273−
274− if (s->resampling) {
275− out->sample_rate = outlink->sample_rate;
276− /* Only convert in->pts if there is a discontinuous jump.
277− This ensures that out->pts tracks the number of samples actually
278− output by the resampler in the absence of such a jump.
279− Otherwise, the rounding in av_rescale_q() and av_rescale()
280− causes off-by-1 errors. */
281− if (in->pts != AV_NOPTS_VALUE && in->pts != s->next_in_pts) {
282− out->pts = av_rescale_q(in->pts, inlink->time_base,
283− outlink->time_base) -
284− av_rescale(delay, outlink->sample_rate,
285− inlink->sample_rate);
286− } else
287− out->pts = s->next_pts;
288−
289− s->next_pts = out->pts + out->nb_samples;
290− s->next_in_pts = in->pts + in->nb_samples;
291− } else
292− out->pts = in->pts;
293−
294− ret = ff_filter_frame(outlink, out);
295− s->got_output = 1;
296− }
297−
298−fail:
299− av_frame_free(&in);
300− } else {
301− in->format = outlink->format;
302− ret = ff_filter_frame(outlink, in);
303− s->got_output = 1;
304− }
305−
306− return ret;
307−}
308−
309−#if FF_API_CHILD_CLASS_NEXT
310−static const AVClass *resample_child_class_next(const AVClass *prev)
311−{
312− return prev ? NULL : avresample_get_class();
313−}
314−#endif
315−
316−static const AVClass *resample_child_class_iterate(void **iter)
317−{
318− const AVClass *c = *iter ? NULL : avresample_get_class();
319− *iter = (void*)(uintptr_t)c;
320− return c;
321−}
322−
323−static void *resample_child_next(void *obj, void *prev)
324−{
325− ResampleContext *s = obj;
326− return prev ? NULL : s->avr;
327−}
328−
329−static const AVClass resample_class = {
330− .class_name = "resample",
331− .item_name = av_default_item_name,
332− .version = LIBAVUTIL_VERSION_INT,
333−#if FF_API_CHILD_CLASS_NEXT
334− .child_class_next = resample_child_class_next,
335−#endif
336− .child_class_iterate = resample_child_class_iterate,
337− .child_next = resample_child_next,
338−};
339−
340−static const AVFilterPad avfilter_af_resample_inputs[] = {
341− {
342− .name = "default",
343− .type = AVMEDIA_TYPE_AUDIO,
344− .filter_frame = filter_frame,
345− },
346− { NULL }
347−};
348−
349−static const AVFilterPad avfilter_af_resample_outputs[] = {
350− {
351− .name = "default",
352− .type = AVMEDIA_TYPE_AUDIO,
353− .config_props = config_output,
354− .request_frame = request_frame
355− },
356− { NULL }
357−};
358−
359−AVFilter ff_af_resample = {
360− .name = "resample",
361− .description = NULL_IF_CONFIG_SMALL("Audio resampling and conversion."),
362− .priv_size = sizeof(ResampleContext),
363− .priv_class = &resample_class,
364− .init_dict = init,
365− .uninit = uninit,
366− .query_formats = query_formats,
367− .inputs = avfilter_af_resample_inputs,
368− .outputs = avfilter_af_resample_outputs,
369−};
libavfilter/allfilters.c+0−1
@@ -129,7 +129,6 @@ extern AVFilter ff_af_lv2; · 128 unmodified lines
129129 extern AVFilter ff_af_mcompand;
130130 extern AVFilter ff_af_pan;
131131 extern AVFilter ff_af_replaygain;
132−extern AVFilter ff_af_resample;
133132 extern AVFilter ff_af_rubberband;
134133 extern AVFilter ff_af_sidechaincompress;
135134 extern AVFilter ff_af_sidechaingate;
libavresample/Makefile+0−19
@@ -1,19 +0,0 @@
1−NAME = avresample
2−DESC = Libav audio resampling library
3−
4−HEADERS = avresample.h \
5− version.h \
6−
7−OBJS = audio_convert.o \
8− audio_data.o \
9− audio_mix.o \
10− audio_mix_matrix.o \
11− dither.o \
12− options.o \
13− resample.o \
14− utils.o \
15−
16−# Windows resource file
17−SLIBOBJS-$(HAVE_GNU_WINDRES) += avresampleres.o
18−
19−TESTPROGS = avresample
libavresample/aarch64/Makefile+0−7
@@ -1,7 +0,0 @@
1−OBJS += aarch64/audio_convert_init.o \
2− aarch64/resample_init.o \
3−
4−OBJS-$(CONFIG_NEON_CLOBBER_TEST) += aarch64/neontest.o
5−
6−NEON-OBJS += aarch64/audio_convert_neon.o \
7− aarch64/resample_neon.o \
libavresample/aarch64/asm-offsets.h+0−28
@@ -1,28 +0,0 @@
1−/*
2− * This file is part of FFmpeg.
3− *
4− * FFmpeg is free software; you can redistribute it and/or
5− * modify it under the terms of the GNU Lesser General Public
6− * License as published by the Free Software Foundation; either
7− * version 2.1 of the License, or (at your option) any later version.
8− *
9− * FFmpeg is distributed in the hope that it will be useful,
10− * but WITHOUT ANY WARRANTY; without even the implied warranty of
11− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12− * Lesser General Public License for more details.
13− *
14− * You should have received a copy of the GNU Lesser General Public
15− * License along with FFmpeg; if not, write to the Free Software
16− * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17− */
18−
19−#ifndef AVRESAMPLE_AARCH64_ASM_OFFSETS_H
20−#define AVRESAMPLE_AARCH64_ASM_OFFSETS_H
21−
22−/* struct ResampleContext */
23−#define FILTER_BANK 0x10
24−#define FILTER_LENGTH 0x18
25−#define PHASE_SHIFT 0x34
26−#define PHASE_MASK (PHASE_SHIFT + 0x04) // loaded as pair
27−
28−#endif /* AVRESAMPLE_AARCH64_ASM_OFFSETS_H */
libavresample/aarch64/audio_convert_init.c+0−49
@@ -1,49 +0,0 @@
1−/*
2− * This file is part of FFmpeg.
3− *
4− * FFmpeg is free software; you can redistribute it and/or
5− * modify it under the terms of the GNU Lesser General Public
6− * License as published by the Free Software Foundation; either
7− * version 2.1 of the License, or (at your option) any later version.
8− *
9− * FFmpeg is distributed in the hope that it will be useful,
10− * but WITHOUT ANY WARRANTY; without even the implied warranty of
11− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12− * Lesser General Public License for more details.
13− *
14− * You should have received a copy of the GNU Lesser General Public
15− * License along with FFmpeg; if not, write to the Free Software
16− * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17− */
18−
19−#include <stdint.h>
20−
21−#include "config.h"
22−#include "libavutil/attributes.h"
23−#include "libavutil/cpu.h"
24−#include "libavutil/aarch64/cpu.h"
25−#include "libavutil/samplefmt.h"
26−#include "libavresample/audio_convert.h"
27−
28−void ff_conv_flt_to_s16_neon(int16_t *dst, const float *src, int len);
29−void ff_conv_fltp_to_s16_neon(int16_t *dst, float *const *src,
30− int len, int channels);
31−void ff_conv_fltp_to_s16_2ch_neon(int16_t *dst, float *const *src,
32− int len, int channels);
33−
34−av_cold void ff_audio_convert_init_aarch64(AudioConvert *ac)
35−{
36− int cpu_flags = av_get_cpu_flags();
37−
38− if (have_neon(cpu_flags)) {
39− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT,
40− 0, 16, 8, "NEON",
41− ff_conv_flt_to_s16_neon);
42− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLTP,
43− 2, 16, 8, "NEON",
44− ff_conv_fltp_to_s16_2ch_neon);
45− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLTP,
46− 0, 16, 8, "NEON",
47− ff_conv_fltp_to_s16_neon);
48− }
49−}
libavresample/aarch64/audio_convert_neon.S+0−363
@@ -1,363 +0,0 @@
1−/*
2− * Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
3− * Copyright (c) 2014 Janne Grunau <janne-libav@jannau.net>
4− *
5− * This file is part of FFmpeg.
6− *
7− * FFmpeg is free software; you can redistribute it and/or
8− * modify it under the terms of the GNU Lesser General Public
9− * License as published by the Free Software Foundation; either
10− * version 2.1 of the License, or (at your option) any later version.
11− *
12− * FFmpeg is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15− * Lesser General Public License for more details.
16− *
17− * You should have received a copy of the GNU Lesser General Public
18− * License along with FFmpeg; if not, write to the Free Software
19− * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20− */
21−
22−#include "config.h"
23−#include "libavutil/aarch64/asm.S"
24−
25−function ff_conv_flt_to_s16_neon, export=1
26− subs x2, x2, #8
27− ld1 {v0.4s}, [x1], #16
28− fcvtzs v4.4s, v0.4s, #31
29− ld1 {v1.4s}, [x1], #16
30− fcvtzs v5.4s, v1.4s, #31
31− b.eq 3f
32− ands x12, x2, #~15
33− b.eq 2f
34−1: subs x12, x12, #16
35− sqrshrn v4.4h, v4.4s, #16
36− ld1 {v2.4s}, [x1], #16
37− fcvtzs v6.4s, v2.4s, #31
38− sqrshrn2 v4.8h, v5.4s, #16
39− ld1 {v3.4s}, [x1], #16
40− fcvtzs v7.4s, v3.4s, #31
41− sqrshrn v6.4h, v6.4s, #16
42− st1 {v4.8h}, [x0], #16
43− sqrshrn2 v6.8h, v7.4s, #16
44− ld1 {v0.4s}, [x1], #16
45− fcvtzs v4.4s, v0.4s, #31
46− ld1 {v1.4s}, [x1], #16
47− fcvtzs v5.4s, v1.4s, #31
48− st1 {v6.8h}, [x0], #16
49− b.ne 1b
50− ands x2, x2, #15
51− b.eq 3f
52−2: ld1 {v2.4s}, [x1], #16
53− sqrshrn v4.4h, v4.4s, #16
54− fcvtzs v6.4s, v2.4s, #31
55− ld1 {v3.4s}, [x1], #16
56− sqrshrn2 v4.8h, v5.4s, #16
57− fcvtzs v7.4s, v3.4s, #31
58− sqrshrn v6.4h, v6.4s, #16
59− st1 {v4.8h}, [x0], #16
60− sqrshrn2 v6.8h, v7.4s, #16
61− st1 {v6.8h}, [x0]
62− ret
63−3: sqrshrn v4.4h, v4.4s, #16
64− sqrshrn2 v4.8h, v5.4s, #16
65− st1 {v4.8h}, [x0]
66− ret
67−endfunc
68−
69−function ff_conv_fltp_to_s16_2ch_neon, export=1
70− ldp x4, x5, [x1]
71− subs x2, x2, #8
72− ld1 {v0.4s}, [x4], #16
73− fcvtzs v4.4s, v0.4s, #31
74− ld1 {v1.4s}, [x4], #16
75− fcvtzs v5.4s, v1.4s, #31
76− ld1 {v2.4s}, [x5], #16
77− fcvtzs v6.4s, v2.4s, #31
78− ld1 {v3.4s}, [x5], #16
79− fcvtzs v7.4s, v3.4s, #31
80− b.eq 3f
81− ands x12, x2, #~15
82− b.eq 2f
83−1: subs x12, x12, #16
84− ld1 {v16.4s}, [x4], #16
85− fcvtzs v20.4s, v16.4s, #31
86− sri v6.4s, v4.4s, #16
87− ld1 {v17.4s}, [x4], #16
88− fcvtzs v21.4s, v17.4s, #31
89− ld1 {v18.4s}, [x5], #16
90− fcvtzs v22.4s, v18.4s, #31
91− ld1 {v19.4s}, [x5], #16
92− sri v7.4s, v5.4s, #16
93− st1 {v6.4s}, [x0], #16
94− fcvtzs v23.4s, v19.4s, #31
95− st1 {v7.4s}, [x0], #16
96− sri v22.4s, v20.4s, #16
97− ld1 {v0.4s}, [x4], #16
98− sri v23.4s, v21.4s, #16
99− st1 {v22.4s}, [x0], #16
100− fcvtzs v4.4s, v0.4s, #31
101− ld1 {v1.4s}, [x4], #16
102− fcvtzs v5.4s, v1.4s, #31
103− ld1 {v2.4s}, [x5], #16
104− fcvtzs v6.4s, v2.4s, #31
105− ld1 {v3.4s}, [x5], #16
106− fcvtzs v7.4s, v3.4s, #31
107− st1 {v23.4s}, [x0], #16
108− b.ne 1b
109− ands x2, x2, #15
110− b.eq 3f
111−2: sri v6.4s, v4.4s, #16
112− ld1 {v0.4s}, [x4], #16
113− fcvtzs v0.4s, v0.4s, #31
114− ld1 {v1.4s}, [x4], #16
115− fcvtzs v1.4s, v1.4s, #31
116− ld1 {v2.4s}, [x5], #16
117− fcvtzs v2.4s, v2.4s, #31
118− sri v7.4s, v5.4s, #16
119− ld1 {v3.4s}, [x5], #16
120− fcvtzs v3.4s, v3.4s, #31
121− sri v2.4s, v0.4s, #16
122− st1 {v6.4s,v7.4s}, [x0], #32
123− sri v3.4s, v1.4s, #16
124− st1 {v2.4s,v3.4s}, [x0], #32
125− ret
126−3: sri v6.4s, v4.4s, #16
127− sri v7.4s, v5.4s, #16
128− st1 {v6.4s,v7.4s}, [x0]
129− ret
130−endfunc
131−
132−function ff_conv_fltp_to_s16_neon, export=1
133− cmp w3, #2
134− b.eq X(ff_conv_fltp_to_s16_2ch_neon)
135− b.gt 1f
136− ldr x1, [x1]
137− b X(ff_conv_flt_to_s16_neon)
138−1:
139− cmp w3, #4
140− lsl x12, x3, #1
141− b.lt 4f
142−
143−5: // 4 channels
144− ldp x4, x5, [x1], #16
145− ldp x6, x7, [x1], #16
146− mov w9, w2
147− mov x8, x0
148− ld1 {v4.4s}, [x4], #16
149− fcvtzs v4.4s, v4.4s, #31
150− ld1 {v5.4s}, [x5], #16
151− fcvtzs v5.4s, v5.4s, #31
152− ld1 {v6.4s}, [x6], #16
153− fcvtzs v6.4s, v6.4s, #31
154− ld1 {v7.4s}, [x7], #16
155− fcvtzs v7.4s, v7.4s, #31
156−6:
157− subs w9, w9, #8
158− ld1 {v0.4s}, [x4], #16
159− fcvtzs v0.4s, v0.4s, #31
160− sri v5.4s, v4.4s, #16
161− ld1 {v1.4s}, [x5], #16
162− fcvtzs v1.4s, v1.4s, #31
163− sri v7.4s, v6.4s, #16
164− ld1 {v2.4s}, [x6], #16
165− fcvtzs v2.4s, v2.4s, #31
166− zip1 v16.4s, v5.4s, v7.4s
167− ld1 {v3.4s}, [x7], #16
168− fcvtzs v3.4s, v3.4s, #31
169− zip2 v17.4s, v5.4s, v7.4s
170− st1 {v16.d}[0], [x8], x12
171− sri v1.4s, v0.4s, #16
172− st1 {v16.d}[1], [x8], x12
173− sri v3.4s, v2.4s, #16
174− st1 {v17.d}[0], [x8], x12
175− zip1 v18.4s, v1.4s, v3.4s
176− st1 {v17.d}[1], [x8], x12
177− zip2 v19.4s, v1.4s, v3.4s
178− b.eq 7f
179− ld1 {v4.4s}, [x4], #16
180− fcvtzs v4.4s, v4.4s, #31
181− st1 {v18.d}[0], [x8], x12
182− ld1 {v5.4s}, [x5], #16
183− fcvtzs v5.4s, v5.4s, #31
184− st1 {v18.d}[1], [x8], x12
185− ld1 {v6.4s}, [x6], #16
186− fcvtzs v6.4s, v6.4s, #31
187− st1 {v19.d}[0], [x8], x12
188− ld1 {v7.4s}, [x7], #16
189− fcvtzs v7.4s, v7.4s, #31
190− st1 {v19.d}[1], [x8], x12
191− b 6b
192−7:
193− st1 {v18.d}[0], [x8], x12
194− st1 {v18.d}[1], [x8], x12
195− st1 {v19.d}[0], [x8], x12
196− st1 {v19.d}[1], [x8], x12
197− subs w3, w3, #4
198− b.eq end
199− cmp w3, #4
200− add x0, x0, #8
201− b.ge 5b
202−
203−4: // 2 channels
204− cmp w3, #2
205− b.lt 4f
206− ldp x4, x5, [x1], #16
207− mov w9, w2
208− mov x8, x0
209− tst w9, #8
210− ld1 {v4.4s}, [x4], #16
211− fcvtzs v4.4s, v4.4s, #31
212− ld1 {v5.4s}, [x5], #16
213− fcvtzs v5.4s, v5.4s, #31
214− ld1 {v6.4s}, [x4], #16
215− fcvtzs v6.4s, v6.4s, #31
216− ld1 {v7.4s}, [x5], #16
217− fcvtzs v7.4s, v7.4s, #31
218− b.eq 6f
219− subs w9, w9, #8
220− b.eq 7f
221− sri v5.4s, v4.4s, #16
222− ld1 {v4.4s}, [x4], #16
223− fcvtzs v4.4s, v4.4s, #31
224− st1 {v5.s}[0], [x8], x12
225− sri v7.4s, v6.4s, #16
226− st1 {v5.s}[1], [x8], x12
227− ld1 {v6.4s}, [x4], #16
228− fcvtzs v6.4s, v6.4s, #31
229− st1 {v5.s}[2], [x8], x12
230− st1 {v5.s}[3], [x8], x12
231− st1 {v7.s}[0], [x8], x12
232− st1 {v7.s}[1], [x8], x12
233− ld1 {v5.4s}, [x5], #16
234− fcvtzs v5.4s, v5.4s, #31
235− st1 {v7.s}[2], [x8], x12
236− st1 {v7.s}[3], [x8], x12
237− ld1 {v7.4s}, [x5], #16
238− fcvtzs v7.4s, v7.4s, #31
239−6:
240− subs w9, w9, #16
241− ld1 {v0.4s}, [x4], #16
242− sri v5.4s, v4.4s, #16
243− fcvtzs v0.4s, v0.4s, #31
244− ld1 {v1.4s}, [x5], #16
245− sri v7.4s, v6.4s, #16
246− st1 {v5.s}[0], [x8], x12
247− st1 {v5.s}[1], [x8], x12
248− fcvtzs v1.4s, v1.4s, #31
249− st1 {v5.s}[2], [x8], x12
250− st1 {v5.s}[3], [x8], x12
251− ld1 {v2.4s}, [x4], #16
252− st1 {v7.s}[0], [x8], x12
253− fcvtzs v2.4s, v2.4s, #31
254− st1 {v7.s}[1], [x8], x12
255− ld1 {v3.4s}, [x5], #16
256− st1 {v7.s}[2], [x8], x12
257− fcvtzs v3.4s, v3.4s, #31
258− st1 {v7.s}[3], [x8], x12
259− sri v1.4s, v0.4s, #16
260− sri v3.4s, v2.4s, #16
261− b.eq 6f
262− ld1 {v4.4s}, [x4], #16
263− st1 {v1.s}[0], [x8], x12
264− fcvtzs v4.4s, v4.4s, #31
265− st1 {v1.s}[1], [x8], x12
266− ld1 {v5.4s}, [x5], #16
267− st1 {v1.s}[2], [x8], x12
268− fcvtzs v5.4s, v5.4s, #31
269− st1 {v1.s}[3], [x8], x12
270− ld1 {v6.4s}, [x4], #16
271− st1 {v3.s}[0], [x8], x12
272− fcvtzs v6.4s, v6.4s, #31
273− st1 {v3.s}[1], [x8], x12
274− ld1 {v7.4s}, [x5], #16
275− st1 {v3.s}[2], [x8], x12
276− fcvtzs v7.4s, v7.4s, #31
277− st1 {v3.s}[3], [x8], x12
278− b.gt 6b
279−6:
280− st1 {v1.s}[0], [x8], x12
281− st1 {v1.s}[1], [x8], x12
282− st1 {v1.s}[2], [x8], x12
283− st1 {v1.s}[3], [x8], x12
284− st1 {v3.s}[0], [x8], x12
285− st1 {v3.s}[1], [x8], x12
286− st1 {v3.s}[2], [x8], x12
287− st1 {v3.s}[3], [x8], x12
288− b 8f
289−7:
290− sri v5.4s, v4.4s, #16
291− sri v7.4s, v6.4s, #16
292− st1 {v5.s}[0], [x8], x12
293− st1 {v5.s}[1], [x8], x12
294− st1 {v5.s}[2], [x8], x12
295− st1 {v5.s}[3], [x8], x12
296− st1 {v7.s}[0], [x8], x12
297− st1 {v7.s}[1], [x8], x12
298− st1 {v7.s}[2], [x8], x12
299− st1 {v7.s}[3], [x8], x12
300−8:
301− subs w3, w3, #2
302− add x0, x0, #4
303− b.eq end
304−
305−4: // 1 channel
306− ldr x4, [x1]
307− tst w2, #8
308− mov w9, w2
309− mov x5, x0
310− ld1 {v0.4s}, [x4], #16
311− fcvtzs v0.4s, v0.4s, #31
312− ld1 {v1.4s}, [x4], #16
313− fcvtzs v1.4s, v1.4s, #31
314− b.ne 8f
315−6:
316− subs w9, w9, #16
317− ld1 {v2.4s}, [x4], #16
318− fcvtzs v2.4s, v2.4s, #31
319− ld1 {v3.4s}, [x4], #16
320− fcvtzs v3.4s, v3.4s, #31
321− st1 {v0.h}[1], [x5], x12
322− st1 {v0.h}[3], [x5], x12
323− st1 {v0.h}[5], [x5], x12
324− st1 {v0.h}[7], [x5], x12
325− st1 {v1.h}[1], [x5], x12
326− st1 {v1.h}[3], [x5], x12
327− st1 {v1.h}[5], [x5], x12
328− st1 {v1.h}[7], [x5], x12
329− b.eq 7f
330− ld1 {v0.4s}, [x4], #16
331− fcvtzs v0.4s, v0.4s, #31
332− ld1 {v1.4s}, [x4], #16
333− fcvtzs v1.4s, v1.4s, #31
334−7:
335− st1 {v2.h}[1], [x5], x12
336− st1 {v2.h}[3], [x5], x12
337− st1 {v2.h}[5], [x5], x12
338− st1 {v2.h}[7], [x5], x12
339− st1 {v3.h}[1], [x5], x12
340− st1 {v3.h}[3], [x5], x12
341− st1 {v3.h}[5], [x5], x12
342− st1 {v3.h}[7], [x5], x12
343− b.gt 6b
344− ret
345−8:
346− subs w9, w9, #8
347− st1 {v0.h}[1], [x5], x12
348− st1 {v0.h}[3], [x5], x12
349− st1 {v0.h}[5], [x5], x12
350− st1 {v0.h}[7], [x5], x12
351− st1 {v1.h}[1], [x5], x12
352− st1 {v1.h}[3], [x5], x12
353− st1 {v1.h}[5], [x5], x12
354− st1 {v1.h}[7], [x5], x12
355− b.eq end
356− ld1 {v0.4s}, [x4], #16
357− fcvtzs v0.4s, v0.4s, #31
358− ld1 {v1.4s}, [x4], #16
359− fcvtzs v1.4s, v1.4s, #31
360− b 6b
361−end:
362− ret
363−endfunc
libavresample/aarch64/neontest.c+0−31
@@ -1,31 +0,0 @@
1−/*
2− * check NEON registers for clobbers
3− * Copyright (c) 2013 Martin Storsjo
4− *
5− * This file is part of FFmpeg.
6− *
7− * FFmpeg is free software; you can redistribute it and/or
8− * modify it under the terms of the GNU Lesser General Public
9− * License as published by the Free Software Foundation; either
10− * version 2.1 of the License, or (at your option) any later version.
11− *
12− * FFmpeg is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15− * Lesser General Public License for more details.
16− *
17− * You should have received a copy of the GNU Lesser General Public
18− * License along with FFmpeg; if not, write to the Free Software
19− * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20− */
21−
22−#include "libavresample/avresample.h"
23−#include "libavutil/aarch64/neontest.h"
24−
25−wrap(avresample_convert(AVAudioResampleContext *avr, uint8_t **output,
26− int out_plane_size, int out_samples, uint8_t **input,
27− int in_plane_size, int in_samples))
28−{
29− testneonclobbers(avresample_convert, avr, output, out_plane_size,
30− out_samples, input, in_plane_size, in_samples);
31−}
libavresample/aarch64/resample_init.c+0−71
@@ -1,71 +0,0 @@
1−/*
2− * This file is part of FFmpeg.
3− *
4− * FFmpeg is free software; you can redistribute it and/or
5− * modify it under the terms of the GNU Lesser General Public
6− * License as published by the Free Software Foundation; either
7− * version 2.1 of the License, or (at your option) any later version.
8− *
9− * FFmpeg is distributed in the hope that it will be useful,
10− * but WITHOUT ANY WARRANTY; without even the implied warranty of
11− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12− * Lesser General Public License for more details.
13− *
14− * You should have received a copy of the GNU Lesser General Public
15− * License along with FFmpeg; if not, write to the Free Software
16− * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17− */
18−
19−#include <stdint.h>
20−
21−#include "config.h"
22−#include "libavutil/cpu.h"
23−#include "libavutil/aarch64/cpu.h"
24−#include "libavutil/internal.h"
25−#include "libavutil/samplefmt.h"
26−#include "libavresample/resample.h"
27−
28−#include "asm-offsets.h"
29−
30−AV_CHECK_OFFSET(struct ResampleContext, filter_bank, FILTER_BANK);
31−AV_CHECK_OFFSET(struct ResampleContext, filter_length, FILTER_LENGTH);
32−AV_CHECK_OFFSET(struct ResampleContext, phase_shift, PHASE_SHIFT);
33−AV_CHECK_OFFSET(struct ResampleContext, phase_mask, PHASE_MASK);
34−
35−void ff_resample_one_dbl_neon(struct ResampleContext *c, void *dst0,
36− int dst_index, const void *src0,
37− unsigned int index, int frac);
38−void ff_resample_one_flt_neon(struct ResampleContext *c, void *dst0,
39− int dst_index, const void *src0,
40− unsigned int index, int frac);
41−void ff_resample_one_s16_neon(struct ResampleContext *c, void *dst0,
42− int dst_index, const void *src0,
43− unsigned int index, int frac);
44−void ff_resample_one_s32_neon(struct ResampleContext *c, void *dst0,
45− int dst_index, const void *src0,
46− unsigned int index, int frac);
47−
48−av_cold void ff_audio_resample_init_aarch64(ResampleContext *c,
49− enum AVSampleFormat sample_fmt)
50−{
51− int cpu_flags = av_get_cpu_flags();
52−
53− if (have_neon(cpu_flags)) {
54− if (!c->linear) {
55− switch (sample_fmt) {
56− case AV_SAMPLE_FMT_DBLP:
57− c->resample_one = ff_resample_one_dbl_neon;
58− break;
59− case AV_SAMPLE_FMT_FLTP:
60− c->resample_one = ff_resample_one_flt_neon;
61− break;
62− case AV_SAMPLE_FMT_S16P:
63− c->resample_one = ff_resample_one_s16_neon;
64− break;
65− case AV_SAMPLE_FMT_S32P:
66− c->resample_one = ff_resample_one_s32_neon;
67− break;
68− }
69− }
70− }
71−}
libavresample/aarch64/resample_neon.S+0−233
@@ -1,233 +0,0 @@
1−/*
2− * Copyright (c) 2014 Janne Grunau <janne-libav@jannau.net>
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−
21−#include "libavutil/aarch64/asm.S"
22−#include "asm-offsets.h"
23−
24−.macro resample_one fmt, es=2
25−.ifnc \fmt, dbl
26− .macro M_MUL2 x:vararg
27− .endm
28− .macro M_MLA2 x:vararg
29− .endm
30−.endif
31−function ff_resample_one_\fmt\()_neon, export=1
32− sxtw x2, w2
33− ldr x9, [x0, #FILTER_BANK]
34− ldr w6, [x0, #FILTER_LENGTH]
35− ldp w7, w8, [x0, #PHASE_SHIFT] // and phase_mask
36− lsr x10, x4, x7 // sample_index
37− and x4, x4, x8
38− lsl x11, x6, #\es // filter_length * elem_size
39− add x3, x3, x10, lsl #\es // src[sample_index]
40− madd x9, x11, x4, x9 // filter
41− cmp w6, #16
42− b.lt 5f
43−8: // remaining filter_length at least 16
44− subs w6, w6, #16
45− LOAD8 v4, v5, v6, v7, x3
46− LOAD8 v16, v17, v18, v19, x9
47− M_MUL v0, v4, v16, v1
48− M_MUL2 v1, v6, v18
49−7:
50− LOAD8 v20, v21, v22, v23, x3
51− M_MLA v0, v5, v17, v1
52− M_MLA2 v1, v7, v19
53− LOAD8 v24, v25, v26, v27, x9
54− M_MLA v0, v20, v24, v1
55− M_MLA2 v1, v22, v26
56− b.eq 6f
57− cmp w6, #16
58− M_MLA v0, v21, v25, v1
59− M_MLA2 v1, v23, v27
60− b.lt 4f
61− subs w6, w6, #16
62− LOAD8 v4, v5, v6, v7, x3
63− LOAD8 v16, v17, v18, v19, x9
64− M_MLA v0, v4, v16, v1
65− M_MLA2 v1, v6, v18
66− b 7b
67−6:
68− M_MLA v0, v21, v25, v1
69− M_MLA2 v1, v23, v27
70− STORE_ONE 0, x1, x2, v1
71− ret
72−5:
73− movi v0.16b, #0
74− movi v1.16b, #0
75−4: // remaining filter_length 1-15
76− cmp w6, #4
77− b.lt 2f
78− subs w6, w6, #4
79− LOAD4 v4, v5, x3
80− LOAD4 v6, v7, x9
81− M_MLA v0, v4, v6, v1
82− M_MLA2 v1, v5, v7
83− b.eq 0f
84− b 4b
85−2: // remaining filter_length 1-3
86− cmp w6, #2
87− b.lt 1f
88− LOAD2 2, x3
89− LOAD2 3, x9
90− subs w6, w6, #2
91− M_MLA v0, v2, v3
92− b.eq 0f
93−1: // remaining filter_length 1
94− LOAD1 6, x3
95− LOAD1 7, x9
96− M_MLA v0, v6, v7
97−0:
98− STORE_ONE 0, x1, x2, v1
99− ret
100−endfunc
101−
102−.purgem LOAD1
103−.purgem LOAD2
104−.purgem LOAD4
105−.purgem LOAD8
106−.purgem M_MLA
107−.purgem M_MLA2
108−.purgem M_MUL
109−.purgem M_MUL2
110−.purgem STORE_ONE
111−.endm
112−
113−
114−.macro LOAD1 d1, addr
115− ldr d\d1, [\addr], #8
116−.endm
117−.macro LOAD2 d1, addr
118− ld1 {v\d1\().2d}, [\addr], #16
119−.endm
120−.macro LOAD4 d1, d2, addr
121− ld1 {\d1\().2d,\d2\().2d}, [\addr], #32
122−.endm
123−.macro LOAD8 d1, d2, d3, d4, addr
124− ld1 {\d1\().2d,\d2\().2d,\d3\().2d,\d4\().2d}, [\addr], #64
125−.endm
126−.macro M_MLA d, r0, r1, d2:vararg
127− fmla \d\().2d, \r0\().2d, \r1\().2d
128−.endm
129−.macro M_MLA2 second:vararg
130− M_MLA \second
131−.endm
132−.macro M_MUL d, r0, r1, d2:vararg
133− fmul \d\().2d, \r0\().2d, \r1\().2d
134−.endm
135−.macro M_MUL2 second:vararg
136− M_MUL \second
137−.endm
138−.macro STORE_ONE rn, addr, idx, d2
139− fadd v\rn\().2d, v\rn\().2d, \d2\().2d
140− faddp d\rn\(), v\rn\().2d
141− str d\rn\(), [\addr, \idx, lsl #3]
142−.endm
143−
144−resample_one dbl, 3
145−
146−
147−.macro LOAD1 d1, addr
148− ldr s\d1, [\addr], #4
149−.endm
150−.macro LOAD2 d1, addr
151− ld1 {v\d1\().2s}, [\addr], #8
152−.endm
153−.macro LOAD4 d1, d2, addr
154− ld1 {\d1\().4s}, [\addr], #16
155−.endm
156−.macro LOAD8 d1, d2, d3, d4, addr
157− ld1 {\d1\().4s,\d2\().4s}, [\addr], #32
158−.endm
159−.macro M_MLA d, r0, r1, d2:vararg
160− fmla \d\().4s, \r0\().4s, \r1\().4s
161−.endm
162−.macro M_MUL d, r0, r1, d2:vararg
163− fmul \d\().4s, \r0\().4s, \r1\().4s
164−.endm
165−.macro STORE_ONE rn, addr, idx, d2
166− faddp v\rn\().4s, v\rn\().4s, v\rn\().4s
167− faddp s\rn\(), v\rn\().2s
168− str s\rn\(), [\addr, \idx, lsl #2]
169−.endm
170−
171−resample_one flt
172−
173−
174−.macro LOAD1 d1, addr
175− ldr h\d1, [\addr], #2
176−.endm
177−.macro LOAD2 d1, addr
178− ldr s\d1, [\addr], #4
179−.endm
180−.macro LOAD4 d1, d2, addr
181− ld1 {\d1\().4h}, [\addr], #8
182−.endm
183−.macro LOAD8 d1, d2, d3, d4, addr
184− ld1 {\d1\().4h,\d2\().4h}, [\addr], #16
185−.endm
186−.macro M_MLA d, r0, r1, d2:vararg
187− smlal \d\().4s, \r0\().4h, \r1\().4h
188−.endm
189−.macro M_MUL d, r0, r1, d2:vararg
190− smull \d\().4s, \r0\().4h, \r1\().4h
191−.endm
192−.macro STORE_ONE rn, addr, idx, d2
193− addp v\rn\().4s, v\rn\().4s, v\rn\().4s
194− addp v\rn\().4s, v\rn\().4s, v\rn\().4s
195− sqrshrn v\rn\().4h, v\rn\().4s, #15
196− str h\rn\(), [\addr, \idx, lsl #1]
197−.endm
198−
199−resample_one s16, 1
200−
201−
202−.macro LOAD1 d1, addr
203− ldr s\d1, [\addr], #4
204−.endm
205−.macro LOAD2 d1, addr
206− ld1 {v\d1\().2s}, [\addr], #8
207−.endm
208−.macro LOAD4 d1, d2, addr
209− ld1 {\d1\().4s}, [\addr], #16
210−.endm
211−.macro LOAD8 d1, d2, d3, d4, addr
212− ld1 {\d1\().4s,\d2\().4s}, [\addr], #32
213−.endm
214−.macro M_MLA d1, r0, r1, d2:vararg
215− smlal \d1\().2d, \r0\().2s, \r1\().2s
216−.ifnb \d2
217− smlal2 \d2\().2d, \r0\().4s, \r1\().4s
218−.endif
219−.endm
220−.macro M_MUL d1, r0, r1, d2:vararg
221− smull \d1\().2d, \r0\().2s, \r1\().2s
222−.ifnb \d2
223− smull2 \d2\().2d, \r0\().4s, \r1\().4s
224−.endif
225−.endm
226−.macro STORE_ONE rn, addr, idx, d2
227− add v\rn\().2d, v\rn\().2d, \d2\().2d
228− addp d\rn\(), v\rn\().2d
229− sqrshrn v\rn\().2s, v\rn\().2d, #30
230− str s\rn\(), [\addr, \idx, lsl #2]
231−.endm
232−
233−resample_one s32
libavresample/arm/Makefile+0−7
@@ -1,7 +0,0 @@
1−OBJS += arm/audio_convert_init.o \
2− arm/resample_init.o
3−
4−OBJS-$(CONFIG_NEON_CLOBBER_TEST) += arm/neontest.o
5−
6−NEON-OBJS += arm/audio_convert_neon.o \
7− arm/resample_neon.o
libavresample/arm/asm-offsets.h+0−29
@@ -1,29 +0,0 @@
1−/*
2− * This file is part of FFmpeg.
3− *
4− * FFmpeg is free software; you can redistribute it and/or
5− * modify it under the terms of the GNU Lesser General Public
6− * License as published by the Free Software Foundation; either
7− * version 2.1 of the License, or (at your option) any later version.
8− *
9− * FFmpeg is distributed in the hope that it will be useful,
10− * but WITHOUT ANY WARRANTY; without even the implied warranty of
11− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12− * Lesser General Public License for more details.
13− *
14− * You should have received a copy of the GNU Lesser General Public
15− * License along with FFmpeg; if not, write to the Free Software
16− * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17− */
18−
19−#ifndef AVRESAMPLE_ARM_ASM_OFFSETS_H
20−#define AVRESAMPLE_ARM_ASM_OFFSETS_H
21−
22−/* struct ResampleContext */
23−#define FILTER_BANK 0x08
24−#define FILTER_LENGTH 0x0c
25−#define SRC_INCR 0x20
26−#define PHASE_SHIFT 0x28
27−#define PHASE_MASK (PHASE_SHIFT + 0x04)
28−
29−#endif /* AVRESAMPLE_ARM_ASM_OFFSETS_H */
libavresample/arm/audio_convert_init.c+0−49
@@ -1,49 +0,0 @@
1−/*
2− * This file is part of FFmpeg.
3− *
4− * FFmpeg is free software; you can redistribute it and/or
5− * modify it under the terms of the GNU Lesser General Public
6− * License as published by the Free Software Foundation; either
7− * version 2.1 of the License, or (at your option) any later version.
8− *
9− * FFmpeg is distributed in the hope that it will be useful,
10− * but WITHOUT ANY WARRANTY; without even the implied warranty of
11− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12− * Lesser General Public License for more details.
13− *
14− * You should have received a copy of the GNU Lesser General Public
15− * License along with FFmpeg; if not, write to the Free Software
16− * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17− */
18−
19−#include <stdint.h>
20−
21−#include "config.h"
22−#include "libavutil/attributes.h"
23−#include "libavutil/cpu.h"
24−#include "libavutil/arm/cpu.h"
25−#include "libavutil/samplefmt.h"
26−#include "libavresample/audio_convert.h"
27−
28−void ff_conv_flt_to_s16_neon(int16_t *dst, const float *src, int len);
29−void ff_conv_fltp_to_s16_neon(int16_t *dst, float *const *src,
30− int len, int channels);
31−void ff_conv_fltp_to_s16_2ch_neon(int16_t *dst, float *const *src,
32− int len, int channels);
33−
34−av_cold void ff_audio_convert_init_arm(AudioConvert *ac)
35−{
36− int cpu_flags = av_get_cpu_flags();
37−
38− if (have_neon(cpu_flags)) {
39− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT,
40− 0, 16, 8, "NEON",
41− ff_conv_flt_to_s16_neon);
42− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLTP,
43− 0, 16, 8, "NEON",
44− ff_conv_fltp_to_s16_neon);
45− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLTP,
46− 2, 16, 8, "NEON",
47− ff_conv_fltp_to_s16_2ch_neon);
48− }
49−}
libavresample/arm/audio_convert_neon.S+0−363
@@ -1,363 +0,0 @@
1−/*
2− * Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
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−
21−#include "config.h"
22−#include "libavutil/arm/asm.S"
23−
24−function ff_conv_flt_to_s16_neon, export=1
25− subs r2, r2, #8
26− vld1.32 {q0}, [r1,:128]!
27− vcvt.s32.f32 q8, q0, #31
28− vld1.32 {q1}, [r1,:128]!
29− vcvt.s32.f32 q9, q1, #31
30− beq 3f
31− bics r12, r2, #15
32− beq 2f
33−1: subs r12, r12, #16
34− vqrshrn.s32 d4, q8, #16
35− vld1.32 {q0}, [r1,:128]!
36− vcvt.s32.f32 q0, q0, #31
37− vqrshrn.s32 d5, q9, #16
38− vld1.32 {q1}, [r1,:128]!
39− vcvt.s32.f32 q1, q1, #31
40− vqrshrn.s32 d6, q0, #16
41− vst1.16 {q2}, [r0,:128]!
42− vqrshrn.s32 d7, q1, #16
43− vld1.32 {q8}, [r1,:128]!
44− vcvt.s32.f32 q8, q8, #31
45− vld1.32 {q9}, [r1,:128]!
46− vcvt.s32.f32 q9, q9, #31
47− vst1.16 {q3}, [r0,:128]!
48− bne 1b
49− ands r2, r2, #15
50− beq 3f
51−2: vld1.32 {q0}, [r1,:128]!
52− vqrshrn.s32 d4, q8, #16
53− vcvt.s32.f32 q0, q0, #31
54− vld1.32 {q1}, [r1,:128]!
55− vqrshrn.s32 d5, q9, #16
56− vcvt.s32.f32 q1, q1, #31
57− vqrshrn.s32 d6, q0, #16
58− vst1.16 {q2}, [r0,:128]!
59− vqrshrn.s32 d7, q1, #16
60− vst1.16 {q3}, [r0,:128]!
61− bx lr
62−3: vqrshrn.s32 d4, q8, #16
63− vqrshrn.s32 d5, q9, #16
64− vst1.16 {q2}, [r0,:128]!
65− bx lr
66−endfunc
67−
68−function ff_conv_fltp_to_s16_2ch_neon, export=1
69− ldm r1, {r1, r3}
70− subs r2, r2, #8
71− vld1.32 {q0}, [r1,:128]!
72− vcvt.s32.f32 q8, q0, #31
73− vld1.32 {q1}, [r1,:128]!
74− vcvt.s32.f32 q9, q1, #31
75− vld1.32 {q10}, [r3,:128]!
76− vcvt.s32.f32 q10, q10, #31
77− vld1.32 {q11}, [r3,:128]!
78− vcvt.s32.f32 q11, q11, #31
79− beq 3f
80− bics r12, r2, #15
81− beq 2f
82−1: subs r12, r12, #16
83− vld1.32 {q0}, [r1,:128]!
84− vcvt.s32.f32 q0, q0, #31
85− vsri.32 q10, q8, #16
86− vld1.32 {q1}, [r1,:128]!
87− vcvt.s32.f32 q1, q1, #31
88− vld1.32 {q12}, [r3,:128]!
89− vcvt.s32.f32 q12, q12, #31
90− vld1.32 {q13}, [r3,:128]!
91− vsri.32 q11, q9, #16
92− vst1.16 {q10}, [r0,:128]!
93− vcvt.s32.f32 q13, q13, #31
94− vst1.16 {q11}, [r0,:128]!
95− vsri.32 q12, q0, #16
96− vld1.32 {q8}, [r1,:128]!
97− vsri.32 q13, q1, #16
98− vst1.16 {q12}, [r0,:128]!
99− vcvt.s32.f32 q8, q8, #31
100− vld1.32 {q9}, [r1,:128]!
101− vcvt.s32.f32 q9, q9, #31
102− vld1.32 {q10}, [r3,:128]!
103− vcvt.s32.f32 q10, q10, #31
104− vld1.32 {q11}, [r3,:128]!
105− vcvt.s32.f32 q11, q11, #31
106− vst1.16 {q13}, [r0,:128]!
107− bne 1b
108− ands r2, r2, #15
109− beq 3f
110−2: vsri.32 q10, q8, #16
111− vld1.32 {q0}, [r1,:128]!
112− vcvt.s32.f32 q0, q0, #31
113− vld1.32 {q1}, [r1,:128]!
114− vcvt.s32.f32 q1, q1, #31
115− vld1.32 {q12}, [r3,:128]!
116− vcvt.s32.f32 q12, q12, #31
117− vsri.32 q11, q9, #16
118− vld1.32 {q13}, [r3,:128]!
119− vcvt.s32.f32 q13, q13, #31
120− vst1.16 {q10}, [r0,:128]!
121− vsri.32 q12, q0, #16
122− vst1.16 {q11}, [r0,:128]!
123− vsri.32 q13, q1, #16
124− vst1.16 {q12-q13},[r0,:128]!
125− bx lr
126−3: vsri.32 q10, q8, #16
127− vsri.32 q11, q9, #16
128− vst1.16 {q10-q11},[r0,:128]!
129− bx lr
130−endfunc
131−
132−function ff_conv_fltp_to_s16_neon, export=1
133− cmp r3, #2
134− itt lt
135− ldrlt r1, [r1]
136− blt X(ff_conv_flt_to_s16_neon)
137− beq X(ff_conv_fltp_to_s16_2ch_neon)
138−
139− push {r4-r8, lr}
140− cmp r3, #4
141− lsl r12, r3, #1
142− blt 4f
143−
144− @ 4 channels
145−5: ldm r1!, {r4-r7}
146− mov lr, r2
147− mov r8, r0
148− vld1.32 {q8}, [r4,:128]!
149− vcvt.s32.f32 q8, q8, #31
150− vld1.32 {q9}, [r5,:128]!
151− vcvt.s32.f32 q9, q9, #31
152− vld1.32 {q10}, [r6,:128]!
153− vcvt.s32.f32 q10, q10, #31
154− vld1.32 {q11}, [r7,:128]!
155− vcvt.s32.f32 q11, q11, #31
156−6: subs lr, lr, #8
157− vld1.32 {q0}, [r4,:128]!
158− vcvt.s32.f32 q0, q0, #31
159− vsri.32 q9, q8, #16
160− vld1.32 {q1}, [r5,:128]!
161− vcvt.s32.f32 q1, q1, #31
162− vsri.32 q11, q10, #16
163− vld1.32 {q2}, [r6,:128]!
164− vcvt.s32.f32 q2, q2, #31
165− vzip.32 d18, d22
166− vld1.32 {q3}, [r7,:128]!
167− vcvt.s32.f32 q3, q3, #31
168− vzip.32 d19, d23
169− vst1.16 {d18}, [r8], r12
170− vsri.32 q1, q0, #16
171− vst1.16 {d22}, [r8], r12
172− vsri.32 q3, q2, #16
173− vst1.16 {d19}, [r8], r12
174− vzip.32 d2, d6
175− vst1.16 {d23}, [r8], r12
176− vzip.32 d3, d7
177− beq 7f
178− vld1.32 {q8}, [r4,:128]!
179− vcvt.s32.f32 q8, q8, #31
180− vst1.16 {d2}, [r8], r12
181− vld1.32 {q9}, [r5,:128]!
182− vcvt.s32.f32 q9, q9, #31
183− vst1.16 {d6}, [r8], r12
184− vld1.32 {q10}, [r6,:128]!
185− vcvt.s32.f32 q10, q10, #31
186− vst1.16 {d3}, [r8], r12
187− vld1.32 {q11}, [r7,:128]!
188− vcvt.s32.f32 q11, q11, #31
189− vst1.16 {d7}, [r8], r12
190− b 6b
191−7: vst1.16 {d2}, [r8], r12
192− vst1.16 {d6}, [r8], r12
193− vst1.16 {d3}, [r8], r12
194− vst1.16 {d7}, [r8], r12
195− subs r3, r3, #4
196− it eq
197− popeq {r4-r8, pc}
198− cmp r3, #4
199− add r0, r0, #8
200− bge 5b
201−
202− @ 2 channels
203−4: cmp r3, #2
204− blt 4f
205− ldm r1!, {r4-r5}
206− mov lr, r2
207− mov r8, r0
208− tst lr, #8
209− vld1.32 {q8}, [r4,:128]!
210− vcvt.s32.f32 q8, q8, #31
211− vld1.32 {q9}, [r5,:128]!
212− vcvt.s32.f32 q9, q9, #31
213− vld1.32 {q10}, [r4,:128]!
214− vcvt.s32.f32 q10, q10, #31
215− vld1.32 {q11}, [r5,:128]!
216− vcvt.s32.f32 q11, q11, #31
217− beq 6f
218− subs lr, lr, #8
219− beq 7f
220− vsri.32 d18, d16, #16
221− vsri.32 d19, d17, #16
222− vld1.32 {q8}, [r4,:128]!
223− vcvt.s32.f32 q8, q8, #31
224− vst1.32 {d18[0]}, [r8], r12
225− vsri.32 d22, d20, #16
226− vst1.32 {d18[1]}, [r8], r12
227− vsri.32 d23, d21, #16
228− vst1.32 {d19[0]}, [r8], r12
229− vst1.32 {d19[1]}, [r8], r12
230− vld1.32 {q9}, [r5,:128]!
231− vcvt.s32.f32 q9, q9, #31
232− vst1.32 {d22[0]}, [r8], r12
233− vst1.32 {d22[1]}, [r8], r12
234− vld1.32 {q10}, [r4,:128]!
235− vcvt.s32.f32 q10, q10, #31
236− vst1.32 {d23[0]}, [r8], r12
237− vst1.32 {d23[1]}, [r8], r12
238− vld1.32 {q11}, [r5,:128]!
239− vcvt.s32.f32 q11, q11, #31
240−6: subs lr, lr, #16
241− vld1.32 {q0}, [r4,:128]!
242− vcvt.s32.f32 q0, q0, #31
243− vsri.32 d18, d16, #16
244− vld1.32 {q1}, [r5,:128]!
245− vcvt.s32.f32 q1, q1, #31
246− vsri.32 d19, d17, #16
247− vld1.32 {q2}, [r4,:128]!
248− vcvt.s32.f32 q2, q2, #31
249− vld1.32 {q3}, [r5,:128]!
250− vcvt.s32.f32 q3, q3, #31
251− vst1.32 {d18[0]}, [r8], r12
252− vsri.32 d22, d20, #16
253− vst1.32 {d18[1]}, [r8], r12
254− vsri.32 d23, d21, #16
255− vst1.32 {d19[0]}, [r8], r12
256− vsri.32 d2, d0, #16
257− vst1.32 {d19[1]}, [r8], r12
258− vsri.32 d3, d1, #16
259− vst1.32 {d22[0]}, [r8], r12
260− vsri.32 d6, d4, #16
261− vst1.32 {d22[1]}, [r8], r12
262− vsri.32 d7, d5, #16
263− vst1.32 {d23[0]}, [r8], r12
264− vst1.32 {d23[1]}, [r8], r12
265− beq 6f
266− vld1.32 {q8}, [r4,:128]!
267− vcvt.s32.f32 q8, q8, #31
268− vst1.32 {d2[0]}, [r8], r12
269− vst1.32 {d2[1]}, [r8], r12
270− vld1.32 {q9}, [r5,:128]!
271− vcvt.s32.f32 q9, q9, #31
272− vst1.32 {d3[0]}, [r8], r12
273− vst1.32 {d3[1]}, [r8], r12
274− vld1.32 {q10}, [r4,:128]!
275− vcvt.s32.f32 q10, q10, #31
276− vst1.32 {d6[0]}, [r8], r12
277− vst1.32 {d6[1]}, [r8], r12
278− vld1.32 {q11}, [r5,:128]!
279− vcvt.s32.f32 q11, q11, #31
280− vst1.32 {d7[0]}, [r8], r12
281− vst1.32 {d7[1]}, [r8], r12
282− bgt 6b
283−6: vst1.32 {d2[0]}, [r8], r12
284− vst1.32 {d2[1]}, [r8], r12
285− vst1.32 {d3[0]}, [r8], r12
286− vst1.32 {d3[1]}, [r8], r12
287− vst1.32 {d6[0]}, [r8], r12
288− vst1.32 {d6[1]}, [r8], r12
289− vst1.32 {d7[0]}, [r8], r12
290− vst1.32 {d7[1]}, [r8], r12
291− b 8f
292−7: vsri.32 d18, d16, #16
293− vsri.32 d19, d17, #16
294− vst1.32 {d18[0]}, [r8], r12
295− vsri.32 d22, d20, #16
296− vst1.32 {d18[1]}, [r8], r12
297− vsri.32 d23, d21, #16
298− vst1.32 {d19[0]}, [r8], r12
299− vst1.32 {d19[1]}, [r8], r12
300− vst1.32 {d22[0]}, [r8], r12
301− vst1.32 {d22[1]}, [r8], r12
302− vst1.32 {d23[0]}, [r8], r12
303− vst1.32 {d23[1]}, [r8], r12
304−8: subs r3, r3, #2
305− add r0, r0, #4
306− it eq
307− popeq {r4-r8, pc}
308−
309− @ 1 channel
310−4: ldr r4, [r1]
311− tst r2, #8
312− mov lr, r2
313− mov r5, r0
314− vld1.32 {q0}, [r4,:128]!
315− vcvt.s32.f32 q0, q0, #31
316− vld1.32 {q1}, [r4,:128]!
317− vcvt.s32.f32 q1, q1, #31
318− bne 8f
319−6: subs lr, lr, #16
320− vld1.32 {q2}, [r4,:128]!
321− vcvt.s32.f32 q2, q2, #31
322− vld1.32 {q3}, [r4,:128]!
323− vcvt.s32.f32 q3, q3, #31
324− vst1.16 {d0[1]}, [r5,:16], r12
325− vst1.16 {d0[3]}, [r5,:16], r12
326− vst1.16 {d1[1]}, [r5,:16], r12
327− vst1.16 {d1[3]}, [r5,:16], r12
328− vst1.16 {d2[1]}, [r5,:16], r12
329− vst1.16 {d2[3]}, [r5,:16], r12
330− vst1.16 {d3[1]}, [r5,:16], r12
331− vst1.16 {d3[3]}, [r5,:16], r12
332− beq 7f
333− vld1.32 {q0}, [r4,:128]!
334− vcvt.s32.f32 q0, q0, #31
335− vld1.32 {q1}, [r4,:128]!
336− vcvt.s32.f32 q1, q1, #31
337−7: vst1.16 {d4[1]}, [r5,:16], r12
338− vst1.16 {d4[3]}, [r5,:16], r12
339− vst1.16 {d5[1]}, [r5,:16], r12
340− vst1.16 {d5[3]}, [r5,:16], r12
341− vst1.16 {d6[1]}, [r5,:16], r12
342− vst1.16 {d6[3]}, [r5,:16], r12
343− vst1.16 {d7[1]}, [r5,:16], r12
344− vst1.16 {d7[3]}, [r5,:16], r12
345− bgt 6b
346− pop {r4-r8, pc}
347−8: subs lr, lr, #8
348− vst1.16 {d0[1]}, [r5,:16], r12
349− vst1.16 {d0[3]}, [r5,:16], r12
350− vst1.16 {d1[1]}, [r5,:16], r12
351− vst1.16 {d1[3]}, [r5,:16], r12
352− vst1.16 {d2[1]}, [r5,:16], r12
353− vst1.16 {d2[3]}, [r5,:16], r12
354− vst1.16 {d3[1]}, [r5,:16], r12
355− vst1.16 {d3[3]}, [r5,:16], r12
356− it eq
357− popeq {r4-r8, pc}
358− vld1.32 {q0}, [r4,:128]!
359− vcvt.s32.f32 q0, q0, #31
360− vld1.32 {q1}, [r4,:128]!
361− vcvt.s32.f32 q1, q1, #31
362− b 6b
363−endfunc
libavresample/arm/neontest.c+0−31
@@ -1,31 +0,0 @@
1−/*
2− * check NEON registers for clobbers
3− * Copyright (c) 2013 Martin Storsjo
4− *
5− * This file is part of FFmpeg.
6− *
7− * FFmpeg is free software; you can redistribute it and/or
8− * modify it under the terms of the GNU Lesser General Public
9− * License as published by the Free Software Foundation; either
10− * version 2.1 of the License, or (at your option) any later version.
11− *
12− * FFmpeg is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15− * Lesser General Public License for more details.
16− *
17− * You should have received a copy of the GNU Lesser General Public
18− * License along with FFmpeg; if not, write to the Free Software
19− * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20− */
21−
22−#include "libavresample/avresample.h"
23−#include "libavutil/arm/neontest.h"
24−
25−wrap(avresample_convert(AVAudioResampleContext *avr, uint8_t **output,
26− int out_plane_size, int out_samples, uint8_t **input,
27− int in_plane_size, int in_samples))
28−{
29− testneonclobbers(avresample_convert, avr, output, out_plane_size,
30− out_samples, input, in_plane_size, in_samples);
31−}
libavresample/arm/resample_init.c+0−74
@@ -1,74 +0,0 @@
1−/*
2− * Copyright (c) 2014 Peter Meerwald <pmeerw@pmeerw.net>
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−
21−#include "config.h"
22−
23−#include "libavutil/cpu.h"
24−#include "libavutil/arm/cpu.h"
25−#include "libavutil/internal.h"
26−#include "libavutil/samplefmt.h"
27−
28−#include "libavresample/resample.h"
29−
30−#include "asm-offsets.h"
31−
32−AV_CHECK_OFFSET(struct ResampleContext, filter_bank, FILTER_BANK);
33−AV_CHECK_OFFSET(struct ResampleContext, filter_length, FILTER_LENGTH);
34−AV_CHECK_OFFSET(struct ResampleContext, src_incr, SRC_INCR);
35−AV_CHECK_OFFSET(struct ResampleContext, phase_shift, PHASE_SHIFT);
36−AV_CHECK_OFFSET(struct ResampleContext, phase_mask, PHASE_MASK);
37−
38−void ff_resample_one_flt_neon(struct ResampleContext *c, void *dst0,
39− int dst_index, const void *src0,
40− unsigned int index, int frac);
41−void ff_resample_one_s16_neon(struct ResampleContext *c, void *dst0,
42− int dst_index, const void *src0,
43− unsigned int index, int frac);
44−void ff_resample_one_s32_neon(struct ResampleContext *c, void *dst0,
45− int dst_index, const void *src0,
46− unsigned int index, int frac);
47−
48−void ff_resample_linear_flt_neon(struct ResampleContext *c, void *dst0,
49− int dst_index, const void *src0,
50− unsigned int index, int frac);
51−
52−av_cold void ff_audio_resample_init_arm(ResampleContext *c,
53− enum AVSampleFormat sample_fmt)
54−{
55− int cpu_flags = av_get_cpu_flags();
56− if (have_neon(cpu_flags)) {
57− switch (sample_fmt) {
58− case AV_SAMPLE_FMT_FLTP:
59− if (c->linear)
60− c->resample_one = ff_resample_linear_flt_neon;
61− else
62− c->resample_one = ff_resample_one_flt_neon;
63− break;
64− case AV_SAMPLE_FMT_S16P:
65− if (!c->linear)
66− c->resample_one = ff_resample_one_s16_neon;
67− break;
68− case AV_SAMPLE_FMT_S32P:
69− if (!c->linear)
70− c->resample_one = ff_resample_one_s32_neon;
71− break;
72− }
73− }
74−}
libavresample/arm/resample_neon.S+0−358
@@ -1,358 +0,0 @@
1−/*
2− * Copyright (c) 2014 Peter Meerwald <pmeerw@pmeerw.net>
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−
21−#include "libavutil/arm/asm.S"
22−
23−#include "asm-offsets.h"
24−
25−.macro resample_one fmt, es=2
26−function ff_resample_one_\fmt\()_neon, export=1
27− push {r4, r5}
28− add r1, r1, r2, lsl #\es
29−
30− ldr r2, [r0, #PHASE_SHIFT+4] /* phase_mask */
31− ldr ip, [sp, #8] /* index */
32− ldr r5, [r0, #FILTER_LENGTH]
33− and r2, ip, r2 /* (index & phase_mask) */
34− ldr r4, [r0, #PHASE_SHIFT]
35− lsr r4, ip, r4 /* compute sample_index */
36− mul r2, r2, r5
37−
38− ldr ip, [r0, #FILTER_BANK]
39− add r3, r3, r4, lsl #\es /* &src[sample_index] */
40−
41− cmp r5, #8
42− add r0, ip, r2, lsl #\es /* filter = &filter_bank[...] */
43−
44− blt 5f
45−8:
46− subs r5, r5, #8
47− LOAD4
48− MUL4
49−7:
50− LOAD4
51− beq 6f
52− cmp r5, #8
53− MLA4
54− blt 4f
55− subs r5, r5, #8
56− LOAD4
57− MLA4
58− b 7b
59−6:
60− MLA4
61− STORE
62− pop {r4, r5}
63− bx lr
64−5:
65− INIT4
66−4: /* remaining filter_length 1 to 7 */
67− cmp r5, #4
68− blt 2f
69− subs r5, r5, #4
70− LOAD4
71− MLA4
72− beq 0f
73−2: /* remaining filter_length 1 to 3 */
74− cmp r5, #2
75− blt 1f
76− subs r5, r5, #2
77− LOAD2
78− MLA2
79− beq 0f
80−1: /* remaining filter_length 1 */
81− LOAD1
82− MLA1
83−0:
84− STORE
85− pop {r4, r5}
86− bx lr
87−endfunc
88−
89−.purgem LOAD1
90−.purgem LOAD2
91−.purgem LOAD4
92−.purgem MLA1
93−.purgem MLA2
94−.purgem MLA4
95−.purgem MUL4
96−.purgem INIT4
97−.purgem STORE
98−.endm
99−
100−
101−/* float32 */
102−.macro LOAD1
103− veor.32 d0, d0
104− vld1.32 {d0[0]}, [r0]! /* load filter */
105− vld1.32 {d4[0]}, [r3]! /* load src */
106−.endm
107−.macro LOAD2
108− vld1.32 {d0}, [r0]! /* load filter */
109− vld1.32 {d4}, [r3]! /* load src */
110−.endm
111−.macro LOAD4
112− vld1.32 {d0,d1}, [r0]! /* load filter */
113− vld1.32 {d4,d5}, [r3]! /* load src */
114−.endm
115−.macro MLA1
116− vmla.f32 d16, d0, d4[0]
117−.endm
118−.macro MLA2
119− vmla.f32 d16, d0, d4
120−.endm
121−.macro MLA4
122− vmla.f32 d16, d0, d4
123− vmla.f32 d17, d1, d5
124−.endm
125−.macro MUL4
126− vmul.f32 d16, d0, d4
127− vmul.f32 d17, d1, d5
128−.endm
129−.macro INIT4
130− veor.f32 q8, q8
131−.endm
132−.macro STORE
133− vpadd.f32 d16, d16, d17
134− vpadd.f32 d16, d16, d16
135− vst1.32 d16[0], [r1]
136−.endm
137−
138−resample_one flt, 2
139−
140−
141−/* s32 */
142−.macro LOAD1
143− veor.32 d0, d0
144− vld1.32 {d0[0]}, [r0]! /* load filter */
145− vld1.32 {d4[0]}, [r3]! /* load src */
146−.endm
147−.macro LOAD2
148− vld1.32 {d0}, [r0]! /* load filter */
149− vld1.32 {d4}, [r3]! /* load src */
150−.endm
151−.macro LOAD4
152− vld1.32 {d0,d1}, [r0]! /* load filter */
153− vld1.32 {d4,d5}, [r3]! /* load src */
154−.endm
155−.macro MLA1
156− vmlal.s32 q8, d0, d4[0]
157−.endm
158−.macro MLA2
159− vmlal.s32 q8, d0, d4
160−.endm
161−.macro MLA4
162− vmlal.s32 q8, d0, d4
163− vmlal.s32 q9, d1, d5
164−.endm
165−.macro MUL4
166− vmull.s32 q8, d0, d4
167− vmull.s32 q9, d1, d5
168−.endm
169−.macro INIT4
170− veor.s64 q8, q8
171− veor.s64 q9, q9
172−.endm
173−.macro STORE
174− vadd.s64 q8, q8, q9
175− vadd.s64 d16, d16, d17
176− vqrshrn.s64 d16, q8, #30
177− vst1.32 d16[0], [r1]
178−.endm
179−
180−resample_one s32, 2
181−
182−
183−/* s16 */
184−.macro LOAD1
185− veor.16 d0, d0
186− vld1.16 {d0[0]}, [r0]! /* load filter */
187− vld1.16 {d4[0]}, [r3]! /* load src */
188−.endm
189−.macro LOAD2
190− veor.16 d0, d0
191− vld1.32 {d0[0]}, [r0]! /* load filter */
192− veor.16 d4, d4
193− vld1.32 {d4[0]}, [r3]! /* load src */
194−.endm
195−.macro LOAD4
196− vld1.16 {d0}, [r0]! /* load filter */
197− vld1.16 {d4}, [r3]! /* load src */
198−.endm
199−.macro MLA1
200− vmlal.s16 q8, d0, d4[0]
201−.endm
202−.macro MLA2
203− vmlal.s16 q8, d0, d4
204−.endm
205−.macro MLA4
206− vmlal.s16 q8, d0, d4
207−.endm
208−.macro MUL4
209− vmull.s16 q8, d0, d4
210−.endm
211−.macro INIT4
212− veor.s32 q8, q8
213−.endm
214−.macro STORE
215− vpadd.s32 d16, d16, d17
216− vpadd.s32 d16, d16, d16
217− vqrshrn.s32 d16, q8, #15
218− vst1.16 d16[0], [r1]
219−.endm
220−
221−resample_one s16, 1
222−
223−
224−.macro resample_linear fmt, es=2
225−function ff_resample_linear_\fmt\()_neon, export=1
226− push {r4, r5}
227− add r1, r1, r2, lsl #\es
228−
229− ldr r2, [r0, #PHASE_SHIFT+4] /* phase_mask */
230− ldr ip, [sp, #8] /* index */
231− ldr r5, [r0, #FILTER_LENGTH]
232− and r2, ip, r2 /* (index & phase_mask) */
233− ldr r4, [r0, #PHASE_SHIFT]
234− lsr r4, ip, r4 /* compute sample_index */
235− mul r2, r2, r5
236−
237− ldr ip, [r0, #FILTER_BANK]
238− add r3, r3, r4, lsl #\es /* &src[sample_index] */
239−
240− cmp r5, #8
241− ldr r4, [r0, #SRC_INCR]
242− add r0, ip, r2, lsl #\es /* filter = &filter_bank[...] */
243− add r2, r0, r5, lsl #\es /* filter[... + c->filter_length] */
244−
245− blt 5f
246−8:
247− subs r5, r5, #8
248− LOAD4
249− MUL4
250−7:
251− LOAD4
252− beq 6f
253− cmp r5, #8
254− MLA4
255− blt 4f
256− subs r5, r5, #8
257− LOAD4
258− MLA4
259− b 7b
260−6:
261− MLA4
262− STORE
263− pop {r4, r5}
264− bx lr
265−5:
266− INIT4
267−4: /* remaining filter_length 1 to 7 */
268− cmp r5, #4
269− blt 2f
270− subs r5, r5, #4
271− LOAD4
272− MLA4
273− beq 0f
274−2: /* remaining filter_length 1 to 3 */
275− cmp r5, #2
276− blt 1f
277− subs r5, r5, #2
278− LOAD2
279− MLA2
280− beq 0f
281−1: /* remaining filter_length 1 */
282− LOAD1
283− MLA1
284−0:
285− STORE
286− pop {r4, r5}
287− bx lr
288−endfunc
289−
290−.purgem LOAD1
291−.purgem LOAD2
292−.purgem LOAD4
293−.purgem MLA1
294−.purgem MLA2
295−.purgem MLA4
296−.purgem MUL4
297−.purgem INIT4
298−.purgem STORE
299−.endm
300−
301−
302−/* float32 linear */
303−.macro LOAD1
304− veor.32 d0, d0
305− veor.32 d2, d2
306− vld1.32 {d0[0]}, [r0]! /* load filter */
307− vld1.32 {d2[0]}, [r2]! /* load filter */
308− vld1.32 {d4[0]}, [r3]! /* load src */
309−.endm
310−.macro LOAD2
311− vld1.32 {d0}, [r0]! /* load filter */
312− vld1.32 {d2}, [r2]! /* load filter */
313− vld1.32 {d4}, [r3]! /* load src */
314−.endm
315−.macro LOAD4
316− vld1.32 {d0,d1}, [r0]! /* load filter */
317− vld1.32 {d2,d3}, [r2]! /* load filter */
318− vld1.32 {d4,d5}, [r3]! /* load src */
319−.endm
320−.macro MLA1
321− vmla.f32 d18, d0, d4[0]
322− vmla.f32 d16, d2, d4[0]
323−.endm
324−.macro MLA2
325− vmla.f32 d18, d0, d4
326− vmla.f32 d16, d2, d4
327−.endm
328−.macro MLA4
329− vmla.f32 q9, q0, q2
330− vmla.f32 q8, q1, q2
331−.endm
332−.macro MUL4
333− vmul.f32 q9, q0, q2
334− vmul.f32 q8, q1, q2
335−.endm
336−.macro INIT4
337− veor.f32 q9, q9
338− veor.f32 q8, q8
339−.endm
340−.macro STORE
341− vldr s0, [sp, #12] /* frac */
342− vmov s1, r4
343− vcvt.f32.s32 d0, d0
344−
345− vsub.f32 q8, q8, q9 /* v2 - val */
346− vpadd.f32 d18, d18, d19
347− vpadd.f32 d16, d16, d17
348− vpadd.f32 d2, d18, d18
349− vpadd.f32 d1, d16, d16
350−
351− vmul.f32 s2, s2, s0 /* (v2 - val) * frac */
352− vdiv.f32 s2, s2, s1 /* / c->src_incr */
353− vadd.f32 s4, s4, s2
354−
355− vstr s4, [r1]
356−.endm
357−
358−resample_linear flt, 2
libavresample/audio_convert.c+0−416
@@ -1,416 +0,0 @@
1−/*
2− * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
3− * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
4− *
5− * This file is part of FFmpeg.
6− *
7− * FFmpeg is free software; you can redistribute it and/or
8− * modify it under the terms of the GNU Lesser General Public
9− * License as published by the Free Software Foundation; either
10− * version 2.1 of the License, or (at your option) any later version.
11− *
12− * FFmpeg is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15− * Lesser General Public License for more details.
16− *
17− * You should have received a copy of the GNU Lesser General Public
18− * License along with FFmpeg; if not, write to the Free Software
19− * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20− */
21−
22−#include <stdint.h>
23−
24−#include "config.h"
25−#include "libavutil/common.h"
26−#include "libavutil/libm.h"
27−#include "libavutil/log.h"
28−#include "libavutil/mem.h"
29−#include "libavutil/samplefmt.h"
30−#include "audio_convert.h"
31−#include "audio_data.h"
32−#include "dither.h"
33−
34−enum ConvFuncType {
35− CONV_FUNC_TYPE_FLAT,
36− CONV_FUNC_TYPE_INTERLEAVE,
37− CONV_FUNC_TYPE_DEINTERLEAVE,
38−};
39−
40−typedef void (conv_func_flat)(uint8_t *out, const uint8_t *in, int len);
41−
42−typedef void (conv_func_interleave)(uint8_t *out, uint8_t *const *in,
43− int len, int channels);
44−
45−typedef void (conv_func_deinterleave)(uint8_t **out, const uint8_t *in, int len,
46− int channels);
47−
48−struct AudioConvert {
49− AVAudioResampleContext *avr;
50− DitherContext *dc;
51− enum AVSampleFormat in_fmt;
52− enum AVSampleFormat out_fmt;
53− int apply_map;
54− int channels;
55− int planes;
56− int ptr_align;
57− int samples_align;
58− int has_optimized_func;
59− const char *func_descr;
60− const char *func_descr_generic;
61− enum ConvFuncType func_type;
62− conv_func_flat *conv_flat;
63− conv_func_flat *conv_flat_generic;
64− conv_func_interleave *conv_interleave;
65− conv_func_interleave *conv_interleave_generic;
66− conv_func_deinterleave *conv_deinterleave;
67− conv_func_deinterleave *conv_deinterleave_generic;
68−};
69−
70−void ff_audio_convert_set_func(AudioConvert *ac, enum AVSampleFormat out_fmt,
71− enum AVSampleFormat in_fmt, int channels,
72− int ptr_align, int samples_align,
73− const char *descr, void *conv)
74−{
75− int found = 0;
76−
77− switch (ac->func_type) {
78− case CONV_FUNC_TYPE_FLAT:
79− if (av_get_packed_sample_fmt(ac->in_fmt) == in_fmt &&
80− av_get_packed_sample_fmt(ac->out_fmt) == out_fmt) {
81− ac->conv_flat = conv;
82− ac->func_descr = descr;
83− ac->ptr_align = ptr_align;
84− ac->samples_align = samples_align;
85− if (ptr_align == 1 && samples_align == 1) {
86− ac->conv_flat_generic = conv;
87− ac->func_descr_generic = descr;
88− } else {
89− ac->has_optimized_func = 1;
90− }
91− found = 1;
92− }
93− break;
94− case CONV_FUNC_TYPE_INTERLEAVE:
95− if (ac->in_fmt == in_fmt && ac->out_fmt == out_fmt &&
96− (!channels || ac->channels == channels)) {
97− ac->conv_interleave = conv;
98− ac->func_descr = descr;
99− ac->ptr_align = ptr_align;
100− ac->samples_align = samples_align;
101− if (ptr_align == 1 && samples_align == 1) {
102− ac->conv_interleave_generic = conv;
103− ac->func_descr_generic = descr;
104− } else {
105− ac->has_optimized_func = 1;
106− }
107− found = 1;
108− }
109− break;
110− case CONV_FUNC_TYPE_DEINTERLEAVE:
111− if (ac->in_fmt == in_fmt && ac->out_fmt == out_fmt &&
112− (!channels || ac->channels == channels)) {
113− ac->conv_deinterleave = conv;
114− ac->func_descr = descr;
115− ac->ptr_align = ptr_align;
116− ac->samples_align = samples_align;
117− if (ptr_align == 1 && samples_align == 1) {
118− ac->conv_deinterleave_generic = conv;
119− ac->func_descr_generic = descr;
120− } else {
121− ac->has_optimized_func = 1;
122− }
123− found = 1;
124− }
125− break;
126− }
127− if (found) {
128− av_log(ac->avr, AV_LOG_DEBUG, "audio_convert: found function: %-4s "
129− "to %-4s (%s)\n", av_get_sample_fmt_name(ac->in_fmt),
130− av_get_sample_fmt_name(ac->out_fmt), descr);
131− }
132−}
133−
134−#define CONV_FUNC_NAME(dst_fmt, src_fmt) conv_ ## src_fmt ## _to_ ## dst_fmt
135−
136−#define CONV_LOOP(otype, expr) \
137− do { \
138− *(otype *)po = expr; \
139− pi += is; \
140− po += os; \
141− } while (po < end); \
142−
143−#define CONV_FUNC_FLAT(ofmt, otype, ifmt, itype, expr) \
144−static void CONV_FUNC_NAME(ofmt, ifmt)(uint8_t *out, const uint8_t *in, \
145− int len) \
146−{ \
147− int is = sizeof(itype); \
148− int os = sizeof(otype); \
149− const uint8_t *pi = in; \
150− uint8_t *po = out; \
151− uint8_t *end = out + os * len; \
152− CONV_LOOP(otype, expr) \
153−}
154−
155−#define CONV_FUNC_INTERLEAVE(ofmt, otype, ifmt, itype, expr) \
156−static void CONV_FUNC_NAME(ofmt, ifmt)(uint8_t *out, const uint8_t **in, \
157− int len, int channels) \
158−{ \
159− int ch; \
160− int out_bps = sizeof(otype); \
161− int is = sizeof(itype); \
162− int os = channels * out_bps; \
163− for (ch = 0; ch < channels; ch++) { \
164− const uint8_t *pi = in[ch]; \
165− uint8_t *po = out + ch * out_bps; \
166− uint8_t *end = po + os * len; \
167− CONV_LOOP(otype, expr) \
168− } \
169−}
170−
171−#define CONV_FUNC_DEINTERLEAVE(ofmt, otype, ifmt, itype, expr) \
172−static void CONV_FUNC_NAME(ofmt, ifmt)(uint8_t **out, const uint8_t *in, \
173− int len, int channels) \
174−{ \
175− int ch; \
176− int in_bps = sizeof(itype); \
177− int is = channels * in_bps; \
178− int os = sizeof(otype); \
179− for (ch = 0; ch < channels; ch++) { \
180− const uint8_t *pi = in + ch * in_bps; \
181− uint8_t *po = out[ch]; \
182− uint8_t *end = po + os * len; \
183− CONV_LOOP(otype, expr) \
184− } \
185−}
186−
187−#define CONV_FUNC_GROUP(ofmt, otype, ifmt, itype, expr) \
188−CONV_FUNC_FLAT( ofmt, otype, ifmt, itype, expr) \
189−CONV_FUNC_INTERLEAVE( ofmt, otype, ifmt ## P, itype, expr) \
190−CONV_FUNC_DEINTERLEAVE(ofmt ## P, otype, ifmt, itype, expr)
191−
192−CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_U8, uint8_t, *(const uint8_t *)pi)
193−CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_U8, uint8_t, (*(const uint8_t *)pi - 0x80) << 8)
194−CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_U8, uint8_t, (*(const uint8_t *)pi - 0x80) << 24)
195−CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t, (*(const uint8_t *)pi - 0x80) * (1.0f / (1 << 7)))
196−CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t, (*(const uint8_t *)pi - 0x80) * (1.0 / (1 << 7)))
197−CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t, (*(const int16_t *)pi >> 8) + 0x80)
198−CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *)pi)
199−CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *)pi << 16)
200−CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *)pi * (1.0f / (1 << 15)))
201−CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *)pi * (1.0 / (1 << 15)))
202−CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t, (*(const int32_t *)pi >> 24) + 0x80)
203−CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *)pi >> 16)
204−CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *)pi)
205−CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *)pi * (1.0f / (1U << 31)))
206−CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *)pi * (1.0 / (1U << 31)))
207−CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8( lrintf(*(const float *)pi * (1 << 7)) + 0x80))
208−CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16( lrintf(*(const float *)pi * (1 << 15))))
209−CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *)pi * (1U << 31))))
210−CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_FLT, float, *(const float *)pi)
211−CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_FLT, float, *(const float *)pi)
212−CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8( lrint(*(const double *)pi * (1 << 7)) + 0x80))
213−CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16( lrint(*(const double *)pi * (1 << 15))))
214−CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *)pi * (1U << 31))))
215−CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_DBL, double, *(const double *)pi)
216−CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_DBL, double, *(const double *)pi)
217−
218−#define SET_CONV_FUNC_GROUP(ofmt, ifmt) \
219−ff_audio_convert_set_func(ac, ofmt, ifmt, 0, 1, 1, "C", CONV_FUNC_NAME(ofmt, ifmt)); \
220−ff_audio_convert_set_func(ac, ofmt ## P, ifmt, 0, 1, 1, "C", CONV_FUNC_NAME(ofmt ## P, ifmt)); \
221−ff_audio_convert_set_func(ac, ofmt, ifmt ## P, 0, 1, 1, "C", CONV_FUNC_NAME(ofmt, ifmt ## P));
222−
223−static void set_generic_function(AudioConvert *ac)
224−{
225− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8)
226− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8)
227− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8)
228− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8)
229− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8)
230− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16)
231− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16)
232− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16)
233− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16)
234− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16)
235− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32)
236− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32)
237− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32)
238− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32)
239− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32)
240− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT)
241− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT)
242− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT)
243− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT)
244− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT)
245− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL)
246− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL)
247− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL)
248− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL)
249− SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL)
250−}
251−
252−void ff_audio_convert_free(AudioConvert **ac)
253−{
254− if (!*ac)
255− return;
256− ff_dither_free(&(*ac)->dc);
257− av_freep(ac);
258−}
259−
260−AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr,
261− enum AVSampleFormat out_fmt,
262− enum AVSampleFormat in_fmt,
263− int channels, int sample_rate,
264− int apply_map)
265−{
266− AudioConvert *ac;
267− int in_planar, out_planar;
268−
269− ac = av_mallocz(sizeof(*ac));
270− if (!ac)
271− return NULL;
272−
273− ac->avr = avr;
274− ac->out_fmt = out_fmt;
275− ac->in_fmt = in_fmt;
276− ac->channels = channels;
277− ac->apply_map = apply_map;
278−
279− if (avr->dither_method != AV_RESAMPLE_DITHER_NONE &&
280− av_get_packed_sample_fmt(out_fmt) == AV_SAMPLE_FMT_S16 &&
281− av_get_bytes_per_sample(in_fmt) > 2) {
282− ac->dc = ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate,
283− apply_map);
284− if (!ac->dc) {
285− av_free(ac);
286− return NULL;
287− }
288− return ac;
289− }
290−
291− in_planar = ff_sample_fmt_is_planar(in_fmt, channels);
292− out_planar = ff_sample_fmt_is_planar(out_fmt, channels);
293−
294− if (in_planar == out_planar) {
295− ac->func_type = CONV_FUNC_TYPE_FLAT;
296− ac->planes = in_planar ? ac->channels : 1;
297− } else if (in_planar)
298− ac->func_type = CONV_FUNC_TYPE_INTERLEAVE;
299− else
300− ac->func_type = CONV_FUNC_TYPE_DEINTERLEAVE;
301−
302− set_generic_function(ac);
303−
304− if (ARCH_AARCH64)
305− ff_audio_convert_init_aarch64(ac);
306− if (ARCH_ARM)
307− ff_audio_convert_init_arm(ac);
308− if (ARCH_X86)
309− ff_audio_convert_init_x86(ac);
310−
311− return ac;
312−}
313−
314−int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in)
315−{
316− int use_generic = 1;
317− int len = in->nb_samples;
318− int p;
319−
320− if (ac->dc) {
321− /* dithered conversion */
322− av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n",
323− len, av_get_sample_fmt_name(ac->in_fmt),
324− av_get_sample_fmt_name(ac->out_fmt));
325−
326− return ff_convert_dither(ac->dc, out, in);
327− }
328−
329− /* determine whether to use the optimized function based on pointer and
330− samples alignment in both the input and output */
331− if (ac->has_optimized_func) {
332− int ptr_align = FFMIN(in->ptr_align, out->ptr_align);
333− int samples_align = FFMIN(in->samples_align, out->samples_align);
334− int aligned_len = FFALIGN(len, ac->samples_align);
335− if (!(ptr_align % ac->ptr_align) && samples_align >= aligned_len) {
336− len = aligned_len;
337− use_generic = 0;
338− }
339− }
340− av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (%s)\n", len,
341− av_get_sample_fmt_name(ac->in_fmt),
342− av_get_sample_fmt_name(ac->out_fmt),
343− use_generic ? ac->func_descr_generic : ac->func_descr);
344−
345− if (ac->apply_map) {
346− ChannelMapInfo *map = &ac->avr->ch_map_info;
347−
348− if (!ff_sample_fmt_is_planar(ac->out_fmt, ac->channels)) {
349− av_log(ac->avr, AV_LOG_ERROR, "cannot remap packed format during conversion\n");
350− return AVERROR(EINVAL);
351− }
352−
353− if (map->do_remap) {
354− if (ff_sample_fmt_is_planar(ac->in_fmt, ac->channels)) {
355− conv_func_flat *convert = use_generic ? ac->conv_flat_generic :
356− ac->conv_flat;
357−
358− for (p = 0; p < ac->planes; p++)
359− if (map->channel_map[p] >= 0)
360− convert(out->data[p], in->data[map->channel_map[p]], len);
361− } else {
362− uint8_t *data[AVRESAMPLE_MAX_CHANNELS];
363− conv_func_deinterleave *convert = use_generic ?
364− ac->conv_deinterleave_generic :
365− ac->conv_deinterleave;
366−
367− for (p = 0; p < ac->channels; p++)
368− data[map->input_map[p]] = out->data[p];
369−
370− convert(data, in->data[0], len, ac->channels);
371− }
372− }
373− if (map->do_copy || map->do_zero) {
374− for (p = 0; p < ac->planes; p++) {
375− if (map->channel_copy[p])
376− memcpy(out->data[p], out->data[map->channel_copy[p]],
377− len * out->stride);
378− else if (map->channel_zero[p])
379− av_samples_set_silence(&out->data[p], 0, len, 1, ac->out_fmt);
380− }
381− }
382− } else {
383− switch (ac->func_type) {
384− case CONV_FUNC_TYPE_FLAT: {
385− if (!in->is_planar)
386− len *= in->channels;
387− if (use_generic) {
388− for (p = 0; p < ac->planes; p++)
389− ac->conv_flat_generic(out->data[p], in->data[p], len);
390− } else {
391− for (p = 0; p < ac->planes; p++)
392− ac->conv_flat(out->data[p], in->data[p], len);
393− }
394− break;
395− }
396− case CONV_FUNC_TYPE_INTERLEAVE:
397− if (use_generic)
398− ac->conv_interleave_generic(out->data[0], in->data, len,
399− ac->channels);
400− else
401− ac->conv_interleave(out->data[0], in->data, len, ac->channels);
402− break;
403− case CONV_FUNC_TYPE_DEINTERLEAVE:
404− if (use_generic)
405− ac->conv_deinterleave_generic(out->data, in->data[0], len,
406− ac->channels);
407− else
408− ac->conv_deinterleave(out->data, in->data[0], len,
409− ac->channels);
410− break;
411− }
412− }
413−
414− out->nb_samples = in->nb_samples;
415− return 0;
416−}
libavresample/audio_convert.h+0−103
@@ -1,103 +0,0 @@
1−/*
2− * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
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−
21−#ifndef AVRESAMPLE_AUDIO_CONVERT_H
22−#define AVRESAMPLE_AUDIO_CONVERT_H
23−
24−#include "libavutil/samplefmt.h"
25−#include "avresample.h"
26−#include "internal.h"
27−#include "audio_data.h"
28−
29−/**
30− * Set conversion function if the parameters match.
31− *
32− * This compares the parameters of the conversion function to the parameters
33− * in the AudioConvert context. If the parameters do not match, no changes are
34− * made to the active functions. If the parameters do match and the alignment
35− * is not constrained, the function is set as the generic conversion function.
36− * If the parameters match and the alignment is constrained, the function is
37− * set as the optimized conversion function.
38− *
39− * @param ac AudioConvert context
40− * @param out_fmt output sample format
41− * @param in_fmt input sample format
42− * @param channels number of channels, or 0 for any number of channels
43− * @param ptr_align buffer pointer alignment, in bytes
44− * @param samples_align buffer size alignment, in samples
45− * @param descr function type description (e.g. "C" or "SSE")
46− * @param conv conversion function pointer
47− */
48−void ff_audio_convert_set_func(AudioConvert *ac, enum AVSampleFormat out_fmt,
49− enum AVSampleFormat in_fmt, int channels,
50− int ptr_align, int samples_align,
51− const char *descr, void *conv);
52−
53−/**
54− * Allocate and initialize AudioConvert context for sample format conversion.
55− *
56− * @param avr AVAudioResampleContext
57− * @param out_fmt output sample format
58− * @param in_fmt input sample format
59− * @param channels number of channels
60− * @param sample_rate sample rate (used for dithering)
61− * @param apply_map apply channel map during conversion
62− * @return newly-allocated AudioConvert context
63− */
64−AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr,
65− enum AVSampleFormat out_fmt,
66− enum AVSampleFormat in_fmt,
67− int channels, int sample_rate,
68− int apply_map);
69−
70−/**
71− * Free AudioConvert.
72− *
73− * The AudioConvert must have been previously allocated with ff_audio_convert_alloc().
74− *
75− * @param ac AudioConvert struct
76− */
77−void ff_audio_convert_free(AudioConvert **ac);
78−
79−/**
80− * Convert audio data from one sample format to another.
81− *
82− * For each call, the alignment of the input and output AudioData buffers are
83− * examined to determine whether to use the generic or optimized conversion
84− * function (when available).
85− *
86− * The number of samples to convert is determined by in->nb_samples. The output
87− * buffer must be large enough to handle this many samples. out->nb_samples is
88− * set by this function before a successful return.
89− *
90− * @param ac AudioConvert context
91− * @param out output audio data
92− * @param in input audio data
93− * @return 0 on success, negative AVERROR code on failure
94− */
95−int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in);
96−
97−/* arch-specific initialization functions */
98−
99−void ff_audio_convert_init_aarch64(AudioConvert *ac);
100−void ff_audio_convert_init_arm(AudioConvert *ac);
101−void ff_audio_convert_init_x86(AudioConvert *ac);
102−
103−#endif /* AVRESAMPLE_AUDIO_CONVERT_H */
libavresample/audio_data.c+0−381
@@ -1,381 +0,0 @@
1−/*
2− * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
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−
21−#include <stdint.h>
22−#include <string.h>
23−
24−#include "libavutil/mem.h"
25−#include "audio_data.h"
26−
27−static const AVClass audio_data_class = {
28− .class_name = "AudioData",
29− .item_name = av_default_item_name,
30− .version = LIBAVUTIL_VERSION_INT,
31−};
32−
33−/*
34− * Calculate alignment for data pointers.
35− */
36−static void calc_ptr_alignment(AudioData *a)
37−{
38− int p;
39− int min_align = 128;
40−
41− for (p = 0; p < a->planes; p++) {
42− int cur_align = 128;
43− while ((intptr_t)a->data[p] % cur_align)
44− cur_align >>= 1;
45− if (cur_align < min_align)
46− min_align = cur_align;
47− }
48− a->ptr_align = min_align;
49−}
50−
51−int ff_sample_fmt_is_planar(enum AVSampleFormat sample_fmt, int channels)
52−{
53− if (channels == 1)
54− return 1;
55− else
56− return av_sample_fmt_is_planar(sample_fmt);
57−}
58−
59−int ff_audio_data_set_channels(AudioData *a, int channels)
60−{
61− if (channels < 1 || channels > AVRESAMPLE_MAX_CHANNELS ||
62− channels > a->allocated_channels)
63− return AVERROR(EINVAL);
64−
65− a->channels = channels;
66− a->planes = a->is_planar ? channels : 1;
67−
68− calc_ptr_alignment(a);
69−
70− return 0;
71−}
72−
73−int ff_audio_data_init(AudioData *a, uint8_t * const *src, int plane_size,
74− int channels, int nb_samples,
75− enum AVSampleFormat sample_fmt, int read_only,
76− const char *name)
77−{
78− int p;
79−
80− memset(a, 0, sizeof(*a));
81− a->class = &audio_data_class;
82−
83− if (channels < 1 || channels > AVRESAMPLE_MAX_CHANNELS) {
84− av_log(a, AV_LOG_ERROR, "invalid channel count: %d\n", channels);
85− return AVERROR(EINVAL);
86− }
87−
88− a->sample_size = av_get_bytes_per_sample(sample_fmt);
89− if (!a->sample_size) {
90− av_log(a, AV_LOG_ERROR, "invalid sample format\n");
91− return AVERROR(EINVAL);
92− }
93− a->is_planar = ff_sample_fmt_is_planar(sample_fmt, channels);
94− a->planes = a->is_planar ? channels : 1;
95− a->stride = a->sample_size * (a->is_planar ? 1 : channels);
96−
97− for (p = 0; p < (a->is_planar ? channels : 1); p++) {
98− if (!src[p]) {
99− av_log(a, AV_LOG_ERROR, "invalid NULL pointer for src[%d]\n", p);
100− return AVERROR(EINVAL);
101− }
102− a->data[p] = src[p];
103− }
104− a->allocated_samples = nb_samples * !read_only;
105− a->nb_samples = nb_samples;
106− a->sample_fmt = sample_fmt;
107− a->channels = channels;
108− a->allocated_channels = channels;
109− a->read_only = read_only;
110− a->allow_realloc = 0;
111− a->name = name ? name : "{no name}";
112−
113− calc_ptr_alignment(a);
114− a->samples_align = plane_size / a->stride;
115−
116− return 0;
117−}
118−
119−AudioData *ff_audio_data_alloc(int channels, int nb_samples,
120− enum AVSampleFormat sample_fmt, const char *name)
121−{
122− AudioData *a;
123− int ret;
124−
125− if (channels < 1 || channels > AVRESAMPLE_MAX_CHANNELS)
126− return NULL;
127−
128− a = av_mallocz(sizeof(*a));
129− if (!a)
130− return NULL;
131−
132− a->sample_size = av_get_bytes_per_sample(sample_fmt);
133− if (!a->sample_size) {
134− av_free(a);
135− return NULL;
136− }
137− a->is_planar = ff_sample_fmt_is_planar(sample_fmt, channels);
138− a->planes = a->is_planar ? channels : 1;
139− a->stride = a->sample_size * (a->is_planar ? 1 : channels);
140−
141− a->class = &audio_data_class;
142− a->sample_fmt = sample_fmt;
143− a->channels = channels;
144− a->allocated_channels = channels;
145− a->read_only = 0;
146− a->allow_realloc = 1;
147− a->name = name ? name : "{no name}";
148−
149− if (nb_samples > 0) {
150− ret = ff_audio_data_realloc(a, nb_samples);
151− if (ret < 0) {
152− av_free(a);
153− return NULL;
154− }
155− return a;
156− } else {
157− calc_ptr_alignment(a);
158− return a;
159− }
160−}
161−
162−int ff_audio_data_realloc(AudioData *a, int nb_samples)
163−{
164− int ret, new_buf_size, plane_size, p;
165−
166− /* check if buffer is already large enough */
167− if (a->allocated_samples >= nb_samples)
168− return 0;
169−
170− /* validate that the output is not read-only and realloc is allowed */
171− if (a->read_only || !a->allow_realloc)
172− return AVERROR(EINVAL);
173−
174− new_buf_size = av_samples_get_buffer_size(&plane_size,
175− a->allocated_channels, nb_samples,
176− a->sample_fmt, 0);
177− if (new_buf_size < 0)
178− return new_buf_size;
179−
180− /* if there is already data in the buffer and the sample format is planar,
181− allocate a new buffer and copy the data, otherwise just realloc the
182− internal buffer and set new data pointers */
183− if (a->nb_samples > 0 && a->is_planar) {
184− uint8_t *new_data[AVRESAMPLE_MAX_CHANNELS] = { NULL };
185−
186− ret = av_samples_alloc(new_data, &plane_size, a->allocated_channels,
187− nb_samples, a->sample_fmt, 0);
188− if (ret < 0)
189− return ret;
190−
191− for (p = 0; p < a->planes; p++)
192− memcpy(new_data[p], a->data[p], a->nb_samples * a->stride);
193−
194− av_freep(&a->buffer);
195− memcpy(a->data, new_data, sizeof(new_data));
196− a->buffer = a->data[0];
197− } else {
198− av_freep(&a->buffer);
199− a->buffer = av_malloc(new_buf_size);
200− if (!a->buffer)
201− return AVERROR(ENOMEM);
202− ret = av_samples_fill_arrays(a->data, &plane_size, a->buffer,
203− a->allocated_channels, nb_samples,
204− a->sample_fmt, 0);
205− if (ret < 0)
206− return ret;
207− }
208− a->buffer_size = new_buf_size;
209− a->allocated_samples = nb_samples;
210−
211− calc_ptr_alignment(a);
212− a->samples_align = plane_size / a->stride;
213−
214− return 0;
215−}
216−
217−void ff_audio_data_free(AudioData **a)
218−{
219− if (!*a)
220− return;
221− av_free((*a)->buffer);
222− av_freep(a);
223−}
224−
225−int ff_audio_data_copy(AudioData *dst, AudioData *src, ChannelMapInfo *map)
226−{
227− int ret, p;
228−
229− /* validate input/output compatibility */
230− if (dst->sample_fmt != src->sample_fmt || dst->channels < src->channels)
231− return AVERROR(EINVAL);
232−
233− if (map && !src->is_planar) {
234− av_log(src, AV_LOG_ERROR, "cannot remap packed format during copy\n");
235− return AVERROR(EINVAL);
236− }
237−
238− /* if the input is empty, just empty the output */
239− if (!src->nb_samples) {
240− dst->nb_samples = 0;
241− return 0;
242− }
243−
244− /* reallocate output if necessary */
245− ret = ff_audio_data_realloc(dst, src->nb_samples);
246− if (ret < 0)
247− return ret;
248−
249− /* copy data */
250− if (map) {
251− if (map->do_remap) {
252− for (p = 0; p < src->planes; p++) {
253− if (map->channel_map[p] >= 0)
254− memcpy(dst->data[p], src->data[map->channel_map[p]],
255− src->nb_samples * src->stride);
256− }
257− }
258− if (map->do_copy || map->do_zero) {
259− for (p = 0; p < src->planes; p++) {
260− if (map->channel_copy[p])
261− memcpy(dst->data[p], dst->data[map->channel_copy[p]],
262− src->nb_samples * src->stride);
263− else if (map->channel_zero[p])
264− av_samples_set_silence(&dst->data[p], 0, src->nb_samples,
265− 1, dst->sample_fmt);
266− }
267− }
268− } else {
269− for (p = 0; p < src->planes; p++)
270− memcpy(dst->data[p], src->data[p], src->nb_samples * src->stride);
271− }
272−
273− dst->nb_samples = src->nb_samples;
274−
275− return 0;
276−}
277−
278−int ff_audio_data_combine(AudioData *dst, int dst_offset, AudioData *src,
279− int src_offset, int nb_samples)
280−{
281− int ret, p, dst_offset2, dst_move_size;
282−
283− /* validate input/output compatibility */
284− if (dst->sample_fmt != src->sample_fmt || dst->channels != src->channels) {
285− av_log(src, AV_LOG_ERROR, "sample format mismatch\n");
286− return AVERROR(EINVAL);
287− }
288−
289− /* validate offsets are within the buffer bounds */
290− if (dst_offset < 0 || dst_offset > dst->nb_samples ||
291− src_offset < 0 || src_offset > src->nb_samples) {
292− av_log(src, AV_LOG_ERROR, "offset out-of-bounds: src=%d dst=%d\n",
293− src_offset, dst_offset);
294− return AVERROR(EINVAL);
295− }
296−
297− /* check offsets and sizes to see if we can just do nothing and return */
298− if (nb_samples > src->nb_samples - src_offset)
299− nb_samples = src->nb_samples - src_offset;
300− if (nb_samples <= 0)
301− return 0;
302−
303− /* validate that the output is not read-only */
304− if (dst->read_only) {
305− av_log(dst, AV_LOG_ERROR, "dst is read-only\n");
306− return AVERROR(EINVAL);
307− }
308−
309− /* reallocate output if necessary */
310− ret = ff_audio_data_realloc(dst, dst->nb_samples + nb_samples);
311− if (ret < 0) {
312− av_log(dst, AV_LOG_ERROR, "error reallocating dst\n");
313− return ret;
314− }
315−
316− dst_offset2 = dst_offset + nb_samples;
317− dst_move_size = dst->nb_samples - dst_offset;
318−
319− for (p = 0; p < src->planes; p++) {
320− if (dst_move_size > 0) {
321− memmove(dst->data[p] + dst_offset2 * dst->stride,
322− dst->data[p] + dst_offset * dst->stride,
323− dst_move_size * dst->stride);
324− }
325− memcpy(dst->data[p] + dst_offset * dst->stride,
326− src->data[p] + src_offset * src->stride,
327− nb_samples * src->stride);
328− }
329− dst->nb_samples += nb_samples;
330−
331− return 0;
332−}
333−
334−void ff_audio_data_drain(AudioData *a, int nb_samples)
335−{
336− if (a->nb_samples <= nb_samples) {
337− /* drain the whole buffer */
338− a->nb_samples = 0;
339− } else {
340− int p;
341− int move_offset = a->stride * nb_samples;
342− int move_size = a->stride * (a->nb_samples - nb_samples);
343−
344− for (p = 0; p < a->planes; p++)
345− memmove(a->data[p], a->data[p] + move_offset, move_size);
346−
347− a->nb_samples -= nb_samples;
348− }
349−}
350−
351−int ff_audio_data_add_to_fifo(AVAudioFifo *af, AudioData *a, int offset,
352− int nb_samples)
353−{
354− uint8_t *offset_data[AVRESAMPLE_MAX_CHANNELS];
355− int offset_size, p;
356−
357− if (offset >= a->nb_samples)
358− return 0;
359− offset_size = offset * a->stride;
360− for (p = 0; p < a->planes; p++)
361− offset_data[p] = a->data[p] + offset_size;
362−
363− return av_audio_fifo_write(af, (void **)offset_data, nb_samples);
364−}
365−
366−int ff_audio_data_read_from_fifo(AVAudioFifo *af, AudioData *a, int nb_samples)
367−{
368− int ret;
369−
370− if (a->read_only)
371− return AVERROR(EINVAL);
372−
373− ret = ff_audio_data_realloc(a, nb_samples);
374− if (ret < 0)
375− return ret;
376−
377− ret = av_audio_fifo_read(af, (void **)a->data, nb_samples);
378− if (ret >= 0)
379− a->nb_samples = ret;
380− return ret;
381−}
libavresample/audio_data.h+0−178
@@ -1,178 +0,0 @@
1−/*
2− * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
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−
21−#ifndef AVRESAMPLE_AUDIO_DATA_H
22−#define AVRESAMPLE_AUDIO_DATA_H
23−
24−#include <stdint.h>
25−
26−#include "libavutil/audio_fifo.h"
27−#include "libavutil/log.h"
28−#include "libavutil/samplefmt.h"
29−#include "avresample.h"
30−#include "internal.h"
31−
32−int ff_sample_fmt_is_planar(enum AVSampleFormat sample_fmt, int channels);
33−
34−/**
35− * Audio buffer used for intermediate storage between conversion phases.
36− */
37−struct AudioData {
38− const AVClass *class; /**< AVClass for logging */
39− uint8_t *data[AVRESAMPLE_MAX_CHANNELS]; /**< data plane pointers */
40− uint8_t *buffer; /**< data buffer */
41− unsigned int buffer_size; /**< allocated buffer size */
42− int allocated_samples; /**< number of samples the buffer can hold */
43− int nb_samples; /**< current number of samples */
44− enum AVSampleFormat sample_fmt; /**< sample format */
45− int channels; /**< channel count */
46− int allocated_channels; /**< allocated channel count */
47− int is_planar; /**< sample format is planar */
48− int planes; /**< number of data planes */
49− int sample_size; /**< bytes per sample */
50− int stride; /**< sample byte offset within a plane */
51− int read_only; /**< data is read-only */
52− int allow_realloc; /**< realloc is allowed */
53− int ptr_align; /**< minimum data pointer alignment */
54− int samples_align; /**< allocated samples alignment */
55− const char *name; /**< name for debug logging */
56−};
57−
58−int ff_audio_data_set_channels(AudioData *a, int channels);
59−
60−/**
61− * Initialize AudioData using a given source.
62− *
63− * This does not allocate an internal buffer. It only sets the data pointers
64− * and audio parameters.
65− *
66− * @param a AudioData struct
67− * @param src source data pointers
68− * @param plane_size plane size, in bytes.
69− * This can be 0 if unknown, but that will lead to
70− * optimized functions not being used in many cases,
71− * which could slow down some conversions.
72− * @param channels channel count
73− * @param nb_samples number of samples in the source data
74− * @param sample_fmt sample format
75− * @param read_only indicates if buffer is read only or read/write
76− * @param name name for debug logging (can be NULL)
77− * @return 0 on success, negative AVERROR value on error
78− */
79−int ff_audio_data_init(AudioData *a, uint8_t * const *src, int plane_size,
80− int channels, int nb_samples,
81− enum AVSampleFormat sample_fmt, int read_only,
82− const char *name);
83−
84−/**
85− * Allocate AudioData.
86− *
87− * This allocates an internal buffer and sets audio parameters.
88− *
89− * @param channels channel count
90− * @param nb_samples number of samples to allocate space for
91− * @param sample_fmt sample format
92− * @param name name for debug logging (can be NULL)
93− * @return newly allocated AudioData struct, or NULL on error
94− */
95−AudioData *ff_audio_data_alloc(int channels, int nb_samples,
96− enum AVSampleFormat sample_fmt,
97− const char *name);
98−
99−/**
100− * Reallocate AudioData.
101− *
102− * The AudioData must have been previously allocated with ff_audio_data_alloc().
103− *
104− * @param a AudioData struct
105− * @param nb_samples number of samples to allocate space for
106− * @return 0 on success, negative AVERROR value on error
107− */
108−int ff_audio_data_realloc(AudioData *a, int nb_samples);
109−
110−/**
111− * Free AudioData.
112− *
113− * The AudioData must have been previously allocated with ff_audio_data_alloc().
114− *
115− * @param a AudioData struct
116− */
117−void ff_audio_data_free(AudioData **a);
118−
119−/**
120− * Copy data from one AudioData to another.
121− *
122− * @param out output AudioData
123− * @param in input AudioData
124− * @param map channel map, NULL if not remapping
125− * @return 0 on success, negative AVERROR value on error
126− */
127−int ff_audio_data_copy(AudioData *out, AudioData *in, ChannelMapInfo *map);
128−
129−/**
130− * Append data from one AudioData to the end of another.
131− *
132− * @param dst destination AudioData
133− * @param dst_offset offset, in samples, to start writing, relative to the
134− * start of dst
135− * @param src source AudioData
136− * @param src_offset offset, in samples, to start copying, relative to the
137− * start of the src
138− * @param nb_samples number of samples to copy
139− * @return 0 on success, negative AVERROR value on error
140− */
141−int ff_audio_data_combine(AudioData *dst, int dst_offset, AudioData *src,
142− int src_offset, int nb_samples);
143−
144−/**
145− * Drain samples from the start of the AudioData.
146− *
147− * Remaining samples are shifted to the start of the AudioData.
148− *
149− * @param a AudioData struct
150− * @param nb_samples number of samples to drain
151− */
152−void ff_audio_data_drain(AudioData *a, int nb_samples);
153−
154−/**
155− * Add samples in AudioData to an AVAudioFifo.
156− *
157− * @param af Audio FIFO Buffer
158− * @param a AudioData struct
159− * @param offset number of samples to skip from the start of the data
160− * @param nb_samples number of samples to add to the FIFO
161− * @return number of samples actually added to the FIFO, or
162− * negative AVERROR code on error
163− */
164−int ff_audio_data_add_to_fifo(AVAudioFifo *af, AudioData *a, int offset,
165− int nb_samples);
166−
167−/**
168− * Read samples from an AVAudioFifo to AudioData.
169− *
170− * @param af Audio FIFO Buffer
171− * @param a AudioData struct
172− * @param nb_samples number of samples to read from the FIFO
173− * @return number of samples actually read from the FIFO, or
174− * negative AVERROR code on error
175− */
176−int ff_audio_data_read_from_fifo(AVAudioFifo *af, AudioData *a, int nb_samples);
177−
178−#endif /* AVRESAMPLE_AUDIO_DATA_H */
libavresample/audio_mix.c+0−742
@@ -1,742 +0,0 @@
1−/*
2− * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
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−
21−#include <stdint.h>
22−
23−#include "libavutil/common.h"
24−#include "libavutil/libm.h"
25−#include "libavutil/samplefmt.h"
26−#include "avresample.h"
27−#include "internal.h"
28−#include "audio_data.h"
29−#include "audio_mix.h"
30−
31−static const char * const coeff_type_names[] = { "q8", "q15", "flt" };
32−
33−struct AudioMix {
34− AVAudioResampleContext *avr;
35− enum AVSampleFormat fmt;
36− enum AVMixCoeffType coeff_type;
37− uint64_t in_layout;
38− uint64_t out_layout;
39− int in_channels;
40− int out_channels;
41−
42− int ptr_align;
43− int samples_align;
44− int has_optimized_func;
45− const char *func_descr;
46− const char *func_descr_generic;
47− mix_func *mix;
48− mix_func *mix_generic;
49−
50− int in_matrix_channels;
51− int out_matrix_channels;
52− int output_zero[AVRESAMPLE_MAX_CHANNELS];
53− int input_skip[AVRESAMPLE_MAX_CHANNELS];
54− int output_skip[AVRESAMPLE_MAX_CHANNELS];
55− int16_t *matrix_q8[AVRESAMPLE_MAX_CHANNELS];
56− int32_t *matrix_q15[AVRESAMPLE_MAX_CHANNELS];
57− float *matrix_flt[AVRESAMPLE_MAX_CHANNELS];
58− void **matrix;
59−};
60−
61−void ff_audio_mix_set_func(AudioMix *am, enum AVSampleFormat fmt,
62− enum AVMixCoeffType coeff_type, int in_channels,
63− int out_channels, int ptr_align, int samples_align,
64− const char *descr, void *mix_func)
65−{
66− if (fmt == am->fmt && coeff_type == am->coeff_type &&
67− ( in_channels == am->in_matrix_channels || in_channels == 0) &&
68− (out_channels == am->out_matrix_channels || out_channels == 0)) {
69− char chan_str[16];
70− am->mix = mix_func;
71− am->func_descr = descr;
72− am->ptr_align = ptr_align;
73− am->samples_align = samples_align;
74− if (ptr_align == 1 && samples_align == 1) {
75− am->mix_generic = mix_func;
76− am->func_descr_generic = descr;
77− } else {
78− am->has_optimized_func = 1;
79− }
80− if (in_channels) {
81− if (out_channels)
82− snprintf(chan_str, sizeof(chan_str), "[%d to %d] ",
83− in_channels, out_channels);
84− else
85− snprintf(chan_str, sizeof(chan_str), "[%d to any] ",
86− in_channels);
87− } else if (out_channels) {
88− snprintf(chan_str, sizeof(chan_str), "[any to %d] ",
89− out_channels);
90− } else {
91− snprintf(chan_str, sizeof(chan_str), "[any to any] ");
92− }
93− av_log(am->avr, AV_LOG_DEBUG, "audio_mix: found function: [fmt=%s] "
94− "[c=%s] %s(%s)\n", av_get_sample_fmt_name(fmt),
95− coeff_type_names[coeff_type], chan_str, descr);
96− }
97−}
98−
99−#define MIX_FUNC_NAME(fmt, cfmt) mix_any_ ## fmt ##_## cfmt ##_c
100−
101−#define MIX_FUNC_GENERIC(fmt, cfmt, stype, ctype, sumtype, expr) \
102−static void MIX_FUNC_NAME(fmt, cfmt)(stype **samples, ctype **matrix, \
103− int len, int out_ch, int in_ch) \
104−{ \
105− int i, in, out; \
106− stype temp[AVRESAMPLE_MAX_CHANNELS]; \
107− for (i = 0; i < len; i++) { \
108− for (out = 0; out < out_ch; out++) { \
109− sumtype sum = 0; \
110− for (in = 0; in < in_ch; in++) \
111− sum += samples[in][i] * matrix[out][in]; \
112− temp[out] = expr; \
113− } \
114− for (out = 0; out < out_ch; out++) \
115− samples[out][i] = temp[out]; \
116− } \
117−}
118−
119−MIX_FUNC_GENERIC(FLTP, FLT, float, float, float, sum)
120−MIX_FUNC_GENERIC(S16P, FLT, int16_t, float, float, av_clip_int16(lrintf(sum)))
121−MIX_FUNC_GENERIC(S16P, Q15, int16_t, int32_t, int64_t, av_clip_int16(sum >> 15))
122−MIX_FUNC_GENERIC(S16P, Q8, int16_t, int16_t, int32_t, av_clip_int16(sum >> 8))
123−
124−/* TODO: templatize the channel-specific C functions */
125−
126−static void mix_2_to_1_fltp_flt_c(float **samples, float **matrix, int len,
127− int out_ch, int in_ch)
128−{
129− float *src0 = samples[0];
130− float *src1 = samples[1];
131− float *dst = src0;
132− float m0 = matrix[0][0];
133− float m1 = matrix[0][1];
134−
135− while (len > 4) {
136− *dst++ = *src0++ * m0 + *src1++ * m1;
137− *dst++ = *src0++ * m0 + *src1++ * m1;
138− *dst++ = *src0++ * m0 + *src1++ * m1;
139− *dst++ = *src0++ * m0 + *src1++ * m1;
140− len -= 4;
141− }
142− while (len > 0) {
143− *dst++ = *src0++ * m0 + *src1++ * m1;
144− len--;
145− }
146−}
147−
148−static void mix_2_to_1_s16p_flt_c(int16_t **samples, float **matrix, int len,
149− int out_ch, int in_ch)
150−{
151− int16_t *src0 = samples[0];
152− int16_t *src1 = samples[1];
153− int16_t *dst = src0;
154− float m0 = matrix[0][0];
155− float m1 = matrix[0][1];
156−
157− while (len > 4) {
158− *dst++ = av_clip_int16(lrintf(*src0++ * m0 + *src1++ * m1));
159− *dst++ = av_clip_int16(lrintf(*src0++ * m0 + *src1++ * m1));
160− *dst++ = av_clip_int16(lrintf(*src0++ * m0 + *src1++ * m1));
161− *dst++ = av_clip_int16(lrintf(*src0++ * m0 + *src1++ * m1));
162− len -= 4;
163− }
164− while (len > 0) {
165− *dst++ = av_clip_int16(lrintf(*src0++ * m0 + *src1++ * m1));
166− len--;
167− }
168−}
169−
170−static void mix_2_to_1_s16p_q8_c(int16_t **samples, int16_t **matrix, int len,
171− int out_ch, int in_ch)
172−{
173− int16_t *src0 = samples[0];
174− int16_t *src1 = samples[1];
175− int16_t *dst = src0;
176− int16_t m0 = matrix[0][0];
177− int16_t m1 = matrix[0][1];
178−
179− while (len > 4) {
180− *dst++ = (*src0++ * m0 + *src1++ * m1) >> 8;
181− *dst++ = (*src0++ * m0 + *src1++ * m1) >> 8;
182− *dst++ = (*src0++ * m0 + *src1++ * m1) >> 8;
183− *dst++ = (*src0++ * m0 + *src1++ * m1) >> 8;
184− len -= 4;
185− }
186− while (len > 0) {
187− *dst++ = (*src0++ * m0 + *src1++ * m1) >> 8;
188− len--;
189− }
190−}
191−
192−static void mix_1_to_2_fltp_flt_c(float **samples, float **matrix, int len,
193− int out_ch, int in_ch)
194−{
195− float v;
196− float *dst0 = samples[0];
197− float *dst1 = samples[1];
198− float *src = dst0;
199− float m0 = matrix[0][0];
200− float m1 = matrix[1][0];
201−
202− while (len > 4) {
203− v = *src++;
204− *dst0++ = v * m0;
205− *dst1++ = v * m1;
206− v = *src++;
207− *dst0++ = v * m0;
208− *dst1++ = v * m1;
209− v = *src++;
210− *dst0++ = v * m0;
211− *dst1++ = v * m1;
212− v = *src++;
213− *dst0++ = v * m0;
214− *dst1++ = v * m1;
215− len -= 4;
216− }
217− while (len > 0) {
218− v = *src++;
219− *dst0++ = v * m0;
220− *dst1++ = v * m1;
221− len--;
222− }
223−}
224−
225−static void mix_6_to_2_fltp_flt_c(float **samples, float **matrix, int len,
226− int out_ch, int in_ch)
227−{
228− float v0, v1;
229− float *src0 = samples[0];
230− float *src1 = samples[1];
231− float *src2 = samples[2];
232− float *src3 = samples[3];
233− float *src4 = samples[4];
234− float *src5 = samples[5];
235− float *dst0 = src0;
236− float *dst1 = src1;
237− float *m0 = matrix[0];
238− float *m1 = matrix[1];
239−
240− while (len > 0) {
241− v0 = *src0++;
242− v1 = *src1++;
243− *dst0++ = v0 * m0[0] +
244− v1 * m0[1] +
245− *src2 * m0[2] +
246− *src3 * m0[3] +
247− *src4 * m0[4] +
248− *src5 * m0[5];
249− *dst1++ = v0 * m1[0] +
250− v1 * m1[1] +
251− *src2++ * m1[2] +
252− *src3++ * m1[3] +
253− *src4++ * m1[4] +
254− *src5++ * m1[5];
255− len--;
256− }
257−}
258−
259−static void mix_2_to_6_fltp_flt_c(float **samples, float **matrix, int len,
260− int out_ch, int in_ch)
261−{
262− float v0, v1;
263− float *dst0 = samples[0];
264− float *dst1 = samples[1];
265− float *dst2 = samples[2];
266− float *dst3 = samples[3];
267− float *dst4 = samples[4];
268− float *dst5 = samples[5];
269− float *src0 = dst0;
270− float *src1 = dst1;
271−
272− while (len > 0) {
273− v0 = *src0++;
274− v1 = *src1++;
275− *dst0++ = v0 * matrix[0][0] + v1 * matrix[0][1];
276− *dst1++ = v0 * matrix[1][0] + v1 * matrix[1][1];
277− *dst2++ = v0 * matrix[2][0] + v1 * matrix[2][1];
278− *dst3++ = v0 * matrix[3][0] + v1 * matrix[3][1];
279− *dst4++ = v0 * matrix[4][0] + v1 * matrix[4][1];
280− *dst5++ = v0 * matrix[5][0] + v1 * matrix[5][1];
281− len--;
282− }
283−}
284−
285−static av_cold int mix_function_init(AudioMix *am)
286−{
287− am->func_descr = am->func_descr_generic = "n/a";
288− am->mix = am->mix_generic = NULL;
289−
290− /* no need to set a mix function when we're skipping mixing */
291− if (!am->in_matrix_channels || !am->out_matrix_channels)
292− return 0;
293−
294− /* any-to-any C versions */
295−
296− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
297− 0, 0, 1, 1, "C", MIX_FUNC_NAME(FLTP, FLT));
298−
299− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
300− 0, 0, 1, 1, "C", MIX_FUNC_NAME(S16P, FLT));
301−
302− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_Q15,
303− 0, 0, 1, 1, "C", MIX_FUNC_NAME(S16P, Q15));
304−
305− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_Q8,
306− 0, 0, 1, 1, "C", MIX_FUNC_NAME(S16P, Q8));
307−
308− /* channel-specific C versions */
309−
310− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
311− 2, 1, 1, 1, "C", mix_2_to_1_fltp_flt_c);
312−
313− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
314− 2, 1, 1, 1, "C", mix_2_to_1_s16p_flt_c);
315−
316− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_Q8,
317− 2, 1, 1, 1, "C", mix_2_to_1_s16p_q8_c);
318−
319− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
320− 1, 2, 1, 1, "C", mix_1_to_2_fltp_flt_c);
321−
322− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
323− 6, 2, 1, 1, "C", mix_6_to_2_fltp_flt_c);
324−
325− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
326− 2, 6, 1, 1, "C", mix_2_to_6_fltp_flt_c);
327−
328− if (ARCH_X86)
329− ff_audio_mix_init_x86(am);
330−
331− if (!am->mix) {
332− av_log(am->avr, AV_LOG_ERROR, "audio_mix: NO FUNCTION FOUND: [fmt=%s] "
333− "[c=%s] [%d to %d]\n", av_get_sample_fmt_name(am->fmt),
334− coeff_type_names[am->coeff_type], am->in_channels,
335− am->out_channels);
336− return AVERROR_PATCHWELCOME;
337− }
338− return 0;
339−}
340−
341−AudioMix *ff_audio_mix_alloc(AVAudioResampleContext *avr)
342−{
343− AudioMix *am;
344− int ret;
345−
346− am = av_mallocz(sizeof(*am));
347− if (!am)
348− return NULL;
349− am->avr = avr;
350−
351− if (avr->internal_sample_fmt != AV_SAMPLE_FMT_S16P &&
352− avr->internal_sample_fmt != AV_SAMPLE_FMT_FLTP) {
353− av_log(avr, AV_LOG_ERROR, "Unsupported internal format for "
354− "mixing: %s\n",
355− av_get_sample_fmt_name(avr->internal_sample_fmt));
356− goto error;
357− }
358−
359− am->fmt = avr->internal_sample_fmt;
360− am->coeff_type = avr->mix_coeff_type;
361− am->in_layout = avr->in_channel_layout;
362− am->out_layout = avr->out_channel_layout;
363− am->in_channels = avr->in_channels;
364− am->out_channels = avr->out_channels;
365−
366− /* build matrix if the user did not already set one */
367− if (avr->mix_matrix) {
368− ret = ff_audio_mix_set_matrix(am, avr->mix_matrix, avr->in_channels);
369− if (ret < 0)
370− goto error;
371− av_freep(&avr->mix_matrix);
372− } else {
373− double *matrix_dbl = av_mallocz(avr->out_channels * avr->in_channels *
374− sizeof(*matrix_dbl));
375− if (!matrix_dbl)
376− goto error;
377−
378− ret = avresample_build_matrix(avr->in_channel_layout,
379− avr->out_channel_layout,
380− avr->center_mix_level,
381− avr->surround_mix_level,
382− avr->lfe_mix_level,
383− avr->normalize_mix_level,
384− matrix_dbl,
385− avr->in_channels,
386− avr->matrix_encoding);
387− if (ret < 0) {
388− av_free(matrix_dbl);
389− goto error;
390− }
391−
392− ret = ff_audio_mix_set_matrix(am, matrix_dbl, avr->in_channels);
393− if (ret < 0) {
394− av_log(avr, AV_LOG_ERROR, "error setting mix matrix\n");
395− av_free(matrix_dbl);
396− goto error;
397− }
398−
399− av_free(matrix_dbl);
400− }
401−
402− return am;
403−
404−error:
405− av_free(am);
406− return NULL;
407−}
408−
409−void ff_audio_mix_free(AudioMix **am_p)
410−{
411− AudioMix *am;
412−
413− if (!*am_p)
414− return;
415− am = *am_p;
416−
417− if (am->matrix) {
418− av_free(am->matrix[0]);
419− am->matrix = NULL;
420− }
421− memset(am->matrix_q8, 0, sizeof(am->matrix_q8 ));
422− memset(am->matrix_q15, 0, sizeof(am->matrix_q15));
423− memset(am->matrix_flt, 0, sizeof(am->matrix_flt));
424−
425− av_freep(am_p);
426−}
427−
428−int ff_audio_mix(AudioMix *am, AudioData *src)
429−{
430− int use_generic = 1;
431− int len = src->nb_samples;
432− int i, j;
433−
434− /* determine whether to use the optimized function based on pointer and
435− samples alignment in both the input and output */
436− if (am->has_optimized_func) {
437− int aligned_len = FFALIGN(len, am->samples_align);
438− if (!(src->ptr_align % am->ptr_align) &&
439− src->samples_align >= aligned_len) {
440− len = aligned_len;
441− use_generic = 0;
442− }
443− }
444− av_log(am->avr, AV_LOG_TRACE, "audio_mix: %d samples - %d to %d channels (%s)\n",
445− src->nb_samples, am->in_channels, am->out_channels,
446− use_generic ? am->func_descr_generic : am->func_descr);
447−
448− if (am->in_matrix_channels && am->out_matrix_channels) {
449− uint8_t **data;
450− uint8_t *data0[AVRESAMPLE_MAX_CHANNELS] = { NULL };
451−
452− if (am->out_matrix_channels < am->out_channels ||
453− am->in_matrix_channels < am->in_channels) {
454− for (i = 0, j = 0; i < FFMAX(am->in_channels, am->out_channels); i++) {
455− if (am->input_skip[i] || am->output_skip[i] || am->output_zero[i])
456− continue;
457− data0[j++] = src->data[i];
458− }
459− data = data0;
460− } else {
461− data = src->data;
462− }
463−
464− if (use_generic)
465− am->mix_generic(data, am->matrix, len, am->out_matrix_channels,
466− am->in_matrix_channels);
467− else
468− am->mix(data, am->matrix, len, am->out_matrix_channels,
469− am->in_matrix_channels);
470− }
471−
472− if (am->out_matrix_channels < am->out_channels) {
473− for (i = 0; i < am->out_channels; i++)
474− if (am->output_zero[i])
475− av_samples_set_silence(&src->data[i], 0, len, 1, am->fmt);
476− }
477−
478− ff_audio_data_set_channels(src, am->out_channels);
479−
480− return 0;
481−}
482−
483−int ff_audio_mix_get_matrix(AudioMix *am, double *matrix, int stride)
484−{
485− int i, o, i0, o0;
486−
487− if ( am->in_channels <= 0 || am->in_channels > AVRESAMPLE_MAX_CHANNELS ||
488− am->out_channels <= 0 || am->out_channels > AVRESAMPLE_MAX_CHANNELS) {
489− av_log(am->avr, AV_LOG_ERROR, "Invalid channel counts\n");
490− return AVERROR(EINVAL);
491− }
492−
493−#define GET_MATRIX_CONVERT(suffix, scale) \
494− if (!am->matrix_ ## suffix[0]) { \
495− av_log(am->avr, AV_LOG_ERROR, "matrix is not set\n"); \
496− return AVERROR(EINVAL); \
497− } \
498− for (o = 0, o0 = 0; o < am->out_channels; o++) { \
499− for (i = 0, i0 = 0; i < am->in_channels; i++) { \
500− if (am->input_skip[i] || am->output_zero[o]) \
501− matrix[o * stride + i] = 0.0; \
502− else \
503− matrix[o * stride + i] = am->matrix_ ## suffix[o0][i0] * \
504− (scale); \
505− if (!am->input_skip[i]) \
506− i0++; \
507− } \
508− if (!am->output_zero[o]) \
509− o0++; \
510− }
511−
512− switch (am->coeff_type) {
513− case AV_MIX_COEFF_TYPE_Q8:
514− GET_MATRIX_CONVERT(q8, 1.0 / 256.0);
515− break;
516− case AV_MIX_COEFF_TYPE_Q15:
517− GET_MATRIX_CONVERT(q15, 1.0 / 32768.0);
518− break;
519− case AV_MIX_COEFF_TYPE_FLT:
520− GET_MATRIX_CONVERT(flt, 1.0);
521− break;
522− default:
523− av_log(am->avr, AV_LOG_ERROR, "Invalid mix coeff type\n");
524− return AVERROR(EINVAL);
525− }
526−
527− return 0;
528−}
529−
530−static void reduce_matrix(AudioMix *am, const double *matrix, int stride)
531−{
532− int i, o;
533−
534− memset(am->output_zero, 0, sizeof(am->output_zero));
535− memset(am->input_skip, 0, sizeof(am->input_skip));
536− memset(am->output_skip, 0, sizeof(am->output_skip));
537−
538− /* exclude output channels if they can be zeroed instead of mixed */
539− for (o = 0; o < am->out_channels; o++) {
540− int zero = 1;
541−
542− /* check if the output is always silent */
543− for (i = 0; i < am->in_channels; i++) {
544− if (matrix[o * stride + i] != 0.0) {
545− zero = 0;
546− break;
547− }
548− }
549− /* check if the corresponding input channel makes a contribution to
550− any output channel */
551− if (o < am->in_channels) {
552− for (i = 0; i < am->out_channels; i++) {
553− if (matrix[i * stride + o] != 0.0) {
554− zero = 0;
555− break;
556− }
557− }
558− }
559− if (zero) {
560− am->output_zero[o] = 1;
561− am->out_matrix_channels--;
562− if (o < am->in_channels)
563− am->in_matrix_channels--;
564− }
565− }
566− if (am->out_matrix_channels == 0 || am->in_matrix_channels == 0) {
567− am->out_matrix_channels = 0;
568− am->in_matrix_channels = 0;
569− return;
570− }
571−
572− /* skip input channels that contribute fully only to the corresponding
573− output channel */
574− for (i = 0; i < FFMIN(am->in_channels, am->out_channels); i++) {
575− int skip = 1;
576−
577− for (o = 0; o < am->out_channels; o++) {
578− int i0;
579− if ((o != i && matrix[o * stride + i] != 0.0) ||
580− (o == i && matrix[o * stride + i] != 1.0)) {
581− skip = 0;
582− break;
583− }
584− /* if the input contributes fully to the output, also check that no
585− other inputs contribute to this output */
586− if (o == i) {
587− for (i0 = 0; i0 < am->in_channels; i0++) {
588− if (i0 != i && matrix[o * stride + i0] != 0.0) {
589− skip = 0;
590− break;
591− }
592− }
593− }
594− }
595− if (skip) {
596− am->input_skip[i] = 1;
597− am->in_matrix_channels--;
598− }
599− }
600− /* skip input channels that do not contribute to any output channel */
601− for (; i < am->in_channels; i++) {
602− int contrib = 0;
603−
604− for (o = 0; o < am->out_channels; o++) {
605− if (matrix[o * stride + i] != 0.0) {
606− contrib = 1;
607− break;
608− }
609− }
610− if (!contrib) {
611− am->input_skip[i] = 1;
612− am->in_matrix_channels--;
613− }
614− }
615− if (am->in_matrix_channels == 0) {
616− am->out_matrix_channels = 0;
617− return;
618− }
619−
620− /* skip output channels that only get full contribution from the
621− corresponding input channel */
622− for (o = 0; o < FFMIN(am->in_channels, am->out_channels); o++) {
623− int skip = 1;
624− int o0;
625−
626− for (i = 0; i < am->in_channels; i++) {
627− if ((o != i && matrix[o * stride + i] != 0.0) ||
628− (o == i && matrix[o * stride + i] != 1.0)) {
629− skip = 0;
630− break;
631− }
632− }
633− /* check if the corresponding input channel makes a contribution to
634− any other output channel */
635− i = o;
636− for (o0 = 0; o0 < am->out_channels; o0++) {
637− if (o0 != i && matrix[o0 * stride + i] != 0.0) {
638− skip = 0;
639− break;
640− }
641− }
642− if (skip) {
643− am->output_skip[o] = 1;
644− am->out_matrix_channels--;
645− }
646− }
647− if (am->out_matrix_channels == 0) {
648− am->in_matrix_channels = 0;
649− return;
650− }
651−}
652−
653−int ff_audio_mix_set_matrix(AudioMix *am, const double *matrix, int stride)
654−{
655− int i, o, i0, o0, ret;
656− char in_layout_name[128];
657− char out_layout_name[128];
658−
659− if ( am->in_channels <= 0 || am->in_channels > AVRESAMPLE_MAX_CHANNELS ||
660− am->out_channels <= 0 || am->out_channels > AVRESAMPLE_MAX_CHANNELS) {
661− av_log(am->avr, AV_LOG_ERROR, "Invalid channel counts\n");
662− return AVERROR(EINVAL);
663− }
664−
665− if (am->matrix) {
666− av_free(am->matrix[0]);
667− am->matrix = NULL;
668− }
669−
670− am->in_matrix_channels = am->in_channels;
671− am->out_matrix_channels = am->out_channels;
672−
673− reduce_matrix(am, matrix, stride);
674−
675−#define CONVERT_MATRIX(type, expr) \
676− am->matrix_## type[0] = av_mallocz(am->out_matrix_channels * \
677− am->in_matrix_channels * \
678− sizeof(*am->matrix_## type[0])); \
679− if (!am->matrix_## type[0]) \
680− return AVERROR(ENOMEM); \
681− for (o = 0, o0 = 0; o < am->out_channels; o++) { \
682− if (am->output_zero[o] || am->output_skip[o]) \
683− continue; \
684− if (o0 > 0) \
685− am->matrix_## type[o0] = am->matrix_## type[o0 - 1] + \
686− am->in_matrix_channels; \
687− for (i = 0, i0 = 0; i < am->in_channels; i++) { \
688− double v; \
689− if (am->input_skip[i] || am->output_zero[i]) \
690− continue; \
691− v = matrix[o * stride + i]; \
692− am->matrix_## type[o0][i0] = expr; \
693− i0++; \
694− } \
695− o0++; \
696− } \
697− am->matrix = (void **)am->matrix_## type;
698−
699− if (am->in_matrix_channels && am->out_matrix_channels) {
700− switch (am->coeff_type) {
701− case AV_MIX_COEFF_TYPE_Q8:
702− CONVERT_MATRIX(q8, av_clip_int16(lrint(256.0 * v)))
703− break;
704− case AV_MIX_COEFF_TYPE_Q15:
705− CONVERT_MATRIX(q15, av_clipl_int32(llrint(32768.0 * v)))
706− break;
707− case AV_MIX_COEFF_TYPE_FLT:
708− CONVERT_MATRIX(flt, v)
709− break;
710− default:
711− av_log(am->avr, AV_LOG_ERROR, "Invalid mix coeff type\n");
712− return AVERROR(EINVAL);
713− }
714− }
715−
716− ret = mix_function_init(am);
717− if (ret < 0)
718− return ret;
719−
720− av_get_channel_layout_string(in_layout_name, sizeof(in_layout_name),
721− am->in_channels, am->in_layout);
722− av_get_channel_layout_string(out_layout_name, sizeof(out_layout_name),
723− am->out_channels, am->out_layout);
724− av_log(am->avr, AV_LOG_DEBUG, "audio_mix: %s to %s\n",
725− in_layout_name, out_layout_name);
726− av_log(am->avr, AV_LOG_DEBUG, "matrix size: %d x %d\n",
727− am->in_matrix_channels, am->out_matrix_channels);
728− for (o = 0; o < am->out_channels; o++) {
729− for (i = 0; i < am->in_channels; i++) {
730− if (am->output_zero[o])
731− av_log(am->avr, AV_LOG_DEBUG, " (ZERO)");
732− else if (am->input_skip[i] || am->output_zero[i] || am->output_skip[o])
733− av_log(am->avr, AV_LOG_DEBUG, " (SKIP)");
734− else
735− av_log(am->avr, AV_LOG_DEBUG, " %0.3f ",
736− matrix[o * am->in_channels + i]);
737− }
738− av_log(am->avr, AV_LOG_DEBUG, "\n");
739− }
740−
741− return 0;
742−}
libavresample/audio_mix.h+0−94
@@ -1,94 +0,0 @@
1−/*
2− * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
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−
21−#ifndef AVRESAMPLE_AUDIO_MIX_H
22−#define AVRESAMPLE_AUDIO_MIX_H
23−
24−#include <stdint.h>
25−
26−#include "libavutil/samplefmt.h"
27−#include "avresample.h"
28−#include "internal.h"
29−#include "audio_data.h"
30−
31−typedef void (mix_func)(uint8_t **src, void **matrix, int len, int out_ch,
32− int in_ch);
33−
34−/**
35− * Set mixing function if the parameters match.
36− *
37− * This compares the parameters of the mixing function to the parameters in the
38− * AudioMix context. If the parameters do not match, no changes are made to the
39− * active functions. If the parameters do match and the alignment is not
40− * constrained, the function is set as the generic mixing function. If the
41− * parameters match and the alignment is constrained, the function is set as
42− * the optimized mixing function.
43− *
44− * @param am AudioMix context
45− * @param fmt input/output sample format
46− * @param coeff_type mixing coefficient type
47− * @param in_channels number of input channels, or 0 for any number of channels
48− * @param out_channels number of output channels, or 0 for any number of channels
49− * @param ptr_align buffer pointer alignment, in bytes
50− * @param samples_align buffer size alignment, in samples
51− * @param descr function type description (e.g. "C" or "SSE")
52− * @param mix_func mixing function pointer
53− */
54−void ff_audio_mix_set_func(AudioMix *am, enum AVSampleFormat fmt,
55− enum AVMixCoeffType coeff_type, int in_channels,
56− int out_channels, int ptr_align, int samples_align,
57− const char *descr, void *mix_func);
58−
59−/**
60− * Allocate and initialize an AudioMix context.
61− *
62− * The parameters in the AVAudioResampleContext are used to initialize the
63− * AudioMix context.
64− *
65− * @param avr AVAudioResampleContext
66− * @return newly-allocated AudioMix context.
67− */
68−AudioMix *ff_audio_mix_alloc(AVAudioResampleContext *avr);
69−
70−/**
71− * Free an AudioMix context.
72− */
73−void ff_audio_mix_free(AudioMix **am);
74−
75−/**
76− * Apply channel mixing to audio data using the current mixing matrix.
77− */
78−int ff_audio_mix(AudioMix *am, AudioData *src);
79−
80−/**
81− * Get the current mixing matrix.
82− */
83−int ff_audio_mix_get_matrix(AudioMix *am, double *matrix, int stride);
84−
85−/**
86− * Set the current mixing matrix.
87− */
88−int ff_audio_mix_set_matrix(AudioMix *am, const double *matrix, int stride);
89−
90−/* arch-specific initialization functions */
91−
92−void ff_audio_mix_init_x86(AudioMix *am);
93−
94−#endif /* AVRESAMPLE_AUDIO_MIX_H */
libavresample/audio_mix_matrix.c+0−294
@@ -1,294 +0,0 @@
1−/*
2− * Copyright (C) 2011 Michael Niedermayer (michaelni@gmx.at)
3− * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
4− *
5− * This file is part of FFmpeg.
6− *
7− * FFmpeg is free software; you can redistribute it and/or
8− * modify it under the terms of the GNU Lesser General Public
9− * License as published by the Free Software Foundation; either
10− * version 2.1 of the License, or (at your option) any later version.
11− *
12− * FFmpeg is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15− * Lesser General Public License for more details.
16− *
17− * You should have received a copy of the GNU Lesser General Public
18− * License along with FFmpeg; if not, write to the Free Software
19− * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20− */
21−
22−#include <stdint.h>
23−
24−#include "libavutil/common.h"
25−#include "libavutil/libm.h"
26−#include "libavutil/samplefmt.h"
27−#include "avresample.h"
28−#include "internal.h"
29−#include "audio_data.h"
30−#include "audio_mix.h"
31−
32−/* channel positions */
33−#define FRONT_LEFT 0
34−#define FRONT_RIGHT 1
35−#define FRONT_CENTER 2
36−#define LOW_FREQUENCY 3
37−#define BACK_LEFT 4
38−#define BACK_RIGHT 5
39−#define FRONT_LEFT_OF_CENTER 6
40−#define FRONT_RIGHT_OF_CENTER 7
41−#define BACK_CENTER 8
42−#define SIDE_LEFT 9
43−#define SIDE_RIGHT 10
44−#define TOP_CENTER 11
45−#define TOP_FRONT_LEFT 12
46−#define TOP_FRONT_CENTER 13
47−#define TOP_FRONT_RIGHT 14
48−#define TOP_BACK_LEFT 15
49−#define TOP_BACK_CENTER 16
50−#define TOP_BACK_RIGHT 17
51−#define STEREO_LEFT 29
52−#define STEREO_RIGHT 30
53−#define WIDE_LEFT 31
54−#define WIDE_RIGHT 32
55−#define SURROUND_DIRECT_LEFT 33
56−#define SURROUND_DIRECT_RIGHT 34
57−#define LOW_FREQUENCY_2 35
58−
59−#define SQRT3_2 1.22474487139158904909 /* sqrt(3/2) */
60−
61−static av_always_inline int even(uint64_t layout)
62−{
63− return (!layout || !!(layout & (layout - 1)));
64−}
65−
66−static int sane_layout(uint64_t layout)
67−{
68− /* check that there is at least 1 front speaker */
69− if (!(layout & AV_CH_LAYOUT_SURROUND))
70− return 0;
71−
72− /* check for left/right symmetry */
73− if (!even(layout & (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT)) ||
74− !even(layout & (AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT)) ||
75− !even(layout & (AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT)) ||
76− !even(layout & (AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER)) ||
77− !even(layout & (AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT)) ||
78− !even(layout & (AV_CH_TOP_BACK_LEFT | AV_CH_TOP_BACK_RIGHT)) ||
79− !even(layout & (AV_CH_STEREO_LEFT | AV_CH_STEREO_RIGHT)) ||
80− !even(layout & (AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT)) ||
81− !even(layout & (AV_CH_SURROUND_DIRECT_LEFT | AV_CH_SURROUND_DIRECT_RIGHT)))
82− return 0;
83−
84− return 1;
85−}
86−
87−int avresample_build_matrix(uint64_t in_layout, uint64_t out_layout,
88− double center_mix_level, double surround_mix_level,
89− double lfe_mix_level, int normalize,
90− double *matrix_out, int stride,
91− enum AVMatrixEncoding matrix_encoding)
92−{
93− int i, j, out_i, out_j;
94− double matrix[64][64] = {{0}};
95− int64_t unaccounted;
96− double maxcoef = 0;
97− int in_channels, out_channels;
98−
99− if ((out_layout & AV_CH_LAYOUT_STEREO_DOWNMIX) == AV_CH_LAYOUT_STEREO_DOWNMIX) {
100− out_layout = AV_CH_LAYOUT_STEREO;
101− }
102−
103− unaccounted = in_layout & ~out_layout;
104−
105− in_channels = av_get_channel_layout_nb_channels( in_layout);
106− out_channels = av_get_channel_layout_nb_channels(out_layout);
107−
108− memset(matrix_out, 0, out_channels * stride * sizeof(*matrix_out));
109−
110− /* check if layouts are supported */
111− if (!in_layout || in_channels > AVRESAMPLE_MAX_CHANNELS)
112− return AVERROR(EINVAL);
113− if (!out_layout || out_channels > AVRESAMPLE_MAX_CHANNELS)
114− return AVERROR(EINVAL);
115−
116− /* check if layouts are unbalanced or abnormal */
117− if (!sane_layout(in_layout) || !sane_layout(out_layout))
118− return AVERROR_PATCHWELCOME;
119−
120− /* route matching input/output channels */
121− for (i = 0; i < 64; i++) {
122− if (in_layout & out_layout & (1ULL << i))
123− matrix[i][i] = 1.0;
124− }
125−
126− /* mix front center to front left/right */
127− if (unaccounted & AV_CH_FRONT_CENTER) {
128− if ((out_layout & AV_CH_LAYOUT_STEREO) == AV_CH_LAYOUT_STEREO) {
129− if ((in_layout & AV_CH_LAYOUT_STEREO) == AV_CH_LAYOUT_STEREO) {
130− matrix[FRONT_LEFT ][FRONT_CENTER] += center_mix_level;
131− matrix[FRONT_RIGHT][FRONT_CENTER] += center_mix_level;
132− } else {
133− matrix[FRONT_LEFT ][FRONT_CENTER] += M_SQRT1_2;
134− matrix[FRONT_RIGHT][FRONT_CENTER] += M_SQRT1_2;
135− }
136− } else
137− return AVERROR_PATCHWELCOME;
138− }
139− /* mix front left/right to center */
140− if (unaccounted & AV_CH_LAYOUT_STEREO) {
141− if (out_layout & AV_CH_FRONT_CENTER) {
142− matrix[FRONT_CENTER][FRONT_LEFT ] += M_SQRT1_2;
143− matrix[FRONT_CENTER][FRONT_RIGHT] += M_SQRT1_2;
144− /* mix left/right/center to center */
145− if (in_layout & AV_CH_FRONT_CENTER)
146− matrix[FRONT_CENTER][FRONT_CENTER] = center_mix_level * M_SQRT2;
147− } else
148− return AVERROR_PATCHWELCOME;
149− }
150− /* mix back center to back, side, or front */
151− if (unaccounted & AV_CH_BACK_CENTER) {
152− if (out_layout & AV_CH_BACK_LEFT) {
153− matrix[BACK_LEFT ][BACK_CENTER] += M_SQRT1_2;
154− matrix[BACK_RIGHT][BACK_CENTER] += M_SQRT1_2;
155− } else if (out_layout & AV_CH_SIDE_LEFT) {
156− matrix[SIDE_LEFT ][BACK_CENTER] += M_SQRT1_2;
157− matrix[SIDE_RIGHT][BACK_CENTER] += M_SQRT1_2;
158− } else if (out_layout & AV_CH_FRONT_LEFT) {
159− if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY ||
160− matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
161− if (unaccounted & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT)) {
162− matrix[FRONT_LEFT ][BACK_CENTER] -= surround_mix_level * M_SQRT1_2;
163− matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
164− } else {
165− matrix[FRONT_LEFT ][BACK_CENTER] -= surround_mix_level;
166− matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level;
167− }
168− } else {
169− matrix[FRONT_LEFT ][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
170− matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
171− }
172− } else if (out_layout & AV_CH_FRONT_CENTER) {
173− matrix[FRONT_CENTER][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
174− } else
175− return AVERROR_PATCHWELCOME;
176− }
177− /* mix back left/right to back center, side, or front */
178− if (unaccounted & AV_CH_BACK_LEFT) {
179− if (out_layout & AV_CH_BACK_CENTER) {
180− matrix[BACK_CENTER][BACK_LEFT ] += M_SQRT1_2;
181− matrix[BACK_CENTER][BACK_RIGHT] += M_SQRT1_2;
182− } else if (out_layout & AV_CH_SIDE_LEFT) {
183− /* if side channels do not exist in the input, just copy back
184− channels to side channels, otherwise mix back into side */
185− if (in_layout & AV_CH_SIDE_LEFT) {
186− matrix[SIDE_LEFT ][BACK_LEFT ] += M_SQRT1_2;
187− matrix[SIDE_RIGHT][BACK_RIGHT] += M_SQRT1_2;
188− } else {
189− matrix[SIDE_LEFT ][BACK_LEFT ] += 1.0;
190− matrix[SIDE_RIGHT][BACK_RIGHT] += 1.0;
191− }
192− } else if (out_layout & AV_CH_FRONT_LEFT) {
193− if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
194− matrix[FRONT_LEFT ][BACK_LEFT ] -= surround_mix_level * M_SQRT1_2;
195− matrix[FRONT_LEFT ][BACK_RIGHT] -= surround_mix_level * M_SQRT1_2;
196− matrix[FRONT_RIGHT][BACK_LEFT ] += surround_mix_level * M_SQRT1_2;
197− matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level * M_SQRT1_2;
198− } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
199− matrix[FRONT_LEFT ][BACK_LEFT ] -= surround_mix_level * SQRT3_2;
200− matrix[FRONT_LEFT ][BACK_RIGHT] -= surround_mix_level * M_SQRT1_2;
201− matrix[FRONT_RIGHT][BACK_LEFT ] += surround_mix_level * M_SQRT1_2;
202− matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level * SQRT3_2;
203− } else {
204− matrix[FRONT_LEFT ][BACK_LEFT ] += surround_mix_level;
205− matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level;
206− }
207− } else if (out_layout & AV_CH_FRONT_CENTER) {
208− matrix[FRONT_CENTER][BACK_LEFT ] += surround_mix_level * M_SQRT1_2;
209− matrix[FRONT_CENTER][BACK_RIGHT] += surround_mix_level * M_SQRT1_2;
210− } else
211− return AVERROR_PATCHWELCOME;
212− }
213− /* mix side left/right into back or front */
214− if (unaccounted & AV_CH_SIDE_LEFT) {
215− if (out_layout & AV_CH_BACK_LEFT) {
216− /* if back channels do not exist in the input, just copy side
217− channels to back channels, otherwise mix side into back */
218− if (in_layout & AV_CH_BACK_LEFT) {
219− matrix[BACK_LEFT ][SIDE_LEFT ] += M_SQRT1_2;
220− matrix[BACK_RIGHT][SIDE_RIGHT] += M_SQRT1_2;
221− } else {
222− matrix[BACK_LEFT ][SIDE_LEFT ] += 1.0;
223− matrix[BACK_RIGHT][SIDE_RIGHT] += 1.0;
224− }
225− } else if (out_layout & AV_CH_BACK_CENTER) {
226− matrix[BACK_CENTER][SIDE_LEFT ] += M_SQRT1_2;
227− matrix[BACK_CENTER][SIDE_RIGHT] += M_SQRT1_2;
228− } else if (out_layout & AV_CH_FRONT_LEFT) {
229− if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
230− matrix[FRONT_LEFT ][SIDE_LEFT ] -= surround_mix_level * M_SQRT1_2;
231− matrix[FRONT_LEFT ][SIDE_RIGHT] -= surround_mix_level * M_SQRT1_2;
232− matrix[FRONT_RIGHT][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2;
233− matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level * M_SQRT1_2;
234− } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
235− matrix[FRONT_LEFT ][SIDE_LEFT ] -= surround_mix_level * SQRT3_2;
236− matrix[FRONT_LEFT ][SIDE_RIGHT] -= surround_mix_level * M_SQRT1_2;
237− matrix[FRONT_RIGHT][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2;
238− matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level * SQRT3_2;
239− } else {
240− matrix[FRONT_LEFT ][SIDE_LEFT ] += surround_mix_level;
241− matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level;
242− }
243− } else if (out_layout & AV_CH_FRONT_CENTER) {
244− matrix[FRONT_CENTER][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2;
245− matrix[FRONT_CENTER][SIDE_RIGHT] += surround_mix_level * M_SQRT1_2;
246− } else
247− return AVERROR_PATCHWELCOME;
248− }
249− /* mix left-of-center/right-of-center into front left/right or center */
250− if (unaccounted & AV_CH_FRONT_LEFT_OF_CENTER) {
251− if (out_layout & AV_CH_FRONT_LEFT) {
252− matrix[FRONT_LEFT ][FRONT_LEFT_OF_CENTER ] += 1.0;
253− matrix[FRONT_RIGHT][FRONT_RIGHT_OF_CENTER] += 1.0;
254− } else if (out_layout & AV_CH_FRONT_CENTER) {
255− matrix[FRONT_CENTER][FRONT_LEFT_OF_CENTER ] += M_SQRT1_2;
256− matrix[FRONT_CENTER][FRONT_RIGHT_OF_CENTER] += M_SQRT1_2;
257− } else
258− return AVERROR_PATCHWELCOME;
259− }
260− /* mix LFE into front left/right or center */
261− if (unaccounted & AV_CH_LOW_FREQUENCY) {
262− if (out_layout & AV_CH_FRONT_CENTER) {
263− matrix[FRONT_CENTER][LOW_FREQUENCY] += lfe_mix_level;
264− } else if (out_layout & AV_CH_FRONT_LEFT) {
265− matrix[FRONT_LEFT ][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2;
266− matrix[FRONT_RIGHT][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2;
267− } else
268− return AVERROR_PATCHWELCOME;
269− }
270−
271− /* transfer internal matrix to output matrix and calculate maximum
272− per-channel coefficient sum */
273− for (out_i = i = 0; out_i < out_channels && i < 64; i++) {
274− double sum = 0;
275− for (out_j = j = 0; out_j < in_channels && j < 64; j++) {
276− matrix_out[out_i * stride + out_j] = matrix[i][j];
277− sum += fabs(matrix[i][j]);
278− if (in_layout & (1ULL << j))
279− out_j++;
280− }
281− maxcoef = FFMAX(maxcoef, sum);
282− if (out_layout & (1ULL << i))
283− out_i++;
284− }
285−
286− /* normalize */
287− if (normalize && maxcoef > 1.0) {
288− for (i = 0; i < out_channels; i++)
289− for (j = 0; j < in_channels; j++)
290− matrix_out[i * stride + j] /= maxcoef;
291− }
292−
293− return 0;
294−}
libavresample/avresample.h+0−595
@@ -1,595 +0,0 @@
1−/*
2− * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
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−
21−#ifndef AVRESAMPLE_AVRESAMPLE_H
22−#define AVRESAMPLE_AVRESAMPLE_H
23−
24−/**
25− * @file
26− * @ingroup lavr
27− * external API header
28− */
29−
30−/**
31− * @defgroup lavr libavresample
32− * @{
33− *
34− * Libavresample (lavr) is a library that handles audio resampling, sample
35− * format conversion and mixing.
36− *
37− * Interaction with lavr is done through AVAudioResampleContext, which is
38− * allocated with avresample_alloc_context(). It is opaque, so all parameters
39− * must be set with the @ref avoptions API.
40− *
41− * For example the following code will setup conversion from planar float sample
42− * format to interleaved signed 16-bit integer, downsampling from 48kHz to
43− * 44.1kHz and downmixing from 5.1 channels to stereo (using the default mixing
44− * matrix):
45− * @code
46− * AVAudioResampleContext *avr = avresample_alloc_context();
47− * av_opt_set_int(avr, "in_channel_layout", AV_CH_LAYOUT_5POINT1, 0);
48− * av_opt_set_int(avr, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0);
49− * av_opt_set_int(avr, "in_sample_rate", 48000, 0);
50− * av_opt_set_int(avr, "out_sample_rate", 44100, 0);
51− * av_opt_set_int(avr, "in_sample_fmt", AV_SAMPLE_FMT_FLTP, 0);
52− * av_opt_set_int(avr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
53− * @endcode
54− *
55− * Once the context is initialized, it must be opened with avresample_open(). If
56− * you need to change the conversion parameters, you must close the context with
57− * avresample_close(), change the parameters as described above, then reopen it
58− * again.
59− *
60− * The conversion itself is done by repeatedly calling avresample_convert().
61− * Note that the samples may get buffered in two places in lavr. The first one
62− * is the output FIFO, where the samples end up if the output buffer is not
63− * large enough. The data stored in there may be retrieved at any time with
64− * avresample_read(). The second place is the resampling delay buffer,
65− * applicable only when resampling is done. The samples in it require more input
66− * before they can be processed. Their current amount is returned by
67− * avresample_get_delay(). At the end of conversion the resampling buffer can be
68− * flushed by calling avresample_convert() with NULL input.
69− *
70− * The following code demonstrates the conversion loop assuming the parameters
71− * from above and caller-defined functions get_input() and handle_output():
72− * @code
73− * uint8_t **input;
74− * int in_linesize, in_samples;
75− *
76− * while (get_input(&input, &in_linesize, &in_samples)) {
77− * uint8_t *output
78− * int out_linesize;
79− * int out_samples = avresample_get_out_samples(avr, in_samples);
80− *
81− * av_samples_alloc(&output, &out_linesize, 2, out_samples,
82− * AV_SAMPLE_FMT_S16, 0);
83− * out_samples = avresample_convert(avr, &output, out_linesize, out_samples,
84− * input, in_linesize, in_samples);
85− * handle_output(output, out_linesize, out_samples);
86− * av_freep(&output);
87− * }
88− * @endcode
89− *
90− * When the conversion is finished and the FIFOs are flushed if required, the
91− * conversion context and everything associated with it must be freed with
92− * avresample_free().
93− */
94−
95−#include "libavutil/avutil.h"
96−#include "libavutil/channel_layout.h"
97−#include "libavutil/dict.h"
98−#include "libavutil/frame.h"
99−#include "libavutil/log.h"
100−#include "libavutil/mathematics.h"
101−
102−#include "libavresample/version.h"
103−
104−#define AVRESAMPLE_MAX_CHANNELS 32
105−
106−typedef struct AVAudioResampleContext AVAudioResampleContext;
107−
108−/**
109− * @deprecated use libswresample
110− *
111− * Mixing Coefficient Types */
112−enum attribute_deprecated AVMixCoeffType {
113− AV_MIX_COEFF_TYPE_Q8, /** 16-bit 8.8 fixed-point */
114− AV_MIX_COEFF_TYPE_Q15, /** 32-bit 17.15 fixed-point */
115− AV_MIX_COEFF_TYPE_FLT, /** floating-point */
116− AV_MIX_COEFF_TYPE_NB, /** Number of coeff types. Not part of ABI */
117−};
118−
119−/**
120− * @deprecated use libswresample
121− *
122− * Resampling Filter Types */
123−enum attribute_deprecated AVResampleFilterType {
124− AV_RESAMPLE_FILTER_TYPE_CUBIC, /**< Cubic */
125− AV_RESAMPLE_FILTER_TYPE_BLACKMAN_NUTTALL, /**< Blackman Nuttall Windowed Sinc */
126− AV_RESAMPLE_FILTER_TYPE_KAISER, /**< Kaiser Windowed Sinc */
127−};
128−
129−/**
130− * @deprecated use libswresample
131− */
132−enum attribute_deprecated AVResampleDitherMethod {
133− AV_RESAMPLE_DITHER_NONE, /**< Do not use dithering */
134− AV_RESAMPLE_DITHER_RECTANGULAR, /**< Rectangular Dither */
135− AV_RESAMPLE_DITHER_TRIANGULAR, /**< Triangular Dither*/
136− AV_RESAMPLE_DITHER_TRIANGULAR_HP, /**< Triangular Dither with High Pass */
137− AV_RESAMPLE_DITHER_TRIANGULAR_NS, /**< Triangular Dither with Noise Shaping */
138− AV_RESAMPLE_DITHER_NB, /**< Number of dither types. Not part of ABI. */
139−};
140−
141−/**
142− *
143− * @deprecated use libswresample
144− *
145− * Return the LIBAVRESAMPLE_VERSION_INT constant.
146− */
147−attribute_deprecated
148−unsigned avresample_version(void);
149−
150−/**
151− *
152− * @deprecated use libswresample
153− *
154− * Return the libavresample build-time configuration.
155− * @return configure string
156− */
157−attribute_deprecated
158−const char *avresample_configuration(void);
159−
160−/**
161− *
162− * @deprecated use libswresample
163− *
164− * Return the libavresample license.
165− */
166−attribute_deprecated
167−const char *avresample_license(void);
168−
169−/**
170− *
171− * @deprecated use libswresample
172− *
173− * Get the AVClass for AVAudioResampleContext.
174− *
175− * Can be used in combination with AV_OPT_SEARCH_FAKE_OBJ for examining options
176− * without allocating a context.
177− *
178− * @see av_opt_find().
179− *
180− * @return AVClass for AVAudioResampleContext
181− */
182−attribute_deprecated
183−const AVClass *avresample_get_class(void);
184−
185−/**
186− *
187− * @deprecated use libswresample
188− *
189− * Allocate AVAudioResampleContext and set options.
190− *
191− * @return allocated audio resample context, or NULL on failure
192− */
193−attribute_deprecated
194−AVAudioResampleContext *avresample_alloc_context(void);
195−
196−/**
197− *
198− * @deprecated use libswresample
199− *
200− * Initialize AVAudioResampleContext.
201− * @note The context must be configured using the AVOption API.
202− * @note The fields "in_channel_layout", "out_channel_layout",
203− * "in_sample_rate", "out_sample_rate", "in_sample_fmt",
204− * "out_sample_fmt" must be set.
205− *
206− * @see av_opt_set_int()
207− * @see av_opt_set_dict()
208− * @see av_get_default_channel_layout()
209− *
210− * @param avr audio resample context
211− * @return 0 on success, negative AVERROR code on failure
212− */
213−attribute_deprecated
214−int avresample_open(AVAudioResampleContext *avr);
215−
216−/**
217− *
218− * @deprecated use libswresample
219− *
220− * Check whether an AVAudioResampleContext is open or closed.
221− *
222− * @param avr AVAudioResampleContext to check
223− * @return 1 if avr is open, 0 if avr is closed.
224− */
225−attribute_deprecated
226−int avresample_is_open(AVAudioResampleContext *avr);
227−
228−/**
229− *
230− * @deprecated use libswresample
231− *
232− * Close AVAudioResampleContext.
233− *
234− * This closes the context, but it does not change the parameters. The context
235− * can be reopened with avresample_open(). It does, however, clear the output
236− * FIFO and any remaining leftover samples in the resampling delay buffer. If
237− * there was a custom matrix being used, that is also cleared.
238− *
239− * @see avresample_convert()
240− * @see avresample_set_matrix()
241− *
242− * @param avr audio resample context
243− */
244−attribute_deprecated
245−void avresample_close(AVAudioResampleContext *avr);
246−
247−/**
248− *
249− * @deprecated use libswresample
250− *
251− * Free AVAudioResampleContext and associated AVOption values.
252− *
253− * This also calls avresample_close() before freeing.
254− *
255− * @param avr audio resample context
256− */
257−attribute_deprecated
258−void avresample_free(AVAudioResampleContext **avr);
259−
260−/**
261− *
262− * @deprecated use libswresample
263− *
264− * Generate a channel mixing matrix.
265− *
266− * This function is the one used internally by libavresample for building the
267− * default mixing matrix. It is made public just as a utility function for
268− * building custom matrices.
269− *
270− * @param in_layout input channel layout
271− * @param out_layout output channel layout
272− * @param center_mix_level mix level for the center channel
273− * @param surround_mix_level mix level for the surround channel(s)
274− * @param lfe_mix_level mix level for the low-frequency effects channel
275− * @param normalize if 1, coefficients will be normalized to prevent
276− * overflow. if 0, coefficients will not be
277− * normalized.
278− * @param[out] matrix mixing coefficients; matrix[i + stride * o] is
279− * the weight of input channel i in output channel o.
280− * @param stride distance between adjacent input channels in the
281− * matrix array
282− * @param matrix_encoding matrixed stereo downmix mode (e.g. dplii)
283− * @return 0 on success, negative AVERROR code on failure
284− */
285−attribute_deprecated
286−int avresample_build_matrix(uint64_t in_layout, uint64_t out_layout,
287− double center_mix_level, double surround_mix_level,
288− double lfe_mix_level, int normalize, double *matrix,
289− int stride, enum AVMatrixEncoding matrix_encoding);
290−
291−/**
292− *
293− * @deprecated use libswresample
294− *
295− * Get the current channel mixing matrix.
296− *
297− * If no custom matrix has been previously set or the AVAudioResampleContext is
298− * not open, an error is returned.
299− *
300− * @param avr audio resample context
301− * @param matrix mixing coefficients; matrix[i + stride * o] is the weight of
302− * input channel i in output channel o.
303− * @param stride distance between adjacent input channels in the matrix array
304− * @return 0 on success, negative AVERROR code on failure
305− */
306−attribute_deprecated
307−int avresample_get_matrix(AVAudioResampleContext *avr, double *matrix,
308− int stride);
309−
310−/**
311− *
312− * @deprecated use libswresample
313− *
314− * Set channel mixing matrix.
315− *
316− * Allows for setting a custom mixing matrix, overriding the default matrix
317− * generated internally during avresample_open(). This function can be called
318− * anytime on an allocated context, either before or after calling
319− * avresample_open(), as long as the channel layouts have been set.
320− * avresample_convert() always uses the current matrix.
321− * Calling avresample_close() on the context will clear the current matrix.
322− *
323− * @see avresample_close()
324− *
325− * @param avr audio resample context
326− * @param matrix mixing coefficients; matrix[i + stride * o] is the weight of
327− * input channel i in output channel o.
328− * @param stride distance between adjacent input channels in the matrix array
329− * @return 0 on success, negative AVERROR code on failure
330− */
331−attribute_deprecated
332−int avresample_set_matrix(AVAudioResampleContext *avr, const double *matrix,
333− int stride);
334−
335−/**
336− *
337− * @deprecated use libswresample
338− *
339− * Set a customized input channel mapping.
340− *
341− * This function can only be called when the allocated context is not open.
342− * Also, the input channel layout must have already been set.
343− *
344− * Calling avresample_close() on the context will clear the channel mapping.
345− *
346− * The map for each input channel specifies the channel index in the source to
347− * use for that particular channel, or -1 to mute the channel. Source channels
348− * can be duplicated by using the same index for multiple input channels.
349− *
350− * Examples:
351− *
352− * Reordering 5.1 AAC order (C,L,R,Ls,Rs,LFE) to FFmpeg order (L,R,C,LFE,Ls,Rs):
353− * { 1, 2, 0, 5, 3, 4 }
354− *
355− * Muting the 3rd channel in 4-channel input:
356− * { 0, 1, -1, 3 }
357− *
358− * Duplicating the left channel of stereo input:
359− * { 0, 0 }
360− *
361− * @param avr audio resample context
362− * @param channel_map customized input channel mapping
363− * @return 0 on success, negative AVERROR code on failure
364− */
365−attribute_deprecated
366−int avresample_set_channel_mapping(AVAudioResampleContext *avr,
367− const int *channel_map);
368−
369−/**
370− *
371− * @deprecated use libswresample
372− *
373− * Set compensation for resampling.
374− *
375− * This can be called anytime after avresample_open(). If resampling is not
376− * automatically enabled because of a sample rate conversion, the
377− * "force_resampling" option must have been set to 1 when opening the context
378− * in order to use resampling compensation.
379− *
380− * @param avr audio resample context
381− * @param sample_delta compensation delta, in samples
382− * @param compensation_distance compensation distance, in samples
383− * @return 0 on success, negative AVERROR code on failure
384− */
385−attribute_deprecated
386−int avresample_set_compensation(AVAudioResampleContext *avr, int sample_delta,
387− int compensation_distance);
388−
389−/**
390− *
391− * @deprecated use libswresample
392− *
393− * Provide the upper bound on the number of samples the configured
394− * conversion would output.
395− *
396− * @param avr audio resample context
397− * @param in_nb_samples number of input samples
398− *
399− * @return number of samples or AVERROR(EINVAL) if the value
400− * would exceed INT_MAX
401− */
402−attribute_deprecated
403−int avresample_get_out_samples(AVAudioResampleContext *avr, int in_nb_samples);
404−
405−/**
406− *
407− * @deprecated use libswresample
408− *
409− * Convert input samples and write them to the output FIFO.
410− *
411− * The upper bound on the number of output samples can be obtained through
412− * avresample_get_out_samples().
413− *
414− * The output data can be NULL or have fewer allocated samples than required.
415− * In this case, any remaining samples not written to the output will be added
416− * to an internal FIFO buffer, to be returned at the next call to this function
417− * or to avresample_read().
418− *
419− * If converting sample rate, there may be data remaining in the internal
420− * resampling delay buffer. avresample_get_delay() tells the number of remaining
421− * samples. To get this data as output, call avresample_convert() with NULL
422− * input.
423− *
424− * At the end of the conversion process, there may be data remaining in the
425− * internal FIFO buffer. avresample_available() tells the number of remaining
426− * samples. To get this data as output, either call avresample_convert() with
427− * NULL input or call avresample_read().
428− *
429− * @see avresample_get_out_samples()
430− * @see avresample_read()
431− * @see avresample_get_delay()
432− *
433− * @param avr audio resample context
434− * @param output output data pointers
435− * @param out_plane_size output plane size, in bytes.
436− * This can be 0 if unknown, but that will lead to
437− * optimized functions not being used directly on the
438− * output, which could slow down some conversions.
439− * @param out_samples maximum number of samples that the output buffer can hold
440− * @param input input data pointers
441− * @param in_plane_size input plane size, in bytes
442− * This can be 0 if unknown, but that will lead to
443− * optimized functions not being used directly on the
444− * input, which could slow down some conversions.
445− * @param in_samples number of input samples to convert
446− * @return number of samples written to the output buffer,
447− * not including converted samples added to the internal
448− * output FIFO
449− */
450−attribute_deprecated
451−int avresample_convert(AVAudioResampleContext *avr, uint8_t **output,
452− int out_plane_size, int out_samples,
453− uint8_t * const *input, int in_plane_size,
454− int in_samples);
455−
456−/**
457− *
458− * @deprecated use libswresample
459− *
460− * Return the number of samples currently in the resampling delay buffer.
461− *
462− * When resampling, there may be a delay between the input and output. Any
463− * unconverted samples in each call are stored internally in a delay buffer.
464− * This function allows the user to determine the current number of samples in
465− * the delay buffer, which can be useful for synchronization.
466− *
467− * @see avresample_convert()
468− *
469− * @param avr audio resample context
470− * @return number of samples currently in the resampling delay buffer
471− */
472−attribute_deprecated
473−int avresample_get_delay(AVAudioResampleContext *avr);
474−
475−/**
476− *
477− * @deprecated use libswresample
478− *
479− * Return the number of available samples in the output FIFO.
480− *
481− * During conversion, if the user does not specify an output buffer or
482− * specifies an output buffer that is smaller than what is needed, remaining
483− * samples that are not written to the output are stored to an internal FIFO
484− * buffer. The samples in the FIFO can be read with avresample_read() or
485− * avresample_convert().
486− *
487− * @see avresample_read()
488− * @see avresample_convert()
489− *
490− * @param avr audio resample context
491− * @return number of samples available for reading
492− */
493−attribute_deprecated
494−int avresample_available(AVAudioResampleContext *avr);
495−
496−/**
497− *
498− * @deprecated use libswresample
499− *
500− * Read samples from the output FIFO.
501− *
502− * During conversion, if the user does not specify an output buffer or
503− * specifies an output buffer that is smaller than what is needed, remaining
504− * samples that are not written to the output are stored to an internal FIFO
505− * buffer. This function can be used to read samples from that internal FIFO.
506− *
507− * @see avresample_available()
508− * @see avresample_convert()
509− *
510− * @param avr audio resample context
511− * @param output output data pointers. May be NULL, in which case
512− * nb_samples of data is discarded from output FIFO.
513− * @param nb_samples number of samples to read from the FIFO
514− * @return the number of samples written to output
515− */
516−attribute_deprecated
517−int avresample_read(AVAudioResampleContext *avr, uint8_t **output, int nb_samples);
518−
519−/**
520− *
521− * @deprecated use libswresample
522− *
523− * Convert the samples in the input AVFrame and write them to the output AVFrame.
524− *
525− * Input and output AVFrames must have channel_layout, sample_rate and format set.
526− *
527− * The upper bound on the number of output samples is obtained through
528− * avresample_get_out_samples().
529− *
530− * If the output AVFrame does not have the data pointers allocated the nb_samples
531− * field will be set using avresample_get_out_samples() and av_frame_get_buffer()
532− * is called to allocate the frame.
533− *
534− * The output AVFrame can be NULL or have fewer allocated samples than required.
535− * In this case, any remaining samples not written to the output will be added
536− * to an internal FIFO buffer, to be returned at the next call to this function
537− * or to avresample_convert() or to avresample_read().
538− *
539− * If converting sample rate, there may be data remaining in the internal
540− * resampling delay buffer. avresample_get_delay() tells the number of
541− * remaining samples. To get this data as output, call this function or
542− * avresample_convert() with NULL input.
543− *
544− * At the end of the conversion process, there may be data remaining in the
545− * internal FIFO buffer. avresample_available() tells the number of remaining
546− * samples. To get this data as output, either call this function or
547− * avresample_convert() with NULL input or call avresample_read().
548− *
549− * If the AVAudioResampleContext configuration does not match the output and
550− * input AVFrame settings the conversion does not take place and depending on
551− * which AVFrame is not matching AVERROR_OUTPUT_CHANGED, AVERROR_INPUT_CHANGED
552− * or AVERROR_OUTPUT_CHANGED|AVERROR_INPUT_CHANGED is returned.
553− *
554− * @see avresample_get_out_samples()
555− * @see avresample_available()
556− * @see avresample_convert()
557− * @see avresample_read()
558− * @see avresample_get_delay()
559− *
560− * @param avr audio resample context
561− * @param output output AVFrame
562− * @param input input AVFrame
563− * @return 0 on success, AVERROR on failure or nonmatching
564− * configuration.
565− */
566−attribute_deprecated
567−int avresample_convert_frame(AVAudioResampleContext *avr,
568− AVFrame *output, AVFrame *input);
569−
570−/**
571− *
572− * @deprecated use libswresample
573− *
574− * Configure or reconfigure the AVAudioResampleContext using the information
575− * provided by the AVFrames.
576− *
577− * The original resampling context is reset even on failure.
578− * The function calls avresample_close() internally if the context is open.
579− *
580− * @see avresample_open();
581− * @see avresample_close();
582− *
583− * @param avr audio resample context
584− * @param out output AVFrame
585− * @param in input AVFrame
586− * @return 0 on success, AVERROR on failure.
587− */
588−attribute_deprecated
589−int avresample_config(AVAudioResampleContext *avr, AVFrame *out, AVFrame *in);
590−
591−/**
592− * @}
593− */
594−
595−#endif /* AVRESAMPLE_AVRESAMPLE_H */
libavresample/avresampleres.rc+0−55
@@ -1,55 +0,0 @@
1−/*
2− * Windows resource file for libavresample
3− *
4− * Copyright (C) 2012 James Almer
5− * Copyright (C) 2013 Tiancheng "Timothy" Gu
6− *
7− * This file is part of FFmpeg.
8− *
9− * FFmpeg is free software; you can redistribute it and/or
10− * modify it under the terms of the GNU Lesser General Public
11− * License as published by the Free Software Foundation; either
12− * version 2.1 of the License, or (at your option) any later version.
13− *
14− * FFmpeg is distributed in the hope that it will be useful,
15− * but WITHOUT ANY WARRANTY; without even the implied warranty of
16− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17− * Lesser General Public License for more details.
18− *
19− * You should have received a copy of the GNU Lesser General Public
20− * License along with FFmpeg; if not, write to the Free Software
21− * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22− */
23−
24−#include <windows.h>
25−#include "libavresample/version.h"
26−#include "libavutil/ffversion.h"
27−#include "config.h"
28−
29−1 VERSIONINFO
30−FILEVERSION LIBAVRESAMPLE_VERSION_MAJOR, LIBAVRESAMPLE_VERSION_MINOR, LIBAVRESAMPLE_VERSION_MICRO, 0
31−PRODUCTVERSION LIBAVRESAMPLE_VERSION_MAJOR, LIBAVRESAMPLE_VERSION_MINOR, LIBAVRESAMPLE_VERSION_MICRO, 0
32−FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
33−FILEOS VOS_NT_WINDOWS32
34−FILETYPE VFT_DLL
35−{
36− BLOCK "StringFileInfo"
37− {
38− BLOCK "040904B0"
39− {
40− VALUE "CompanyName", "FFmpeg Project"
41− VALUE "FileDescription", "Libav audio resampling library"
42− VALUE "FileVersion", AV_STRINGIFY(LIBAVRESAMPLE_VERSION)
43− VALUE "InternalName", "libavresample"
44− VALUE "LegalCopyright", "Copyright (C) 2000-" AV_STRINGIFY(CONFIG_THIS_YEAR) " FFmpeg Project"
45− VALUE "OriginalFilename", "avresample" BUILDSUF "-" AV_STRINGIFY(LIBAVRESAMPLE_VERSION_MAJOR) SLIBSUF
46− VALUE "ProductName", "FFmpeg"
47− VALUE "ProductVersion", FFMPEG_VERSION
48− }
49− }
50−
51− BLOCK "VarFileInfo"
52− {
53− VALUE "Translation", 0x0409, 0x04B0
54− }
55−}
libavresample/dither.c+0−440
@@ -1,440 +0,0 @@
1−/*
2− * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
3− *
4− * Triangular with Noise Shaping is based on opusfile.
5− * Copyright (c) 1994-2012 by the Xiph.Org Foundation and contributors
6− *
7− * This file is part of FFmpeg.
8− *
9− * FFmpeg is free software; you can redistribute it and/or
10− * modify it under the terms of the GNU Lesser General Public
11− * License as published by the Free Software Foundation; either
12− * version 2.1 of the License, or (at your option) any later version.
13− *
14− * FFmpeg is distributed in the hope that it will be useful,
15− * but WITHOUT ANY WARRANTY; without even the implied warranty of
16− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17− * Lesser General Public License for more details.
18− *
19− * You should have received a copy of the GNU Lesser General Public
20− * License along with FFmpeg; if not, write to the Free Software
21− * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22− */
23−
24−/**
25− * @file
26− * Dithered Audio Sample Quantization
27− *
28− * Converts from dbl, flt, or s32 to s16 using dithering.
29− */
30−
31−#include <math.h>
32−#include <stdint.h>
33−
34−#include "libavutil/attributes.h"
35−#include "libavutil/common.h"
36−#include "libavutil/lfg.h"
37−#include "libavutil/mem.h"
38−#include "libavutil/samplefmt.h"
39−#include "audio_convert.h"
40−#include "dither.h"
41−#include "internal.h"
42−
43−typedef struct DitherState {
44− int mute;
45− unsigned int seed;
46− AVLFG lfg;
47− float *noise_buf;
48− int noise_buf_size;
49− int noise_buf_ptr;
50− float dither_a[4];
51− float dither_b[4];
52−} DitherState;
53−
54−struct DitherContext {
55− DitherDSPContext ddsp;
56− enum AVResampleDitherMethod method;
57− int apply_map;
58− ChannelMapInfo *ch_map_info;
59−
60− int mute_dither_threshold; // threshold for disabling dither
61− int mute_reset_threshold; // threshold for resetting noise shaping
62− const float *ns_coef_b; // noise shaping coeffs
63− const float *ns_coef_a; // noise shaping coeffs
64−
65− int channels;
66− DitherState *state; // dither states for each channel
67−
68− AudioData *flt_data; // input data in fltp
69− AudioData *s16_data; // dithered output in s16p
70− AudioConvert *ac_in; // converter for input to fltp
71− AudioConvert *ac_out; // converter for s16p to s16 (if needed)
72−
73− void (*quantize)(int16_t *dst, const float *src, float *dither, int len);
74− int samples_align;
75−};
76−
77−/* mute threshold, in seconds */
78−#define MUTE_THRESHOLD_SEC 0.000333
79−
80−/* scale factor for 16-bit output.
81− The signal is attenuated slightly to avoid clipping */
82−#define S16_SCALE 32753.0f
83−
84−/* scale to convert lfg from INT_MIN/INT_MAX to -0.5/0.5 */
85−#define LFG_SCALE (1.0f / (2.0f * INT32_MAX))
86−
87−/* noise shaping coefficients */
88−
89−static const float ns_48_coef_b[4] = {
90− 2.2374f, -0.7339f, -0.1251f, -0.6033f
91−};
92−
93−static const float ns_48_coef_a[4] = {
94− 0.9030f, 0.0116f, -0.5853f, -0.2571f
95−};
96−
97−static const float ns_44_coef_b[4] = {
98− 2.2061f, -0.4707f, -0.2534f, -0.6213f
99−};
100−
101−static const float ns_44_coef_a[4] = {
102− 1.0587f, 0.0676f, -0.6054f, -0.2738f
103−};
104−
105−static void dither_int_to_float_rectangular_c(float *dst, int *src, int len)
106−{
107− int i;
108− for (i = 0; i < len; i++)
109− dst[i] = src[i] * LFG_SCALE;
110−}
111−
112−static void dither_int_to_float_triangular_c(float *dst, int *src0, int len)
113−{
114− int i;
115− int *src1 = src0 + len;
116−
117− for (i = 0; i < len; i++) {
118− float r = src0[i] * LFG_SCALE;
119− r += src1[i] * LFG_SCALE;
120− dst[i] = r;
121− }
122−}
123−
124−static void quantize_c(int16_t *dst, const float *src, float *dither, int len)
125−{
126− int i;
127− for (i = 0; i < len; i++)
128− dst[i] = av_clip_int16(lrintf(src[i] * S16_SCALE + dither[i]));
129−}
130−
131−#define SQRT_1_6 0.40824829046386301723f
132−
133−static void dither_highpass_filter(float *src, int len)
134−{
135− int i;
136−
137− /* filter is from libswresample in FFmpeg */
138− for (i = 0; i < len - 2; i++)
139− src[i] = (-src[i] + 2 * src[i + 1] - src[i + 2]) * SQRT_1_6;
140−}
141−
142−static int generate_dither_noise(DitherContext *c, DitherState *state,
143− int min_samples)
144−{
145− int i;
146− int nb_samples = FFALIGN(min_samples, 16) + 16;
147− int buf_samples = nb_samples *
148− (c->method == AV_RESAMPLE_DITHER_RECTANGULAR ? 1 : 2);
149− unsigned int *noise_buf_ui;
150−
151− av_freep(&state->noise_buf);
152− state->noise_buf_size = state->noise_buf_ptr = 0;
153−
154− state->noise_buf = av_malloc(buf_samples * sizeof(*state->noise_buf));
155− if (!state->noise_buf)
156− return AVERROR(ENOMEM);
157− state->noise_buf_size = FFALIGN(min_samples, 16);
158− noise_buf_ui = (unsigned int *)state->noise_buf;
159−
160− av_lfg_init(&state->lfg, state->seed);
161− for (i = 0; i < buf_samples; i++)
162− noise_buf_ui[i] = av_lfg_get(&state->lfg);
163−
164− c->ddsp.dither_int_to_float(state->noise_buf, noise_buf_ui, nb_samples);
165−
166− if (c->method == AV_RESAMPLE_DITHER_TRIANGULAR_HP)
167− dither_highpass_filter(state->noise_buf, nb_samples);
168−
169− return 0;
170−}
171−
172−static void quantize_triangular_ns(DitherContext *c, DitherState *state,
173− int16_t *dst, const float *src,
174− int nb_samples)
175−{
176− int i, j;
177− float *dither = &state->noise_buf[state->noise_buf_ptr];
178−
179− if (state->mute > c->mute_reset_threshold)
180− memset(state->dither_a, 0, sizeof(state->dither_a));
181−
182− for (i = 0; i < nb_samples; i++) {
183− float err = 0;
184− float sample = src[i] * S16_SCALE;
185−
186− for (j = 0; j < 4; j++) {
187− err += c->ns_coef_b[j] * state->dither_b[j] -
188− c->ns_coef_a[j] * state->dither_a[j];
189− }
190− for (j = 3; j > 0; j--) {
191− state->dither_a[j] = state->dither_a[j - 1];
192− state->dither_b[j] = state->dither_b[j - 1];
193− }
194− state->dither_a[0] = err;
195− sample -= err;
196−
197− if (state->mute > c->mute_dither_threshold) {
198− dst[i] = av_clip_int16(lrintf(sample));
199− state->dither_b[0] = 0;
200− } else {
201− dst[i] = av_clip_int16(lrintf(sample + dither[i]));
202− state->dither_b[0] = av_clipf(dst[i] - sample, -1.5f, 1.5f);
203− }
204−
205− state->mute++;
206− if (src[i])
207− state->mute = 0;
208− }
209−}
210−
211−static int convert_samples(DitherContext *c, int16_t **dst, float * const *src,
212− int channels, int nb_samples)
213−{
214− int ch, ret;
215− int aligned_samples = FFALIGN(nb_samples, 16);
216−
217− for (ch = 0; ch < channels; ch++) {
218− DitherState *state = &c->state[ch];
219−
220− if (state->noise_buf_size < aligned_samples) {
221− ret = generate_dither_noise(c, state, nb_samples);
222− if (ret < 0)
223− return ret;
224− } else if (state->noise_buf_size - state->noise_buf_ptr < aligned_samples) {
225− state->noise_buf_ptr = 0;
226− }
227−
228− if (c->method == AV_RESAMPLE_DITHER_TRIANGULAR_NS) {
229− quantize_triangular_ns(c, state, dst[ch], src[ch], nb_samples);
230− } else {
231− c->quantize(dst[ch], src[ch],
232− &state->noise_buf[state->noise_buf_ptr],
233− FFALIGN(nb_samples, c->samples_align));
234− }
235−
236− state->noise_buf_ptr += aligned_samples;
237− }
238−
239− return 0;
240−}
241−
242−int ff_convert_dither(DitherContext *c, AudioData *dst, AudioData *src)
243−{
244− int ret;
245− AudioData *flt_data;
246−
247− /* output directly to dst if it is planar */
248− if (dst->sample_fmt == AV_SAMPLE_FMT_S16P)
249− c->s16_data = dst;
250− else {
251− /* make sure s16_data is large enough for the output */
252− ret = ff_audio_data_realloc(c->s16_data, src->nb_samples);
253− if (ret < 0)
254− return ret;
255− }
256−
257− if (src->sample_fmt != AV_SAMPLE_FMT_FLTP || c->apply_map) {
258− /* make sure flt_data is large enough for the input */
259− ret = ff_audio_data_realloc(c->flt_data, src->nb_samples);
260− if (ret < 0)
261− return ret;
262− flt_data = c->flt_data;
263− }
264−
265− if (src->sample_fmt != AV_SAMPLE_FMT_FLTP) {
266− /* convert input samples to fltp and scale to s16 range */
267− ret = ff_audio_convert(c->ac_in, flt_data, src);
268− if (ret < 0)
269− return ret;
270− } else if (c->apply_map) {
271− ret = ff_audio_data_copy(flt_data, src, c->ch_map_info);
272− if (ret < 0)
273− return ret;
274− } else {
275− flt_data = src;
276− }
277−
278− /* check alignment and padding constraints */
279− if (c->method != AV_RESAMPLE_DITHER_TRIANGULAR_NS) {
280− int ptr_align = FFMIN(flt_data->ptr_align, c->s16_data->ptr_align);
281− int samples_align = FFMIN(flt_data->samples_align, c->s16_data->samples_align);
282− int aligned_len = FFALIGN(src->nb_samples, c->ddsp.samples_align);
283−
284− if (!(ptr_align % c->ddsp.ptr_align) && samples_align >= aligned_len) {
285− c->quantize = c->ddsp.quantize;
286− c->samples_align = c->ddsp.samples_align;
287− } else {
288− c->quantize = quantize_c;
289− c->samples_align = 1;
290− }
291− }
292−
293− ret = convert_samples(c, (int16_t **)c->s16_data->data,
294− (float * const *)flt_data->data, src->channels,
295− src->nb_samples);
296− if (ret < 0)
297− return ret;
298−
299− c->s16_data->nb_samples = src->nb_samples;
300−
301− /* interleave output to dst if needed */
302− if (dst->sample_fmt == AV_SAMPLE_FMT_S16) {
303− ret = ff_audio_convert(c->ac_out, dst, c->s16_data);
304− if (ret < 0)
305− return ret;
306− } else
307− c->s16_data = NULL;
308−
309− return 0;
310−}
311−
312−void ff_dither_free(DitherContext **cp)
313−{
314− DitherContext *c = *cp;
315− int ch;
316−
317− if (!c)
318− return;
319− ff_audio_data_free(&c->flt_data);
320− ff_audio_data_free(&c->s16_data);
321− ff_audio_convert_free(&c->ac_in);
322− ff_audio_convert_free(&c->ac_out);
323− for (ch = 0; ch < c->channels; ch++)
324− av_free(c->state[ch].noise_buf);
325− av_free(c->state);
326− av_freep(cp);
327−}
328−
329−static av_cold void dither_init(DitherDSPContext *ddsp,
330− enum AVResampleDitherMethod method)
331−{
332− ddsp->quantize = quantize_c;
333− ddsp->ptr_align = 1;
334− ddsp->samples_align = 1;
335−
336− if (method == AV_RESAMPLE_DITHER_RECTANGULAR)
337− ddsp->dither_int_to_float = dither_int_to_float_rectangular_c;
338− else
339− ddsp->dither_int_to_float = dither_int_to_float_triangular_c;
340−
341− if (ARCH_X86)
342− ff_dither_init_x86(ddsp, method);
343−}
344−
345−DitherContext *ff_dither_alloc(AVAudioResampleContext *avr,
346− enum AVSampleFormat out_fmt,
347− enum AVSampleFormat in_fmt,
348− int channels, int sample_rate, int apply_map)
349−{
350− AVLFG seed_gen;
351− DitherContext *c;
352− int ch;
353−
354− if (av_get_packed_sample_fmt(out_fmt) != AV_SAMPLE_FMT_S16 ||
355− av_get_bytes_per_sample(in_fmt) <= 2) {
356− av_log(avr, AV_LOG_ERROR, "dithering %s to %s is not supported\n",
357− av_get_sample_fmt_name(in_fmt), av_get_sample_fmt_name(out_fmt));
358− return NULL;
359− }
360−
361− c = av_mallocz(sizeof(*c));
362− if (!c)
363− return NULL;
364−
365− c->apply_map = apply_map;
366− if (apply_map)
367− c->ch_map_info = &avr->ch_map_info;
368−
369− if (avr->dither_method == AV_RESAMPLE_DITHER_TRIANGULAR_NS &&
370− sample_rate != 48000 && sample_rate != 44100) {
371− av_log(avr, AV_LOG_WARNING, "sample rate must be 48000 or 44100 Hz "
372− "for triangular_ns dither. using triangular_hp instead.\n");
373− avr->dither_method = AV_RESAMPLE_DITHER_TRIANGULAR_HP;
374− }
375− c->method = avr->dither_method;
376− dither_init(&c->ddsp, c->method);
377−
378− if (c->method == AV_RESAMPLE_DITHER_TRIANGULAR_NS) {
379− if (sample_rate == 48000) {
380− c->ns_coef_b = ns_48_coef_b;
381− c->ns_coef_a = ns_48_coef_a;
382− } else {
383− c->ns_coef_b = ns_44_coef_b;
384− c->ns_coef_a = ns_44_coef_a;
385− }
386− }
387−
388− /* Either s16 or s16p output format is allowed, but s16p is used
389− internally, so we need to use a temp buffer and interleave if the output
390− format is s16 */
391− if (out_fmt != AV_SAMPLE_FMT_S16P) {
392− c->s16_data = ff_audio_data_alloc(channels, 1024, AV_SAMPLE_FMT_S16P,
393− "dither s16 buffer");
394− if (!c->s16_data)
395− goto fail;
396−
397− c->ac_out = ff_audio_convert_alloc(avr, out_fmt, AV_SAMPLE_FMT_S16P,
398− channels, sample_rate, 0);
399− if (!c->ac_out)
400− goto fail;
401− }
402−
403− if (in_fmt != AV_SAMPLE_FMT_FLTP || c->apply_map) {
404− c->flt_data = ff_audio_data_alloc(channels, 1024, AV_SAMPLE_FMT_FLTP,
405− "dither flt buffer");
406− if (!c->flt_data)
407− goto fail;
408− }
409− if (in_fmt != AV_SAMPLE_FMT_FLTP) {
410− c->ac_in = ff_audio_convert_alloc(avr, AV_SAMPLE_FMT_FLTP, in_fmt,
411− channels, sample_rate, c->apply_map);
412− if (!c->ac_in)
413− goto fail;
414− }
415−
416− c->state = av_mallocz(channels * sizeof(*c->state));
417− if (!c->state)
418− goto fail;
419− c->channels = channels;
420−
421− /* calculate thresholds for turning off dithering during periods of
422− silence to avoid replacing digital silence with quiet dither noise */
423− c->mute_dither_threshold = lrintf(sample_rate * MUTE_THRESHOLD_SEC);
424− c->mute_reset_threshold = c->mute_dither_threshold * 4;
425−
426− /* initialize dither states */
427− av_lfg_init(&seed_gen, 0xC0FFEE);
428− for (ch = 0; ch < channels; ch++) {
429− DitherState *state = &c->state[ch];
430− state->mute = c->mute_reset_threshold + 1;
431− state->seed = av_lfg_get(&seed_gen);
432− generate_dither_noise(c, state, FFMAX(32768, sample_rate / 2));
433− }
434−
435− return c;
436−
437−fail:
438− ff_dither_free(&c);
439− return NULL;
440−}
libavresample/dither.h+0−93
@@ -1,93 +0,0 @@
1−/*
2− * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
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−
21−#ifndef AVRESAMPLE_DITHER_H
22−#define AVRESAMPLE_DITHER_H
23−
24−#include "avresample.h"
25−#include "audio_data.h"
26−
27−typedef struct DitherContext DitherContext;
28−
29−typedef struct DitherDSPContext {
30− /**
31− * Convert samples from flt to s16 with added dither noise.
32− *
33− * @param dst destination float array, range -0.5 to 0.5
34− * @param src source int array, range INT_MIN to INT_MAX.
35− * @param dither float dither noise array
36− * @param len number of samples
37− */
38− void (*quantize)(int16_t *dst, const float *src, float *dither, int len);
39−
40− int ptr_align; ///< src and dst constraints for quantize()
41− int samples_align; ///< len constraints for quantize()
42−
43− /**
44− * Convert dither noise from int to float with triangular distribution.
45− *
46− * @param dst destination float array, range -0.5 to 0.5
47− * constraints: 32-byte aligned
48− * @param src0 source int array, range INT_MIN to INT_MAX.
49− * the array size is len * 2
50− * constraints: 32-byte aligned
51− * @param len number of output noise samples
52− * constraints: multiple of 16
53− */
54− void (*dither_int_to_float)(float *dst, int *src0, int len);
55−} DitherDSPContext;
56−
57−/**
58− * Allocate and initialize a DitherContext.
59− *
60− * The parameters in the AVAudioResampleContext are used to initialize the
61− * DitherContext.
62− *
63− * @param avr AVAudioResampleContext
64− * @return newly-allocated DitherContext
65− */
66−DitherContext *ff_dither_alloc(AVAudioResampleContext *avr,
67− enum AVSampleFormat out_fmt,
68− enum AVSampleFormat in_fmt,
69− int channels, int sample_rate, int apply_map);
70−
71−/**
72− * Free a DitherContext.
73− *
74− * @param c DitherContext
75− */
76−void ff_dither_free(DitherContext **c);
77−
78−/**
79− * Convert audio sample format with dithering.
80− *
81− * @param c DitherContext
82− * @param dst destination audio data
83− * @param src source audio data
84− * @return 0 if ok, negative AVERROR code on failure
85− */
86−int ff_convert_dither(DitherContext *c, AudioData *dst, AudioData *src);
87−
88−/* arch-specific initialization functions */
89−
90−void ff_dither_init_x86(DitherDSPContext *ddsp,
91− enum AVResampleDitherMethod method);
92−
93−#endif /* AVRESAMPLE_DITHER_H */
libavresample/internal.h+0−116
@@ -1,116 +0,0 @@
1−/*
2− * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
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−
21−#ifndef AVRESAMPLE_INTERNAL_H
22−#define AVRESAMPLE_INTERNAL_H
23−
24−#include "libavutil/audio_fifo.h"
25−#include "libavutil/log.h"
26−#include "libavutil/opt.h"
27−#include "libavutil/samplefmt.h"
28−#include "avresample.h"
29−
30−typedef struct AudioData AudioData;
31−typedef struct AudioConvert AudioConvert;
32−typedef struct AudioMix AudioMix;
33−typedef struct ResampleContext ResampleContext;
34−
35−enum RemapPoint {
36− REMAP_NONE,
37− REMAP_IN_COPY,
38− REMAP_IN_CONVERT,
39− REMAP_OUT_COPY,
40− REMAP_OUT_CONVERT,
41−};
42−
43−typedef struct ChannelMapInfo {
44− int channel_map[AVRESAMPLE_MAX_CHANNELS]; /**< source index of each output channel, -1 if not remapped */
45− int do_remap; /**< remap needed */
46− int channel_copy[AVRESAMPLE_MAX_CHANNELS]; /**< dest index to copy from */
47− int do_copy; /**< copy needed */
48− int channel_zero[AVRESAMPLE_MAX_CHANNELS]; /**< dest index to zero */
49− int do_zero; /**< zeroing needed */
50− int input_map[AVRESAMPLE_MAX_CHANNELS]; /**< dest index of each input channel */
51−} ChannelMapInfo;
52−
53−struct AVAudioResampleContext {
54− const AVClass *av_class; /**< AVClass for logging and AVOptions */
55−
56− uint64_t in_channel_layout; /**< input channel layout */
57− enum AVSampleFormat in_sample_fmt; /**< input sample format */
58− int in_sample_rate; /**< input sample rate */
59− uint64_t out_channel_layout; /**< output channel layout */
60− enum AVSampleFormat out_sample_fmt; /**< output sample format */
61− int out_sample_rate; /**< output sample rate */
62− enum AVSampleFormat internal_sample_fmt; /**< internal sample format */
63− enum AVMixCoeffType mix_coeff_type; /**< mixing coefficient type */
64− double center_mix_level; /**< center mix level */
65− double surround_mix_level; /**< surround mix level */
66− double lfe_mix_level; /**< lfe mix level */
67− int normalize_mix_level; /**< enable mix level normalization */
68− int force_resampling; /**< force resampling */
69− int filter_size; /**< length of each FIR filter in the resampling filterbank relative to the cutoff frequency */
70− int phase_shift; /**< log2 of the number of entries in the resampling polyphase filterbank */
71− int linear_interp; /**< if 1 then the resampling FIR filter will be linearly interpolated */
72− double cutoff; /**< resampling cutoff frequency. 1.0 corresponds to half the output sample rate */
73− enum AVResampleFilterType filter_type; /**< resampling filter type */
74− int kaiser_beta; /**< beta value for Kaiser window (only applicable if filter_type == AV_FILTER_TYPE_KAISER) */
75− enum AVResampleDitherMethod dither_method; /**< dither method */
76−
77− int in_channels; /**< number of input channels */
78− int out_channels; /**< number of output channels */
79− int resample_channels; /**< number of channels used for resampling */
80− int downmix_needed; /**< downmixing is needed */
81− int upmix_needed; /**< upmixing is needed */
82− int mixing_needed; /**< either upmixing or downmixing is needed */
83− int resample_needed; /**< resampling is needed */
84− int in_convert_needed; /**< input sample format conversion is needed */
85− int out_convert_needed; /**< output sample format conversion is needed */
86− int in_copy_needed; /**< input data copy is needed */
87−
88− AudioData *in_buffer; /**< buffer for converted input */
89− AudioData *resample_out_buffer; /**< buffer for output from resampler */
90− AudioData *out_buffer; /**< buffer for converted output */
91− AVAudioFifo *out_fifo; /**< FIFO for output samples */
92−
93− AudioConvert *ac_in; /**< input sample format conversion context */
94− AudioConvert *ac_out; /**< output sample format conversion context */
95− ResampleContext *resample; /**< resampling context */
96− AudioMix *am; /**< channel mixing context */
97− enum AVMatrixEncoding matrix_encoding; /**< matrixed stereo encoding */
98−
99− /**
100− * mix matrix
101− * only used if avresample_set_matrix() is called before avresample_open()
102− */
103− double *mix_matrix;
104−
105− int use_channel_map;
106− enum RemapPoint remap_point;
107− ChannelMapInfo ch_map_info;
108−};
109−
110−
111−void ff_audio_resample_init_aarch64(ResampleContext *c,
112− enum AVSampleFormat sample_fmt);
113−void ff_audio_resample_init_arm(ResampleContext *c,
114− enum AVSampleFormat sample_fmt);
115−
116−#endif /* AVRESAMPLE_INTERNAL_H */
libavresample/libavresample.v+0−6
@@ -1,6 +0,0 @@
1−LIBAVRESAMPLE_MAJOR {
2− global:
3− av*;
4− local:
5− *;
6−};
libavresample/options.c+0−113
@@ -1,113 +0,0 @@
1−/*
2− * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
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−
21−#include <stdint.h>
22−
23−#include "libavutil/mathematics.h"
24−#include "libavutil/mem.h"
25−#include "libavutil/opt.h"
26−#include "avresample.h"
27−#include "internal.h"
28−#include "audio_mix.h"
29−
30−/**
31− * @file
32− * Options definition for AVAudioResampleContext.
33− */
34−
35−#define OFFSET(x) offsetof(AVAudioResampleContext, x)
36−#define PARAM AV_OPT_FLAG_AUDIO_PARAM
37−
38−static const AVOption avresample_options[] = {
39− { "in_channel_layout", "Input Channel Layout", OFFSET(in_channel_layout), AV_OPT_TYPE_INT64, { .i64 = 0 }, INT64_MIN, INT64_MAX, PARAM },
40− { "in_sample_fmt", "Input Sample Format", OFFSET(in_sample_fmt), AV_OPT_TYPE_INT, { .i64 = AV_SAMPLE_FMT_S16 }, AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_NB-1, PARAM },
41− { "in_sample_rate", "Input Sample Rate", OFFSET(in_sample_rate), AV_OPT_TYPE_INT, { .i64 = 48000 }, 1, INT_MAX, PARAM },
42− { "out_channel_layout", "Output Channel Layout", OFFSET(out_channel_layout), AV_OPT_TYPE_INT64, { .i64 = 0 }, INT64_MIN, INT64_MAX, PARAM },
43− { "out_sample_fmt", "Output Sample Format", OFFSET(out_sample_fmt), AV_OPT_TYPE_INT, { .i64 = AV_SAMPLE_FMT_S16 }, AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_NB-1, PARAM },
44− { "out_sample_rate", "Output Sample Rate", OFFSET(out_sample_rate), AV_OPT_TYPE_INT, { .i64 = 48000 }, 1, INT_MAX, PARAM },
45− { "internal_sample_fmt", "Internal Sample Format", OFFSET(internal_sample_fmt), AV_OPT_TYPE_INT, { .i64 = AV_SAMPLE_FMT_NONE }, AV_SAMPLE_FMT_NONE, AV_SAMPLE_FMT_NB-1, PARAM, "internal_sample_fmt" },
46− {"u8" , "8-bit unsigned integer", 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_U8 }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
47− {"s16", "16-bit signed integer", 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_S16 }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
48− {"s32", "32-bit signed integer", 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_S32 }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
49− {"flt", "32-bit float", 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_FLT }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
50− {"dbl", "64-bit double", 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_DBL }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
51− {"u8p" , "8-bit unsigned integer planar", 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_U8P }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
52− {"s16p", "16-bit signed integer planar", 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_S16P }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
53− {"s32p", "32-bit signed integer planar", 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_S32P }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
54− {"fltp", "32-bit float planar", 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_FLTP }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
55− {"dblp", "64-bit double planar", 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_DBLP }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
56− { "mix_coeff_type", "Mixing Coefficient Type", OFFSET(mix_coeff_type), AV_OPT_TYPE_INT, { .i64 = AV_MIX_COEFF_TYPE_FLT }, AV_MIX_COEFF_TYPE_Q8, AV_MIX_COEFF_TYPE_NB-1, PARAM, "mix_coeff_type" },
57− { "q8", "16-bit 8.8 Fixed-Point", 0, AV_OPT_TYPE_CONST, { .i64 = AV_MIX_COEFF_TYPE_Q8 }, INT_MIN, INT_MAX, PARAM, "mix_coeff_type" },
58− { "q15", "32-bit 17.15 Fixed-Point", 0, AV_OPT_TYPE_CONST, { .i64 = AV_MIX_COEFF_TYPE_Q15 }, INT_MIN, INT_MAX, PARAM, "mix_coeff_type" },
59− { "flt", "Floating-Point", 0, AV_OPT_TYPE_CONST, { .i64 = AV_MIX_COEFF_TYPE_FLT }, INT_MIN, INT_MAX, PARAM, "mix_coeff_type" },
60− { "center_mix_level", "Center Mix Level", OFFSET(center_mix_level), AV_OPT_TYPE_DOUBLE, { .dbl = M_SQRT1_2 }, -32.0, 32.0, PARAM },
61− { "surround_mix_level", "Surround Mix Level", OFFSET(surround_mix_level), AV_OPT_TYPE_DOUBLE, { .dbl = M_SQRT1_2 }, -32.0, 32.0, PARAM },
62− { "lfe_mix_level", "LFE Mix Level", OFFSET(lfe_mix_level), AV_OPT_TYPE_DOUBLE, { .dbl = 0.0 }, -32.0, 32.0, PARAM },
63− { "normalize_mix_level", "Normalize Mix Level", OFFSET(normalize_mix_level), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, PARAM },
64− { "force_resampling", "Force Resampling", OFFSET(force_resampling), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, PARAM },
65− { "filter_size", "Resampling Filter Size", OFFSET(filter_size), AV_OPT_TYPE_INT, { .i64 = 16 }, 0, 32, /* ??? */ PARAM },
66− { "phase_shift", "Resampling Phase Shift", OFFSET(phase_shift), AV_OPT_TYPE_INT, { .i64 = 10 }, 0, 30, /* ??? */ PARAM },
67− { "linear_interp", "Use Linear Interpolation", OFFSET(linear_interp), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, PARAM },
68− { "cutoff", "Cutoff Frequency Ratio", OFFSET(cutoff), AV_OPT_TYPE_DOUBLE, { .dbl = 0.8 }, 0.0, 1.0, PARAM },
69− /* duplicate option in order to work with avconv */
70− { "resample_cutoff", "Cutoff Frequency Ratio", OFFSET(cutoff), AV_OPT_TYPE_DOUBLE, { .dbl = 0.8 }, 0.0, 1.0, PARAM },
71− { "matrix_encoding", "Matrixed Stereo Encoding", OFFSET(matrix_encoding), AV_OPT_TYPE_INT, {.i64 = AV_MATRIX_ENCODING_NONE}, AV_MATRIX_ENCODING_NONE, AV_MATRIX_ENCODING_NB-1, PARAM, "matrix_encoding" },
72− { "none", "None", 0, AV_OPT_TYPE_CONST, { .i64 = AV_MATRIX_ENCODING_NONE }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
73− { "dolby", "Dolby", 0, AV_OPT_TYPE_CONST, { .i64 = AV_MATRIX_ENCODING_DOLBY }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
74− { "dplii", "Dolby Pro Logic II", 0, AV_OPT_TYPE_CONST, { .i64 = AV_MATRIX_ENCODING_DPLII }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
75− { "filter_type", "Filter Type", OFFSET(filter_type), AV_OPT_TYPE_INT, { .i64 = AV_RESAMPLE_FILTER_TYPE_KAISER }, AV_RESAMPLE_FILTER_TYPE_CUBIC, AV_RESAMPLE_FILTER_TYPE_KAISER, PARAM, "filter_type" },
76− { "cubic", "Cubic", 0, AV_OPT_TYPE_CONST, { .i64 = AV_RESAMPLE_FILTER_TYPE_CUBIC }, INT_MIN, INT_MAX, PARAM, "filter_type" },
77− { "blackman_nuttall", "Blackman Nuttall Windowed Sinc", 0, AV_OPT_TYPE_CONST, { .i64 = AV_RESAMPLE_FILTER_TYPE_BLACKMAN_NUTTALL }, INT_MIN, INT_MAX, PARAM, "filter_type" },
78− { "kaiser", "Kaiser Windowed Sinc", 0, AV_OPT_TYPE_CONST, { .i64 = AV_RESAMPLE_FILTER_TYPE_KAISER }, INT_MIN, INT_MAX, PARAM, "filter_type" },
79− { "kaiser_beta", "Kaiser Window Beta", OFFSET(kaiser_beta), AV_OPT_TYPE_INT, { .i64 = 9 }, 2, 16, PARAM },
80− { "dither_method", "Dither Method", OFFSET(dither_method), AV_OPT_TYPE_INT, { .i64 = AV_RESAMPLE_DITHER_NONE }, 0, AV_RESAMPLE_DITHER_NB-1, PARAM, "dither_method"},
81− {"none", "No Dithering", 0, AV_OPT_TYPE_CONST, { .i64 = AV_RESAMPLE_DITHER_NONE }, INT_MIN, INT_MAX, PARAM, "dither_method"},
82− {"rectangular", "Rectangular Dither", 0, AV_OPT_TYPE_CONST, { .i64 = AV_RESAMPLE_DITHER_RECTANGULAR }, INT_MIN, INT_MAX, PARAM, "dither_method"},
83− {"triangular", "Triangular Dither", 0, AV_OPT_TYPE_CONST, { .i64 = AV_RESAMPLE_DITHER_TRIANGULAR }, INT_MIN, INT_MAX, PARAM, "dither_method"},
84− {"triangular_hp", "Triangular Dither With High Pass", 0, AV_OPT_TYPE_CONST, { .i64 = AV_RESAMPLE_DITHER_TRIANGULAR_HP }, INT_MIN, INT_MAX, PARAM, "dither_method"},
85− {"triangular_ns", "Triangular Dither With Noise Shaping", 0, AV_OPT_TYPE_CONST, { .i64 = AV_RESAMPLE_DITHER_TRIANGULAR_NS }, INT_MIN, INT_MAX, PARAM, "dither_method"},
86− { NULL },
87−};
88−
89−static const AVClass av_resample_context_class = {
90− .class_name = "AVAudioResampleContext",
91− .item_name = av_default_item_name,
92− .option = avresample_options,
93− .version = LIBAVUTIL_VERSION_INT,
94−};
95−
96−AVAudioResampleContext *avresample_alloc_context(void)
97−{
98− AVAudioResampleContext *avr;
99−
100− avr = av_mallocz(sizeof(*avr));
101− if (!avr)
102− return NULL;
103−
104− avr->av_class = &av_resample_context_class;
105− av_opt_set_defaults(avr);
106−
107− return avr;
108−}
109−
110−const AVClass *avresample_get_class(void)
111−{
112− return &av_resample_context_class;
113−}
libavresample/resample.c+0−446
@@ -1,446 +0,0 @@
1−/*
2− * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
3− * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
4− *
5− * This file is part of FFmpeg.
6− *
7− * FFmpeg is free software; you can redistribute it and/or
8− * modify it under the terms of the GNU Lesser General Public
9− * License as published by the Free Software Foundation; either
10− * version 2.1 of the License, or (at your option) any later version.
11− *
12− * FFmpeg is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15− * Lesser General Public License for more details.
16− *
17− * You should have received a copy of the GNU Lesser General Public
18− * License along with FFmpeg; if not, write to the Free Software
19− * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20− */
21−
22−#include "libavutil/common.h"
23−#include "libavutil/libm.h"
24−#include "libavutil/log.h"
25−#include "internal.h"
26−#include "resample.h"
27−#include "audio_data.h"
28−
29−
30−/* double template */
31−#define CONFIG_RESAMPLE_DBL
32−#include "resample_template.c"
33−#undef CONFIG_RESAMPLE_DBL
34−
35−/* float template */
36−#define CONFIG_RESAMPLE_FLT
37−#include "resample_template.c"
38−#undef CONFIG_RESAMPLE_FLT
39−
40−/* s32 template */
41−#define CONFIG_RESAMPLE_S32
42−#include "resample_template.c"
43−#undef CONFIG_RESAMPLE_S32
44−
45−/* s16 template */
46−#include "resample_template.c"
47−
48−
49−/* 0th order modified Bessel function of the first kind. */
50−static double bessel(double x)
51−{
52− double v = 1;
53− double lastv = 0;
54− double t = 1;
55− int i;
56−
57− x = x * x / 4;
58− for (i = 1; v != lastv; i++) {
59− lastv = v;
60− t *= x / (i * i);
61− v += t;
62− }
63− return v;
64−}
65−
66−/* Build a polyphase filterbank. */
67−static int build_filter(ResampleContext *c, double factor)
68−{
69− int ph, i;
70− double x, y, w;
71− double *tab;
72− int tap_count = c->filter_length;
73− int phase_count = 1 << c->phase_shift;
74− const int center = (tap_count - 1) / 2;
75−
76− tab = av_malloc(tap_count * sizeof(*tab));
77− if (!tab)
78− return AVERROR(ENOMEM);
79−
80− for (ph = 0; ph < phase_count; ph++) {
81− double norm = 0;
82− for (i = 0; i < tap_count; i++) {
83− x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor;
84− if (x == 0) y = 1.0;
85− else y = sin(x) / x;
86− switch (c->filter_type) {
87− case AV_RESAMPLE_FILTER_TYPE_CUBIC: {
88− const float d = -0.5; //first order derivative = -0.5
89− x = fabs(((double)(i - center) - (double)ph / phase_count) * factor);
90− if (x < 1.0) y = 1 - 3 * x*x + 2 * x*x*x + d * ( -x*x + x*x*x);
91− else y = d * (-4 + 8 * x - 5 * x*x + x*x*x);
92− break;
93− }
94− case AV_RESAMPLE_FILTER_TYPE_BLACKMAN_NUTTALL:
95− w = 2.0 * x / (factor * tap_count) + M_PI;
96− y *= 0.3635819 - 0.4891775 * cos( w) +
97− 0.1365995 * cos(2 * w) -
98− 0.0106411 * cos(3 * w);
99− break;
100− case AV_RESAMPLE_FILTER_TYPE_KAISER:
101− w = 2.0 * x / (factor * tap_count * M_PI);
102− y *= bessel(c->kaiser_beta * sqrt(FFMAX(1 - w * w, 0)));
103− break;
104− }
105−
106− tab[i] = y;
107− norm += y;
108− }
109− /* normalize so that an uniform color remains the same */
110− for (i = 0; i < tap_count; i++)
111− tab[i] = tab[i] / norm;
112−
113− c->set_filter(c->filter_bank, tab, ph, tap_count);
114− }
115−
116− av_free(tab);
117− return 0;
118−}
119−
120−ResampleContext *ff_audio_resample_init(AVAudioResampleContext *avr)
121−{
122− ResampleContext *c;
123− int out_rate = avr->out_sample_rate;
124− int in_rate = avr->in_sample_rate;
125− double factor = FFMIN(out_rate * avr->cutoff / in_rate, 1.0);
126− int phase_count = 1 << avr->phase_shift;
127− int felem_size;
128−
129− if (avr->internal_sample_fmt != AV_SAMPLE_FMT_S16P &&
130− avr->internal_sample_fmt != AV_SAMPLE_FMT_S32P &&
131− avr->internal_sample_fmt != AV_SAMPLE_FMT_FLTP &&
132− avr->internal_sample_fmt != AV_SAMPLE_FMT_DBLP) {
133− av_log(avr, AV_LOG_ERROR, "Unsupported internal format for "
134− "resampling: %s\n",
135− av_get_sample_fmt_name(avr->internal_sample_fmt));
136− return NULL;
137− }
138− c = av_mallocz(sizeof(*c));
139− if (!c)
140− return NULL;
141−
142− c->avr = avr;
143− c->phase_shift = avr->phase_shift;
144− c->phase_mask = phase_count - 1;
145− c->linear = avr->linear_interp;
146− c->filter_length = FFMAX((int)ceil(avr->filter_size / factor), 1);
147− c->filter_type = avr->filter_type;
148− c->kaiser_beta = avr->kaiser_beta;
149−
150− switch (avr->internal_sample_fmt) {
151− case AV_SAMPLE_FMT_DBLP:
152− c->resample_one = c->linear ? resample_linear_dbl : resample_one_dbl;
153− c->resample_nearest = resample_nearest_dbl;
154− c->set_filter = set_filter_dbl;
155− break;
156− case AV_SAMPLE_FMT_FLTP:
157− c->resample_one = c->linear ? resample_linear_flt : resample_one_flt;
158− c->resample_nearest = resample_nearest_flt;
159− c->set_filter = set_filter_flt;
160− break;
161− case AV_SAMPLE_FMT_S32P:
162− c->resample_one = c->linear ? resample_linear_s32 : resample_one_s32;
163− c->resample_nearest = resample_nearest_s32;
164− c->set_filter = set_filter_s32;
165− break;
166− case AV_SAMPLE_FMT_S16P:
167− c->resample_one = c->linear ? resample_linear_s16 : resample_one_s16;
168− c->resample_nearest = resample_nearest_s16;
169− c->set_filter = set_filter_s16;
170− break;
171− }
172−
173− if (ARCH_AARCH64)
174− ff_audio_resample_init_aarch64(c, avr->internal_sample_fmt);
175− if (ARCH_ARM)
176− ff_audio_resample_init_arm(c, avr->internal_sample_fmt);
177−
178− felem_size = av_get_bytes_per_sample(avr->internal_sample_fmt);
179− c->filter_bank = av_mallocz(c->filter_length * (phase_count + 1) * felem_size);
180− if (!c->filter_bank)
181− goto error;
182−
183− if (build_filter(c, factor) < 0)
184− goto error;
185−
186− memcpy(&c->filter_bank[(c->filter_length * phase_count + 1) * felem_size],
187− c->filter_bank, (c->filter_length - 1) * felem_size);
188− memcpy(&c->filter_bank[c->filter_length * phase_count * felem_size],
189− &c->filter_bank[(c->filter_length - 1) * felem_size], felem_size);
190−
191− c->compensation_distance = 0;
192− if (!av_reduce(&c->src_incr, &c->dst_incr, out_rate,
193− in_rate * (int64_t)phase_count, INT32_MAX / 2))
194− goto error;
195− c->ideal_dst_incr = c->dst_incr;
196−
197− c->padding_size = (c->filter_length - 1) / 2;
198− c->initial_padding_filled = 0;
199− c->index = 0;
200− c->frac = 0;
201−
202− /* allocate internal buffer */
203− c->buffer = ff_audio_data_alloc(avr->resample_channels, c->padding_size,
204− avr->internal_sample_fmt,
205− "resample buffer");
206− if (!c->buffer)
207− goto error;
208− c->buffer->nb_samples = c->padding_size;
209− c->initial_padding_samples = c->padding_size;
210−
211− av_log(avr, AV_LOG_DEBUG, "resample: %s from %d Hz to %d Hz\n",
212− av_get_sample_fmt_name(avr->internal_sample_fmt),
213− avr->in_sample_rate, avr->out_sample_rate);
214−
215− return c;
216−
217−error:
218− ff_audio_data_free(&c->buffer);
219− av_free(c->filter_bank);
220− av_free(c);
221− return NULL;
222−}
223−
224−void ff_audio_resample_free(ResampleContext **c)
225−{
226− if (!*c)
227− return;
228− ff_audio_data_free(&(*c)->buffer);
229− av_free((*c)->filter_bank);
230− av_freep(c);
231−}
232−
233−int avresample_set_compensation(AVAudioResampleContext *avr, int sample_delta,
234− int compensation_distance)
235−{
236− ResampleContext *c;
237−
238− if (compensation_distance < 0)
239− return AVERROR(EINVAL);
240− if (!compensation_distance && sample_delta)
241− return AVERROR(EINVAL);
242−
243− if (!avr->resample_needed) {
244− av_log(avr, AV_LOG_ERROR, "Unable to set resampling compensation\n");
245− return AVERROR(EINVAL);
246− }
247− c = avr->resample;
248− c->compensation_distance = compensation_distance;
249− if (compensation_distance) {
250− c->dst_incr = c->ideal_dst_incr - c->ideal_dst_incr *
251− (int64_t)sample_delta / compensation_distance;
252− } else {
253− c->dst_incr = c->ideal_dst_incr;
254− }
255−
256− return 0;
257−}
258−
259−static int resample(ResampleContext *c, void *dst, const void *src,
260− int *consumed, int src_size, int dst_size, int update_ctx,
261− int nearest_neighbour)
262−{
263− int dst_index;
264− unsigned int index = c->index;
265− int frac = c->frac;
266− int dst_incr_frac = c->dst_incr % c->src_incr;
267− int dst_incr = c->dst_incr / c->src_incr;
268− int compensation_distance = c->compensation_distance;
269−
270− if (!dst != !src)
271− return AVERROR(EINVAL);
272−
273− if (nearest_neighbour) {
274− uint64_t index2 = ((uint64_t)index) << 32;
275− int64_t incr = (1LL << 32) * c->dst_incr / c->src_incr;
276− dst_size = FFMIN(dst_size,
277− (src_size-1-index) * (int64_t)c->src_incr /
278− c->dst_incr);
279−
280− if (dst) {
281− for(dst_index = 0; dst_index < dst_size; dst_index++) {
282− c->resample_nearest(dst, dst_index, src, index2 >> 32);
283− index2 += incr;
284− }
285− } else {
286− dst_index = dst_size;
287− }
288− index += dst_index * dst_incr;
289− index += (frac + dst_index * (int64_t)dst_incr_frac) / c->src_incr;
290− frac = (frac + dst_index * (int64_t)dst_incr_frac) % c->src_incr;
291− } else {
292− for (dst_index = 0; dst_index < dst_size; dst_index++) {
293− int sample_index = index >> c->phase_shift;
294−
295− if (sample_index + c->filter_length > src_size)
296− break;
297−
298− if (dst)
299− c->resample_one(c, dst, dst_index, src, index, frac);
300−
301− frac += dst_incr_frac;
302− index += dst_incr;
303− if (frac >= c->src_incr) {
304− frac -= c->src_incr;
305− index++;
306− }
307− if (dst_index + 1 == compensation_distance) {
308− compensation_distance = 0;
309− dst_incr_frac = c->ideal_dst_incr % c->src_incr;
310− dst_incr = c->ideal_dst_incr / c->src_incr;
311− }
312− }
313− }
314− if (consumed)
315− *consumed = index >> c->phase_shift;
316−
317− if (update_ctx) {
318− index &= c->phase_mask;
319−
320− if (compensation_distance) {
321− compensation_distance -= dst_index;
322− if (compensation_distance <= 0)
323− return AVERROR_BUG;
324− }
325− c->frac = frac;
326− c->index = index;
327− c->dst_incr = dst_incr_frac + c->src_incr*dst_incr;
328− c->compensation_distance = compensation_distance;
329− }
330−
331− return dst_index;
332−}
333−
334−int ff_audio_resample(ResampleContext *c, AudioData *dst, AudioData *src)
335−{
336− int ch, in_samples, in_leftover, consumed = 0, out_samples = 0;
337− int ret = AVERROR(EINVAL);
338− int nearest_neighbour = (c->compensation_distance == 0 &&
339− c->filter_length == 1 &&
340− c->phase_shift == 0);
341−
342− in_samples = src ? src->nb_samples : 0;
343− in_leftover = c->buffer->nb_samples;
344−
345− /* add input samples to the internal buffer */
346− if (src) {
347− ret = ff_audio_data_combine(c->buffer, in_leftover, src, 0, in_samples);
348− if (ret < 0)
349− return ret;
350− } else if (in_leftover <= c->final_padding_samples) {
351− /* no remaining samples to flush */
352− return 0;
353− }
354−
355− if (!c->initial_padding_filled) {
356− int bps = av_get_bytes_per_sample(c->avr->internal_sample_fmt);
357− int i;
358−
359− if (src && c->buffer->nb_samples < 2 * c->padding_size)
360− return 0;
361−
362− for (i = 0; i < c->padding_size; i++)
363− for (ch = 0; ch < c->buffer->channels; ch++) {
364− if (c->buffer->nb_samples > 2 * c->padding_size - i) {
365− memcpy(c->buffer->data[ch] + bps * i,
366− c->buffer->data[ch] + bps * (2 * c->padding_size - i), bps);
367− } else {
368− memset(c->buffer->data[ch] + bps * i, 0, bps);
369− }
370− }
371− c->initial_padding_filled = 1;
372− }
373−
374− if (!src && !c->final_padding_filled) {
375− int bps = av_get_bytes_per_sample(c->avr->internal_sample_fmt);
376− int i;
377−
378− ret = ff_audio_data_realloc(c->buffer,
379− FFMAX(in_samples, in_leftover) +
380− c->padding_size);
381− if (ret < 0) {
382− av_log(c->avr, AV_LOG_ERROR, "Error reallocating resampling buffer\n");
383− return AVERROR(ENOMEM);
384− }
385−
386− for (i = 0; i < c->padding_size; i++)
387− for (ch = 0; ch < c->buffer->channels; ch++) {
388− if (in_leftover > i) {
389− memcpy(c->buffer->data[ch] + bps * (in_leftover + i),
390− c->buffer->data[ch] + bps * (in_leftover - i - 1),
391− bps);
392− } else {
393− memset(c->buffer->data[ch] + bps * (in_leftover + i),
394− 0, bps);
395− }
396− }
397− c->buffer->nb_samples += c->padding_size;
398− c->final_padding_samples = c->padding_size;
399− c->final_padding_filled = 1;
400− }
401−
402−
403− /* calculate output size and reallocate output buffer if needed */
404− /* TODO: try to calculate this without the dummy resample() run */
405− if (!dst->read_only && dst->allow_realloc) {
406− out_samples = resample(c, NULL, NULL, NULL, c->buffer->nb_samples,
407− INT_MAX, 0, nearest_neighbour);
408− ret = ff_audio_data_realloc(dst, out_samples);
409− if (ret < 0) {
410− av_log(c->avr, AV_LOG_ERROR, "error reallocating output\n");
411− return ret;
412− }
413− }
414−
415− /* resample each channel plane */
416− for (ch = 0; ch < c->buffer->channels; ch++) {
417− out_samples = resample(c, (void *)dst->data[ch],
418− (const void *)c->buffer->data[ch], &consumed,
419− c->buffer->nb_samples, dst->allocated_samples,
420− ch + 1 == c->buffer->channels, nearest_neighbour);
421− }
422− if (out_samples < 0) {
423− av_log(c->avr, AV_LOG_ERROR, "error during resampling\n");
424− return out_samples;
425− }
426−
427− /* drain consumed samples from the internal buffer */
428− ff_audio_data_drain(c->buffer, consumed);
429− c->initial_padding_samples = FFMAX(c->initial_padding_samples - consumed, 0);
430−
431− av_log(c->avr, AV_LOG_TRACE, "resampled %d in + %d leftover to %d out + %d leftover\n",
432− in_samples, in_leftover, out_samples, c->buffer->nb_samples);
433−
434− dst->nb_samples = out_samples;
435− return 0;
436−}
437−
438−int avresample_get_delay(AVAudioResampleContext *avr)
439−{
440− ResampleContext *c = avr->resample;
441−
442− if (!avr->resample_needed || !avr->resample)
443− return 0;
444−
445− return FFMAX(c->buffer->nb_samples - c->padding_size, 0);
446−}
libavresample/resample.h+0−96
@@ -1,96 +0,0 @@
1−/*
2− * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
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−
21−#ifndef AVRESAMPLE_RESAMPLE_H
22−#define AVRESAMPLE_RESAMPLE_H
23−
24−#include "avresample.h"
25−#include "internal.h"
26−#include "audio_data.h"
27−
28−struct ResampleContext {
29− AVAudioResampleContext *avr;
30− AudioData *buffer;
31− uint8_t *filter_bank;
32− int filter_length;
33− int ideal_dst_incr;
34− int dst_incr;
35− unsigned int index;
36− int frac;
37− int src_incr;
38− int compensation_distance;
39− int phase_shift;
40− int phase_mask;
41− int linear;
42− enum AVResampleFilterType filter_type;
43− int kaiser_beta;
44− void (*set_filter)(void *filter, double *tab, int phase, int tap_count);
45− void (*resample_one)(struct ResampleContext *c, void *dst0,
46− int dst_index, const void *src0,
47− unsigned int index, int frac);
48− void (*resample_nearest)(void *dst0, int dst_index,
49− const void *src0, unsigned int index);
50− int padding_size;
51− int initial_padding_filled;
52− int initial_padding_samples;
53− int final_padding_filled;
54− int final_padding_samples;
55−};
56−
57−/**
58− * Allocate and initialize a ResampleContext.
59− *
60− * The parameters in the AVAudioResampleContext are used to initialize the
61− * ResampleContext.
62− *
63− * @param avr AVAudioResampleContext
64− * @return newly-allocated ResampleContext
65− */
66−ResampleContext *ff_audio_resample_init(AVAudioResampleContext *avr);
67−
68−/**
69− * Free a ResampleContext.
70− *
71− * @param c ResampleContext
72− */
73−void ff_audio_resample_free(ResampleContext **c);
74−
75−/**
76− * Resample audio data.
77− *
78− * Changes the sample rate.
79− *
80− * @par
81− * All samples in the source data may not be consumed depending on the
82− * resampling parameters and the size of the output buffer. The unconsumed
83− * samples are automatically added to the start of the source in the next call.
84− * If the destination data can be reallocated, that may be done in this function
85− * in order to fit all available output. If it cannot be reallocated, fewer
86− * input samples will be consumed in order to have the output fit in the
87− * destination data buffers.
88− *
89− * @param c ResampleContext
90− * @param dst destination audio data
91− * @param src source audio data
92− * @return 0 on success, negative AVERROR code on failure
93− */
94−int ff_audio_resample(ResampleContext *c, AudioData *dst, AudioData *src);
95−
96−#endif /* AVRESAMPLE_RESAMPLE_H */
libavresample/resample_template.c+0−118
@@ -1,118 +0,0 @@
1−/*
2− * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
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−
21−#include <math.h>
22−#include <stdint.h>
23−
24−#include "libavutil/common.h"
25−#include "internal.h"
26−
27−#if defined(CONFIG_RESAMPLE_DBL)
28−#define SET_TYPE(func) func ## _dbl
29−#define FELEM double
30−#define FELEM2 double
31−#define FELEML double
32−#define OUT(d, v) d = v
33−#define DBL_TO_FELEM(d, v) d = v
34−#elif defined(CONFIG_RESAMPLE_FLT)
35−#define SET_TYPE(func) func ## _flt
36−#define FELEM float
37−#define FELEM2 float
38−#define FELEML float
39−#define OUT(d, v) d = v
40−#define DBL_TO_FELEM(d, v) d = v
41−#elif defined(CONFIG_RESAMPLE_S32)
42−#define SET_TYPE(func) func ## _s32
43−#define FELEM int32_t
44−#define FELEM2 int64_t
45−#define FELEML int64_t
46−#define OUT(d, v) d = av_clipl_int32((v + (1 << 29)) >> 30)
47−#define DBL_TO_FELEM(d, v) d = av_clipl_int32(llrint(v * (1 << 30)));
48−#else
49−#define SET_TYPE(func) func ## _s16
50−#define FELEM int16_t
51−#define FELEM2 int32_t
52−#define FELEML int64_t
53−#define OUT(d, v) d = av_clip_int16((v + (1 << 14)) >> 15)
54−#define DBL_TO_FELEM(d, v) d = av_clip_int16(lrint(v * (1 << 15)))
55−#endif
56−
57−static void SET_TYPE(resample_nearest)(void *dst0, int dst_index, const void *src0, unsigned int index)
58−{
59− FELEM *dst = dst0;
60− const FELEM *src = src0;
61− dst[dst_index] = src[index];
62−}
63−
64−static void SET_TYPE(resample_linear)(ResampleContext *c, void *dst0, int dst_index,
65− const void *src0, unsigned int index, int frac)
66−{
67− FELEM *dst = dst0;
68− const FELEM *src = src0;
69− int i;
70− unsigned int sample_index = index >> c->phase_shift;
71− FELEM2 val = 0;
72− FELEM *filter = ((FELEM *)c->filter_bank) +
73− c->filter_length * (index & c->phase_mask);
74− FELEM2 v2 = 0;
75−
76− for (i = 0; i < c->filter_length; i++) {
77− val += src[sample_index + i] * (FELEM2)filter[i];
78− v2 += src[sample_index + i] * (FELEM2)filter[i + c->filter_length];
79− }
80− val += (v2 - val) * (FELEML)frac / c->src_incr;
81−
82− OUT(dst[dst_index], val);
83−}
84−
85−static void SET_TYPE(resample_one)(ResampleContext *c,
86− void *dst0, int dst_index, const void *src0,
87− unsigned int index, int frac)
88−{
89− FELEM *dst = dst0;
90− const FELEM *src = src0;
91− int i;
92− unsigned int sample_index = index >> c->phase_shift;
93− FELEM2 val = 0;
94− FELEM *filter = ((FELEM *)c->filter_bank) +
95− c->filter_length * (index & c->phase_mask);
96−
97− for (i = 0; i < c->filter_length; i++)
98− val += src[sample_index + i] * (FELEM2)filter[i];
99−
100− OUT(dst[dst_index], val);
101−}
102−
103−static void SET_TYPE(set_filter)(void *filter0, double *tab, int phase,
104− int tap_count)
105−{
106− int i;
107− FELEM *filter = ((FELEM *)filter0) + phase * tap_count;
108− for (i = 0; i < tap_count; i++) {
109− DBL_TO_FELEM(filter[i], tab[i]);
110− }
111−}
112−
113−#undef SET_TYPE
114−#undef FELEM
115−#undef FELEM2
116−#undef FELEML
117−#undef OUT
118−#undef DBL_TO_FELEM
libavresample/tests/.gitignore+0−1
@@ -1 +0,0 @@
1−/avresample
libavresample/tests/avresample.c+0−342
@@ -1,342 +0,0 @@
1−/*
2− * Copyright (c) 2002 Fabrice Bellard
3− * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
4− *
5− * This file is part of FFmpeg.
6− *
7− * FFmpeg is free software; you can redistribute it and/or
8− * modify it under the terms of the GNU Lesser General Public
9− * License as published by the Free Software Foundation; either
10− * version 2.1 of the License, or (at your option) any later version.
11− *
12− * FFmpeg is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15− * Lesser General Public License for more details.
16− *
17− * You should have received a copy of the GNU Lesser General Public
18− * License along with FFmpeg; if not, write to the Free Software
19− * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20− */
21−
22−#include <stdint.h>
23−#include <stdio.h>
24−
25−#include "libavutil/avstring.h"
26−#include "libavutil/common.h"
27−#include "libavutil/lfg.h"
28−#include "libavutil/libm.h"
29−#include "libavutil/log.h"
30−#include "libavutil/mem.h"
31−#include "libavutil/opt.h"
32−#include "libavutil/samplefmt.h"
33−
34−#include "libavresample/avresample.h"
35−
36−static double dbl_rand(AVLFG *lfg)
37−{
38− return 2.0 * (av_lfg_get(lfg) / (double)UINT_MAX) - 1.0;
39−}
40−
41−#define PUT_FUNC(name, fmt, type, expr) \
42−static void put_sample_ ## name(void **data, enum AVSampleFormat sample_fmt,\
43− int channels, int sample, int ch, \
44− double v_dbl) \
45−{ \
46− type v = expr; \
47− type **out = (type **)data; \
48− if (av_sample_fmt_is_planar(sample_fmt)) \
49− out[ch][sample] = v; \
50− else \
51− out[0][sample * channels + ch] = v; \
52−}
53−
54−PUT_FUNC(u8, AV_SAMPLE_FMT_U8, uint8_t, av_clip_uint8 ( lrint(v_dbl * (1 << 7)) + 128))
55−PUT_FUNC(s16, AV_SAMPLE_FMT_S16, int16_t, av_clip_int16 ( lrint(v_dbl * (1 << 15))))
56−PUT_FUNC(s32, AV_SAMPLE_FMT_S32, int32_t, av_clipl_int32(llrint(v_dbl * (1U << 31))))
57−PUT_FUNC(flt, AV_SAMPLE_FMT_FLT, float, v_dbl)
58−PUT_FUNC(dbl, AV_SAMPLE_FMT_DBL, double, v_dbl)
59−
60−static void put_sample(void **data, enum AVSampleFormat sample_fmt,
61− int channels, int sample, int ch, double v_dbl)
62−{
63− switch (av_get_packed_sample_fmt(sample_fmt)) {
64− case AV_SAMPLE_FMT_U8:
65− put_sample_u8(data, sample_fmt, channels, sample, ch, v_dbl);
66− break;
67− case AV_SAMPLE_FMT_S16:
68− put_sample_s16(data, sample_fmt, channels, sample, ch, v_dbl);
69− break;
70− case AV_SAMPLE_FMT_S32:
71− put_sample_s32(data, sample_fmt, channels, sample, ch, v_dbl);
72− break;
73− case AV_SAMPLE_FMT_FLT:
74− put_sample_flt(data, sample_fmt, channels, sample, ch, v_dbl);
75− break;
76− case AV_SAMPLE_FMT_DBL:
77− put_sample_dbl(data, sample_fmt, channels, sample, ch, v_dbl);
78− break;
79− }
80−}
81−
82−static void audiogen(AVLFG *rnd, void **data, enum AVSampleFormat sample_fmt,
83− int channels, int sample_rate, int nb_samples)
84−{
85− int i, ch, k;
86− double v, f, a, ampa;
87− double tabf1[AVRESAMPLE_MAX_CHANNELS];
88− double tabf2[AVRESAMPLE_MAX_CHANNELS];
89− double taba[AVRESAMPLE_MAX_CHANNELS];
90−
91−#define PUT_SAMPLE put_sample(data, sample_fmt, channels, k, ch, v);
92−
93− k = 0;
94−
95− /* 1 second of single freq sine at 1000 Hz */
96− a = 0;
97− for (i = 0; i < 1 * sample_rate && k < nb_samples; i++, k++) {
98− v = sin(a) * 0.30;
99− for (ch = 0; ch < channels; ch++)
100− PUT_SAMPLE
101− a += M_PI * 1000.0 * 2.0 / sample_rate;
102− }
103−
104− /* 1 second of varying frequency between 100 and 10000 Hz */
105− a = 0;
106− for (i = 0; i < 1 * sample_rate && k < nb_samples; i++, k++) {
107− v = sin(a) * 0.30;
108− for (ch = 0; ch < channels; ch++)
109− PUT_SAMPLE
110− f = 100.0 + (((10000.0 - 100.0) * i) / sample_rate);
111− a += M_PI * f * 2.0 / sample_rate;
112− }
113−
114− /* 0.5 second of low amplitude white noise */
115− for (i = 0; i < sample_rate / 2 && k < nb_samples; i++, k++) {
116− v = dbl_rand(rnd) * 0.30;
117− for (ch = 0; ch < channels; ch++)
118− PUT_SAMPLE
119− }
120−
121− /* 0.5 second of high amplitude white noise */
122− for (i = 0; i < sample_rate / 2 && k < nb_samples; i++, k++) {
123− v = dbl_rand(rnd);
124− for (ch = 0; ch < channels; ch++)
125− PUT_SAMPLE
126− }
127−
128− /* 1 second of unrelated ramps for each channel */
129− for (ch = 0; ch < channels; ch++) {
130− taba[ch] = 0;
131− tabf1[ch] = 100 + av_lfg_get(rnd) % 5000;
132− tabf2[ch] = 100 + av_lfg_get(rnd) % 5000;
133− }
134− for (i = 0; i < 1 * sample_rate && k < nb_samples; i++, k++) {
135− for (ch = 0; ch < channels; ch++) {
136− v = sin(taba[ch]) * 0.30;
137− PUT_SAMPLE
138− f = tabf1[ch] + (((tabf2[ch] - tabf1[ch]) * i) / sample_rate);
139− taba[ch] += M_PI * f * 2.0 / sample_rate;
140− }
141− }
142−
143− /* 2 seconds of 500 Hz with varying volume */
144− a = 0;
145− ampa = 0;
146− for (i = 0; i < 2 * sample_rate && k < nb_samples; i++, k++) {
147− for (ch = 0; ch < channels; ch++) {
148− double amp = (1.0 + sin(ampa)) * 0.15;
149− if (ch & 1)
150− amp = 0.30 - amp;
151− v = sin(a) * amp;
152− PUT_SAMPLE
153− a += M_PI * 500.0 * 2.0 / sample_rate;
154− ampa += M_PI * 2.0 / sample_rate;
155− }
156− }
157−}
158−
159−/* formats, rates, and layouts are ordered for priority in testing.
160− e.g. 'avresample-test 4 2 2' will test all input/output combinations of
161− S16/FLTP/S16P/FLT, 48000/44100, and stereo/mono */
162−
163−static const enum AVSampleFormat formats[] = {
164− AV_SAMPLE_FMT_S16,
165− AV_SAMPLE_FMT_FLTP,
166− AV_SAMPLE_FMT_S16P,
167− AV_SAMPLE_FMT_FLT,
168− AV_SAMPLE_FMT_S32P,
169− AV_SAMPLE_FMT_S32,
170− AV_SAMPLE_FMT_U8P,
171− AV_SAMPLE_FMT_U8,
172− AV_SAMPLE_FMT_DBLP,
173− AV_SAMPLE_FMT_DBL,
174−};
175−
176−static const int rates[] = {
177− 48000,
178− 44100,
179− 16000
180−};
181−
182−static const uint64_t layouts[] = {
183− AV_CH_LAYOUT_STEREO,
184− AV_CH_LAYOUT_MONO,
185− AV_CH_LAYOUT_5POINT1,
186− AV_CH_LAYOUT_7POINT1,
187−};
188−
189−int main(int argc, char **argv)
190−{
191− AVAudioResampleContext *s;
192− AVLFG rnd;
193− int ret = 0;
194− uint8_t *in_buf = NULL;
195− uint8_t *out_buf = NULL;
196− unsigned int in_buf_size;
197− unsigned int out_buf_size;
198− uint8_t *in_data[AVRESAMPLE_MAX_CHANNELS] = { 0 };
199− uint8_t *out_data[AVRESAMPLE_MAX_CHANNELS] = { 0 };
200− int in_linesize;
201− int out_linesize;
202− uint64_t in_ch_layout;
203− int in_channels;
204− enum AVSampleFormat in_fmt;
205− int in_rate;
206− uint64_t out_ch_layout;
207− int out_channels;
208− enum AVSampleFormat out_fmt;
209− int out_rate;
210− int num_formats, num_rates, num_layouts;
211− int i, j, k, l, m, n;
212−
213− num_formats = 2;
214− num_rates = 2;
215− num_layouts = 2;
216− if (argc > 1) {
217− if (!av_strncasecmp(argv[1], "-h", 3)) {
218− av_log(NULL, AV_LOG_INFO, "Usage: avresample-test [<num formats> "
219− "[<num sample rates> [<num channel layouts>]]]\n"
220− "Default is 2 2 2\n");
221− return 0;
222− }
223− num_formats = strtol(argv[1], NULL, 0);
224− num_formats = av_clip(num_formats, 1, FF_ARRAY_ELEMS(formats));
225− }
226− if (argc > 2) {
227− num_rates = strtol(argv[2], NULL, 0);
228− num_rates = av_clip(num_rates, 1, FF_ARRAY_ELEMS(rates));
229− }
230− if (argc > 3) {
231− num_layouts = strtol(argv[3], NULL, 0);
232− num_layouts = av_clip(num_layouts, 1, FF_ARRAY_ELEMS(layouts));
233− }
234−
235− av_log_set_level(AV_LOG_DEBUG);
236−
237− av_lfg_init(&rnd, 0xC0FFEE);
238−
239− in_buf_size = av_samples_get_buffer_size(&in_linesize, 8, 48000 * 6,
240− AV_SAMPLE_FMT_DBLP, 0);
241− out_buf_size = in_buf_size;
242−
243− in_buf = av_malloc(in_buf_size);
244− if (!in_buf)
245− goto end;
246− out_buf = av_malloc(out_buf_size);
247− if (!out_buf)
248− goto end;
249−
250− s = avresample_alloc_context();
251− if (!s) {
252− av_log(NULL, AV_LOG_ERROR, "Error allocating AVAudioResampleContext\n");
253− ret = 1;
254− goto end;
255− }
256−
257− for (i = 0; i < num_formats; i++) {
258− in_fmt = formats[i];
259− for (k = 0; k < num_layouts; k++) {
260− in_ch_layout = layouts[k];
261− in_channels = av_get_channel_layout_nb_channels(in_ch_layout);
262− for (m = 0; m < num_rates; m++) {
263− in_rate = rates[m];
264−
265− ret = av_samples_fill_arrays(in_data, &in_linesize, in_buf,
266− in_channels, in_rate * 6,
267− in_fmt, 0);
268− if (ret < 0) {
269− av_log(s, AV_LOG_ERROR, "failed in_data fill arrays\n");
270− goto end;
271− }
272− audiogen(&rnd, (void **)in_data, in_fmt, in_channels, in_rate, in_rate * 6);
273−
274− for (j = 0; j < num_formats; j++) {
275− out_fmt = formats[j];
276− for (l = 0; l < num_layouts; l++) {
277− out_ch_layout = layouts[l];
278− out_channels = av_get_channel_layout_nb_channels(out_ch_layout);
279− for (n = 0; n < num_rates; n++) {
280− out_rate = rates[n];
281−
282− av_log(NULL, AV_LOG_INFO, "%s to %s, %d to %d channels, %d Hz to %d Hz\n",
283− av_get_sample_fmt_name(in_fmt), av_get_sample_fmt_name(out_fmt),
284− in_channels, out_channels, in_rate, out_rate);
285−
286− ret = av_samples_fill_arrays(out_data, &out_linesize,
287− out_buf, out_channels,
288− out_rate * 6, out_fmt, 0);
289− if (ret < 0) {
290− av_log(s, AV_LOG_ERROR, "failed out_data fill arrays\n");
291− goto end;
292− }
293−
294− av_opt_set_int(s, "in_channel_layout", in_ch_layout, 0);
295− av_opt_set_int(s, "in_sample_fmt", in_fmt, 0);
296− av_opt_set_int(s, "in_sample_rate", in_rate, 0);
297− av_opt_set_int(s, "out_channel_layout", out_ch_layout, 0);
298− av_opt_set_int(s, "out_sample_fmt", out_fmt, 0);
299− av_opt_set_int(s, "out_sample_rate", out_rate, 0);
300−
301− av_opt_set_int(s, "internal_sample_fmt", AV_SAMPLE_FMT_FLTP, 0);
302−
303− ret = avresample_open(s);
304− if (ret < 0) {
305− av_log(s, AV_LOG_ERROR, "Error opening context\n");
306− goto end;
307− }
308−
309− ret = avresample_convert(s, out_data, out_linesize, out_rate * 6,
310− in_data, in_linesize, in_rate * 6);
311− if (ret < 0) {
312− char errbuf[256];
313− av_strerror(ret, errbuf, sizeof(errbuf));
314− av_log(NULL, AV_LOG_ERROR, "%s\n", errbuf);
315− goto end;
316− }
317− av_log(NULL, AV_LOG_INFO, "Converted %d samples to %d samples\n",
318− in_rate * 6, ret);
319− if (avresample_get_delay(s) > 0)
320− av_log(NULL, AV_LOG_INFO, "%d delay samples not converted\n",
321− avresample_get_delay(s));
322− if (avresample_available(s) > 0)
323− av_log(NULL, AV_LOG_INFO, "%d samples available for output\n",
324− avresample_available(s));
325− av_log(NULL, AV_LOG_INFO, "\n");
326−
327− avresample_close(s);
328− }
329− }
330− }
331− }
332− }
333− }
334−
335− ret = 0;
336−
337−end:
338− av_freep(&in_buf);
339− av_freep(&out_buf);
340− avresample_free(&s);
341− return ret;
342−}
libavresample/utils.c+0−793
@@ -1,793 +0,0 @@
1−/*
2− * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
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−
21−#include "libavutil/common.h"
22−#include "libavutil/dict.h"
23−// #include "libavutil/error.h"
24−#include "libavutil/frame.h"
25−#include "libavutil/log.h"
26−#include "libavutil/mem.h"
27−#include "libavutil/opt.h"
28−
29−#include "avresample.h"
30−#include "internal.h"
31−#include "audio_data.h"
32−#include "audio_convert.h"
33−#include "audio_mix.h"
34−#include "resample.h"
35−
36−int avresample_open(AVAudioResampleContext *avr)
37−{
38− int ret;
39−
40− if (avresample_is_open(avr)) {
41− av_log(avr, AV_LOG_ERROR, "The resampling context is already open.\n");
42− return AVERROR(EINVAL);
43− }
44−
45− /* set channel mixing parameters */
46− avr->in_channels = av_get_channel_layout_nb_channels(avr->in_channel_layout);
47− if (avr->in_channels <= 0 || avr->in_channels > AVRESAMPLE_MAX_CHANNELS) {
48− av_log(avr, AV_LOG_ERROR, "Invalid input channel layout: %"PRIu64"\n",
49− avr->in_channel_layout);
50− return AVERROR(EINVAL);
51− }
52− avr->out_channels = av_get_channel_layout_nb_channels(avr->out_channel_layout);
53− if (avr->out_channels <= 0 || avr->out_channels > AVRESAMPLE_MAX_CHANNELS) {
54− av_log(avr, AV_LOG_ERROR, "Invalid output channel layout: %"PRIu64"\n",
55− avr->out_channel_layout);
56− return AVERROR(EINVAL);
57− }
58− avr->resample_channels = FFMIN(avr->in_channels, avr->out_channels);
59− avr->downmix_needed = avr->in_channels > avr->out_channels;
60− avr->upmix_needed = avr->out_channels > avr->in_channels ||
61− (!avr->downmix_needed && (avr->mix_matrix ||
62− avr->in_channel_layout != avr->out_channel_layout));
63− avr->mixing_needed = avr->downmix_needed || avr->upmix_needed;
64−
65− /* set resampling parameters */
66− avr->resample_needed = avr->in_sample_rate != avr->out_sample_rate ||
67− avr->force_resampling;
68−
69− /* select internal sample format if not specified by the user */
70− if (avr->internal_sample_fmt == AV_SAMPLE_FMT_NONE &&
71− (avr->mixing_needed || avr->resample_needed)) {
72− enum AVSampleFormat in_fmt = av_get_planar_sample_fmt(avr->in_sample_fmt);
73− enum AVSampleFormat out_fmt = av_get_planar_sample_fmt(avr->out_sample_fmt);
74− int max_bps = FFMAX(av_get_bytes_per_sample(in_fmt),
75− av_get_bytes_per_sample(out_fmt));
76− if (max_bps <= 2) {
77− avr->internal_sample_fmt = AV_SAMPLE_FMT_S16P;
78− } else if (avr->mixing_needed) {
79− avr->internal_sample_fmt = AV_SAMPLE_FMT_FLTP;
80− } else {
81− if (max_bps <= 4) {
82− if (in_fmt == AV_SAMPLE_FMT_S32P ||
83− out_fmt == AV_SAMPLE_FMT_S32P) {
84− if (in_fmt == AV_SAMPLE_FMT_FLTP ||
85− out_fmt == AV_SAMPLE_FMT_FLTP) {
86− /* if one is s32 and the other is flt, use dbl */
87− avr->internal_sample_fmt = AV_SAMPLE_FMT_DBLP;
88− } else {
89− /* if one is s32 and the other is s32, s16, or u8, use s32 */
90− avr->internal_sample_fmt = AV_SAMPLE_FMT_S32P;
91− }
92− } else {
93− /* if one is flt and the other is flt, s16 or u8, use flt */
94− avr->internal_sample_fmt = AV_SAMPLE_FMT_FLTP;
95− }
96− } else {
97− /* if either is dbl, use dbl */
98− avr->internal_sample_fmt = AV_SAMPLE_FMT_DBLP;
99− }
100− }
101− av_log(avr, AV_LOG_DEBUG, "Using %s as internal sample format\n",
102− av_get_sample_fmt_name(avr->internal_sample_fmt));
103− }
104−
105− /* we may need to add an extra conversion in order to remap channels if
106− the output format is not planar */
107− if (avr->use_channel_map && !avr->mixing_needed && !avr->resample_needed &&
108− !ff_sample_fmt_is_planar(avr->out_sample_fmt, avr->out_channels)) {
109− avr->internal_sample_fmt = av_get_planar_sample_fmt(avr->out_sample_fmt);
110− }
111−
112− /* set sample format conversion parameters */
113− if (avr->resample_needed || avr->mixing_needed)
114− avr->in_convert_needed = avr->in_sample_fmt != avr->internal_sample_fmt;
115− else
116− avr->in_convert_needed = avr->use_channel_map &&
117− !ff_sample_fmt_is_planar(avr->out_sample_fmt, avr->out_channels);
118−
119− if (avr->resample_needed || avr->mixing_needed || avr->in_convert_needed)
120− avr->out_convert_needed = avr->internal_sample_fmt != avr->out_sample_fmt;
121− else
122− avr->out_convert_needed = avr->in_sample_fmt != avr->out_sample_fmt;
123−
124− avr->in_copy_needed = !avr->in_convert_needed && (avr->mixing_needed ||
125− (avr->use_channel_map && avr->resample_needed));
126−
127− if (avr->use_channel_map) {
128− if (avr->in_copy_needed) {
129− avr->remap_point = REMAP_IN_COPY;
130− av_log(avr, AV_LOG_TRACE, "remap channels during in_copy\n");
131− } else if (avr->in_convert_needed) {
132− avr->remap_point = REMAP_IN_CONVERT;
133− av_log(avr, AV_LOG_TRACE, "remap channels during in_convert\n");
134− } else if (avr->out_convert_needed) {
135− avr->remap_point = REMAP_OUT_CONVERT;
136− av_log(avr, AV_LOG_TRACE, "remap channels during out_convert\n");
137− } else {
138− avr->remap_point = REMAP_OUT_COPY;
139− av_log(avr, AV_LOG_TRACE, "remap channels during out_copy\n");
140− }
141−
142−#ifdef DEBUG
143− {
144− int ch;
145− av_log(avr, AV_LOG_TRACE, "output map: ");
146− if (avr->ch_map_info.do_remap)
147− for (ch = 0; ch < avr->in_channels; ch++)
148− av_log(avr, AV_LOG_TRACE, " % 2d", avr->ch_map_info.channel_map[ch]);
149− else
150− av_log(avr, AV_LOG_TRACE, "n/a");
151− av_log(avr, AV_LOG_TRACE, "\n");
152− av_log(avr, AV_LOG_TRACE, "copy map: ");
153− if (avr->ch_map_info.do_copy)
154− for (ch = 0; ch < avr->in_channels; ch++)
155− av_log(avr, AV_LOG_TRACE, " % 2d", avr->ch_map_info.channel_copy[ch]);
156− else
157− av_log(avr, AV_LOG_TRACE, "n/a");
158− av_log(avr, AV_LOG_TRACE, "\n");
159− av_log(avr, AV_LOG_TRACE, "zero map: ");
160− if (avr->ch_map_info.do_zero)
161− for (ch = 0; ch < avr->in_channels; ch++)
162− av_log(avr, AV_LOG_TRACE, " % 2d", avr->ch_map_info.channel_zero[ch]);
163− else
164− av_log(avr, AV_LOG_TRACE, "n/a");
165− av_log(avr, AV_LOG_TRACE, "\n");
166− av_log(avr, AV_LOG_TRACE, "input map: ");
167− for (ch = 0; ch < avr->in_channels; ch++)
168− av_log(avr, AV_LOG_TRACE, " % 2d", avr->ch_map_info.input_map[ch]);
169− av_log(avr, AV_LOG_TRACE, "\n");
170− }
171−#endif
172− } else
173− avr->remap_point = REMAP_NONE;
174−
175− /* allocate buffers */
176− if (avr->in_copy_needed || avr->in_convert_needed) {
177− avr->in_buffer = ff_audio_data_alloc(FFMAX(avr->in_channels, avr->out_channels),
178− 0, avr->internal_sample_fmt,
179− "in_buffer");
180− if (!avr->in_buffer) {
181− ret = AVERROR(EINVAL);
182− goto error;
183− }
184− }
185− if (avr->resample_needed) {
186− avr->resample_out_buffer = ff_audio_data_alloc(avr->out_channels,
187− 1024, avr->internal_sample_fmt,
188− "resample_out_buffer");
189− if (!avr->resample_out_buffer) {
190− ret = AVERROR(EINVAL);
191− goto error;
192− }
193− }
194− if (avr->out_convert_needed) {
195− avr->out_buffer = ff_audio_data_alloc(avr->out_channels, 0,
196− avr->out_sample_fmt, "out_buffer");
197− if (!avr->out_buffer) {
198− ret = AVERROR(EINVAL);
199− goto error;
200− }
201− }
202− avr->out_fifo = av_audio_fifo_alloc(avr->out_sample_fmt, avr->out_channels,
203− 1024);
204− if (!avr->out_fifo) {
205− ret = AVERROR(ENOMEM);
206− goto error;
207− }
208−
209− /* setup contexts */
210− if (avr->in_convert_needed) {
211− avr->ac_in = ff_audio_convert_alloc(avr, avr->internal_sample_fmt,
212− avr->in_sample_fmt, avr->in_channels,
213− avr->in_sample_rate,
214− avr->remap_point == REMAP_IN_CONVERT);
215− if (!avr->ac_in) {
216− ret = AVERROR(ENOMEM);
217− goto error;
218− }
219− }
220− if (avr->out_convert_needed) {
221− enum AVSampleFormat src_fmt;
222− if (avr->in_convert_needed)
223− src_fmt = avr->internal_sample_fmt;
224− else
225− src_fmt = avr->in_sample_fmt;
226− avr->ac_out = ff_audio_convert_alloc(avr, avr->out_sample_fmt, src_fmt,
227− avr->out_channels,
228− avr->out_sample_rate,
229− avr->remap_point == REMAP_OUT_CONVERT);
230− if (!avr->ac_out) {
231− ret = AVERROR(ENOMEM);
232− goto error;
233− }
234− }
235− if (avr->resample_needed) {
236− avr->resample = ff_audio_resample_init(avr);
237− if (!avr->resample) {
238− ret = AVERROR(ENOMEM);
239− goto error;
240− }
241− }
242− if (avr->mixing_needed) {
243− avr->am = ff_audio_mix_alloc(avr);
244− if (!avr->am) {
245− ret = AVERROR(ENOMEM);
246− goto error;
247− }
248− }
249−
250− return 0;
251−
252−error:
253− avresample_close(avr);
254− return ret;
255−}
256−
257−int avresample_is_open(AVAudioResampleContext *avr)
258−{
259− return !!avr->out_fifo;
260−}
261−
262−void avresample_close(AVAudioResampleContext *avr)
263−{
264− ff_audio_data_free(&avr->in_buffer);
265− ff_audio_data_free(&avr->resample_out_buffer);
266− ff_audio_data_free(&avr->out_buffer);
267− av_audio_fifo_free(avr->out_fifo);
268− avr->out_fifo = NULL;
269− ff_audio_convert_free(&avr->ac_in);
270− ff_audio_convert_free(&avr->ac_out);
271− ff_audio_resample_free(&avr->resample);
272− ff_audio_mix_free(&avr->am);
273− av_freep(&avr->mix_matrix);
274−
275− avr->use_channel_map = 0;
276−}
277−
278−void avresample_free(AVAudioResampleContext **avr)
279−{
280− if (!*avr)
281− return;
282− avresample_close(*avr);
283− av_opt_free(*avr);
284− av_freep(avr);
285−}
286−
287−static int handle_buffered_output(AVAudioResampleContext *avr,
288− AudioData *output, AudioData *converted)
289−{
290− int ret;
291−
292− if (!output || av_audio_fifo_size(avr->out_fifo) > 0 ||
293− (converted && output->allocated_samples < converted->nb_samples)) {
294− if (converted) {
295− /* if there are any samples in the output FIFO or if the
296− user-supplied output buffer is not large enough for all samples,
297− we add to the output FIFO */
298− av_log(avr, AV_LOG_TRACE, "[FIFO] add %s to out_fifo\n", converted->name);
299− ret = ff_audio_data_add_to_fifo(avr->out_fifo, converted, 0,
300− converted->nb_samples);
301− if (ret < 0)
302− return ret;
303− }
304−
305− /* if the user specified an output buffer, read samples from the output
306− FIFO to the user output */
307− if (output && output->allocated_samples > 0) {
308− av_log(avr, AV_LOG_TRACE, "[FIFO] read from out_fifo to output\n");
309− av_log(avr, AV_LOG_TRACE, "[end conversion]\n");
310− return ff_audio_data_read_from_fifo(avr->out_fifo, output,
311− output->allocated_samples);
312− }
313− } else if (converted) {
314− /* copy directly to output if it is large enough or there is not any
315− data in the output FIFO */
316− av_log(avr, AV_LOG_TRACE, "[copy] %s to output\n", converted->name);
317− output->nb_samples = 0;
318− ret = ff_audio_data_copy(output, converted,
319− avr->remap_point == REMAP_OUT_COPY ?
320− &avr->ch_map_info : NULL);
321− if (ret < 0)
322− return ret;
323− av_log(avr, AV_LOG_TRACE, "[end conversion]\n");
324− return output->nb_samples;
325− }
326− av_log(avr, AV_LOG_TRACE, "[end conversion]\n");
327− return 0;
328−}
329−
330−int attribute_align_arg avresample_convert(AVAudioResampleContext *avr,
331− uint8_t **output, int out_plane_size,
332− int out_samples,
333− uint8_t * const *input,
334− int in_plane_size, int in_samples)
335−{
336− AudioData input_buffer;
337− AudioData output_buffer;
338− AudioData *current_buffer;
339− int ret, direct_output;
340−
341− /* reset internal buffers */
342− if (avr->in_buffer) {
343− avr->in_buffer->nb_samples = 0;
344− ff_audio_data_set_channels(avr->in_buffer,
345− avr->in_buffer->allocated_channels);
346− }
347− if (avr->resample_out_buffer) {
348− avr->resample_out_buffer->nb_samples = 0;
349− ff_audio_data_set_channels(avr->resample_out_buffer,
350− avr->resample_out_buffer->allocated_channels);
351− }
352− if (avr->out_buffer) {
353− avr->out_buffer->nb_samples = 0;
354− ff_audio_data_set_channels(avr->out_buffer,
355− avr->out_buffer->allocated_channels);
356− }
357−
358− av_log(avr, AV_LOG_TRACE, "[start conversion]\n");
359−
360− /* initialize output_buffer with output data */
361− direct_output = output && av_audio_fifo_size(avr->out_fifo) == 0;
362− if (output) {
363− ret = ff_audio_data_init(&output_buffer, output, out_plane_size,
364− avr->out_channels, out_samples,
365− avr->out_sample_fmt, 0, "output");
366− if (ret < 0)
367− return ret;
368− output_buffer.nb_samples = 0;
369− }
370−
371− if (input) {
372− /* initialize input_buffer with input data */
373− ret = ff_audio_data_init(&input_buffer, input, in_plane_size,
374− avr->in_channels, in_samples,
375− avr->in_sample_fmt, 1, "input");
376− if (ret < 0)
377− return ret;
378− current_buffer = &input_buffer;
379−
380− if (avr->upmix_needed && !avr->in_convert_needed && !avr->resample_needed &&
381− !avr->out_convert_needed && direct_output && out_samples >= in_samples) {
382− /* in some rare cases we can copy input to output and upmix
383− directly in the output buffer */
384− av_log(avr, AV_LOG_TRACE, "[copy] %s to output\n", current_buffer->name);
385− ret = ff_audio_data_copy(&output_buffer, current_buffer,
386− avr->remap_point == REMAP_OUT_COPY ?
387− &avr->ch_map_info : NULL);
388− if (ret < 0)
389− return ret;
390− current_buffer = &output_buffer;
391− } else if (avr->remap_point == REMAP_OUT_COPY &&
392− (!direct_output || out_samples < in_samples)) {
393− /* if remapping channels during output copy, we may need to
394− * use an intermediate buffer in order to remap before adding
395− * samples to the output fifo */
396− av_log(avr, AV_LOG_TRACE, "[copy] %s to out_buffer\n", current_buffer->name);
397− ret = ff_audio_data_copy(avr->out_buffer, current_buffer,
398− &avr->ch_map_info);
399− if (ret < 0)
400− return ret;
401− current_buffer = avr->out_buffer;
402− } else if (avr->in_copy_needed || avr->in_convert_needed) {
403− /* if needed, copy or convert input to in_buffer, and downmix if
404− applicable */
405− if (avr->in_convert_needed) {
406− ret = ff_audio_data_realloc(avr->in_buffer,
407− current_buffer->nb_samples);
408− if (ret < 0)
409− return ret;
410− av_log(avr, AV_LOG_TRACE, "[convert] %s to in_buffer\n", current_buffer->name);
411− ret = ff_audio_convert(avr->ac_in, avr->in_buffer,
412− current_buffer);
413− if (ret < 0)
414− return ret;
415− } else {
416− av_log(avr, AV_LOG_TRACE, "[copy] %s to in_buffer\n", current_buffer->name);
417− ret = ff_audio_data_copy(avr->in_buffer, current_buffer,
418− avr->remap_point == REMAP_IN_COPY ?
419− &avr->ch_map_info : NULL);
420− if (ret < 0)
421− return ret;
422− }
423− ff_audio_data_set_channels(avr->in_buffer, avr->in_channels);
424− if (avr->downmix_needed) {
425− av_log(avr, AV_LOG_TRACE, "[downmix] in_buffer\n");
426− ret = ff_audio_mix(avr->am, avr->in_buffer);
427− if (ret < 0)
428− return ret;
429− }
430− current_buffer = avr->in_buffer;
431− }
432− } else {
433− /* flush resampling buffer and/or output FIFO if input is NULL */
434− if (!avr->resample_needed)
435− return handle_buffered_output(avr, output ? &output_buffer : NULL,
436− NULL);
437− current_buffer = NULL;
438− }
439−
440− if (avr->resample_needed) {
441− AudioData *resample_out;
442−
443− if (!avr->out_convert_needed && direct_output && out_samples > 0)
444− resample_out = &output_buffer;
445− else
446− resample_out = avr->resample_out_buffer;
447− av_log(avr, AV_LOG_TRACE, "[resample] %s to %s\n",
448− current_buffer ? current_buffer->name : "null",
449− resample_out->name);
450− ret = ff_audio_resample(avr->resample, resample_out,
451− current_buffer);
452− if (ret < 0)
453− return ret;
454−
455− /* if resampling did not produce any samples, just return 0 */
456− if (resample_out->nb_samples == 0) {
457− av_log(avr, AV_LOG_TRACE, "[end conversion]\n");
458− return 0;
459− }
460−
461− current_buffer = resample_out;
462− }
463−
464− if (avr->upmix_needed) {
465− av_log(avr, AV_LOG_TRACE, "[upmix] %s\n", current_buffer->name);
466− ret = ff_audio_mix(avr->am, current_buffer);
467− if (ret < 0)
468− return ret;
469− }
470−
471− /* if we resampled or upmixed directly to output, return here */
472− if (current_buffer == &output_buffer) {
473− av_log(avr, AV_LOG_TRACE, "[end conversion]\n");
474− return current_buffer->nb_samples;
475− }
476−
477− if (avr->out_convert_needed) {
478− if (direct_output && out_samples >= current_buffer->nb_samples) {
479− /* convert directly to output */
480− av_log(avr, AV_LOG_TRACE, "[convert] %s to output\n", current_buffer->name);
481− ret = ff_audio_convert(avr->ac_out, &output_buffer, current_buffer);
482− if (ret < 0)
483− return ret;
484−
485− av_log(avr, AV_LOG_TRACE, "[end conversion]\n");
486− return output_buffer.nb_samples;
487− } else {
488− ret = ff_audio_data_realloc(avr->out_buffer,
489− current_buffer->nb_samples);
490− if (ret < 0)
491− return ret;
492− av_log(avr, AV_LOG_TRACE, "[convert] %s to out_buffer\n", current_buffer->name);
493− ret = ff_audio_convert(avr->ac_out, avr->out_buffer,
494− current_buffer);
495− if (ret < 0)
496− return ret;
497− current_buffer = avr->out_buffer;
498− }
499− }
500−
501− return handle_buffered_output(avr, output ? &output_buffer : NULL,
502− current_buffer);
503−}
504−
505−int avresample_config(AVAudioResampleContext *avr, AVFrame *out, AVFrame *in)
506−{
507− if (avresample_is_open(avr)) {
508− avresample_close(avr);
509− }
510−
511− if (in) {
512− avr->in_channel_layout = in->channel_layout;
513− avr->in_sample_rate = in->sample_rate;
514− avr->in_sample_fmt = in->format;
515− }
516−
517− if (out) {
518− avr->out_channel_layout = out->channel_layout;
519− avr->out_sample_rate = out->sample_rate;
520− avr->out_sample_fmt = out->format;
521− }
522−
523− return 0;
524−}
525−
526−static int config_changed(AVAudioResampleContext *avr,
527− AVFrame *out, AVFrame *in)
528−{
529− int ret = 0;
530−
531− if (in) {
532− if (avr->in_channel_layout != in->channel_layout ||
533− avr->in_sample_rate != in->sample_rate ||
534− avr->in_sample_fmt != in->format) {
535− ret |= AVERROR_INPUT_CHANGED;
536− }
537− }
538−
539− if (out) {
540− if (avr->out_channel_layout != out->channel_layout ||
541− avr->out_sample_rate != out->sample_rate ||
542− avr->out_sample_fmt != out->format) {
543− ret |= AVERROR_OUTPUT_CHANGED;
544− }
545− }
546−
547− return ret;
548−}
549−
550−static inline int convert_frame(AVAudioResampleContext *avr,
551− AVFrame *out, AVFrame *in)
552−{
553− int ret;
554− uint8_t **out_data = NULL, **in_data = NULL;
555− int out_linesize = 0, in_linesize = 0;
556− int out_nb_samples = 0, in_nb_samples = 0;
557−
558− if (out) {
559− out_data = out->extended_data;
560− out_linesize = out->linesize[0];
561− out_nb_samples = out->nb_samples;
562− }
563−
564− if (in) {
565− in_data = in->extended_data;
566− in_linesize = in->linesize[0];
567− in_nb_samples = in->nb_samples;
568− }
569−
570− ret = avresample_convert(avr, out_data, out_linesize,
571− out_nb_samples,
572− in_data, in_linesize,
573− in_nb_samples);
574−
575− if (ret < 0) {
576− if (out)
577− out->nb_samples = 0;
578− return ret;
579− }
580−
581− if (out)
582− out->nb_samples = ret;
583−
584− return 0;
585−}
586−
587−static inline int available_samples(AVFrame *out)
588−{
589− int samples;
590− int bytes_per_sample = av_get_bytes_per_sample(out->format);
591− if (!bytes_per_sample)
592− return AVERROR(EINVAL);
593−
594− samples = out->linesize[0] / bytes_per_sample;
595− if (av_sample_fmt_is_planar(out->format)) {
596− return samples;
597− } else {
598− int channels = av_get_channel_layout_nb_channels(out->channel_layout);
599− return samples / channels;
600− }
601−}
602−
603−int avresample_convert_frame(AVAudioResampleContext *avr,
604− AVFrame *out, AVFrame *in)
605−{
606− int ret, setup = 0;
607−
608− if (!avresample_is_open(avr)) {
609− if ((ret = avresample_config(avr, out, in)) < 0)
610− return ret;
611− if ((ret = avresample_open(avr)) < 0)
612− return ret;
613− setup = 1;
614− } else {
615− // return as is or reconfigure for input changes?
616− if ((ret = config_changed(avr, out, in)))
617− return ret;
618− }
619−
620− if (out) {
621− if (!out->linesize[0]) {
622− out->nb_samples = avresample_get_out_samples(avr, in->nb_samples);
623− if ((ret = av_frame_get_buffer(out, 0)) < 0) {
624− if (setup)
625− avresample_close(avr);
626− return ret;
627− }
628− } else {
629− if (!out->nb_samples)
630− out->nb_samples = available_samples(out);
631− }
632− }
633−
634− return convert_frame(avr, out, in);
635−}
636−
637−int avresample_get_matrix(AVAudioResampleContext *avr, double *matrix,
638− int stride)
639−{
640− int in_channels, out_channels, i, o;
641−
642− if (avr->am)
643− return ff_audio_mix_get_matrix(avr->am, matrix, stride);
644−
645− in_channels = av_get_channel_layout_nb_channels(avr->in_channel_layout);
646− out_channels = av_get_channel_layout_nb_channels(avr->out_channel_layout);
647−
648− if ( in_channels <= 0 || in_channels > AVRESAMPLE_MAX_CHANNELS ||
649− out_channels <= 0 || out_channels > AVRESAMPLE_MAX_CHANNELS) {
650− av_log(avr, AV_LOG_ERROR, "Invalid channel layouts\n");
651− return AVERROR(EINVAL);
652− }
653−
654− if (!avr->mix_matrix) {
655− av_log(avr, AV_LOG_ERROR, "matrix is not set\n");
656− return AVERROR(EINVAL);
657− }
658−
659− for (o = 0; o < out_channels; o++)
660− for (i = 0; i < in_channels; i++)
661− matrix[o * stride + i] = avr->mix_matrix[o * in_channels + i];
662−
663− return 0;
664−}
665−
666−int avresample_set_matrix(AVAudioResampleContext *avr, const double *matrix,
667− int stride)
668−{
669− int in_channels, out_channels, i, o;
670−
671− if (avr->am)
672− return ff_audio_mix_set_matrix(avr->am, matrix, stride);
673−
674− in_channels = av_get_channel_layout_nb_channels(avr->in_channel_layout);
675− out_channels = av_get_channel_layout_nb_channels(avr->out_channel_layout);
676−
677− if ( in_channels <= 0 || in_channels > AVRESAMPLE_MAX_CHANNELS ||
678− out_channels <= 0 || out_channels > AVRESAMPLE_MAX_CHANNELS) {
679− av_log(avr, AV_LOG_ERROR, "Invalid channel layouts\n");
680− return AVERROR(EINVAL);
681− }
682−
683− if (avr->mix_matrix)
684− av_freep(&avr->mix_matrix);
685− avr->mix_matrix = av_malloc(in_channels * out_channels *
686− sizeof(*avr->mix_matrix));
687− if (!avr->mix_matrix)
688− return AVERROR(ENOMEM);
689−
690− for (o = 0; o < out_channels; o++)
691− for (i = 0; i < in_channels; i++)
692− avr->mix_matrix[o * in_channels + i] = matrix[o * stride + i];
693−
694− return 0;
695−}
696−
697−int avresample_set_channel_mapping(AVAudioResampleContext *avr,
698− const int *channel_map)
699−{
700− ChannelMapInfo *info = &avr->ch_map_info;
701− int in_channels, ch, i;
702−
703− in_channels = av_get_channel_layout_nb_channels(avr->in_channel_layout);
704− if (in_channels <= 0 || in_channels > AVRESAMPLE_MAX_CHANNELS) {
705− av_log(avr, AV_LOG_ERROR, "Invalid input channel layout\n");
706− return AVERROR(EINVAL);
707− }
708−
709− memset(info, 0, sizeof(*info));
710− memset(info->input_map, -1, sizeof(info->input_map));
711−
712− for (ch = 0; ch < in_channels; ch++) {
713− if (channel_map[ch] >= in_channels) {
714− av_log(avr, AV_LOG_ERROR, "Invalid channel map\n");
715− return AVERROR(EINVAL);
716− }
717− if (channel_map[ch] < 0) {
718− info->channel_zero[ch] = 1;
719− info->channel_map[ch] = -1;
720− info->do_zero = 1;
721− } else if (info->input_map[channel_map[ch]] >= 0) {
722− info->channel_copy[ch] = info->input_map[channel_map[ch]];
723− info->channel_map[ch] = -1;
724− info->do_copy = 1;
725− } else {
726− info->channel_map[ch] = channel_map[ch];
727− info->input_map[channel_map[ch]] = ch;
728− info->do_remap = 1;
729− }
730− }
731− /* Fill-in unmapped input channels with unmapped output channels.
732− This is used when remapping during conversion from interleaved to
733− planar format. */
734− for (ch = 0, i = 0; ch < in_channels && i < in_channels; ch++, i++) {
735− while (ch < in_channels && info->input_map[ch] >= 0)
736− ch++;
737− while (i < in_channels && info->channel_map[i] >= 0)
738− i++;
739− if (ch >= in_channels || i >= in_channels)
740− break;
741− info->input_map[ch] = i;
742− }
743−
744− avr->use_channel_map = 1;
745− return 0;
746−}
747−
748−int avresample_available(AVAudioResampleContext *avr)
749−{
750− return av_audio_fifo_size(avr->out_fifo);
751−}
752−
753−int avresample_get_out_samples(AVAudioResampleContext *avr, int in_nb_samples)
754−{
755− int64_t samples = avresample_get_delay(avr) + (int64_t)in_nb_samples;
756−
757− if (avr->resample_needed) {
758− samples = av_rescale_rnd(samples,
759− avr->out_sample_rate,
760− avr->in_sample_rate,
761− AV_ROUND_UP);
762− }
763−
764− samples += avresample_available(avr);
765−
766− if (samples > INT_MAX)
767− return AVERROR(EINVAL);
768−
769− return samples;
770−}
771−
772−int avresample_read(AVAudioResampleContext *avr, uint8_t **output, int nb_samples)
773−{
774− if (!output)
775− return av_audio_fifo_drain(avr->out_fifo, nb_samples);
776− return av_audio_fifo_read(avr->out_fifo, (void**)output, nb_samples);
777−}
778−
779−unsigned avresample_version(void)
780−{
781− return LIBAVRESAMPLE_VERSION_INT;
782−}
783−
784−const char *avresample_license(void)
785−{
786−#define LICENSE_PREFIX "libavresample license: "
787− return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
788−}
789−
790−const char *avresample_configuration(void)
791−{
792− return FFMPEG_CONFIGURATION;
793−}
libavresample/version.h+0−50
@@ -1,50 +0,0 @@
1−/*
2− * This file is part of FFmpeg.
3− *
4− * FFmpeg is free software; you can redistribute it and/or
5− * modify it under the terms of the GNU Lesser General Public
6− * License as published by the Free Software Foundation; either
7− * version 2.1 of the License, or (at your option) any later version.
8− *
9− * FFmpeg is distributed in the hope that it will be useful,
10− * but WITHOUT ANY WARRANTY; without even the implied warranty of
11− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12− * Lesser General Public License for more details.
13− *
14− * You should have received a copy of the GNU Lesser General Public
15− * License along with FFmpeg; if not, write to the Free Software
16− * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17− */
18−
19−#ifndef AVRESAMPLE_VERSION_H
20−#define AVRESAMPLE_VERSION_H
21−
22−/**
23− * @file
24− * @ingroup lavr
25− * Libavresample version macros.
26− */
27−
28−#include "libavutil/version.h"
29−
30−#define LIBAVRESAMPLE_VERSION_MAJOR 4
31−#define LIBAVRESAMPLE_VERSION_MINOR 0
32−#define LIBAVRESAMPLE_VERSION_MICRO 0
33−
34−#define LIBAVRESAMPLE_VERSION_INT AV_VERSION_INT(LIBAVRESAMPLE_VERSION_MAJOR, \
35− LIBAVRESAMPLE_VERSION_MINOR, \
36− LIBAVRESAMPLE_VERSION_MICRO)
37−#define LIBAVRESAMPLE_VERSION AV_VERSION(LIBAVRESAMPLE_VERSION_MAJOR, \
38− LIBAVRESAMPLE_VERSION_MINOR, \
39− LIBAVRESAMPLE_VERSION_MICRO)
40−#define LIBAVRESAMPLE_BUILD LIBAVRESAMPLE_VERSION_INT
41−
42−#define LIBAVRESAMPLE_IDENT "Lavr" AV_STRINGIFY(LIBAVRESAMPLE_VERSION)
43−
44−/**
45− * FF_API_* defines may be placed below to indicate public API that will be
46− * dropped at a future version bump. The defines themselves are not part of
47− * the public API and may change, break or disappear at any time.
48− */
49−
50−#endif /* AVRESAMPLE_VERSION_H */
libavresample/x86/Makefile+0−9
@@ -1,9 +0,0 @@
1−OBJS += x86/audio_convert_init.o \
2− x86/audio_mix_init.o \
3− x86/dither_init.o \
4−
5−OBJS-$(CONFIG_XMM_CLOBBER_TEST) += x86/w64xmmtest.o
6−
7−X86ASM-OBJS += x86/audio_convert.o \
8− x86/audio_mix.o \
9− x86/dither.o \
libavresample/x86/audio_convert.asm+0−1261
@@ -1,1261 +0,0 @@
1−;******************************************************************************
2−;* x86 optimized Format Conversion Utils
3−;* Copyright (c) 2008 Loren Merritt
4−;* Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
5−;*
6−;* This file is part of FFmpeg.
7−;*
8−;* FFmpeg is free software; you can redistribute it and/or
9−;* modify it under the terms of the GNU Lesser General Public
10−;* License as published by the Free Software Foundation; either
11−;* version 2.1 of the License, or (at your option) any later version.
12−;*
13−;* FFmpeg is distributed in the hope that it will be useful,
14−;* but WITHOUT ANY WARRANTY; without even the implied warranty of
15−;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16−;* Lesser General Public License for more details.
17−;*
18−;* You should have received a copy of the GNU Lesser General Public
19−;* License along with FFmpeg; if not, write to the Free Software
20−;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21−;******************************************************************************
22−
23−%include "libavutil/x86/x86util.asm"
24−%include "util.asm"
25−
26−SECTION_RODATA 32
27−
28−pf_s32_inv_scale: times 8 dd 0x30000000
29−pf_s32_scale: times 8 dd 0x4f000000
30−pf_s32_clip: times 8 dd 0x4effffff
31−pf_s16_inv_scale: times 4 dd 0x38000000
32−pf_s16_scale: times 4 dd 0x47000000
33−pb_shuf_unpack_even: db -1, -1, 0, 1, -1, -1, 2, 3, -1, -1, 8, 9, -1, -1, 10, 11
34−pb_shuf_unpack_odd: db -1, -1, 4, 5, -1, -1, 6, 7, -1, -1, 12, 13, -1, -1, 14, 15
35−pb_interleave_words: SHUFFLE_MASK_W 0, 4, 1, 5, 2, 6, 3, 7
36−pb_deinterleave_words: SHUFFLE_MASK_W 0, 2, 4, 6, 1, 3, 5, 7
37−pw_zero_even: times 4 dw 0x0000, 0xffff
38−
39−SECTION .text
40−
41−;------------------------------------------------------------------------------
42−; void ff_conv_s16_to_s32(int32_t *dst, const int16_t *src, int len);
43−;------------------------------------------------------------------------------
44−
45−INIT_XMM sse2
46−cglobal conv_s16_to_s32, 3,3,3, dst, src, len
47− lea lenq, [2*lend]
48− lea dstq, [dstq+2*lenq]
49− add srcq, lenq
50− neg lenq
51−.loop:
52− mova m2, [srcq+lenq]
53− pxor m0, m0
54− pxor m1, m1
55− punpcklwd m0, m2
56− punpckhwd m1, m2
57− mova [dstq+2*lenq ], m0
58− mova [dstq+2*lenq+mmsize], m1
59− add lenq, mmsize
60− jl .loop
61− REP_RET
62−
63−;------------------------------------------------------------------------------
64−; void ff_conv_s16_to_flt(float *dst, const int16_t *src, int len);
65−;------------------------------------------------------------------------------
66−
67−%macro CONV_S16_TO_FLT 0
68−cglobal conv_s16_to_flt, 3,3,3, dst, src, len
69− lea lenq, [2*lend]
70− add srcq, lenq
71− lea dstq, [dstq + 2*lenq]
72− neg lenq
73− mova m2, [pf_s16_inv_scale]
74− ALIGN 16
75−.loop:
76− mova m0, [srcq+lenq]
77− S16_TO_S32_SX 0, 1
78− cvtdq2ps m0, m0
79− cvtdq2ps m1, m1
80− mulps m0, m2
81− mulps m1, m2
82− mova [dstq+2*lenq ], m0
83− mova [dstq+2*lenq+mmsize], m1
84− add lenq, mmsize
85− jl .loop
86− REP_RET
87−%endmacro
88−
89−INIT_XMM sse2
90−CONV_S16_TO_FLT
91−INIT_XMM sse4
92−CONV_S16_TO_FLT
93−
94−;------------------------------------------------------------------------------
95−; void ff_conv_s32_to_s16(int16_t *dst, const int32_t *src, int len);
96−;------------------------------------------------------------------------------
97−
98−%macro CONV_S32_TO_S16 0
99−cglobal conv_s32_to_s16, 3,3,4, dst, src, len
100− lea lenq, [2*lend]
101− lea srcq, [srcq+2*lenq]
102− add dstq, lenq
103− neg lenq
104−.loop:
105− mova m0, [srcq+2*lenq ]
106− mova m1, [srcq+2*lenq+ mmsize]
107− mova m2, [srcq+2*lenq+2*mmsize]
108− mova m3, [srcq+2*lenq+3*mmsize]
109− psrad m0, 16
110− psrad m1, 16
111− psrad m2, 16
112− psrad m3, 16
113− packssdw m0, m1
114− packssdw m2, m3
115− mova [dstq+lenq ], m0
116− mova [dstq+lenq+mmsize], m2
117− add lenq, mmsize*2
118− jl .loop
119−%if mmsize == 8
120− emms
121− RET
122−%else
123− REP_RET
124−%endif
125−%endmacro
126−
127−INIT_MMX mmx
128−CONV_S32_TO_S16
129−INIT_XMM sse2
130−CONV_S32_TO_S16
131−
132−;------------------------------------------------------------------------------
133−; void ff_conv_s32_to_flt(float *dst, const int32_t *src, int len);
134−;------------------------------------------------------------------------------
135−
136−%macro CONV_S32_TO_FLT 0
137−cglobal conv_s32_to_flt, 3,3,3, dst, src, len
138− lea lenq, [4*lend]
139− add srcq, lenq
140− add dstq, lenq
141− neg lenq
142− mova m0, [pf_s32_inv_scale]
143− ALIGN 16
144−.loop:
145− cvtdq2ps m1, [srcq+lenq ]
146− cvtdq2ps m2, [srcq+lenq+mmsize]
147− mulps m1, m1, m0
148− mulps m2, m2, m0
149− mova [dstq+lenq ], m1
150− mova [dstq+lenq+mmsize], m2
151− add lenq, mmsize*2
152− jl .loop
153− REP_RET
154−%endmacro
155−
156−INIT_XMM sse2
157−CONV_S32_TO_FLT
158−%if HAVE_AVX_EXTERNAL
159−INIT_YMM avx
160−CONV_S32_TO_FLT
161−%endif
162−
163−;------------------------------------------------------------------------------
164−; void ff_conv_flt_to_s16(int16_t *dst, const float *src, int len);
165−;------------------------------------------------------------------------------
166−
167−INIT_XMM sse2
168−cglobal conv_flt_to_s16, 3,3,5, dst, src, len
169− lea lenq, [2*lend]
170− lea srcq, [srcq+2*lenq]
171− add dstq, lenq
172− neg lenq
173− mova m4, [pf_s16_scale]
174−.loop:
175− mova m0, [srcq+2*lenq ]
176− mova m1, [srcq+2*lenq+1*mmsize]
177− mova m2, [srcq+2*lenq+2*mmsize]
178− mova m3, [srcq+2*lenq+3*mmsize]
179− mulps m0, m4
180− mulps m1, m4
181− mulps m2, m4
182− mulps m3, m4
183− cvtps2dq m0, m0
184− cvtps2dq m1, m1
185− cvtps2dq m2, m2
186− cvtps2dq m3, m3
187− packssdw m0, m1
188− packssdw m2, m3
189− mova [dstq+lenq ], m0
190− mova [dstq+lenq+mmsize], m2
191− add lenq, mmsize*2
192− jl .loop
193− REP_RET
194−
195−;------------------------------------------------------------------------------
196−; void ff_conv_flt_to_s32(int32_t *dst, const float *src, int len);
197−;------------------------------------------------------------------------------
198−
199−%macro CONV_FLT_TO_S32 0
200−cglobal conv_flt_to_s32, 3,3,6, dst, src, len
201− lea lenq, [lend*4]
202− add srcq, lenq
203− add dstq, lenq
204− neg lenq
205− mova m4, [pf_s32_scale]
206− mova m5, [pf_s32_clip]
207−.loop:
208− mulps m0, m4, [srcq+lenq ]
209− mulps m1, m4, [srcq+lenq+1*mmsize]
210− mulps m2, m4, [srcq+lenq+2*mmsize]
211− mulps m3, m4, [srcq+lenq+3*mmsize]
212− minps m0, m0, m5
213− minps m1, m1, m5
214− minps m2, m2, m5
215− minps m3, m3, m5
216− cvtps2dq m0, m0
217− cvtps2dq m1, m1
218− cvtps2dq m2, m2
219− cvtps2dq m3, m3
220− mova [dstq+lenq ], m0
221− mova [dstq+lenq+1*mmsize], m1
222− mova [dstq+lenq+2*mmsize], m2
223− mova [dstq+lenq+3*mmsize], m3
224− add lenq, mmsize*4
225− jl .loop
226− REP_RET
227−%endmacro
228−
229−INIT_XMM sse2
230−CONV_FLT_TO_S32
231−%if HAVE_AVX_EXTERNAL
232−INIT_YMM avx
233−CONV_FLT_TO_S32
234−%endif
235−
236−;------------------------------------------------------------------------------
237−; void ff_conv_s16p_to_s16_2ch(int16_t *dst, int16_t *const *src, int len,
238−; int channels);
239−;------------------------------------------------------------------------------
240−
241−%macro CONV_S16P_TO_S16_2CH 0
242−cglobal conv_s16p_to_s16_2ch, 3,4,5, dst, src0, len, src1
243− mov src1q, [src0q+gprsize]
244− mov src0q, [src0q ]
245− lea lenq, [2*lend]
246− add src0q, lenq
247− add src1q, lenq
248− lea dstq, [dstq+2*lenq]
249− neg lenq
250−.loop:
251− mova m0, [src0q+lenq ]
252− mova m1, [src1q+lenq ]
253− mova m2, [src0q+lenq+mmsize]
254− mova m3, [src1q+lenq+mmsize]
255− SBUTTERFLY2 wd, 0, 1, 4
256− SBUTTERFLY2 wd, 2, 3, 4
257− mova [dstq+2*lenq+0*mmsize], m0
258− mova [dstq+2*lenq+1*mmsize], m1
259− mova [dstq+2*lenq+2*mmsize], m2
260− mova [dstq+2*lenq+3*mmsize], m3
261− add lenq, 2*mmsize
262− jl .loop
263− REP_RET
264−%endmacro
265−
266−INIT_XMM sse2
267−CONV_S16P_TO_S16_2CH
268−%if HAVE_AVX_EXTERNAL
269−INIT_XMM avx
270−CONV_S16P_TO_S16_2CH
271−%endif
272−
273−;------------------------------------------------------------------------------
274−; void ff_conv_s16p_to_s16_6ch(int16_t *dst, int16_t *const *src, int len,
275−; int channels);
276−;------------------------------------------------------------------------------
277−
278−;------------------------------------------------------------------------------
279−; NOTE: In the 6-channel functions, len could be used as an index on x86-64
280−; instead of just a counter, which would avoid incrementing the
281−; pointers, but the extra complexity and amount of code is not worth
282−; the small gain. On x86-32 there are not enough registers to use len
283−; as an index without keeping two of the pointers on the stack and
284−; loading them in each iteration.
285−;------------------------------------------------------------------------------
286−
287−%macro CONV_S16P_TO_S16_6CH 0
288−%if ARCH_X86_64
289−cglobal conv_s16p_to_s16_6ch, 3,8,7, dst, src0, len, src1, src2, src3, src4, src5
290−%else
291−cglobal conv_s16p_to_s16_6ch, 2,7,7, dst, src0, src1, src2, src3, src4, src5
292−%define lend dword r2m
293−%endif
294− mov src1q, [src0q+1*gprsize]
295− mov src2q, [src0q+2*gprsize]
296− mov src3q, [src0q+3*gprsize]
297− mov src4q, [src0q+4*gprsize]
298− mov src5q, [src0q+5*gprsize]
299− mov src0q, [src0q]
300− sub src1q, src0q
301− sub src2q, src0q
302− sub src3q, src0q
303− sub src4q, src0q
304− sub src5q, src0q
305−.loop:
306−%if cpuflag(sse2slow)
307− movq m0, [src0q ] ; m0 = 0, 6, 12, 18, x, x, x, x
308− movq m1, [src0q+src1q] ; m1 = 1, 7, 13, 19, x, x, x, x
309− movq m2, [src0q+src2q] ; m2 = 2, 8, 14, 20, x, x, x, x
310− movq m3, [src0q+src3q] ; m3 = 3, 9, 15, 21, x, x, x, x
311− movq m4, [src0q+src4q] ; m4 = 4, 10, 16, 22, x, x, x, x
312− movq m5, [src0q+src5q] ; m5 = 5, 11, 17, 23, x, x, x, x
313− ; unpack words:
314− punpcklwd m0, m1 ; m0 = 0, 1, 6, 7, 12, 13, 18, 19
315− punpcklwd m2, m3 ; m2 = 4, 5, 10, 11, 16, 17, 22, 23
316− punpcklwd m4, m5 ; m4 = 2, 3, 8, 9, 14, 15, 20, 21
317− ; blend dwords
318− shufps m1, m0, m2, q2020 ; m1 = 0, 1, 12, 13, 2, 3, 14, 15
319− shufps m0, m4, q2031 ; m0 = 6, 7, 18, 19, 4, 5, 16, 17
320− shufps m2, m4, q3131 ; m2 = 8, 9, 20, 21, 10, 11, 22, 23
321− ; shuffle dwords
322− pshufd m0, m0, q1302 ; m0 = 4, 5, 6, 7, 16, 17, 18, 19
323− pshufd m1, m1, q3120 ; m1 = 0, 1, 2, 3, 12, 13, 14, 15
324− pshufd m2, m2, q3120 ; m2 = 8, 9, 10, 11, 20, 21, 22, 23
325− movq [dstq+0*mmsize/2], m1
326− movq [dstq+1*mmsize/2], m0
327− movq [dstq+2*mmsize/2], m2
328− movhps [dstq+3*mmsize/2], m1
329− movhps [dstq+4*mmsize/2], m0
330− movhps [dstq+5*mmsize/2], m2
331− add src0q, mmsize/2
332− add dstq, mmsize*3
333− sub lend, mmsize/4
334−%else
335− mova m0, [src0q ] ; m0 = 0, 6, 12, 18, 24, 30, 36, 42
336− mova m1, [src0q+src1q] ; m1 = 1, 7, 13, 19, 25, 31, 37, 43
337− mova m2, [src0q+src2q] ; m2 = 2, 8, 14, 20, 26, 32, 38, 44
338− mova m3, [src0q+src3q] ; m3 = 3, 9, 15, 21, 27, 33, 39, 45
339− mova m4, [src0q+src4q] ; m4 = 4, 10, 16, 22, 28, 34, 40, 46
340− mova m5, [src0q+src5q] ; m5 = 5, 11, 17, 23, 29, 35, 41, 47
341− ; unpack words:
342− SBUTTERFLY2 wd, 0, 1, 6 ; m0 = 0, 1, 6, 7, 12, 13, 18, 19
343− ; m1 = 24, 25, 30, 31, 36, 37, 42, 43
344− SBUTTERFLY2 wd, 2, 3, 6 ; m2 = 2, 3, 8, 9, 14, 15, 20, 21
345− ; m3 = 26, 27, 32, 33, 38, 39, 44, 45
346− SBUTTERFLY2 wd, 4, 5, 6 ; m4 = 4, 5, 10, 11, 16, 17, 22, 23
347− ; m5 = 28, 29, 34, 35, 40, 41, 46, 47
348− ; blend dwords
349− shufps m6, m0, m2, q2020 ; m6 = 0, 1, 12, 13, 2, 3, 14, 15
350− shufps m0, m4, q2031 ; m0 = 6, 7, 18, 19, 4, 5, 16, 17
351− shufps m2, m4, q3131 ; m2 = 8, 9, 20, 21, 10, 11, 22, 23
352− SWAP 4,6 ; m4 = 0, 1, 12, 13, 2, 3, 14, 15
353− shufps m6, m1, m3, q2020 ; m6 = 24, 25, 36, 37, 26, 27, 38, 39
354− shufps m1, m5, q2031 ; m1 = 30, 31, 42, 43, 28, 29, 40, 41
355− shufps m3, m5, q3131 ; m3 = 32, 33, 44, 45, 34, 35, 46, 47
356− SWAP 5,6 ; m5 = 24, 25, 36, 37, 26, 27, 38, 39
357− ; shuffle dwords
358− pshufd m0, m0, q1302 ; m0 = 4, 5, 6, 7, 16, 17, 18, 19
359− pshufd m2, m2, q3120 ; m2 = 8, 9, 10, 11, 20, 21, 22, 23
360− pshufd m4, m4, q3120 ; m4 = 0, 1, 2, 3, 12, 13, 14, 15
361− pshufd m1, m1, q1302 ; m1 = 28, 29, 30, 31, 40, 41, 42, 43
362− pshufd m3, m3, q3120 ; m3 = 32, 33, 34, 35, 44, 45, 46, 47
363− pshufd m5, m5, q3120 ; m5 = 24, 25, 26, 27, 36, 37, 38, 39
364− ; shuffle qwords
365− punpcklqdq m6, m4, m0 ; m6 = 0, 1, 2, 3, 4, 5, 6, 7
366− punpckhqdq m0, m2 ; m0 = 16, 17, 18, 19, 20, 21, 22, 23
367− shufps m2, m4, q3210 ; m2 = 8, 9, 10, 11, 12, 13, 14, 15
368− SWAP 4,6 ; m4 = 0, 1, 2, 3, 4, 5, 6, 7
369− punpcklqdq m6, m5, m1 ; m6 = 24, 25, 26, 27, 28, 29, 30, 31
370− punpckhqdq m1, m3 ; m1 = 40, 41, 42, 43, 44, 45, 46, 47
371− shufps m3, m5, q3210 ; m3 = 32, 33, 34, 35, 36, 37, 38, 39
372− SWAP 5,6 ; m5 = 24, 25, 26, 27, 28, 29, 30, 31
373− mova [dstq+0*mmsize], m4
374− mova [dstq+1*mmsize], m2
375− mova [dstq+2*mmsize], m0
376− mova [dstq+3*mmsize], m5
377− mova [dstq+4*mmsize], m3
378− mova [dstq+5*mmsize], m1
379− add src0q, mmsize
380− add dstq, mmsize*6
381− sub lend, mmsize/2
382−%endif
383− jg .loop
384− REP_RET
385−%endmacro
386−
387−INIT_XMM sse2
388−CONV_S16P_TO_S16_6CH
389−INIT_XMM sse2slow
390−CONV_S16P_TO_S16_6CH
391−%if HAVE_AVX_EXTERNAL
392−INIT_XMM avx
393−CONV_S16P_TO_S16_6CH
394−%endif
395−
396−;------------------------------------------------------------------------------
397−; void ff_conv_s16p_to_flt_2ch(float *dst, int16_t *const *src, int len,
398−; int channels);
399−;------------------------------------------------------------------------------
400−
401−%macro CONV_S16P_TO_FLT_2CH 0
402−cglobal conv_s16p_to_flt_2ch, 3,4,6, dst, src0, len, src1
403− lea lenq, [2*lend]
404− mov src1q, [src0q+gprsize]
405− mov src0q, [src0q ]
406− lea dstq, [dstq+4*lenq]
407− add src0q, lenq
408− add src1q, lenq
409− neg lenq
410− mova m5, [pf_s32_inv_scale]
411−.loop:
412− mova m2, [src0q+lenq] ; m2 = 0, 2, 4, 6, 8, 10, 12, 14
413− mova m4, [src1q+lenq] ; m4 = 1, 3, 5, 7, 9, 11, 13, 15
414− SBUTTERFLY2 wd, 2, 4, 3 ; m2 = 0, 1, 2, 3, 4, 5, 6, 7
415− ; m4 = 8, 9, 10, 11, 12, 13, 14, 15
416− pxor m3, m3
417− punpcklwd m0, m3, m2 ; m0 = 0, 1, 2, 3
418− punpckhwd m1, m3, m2 ; m1 = 4, 5, 6, 7
419− punpcklwd m2, m3, m4 ; m2 = 8, 9, 10, 11
420− punpckhwd m3, m4 ; m3 = 12, 13, 14, 15
421− cvtdq2ps m0, m0
422− cvtdq2ps m1, m1
423− cvtdq2ps m2, m2
424− cvtdq2ps m3, m3
425− mulps m0, m5
426− mulps m1, m5
427− mulps m2, m5
428− mulps m3, m5
429− mova [dstq+4*lenq ], m0
430− mova [dstq+4*lenq+ mmsize], m1
431− mova [dstq+4*lenq+2*mmsize], m2
432− mova [dstq+4*lenq+3*mmsize], m3
433− add lenq, mmsize
434− jl .loop
435− REP_RET
436−%endmacro
437−
438−INIT_XMM sse2
439−CONV_S16P_TO_FLT_2CH
440−%if HAVE_AVX_EXTERNAL
441−INIT_XMM avx
442−CONV_S16P_TO_FLT_2CH
443−%endif
444−
445−;------------------------------------------------------------------------------
446−; void ff_conv_s16p_to_flt_6ch(float *dst, int16_t *const *src, int len,
447−; int channels);
448−;------------------------------------------------------------------------------
449−
450−%macro CONV_S16P_TO_FLT_6CH 0
451−%if ARCH_X86_64
452−cglobal conv_s16p_to_flt_6ch, 3,8,8, dst, src, len, src1, src2, src3, src4, src5
453−%else
454−cglobal conv_s16p_to_flt_6ch, 2,7,8, dst, src, src1, src2, src3, src4, src5
455−%define lend dword r2m
456−%endif
457− mov src1q, [srcq+1*gprsize]
458− mov src2q, [srcq+2*gprsize]
459− mov src3q, [srcq+3*gprsize]
460− mov src4q, [srcq+4*gprsize]
461− mov src5q, [srcq+5*gprsize]
462− mov srcq, [srcq]
463− sub src1q, srcq
464− sub src2q, srcq
465− sub src3q, srcq
466− sub src4q, srcq
467− sub src5q, srcq
468− mova m7, [pf_s32_inv_scale]
469−%if cpuflag(ssse3)
470− %define unpack_even m6
471− mova m6, [pb_shuf_unpack_even]
472−%if ARCH_X86_64
473− %define unpack_odd m8
474− mova m8, [pb_shuf_unpack_odd]
475−%else
476− %define unpack_odd [pb_shuf_unpack_odd]
477−%endif
478−%endif
479−.loop:
480− movq m0, [srcq ] ; m0 = 0, 6, 12, 18, x, x, x, x
481− movq m1, [srcq+src1q] ; m1 = 1, 7, 13, 19, x, x, x, x
482− movq m2, [srcq+src2q] ; m2 = 2, 8, 14, 20, x, x, x, x
483− movq m3, [srcq+src3q] ; m3 = 3, 9, 15, 21, x, x, x, x
484− movq m4, [srcq+src4q] ; m4 = 4, 10, 16, 22, x, x, x, x
485− movq m5, [srcq+src5q] ; m5 = 5, 11, 17, 23, x, x, x, x
486− ; unpack words:
487− punpcklwd m0, m1 ; m0 = 0, 1, 6, 7, 12, 13, 18, 19
488− punpcklwd m2, m3 ; m2 = 2, 3, 8, 9, 14, 15, 20, 21
489− punpcklwd m4, m5 ; m4 = 4, 5, 10, 11, 16, 17, 22, 23
490− ; blend dwords
491− shufps m1, m4, m0, q3120 ; m1 = 4, 5, 16, 17, 6, 7, 18, 19
492− shufps m0, m2, q2020 ; m0 = 0, 1, 12, 13, 2, 3, 14, 15
493− shufps m2, m4, q3131 ; m2 = 8, 9, 20, 21, 10, 11, 22, 23
494−%if cpuflag(ssse3)
495− pshufb m3, m0, unpack_odd ; m3 = 12, 13, 14, 15
496− pshufb m0, unpack_even ; m0 = 0, 1, 2, 3
497− pshufb m4, m1, unpack_odd ; m4 = 16, 17, 18, 19
498− pshufb m1, unpack_even ; m1 = 4, 5, 6, 7
499− pshufb m5, m2, unpack_odd ; m5 = 20, 21, 22, 23
500− pshufb m2, unpack_even ; m2 = 8, 9, 10, 11
501−%else
502− ; shuffle dwords
503− pshufd m0, m0, q3120 ; m0 = 0, 1, 2, 3, 12, 13, 14, 15
504− pshufd m1, m1, q3120 ; m1 = 4, 5, 6, 7, 16, 17, 18, 19
505− pshufd m2, m2, q3120 ; m2 = 8, 9, 10, 11, 20, 21, 22, 23
506− pxor m6, m6 ; convert s16 in m0-m2 to s32 in m0-m5
507− punpcklwd m3, m6, m0 ; m3 = 0, 1, 2, 3
508− punpckhwd m4, m6, m0 ; m4 = 12, 13, 14, 15
509− punpcklwd m0, m6, m1 ; m0 = 4, 5, 6, 7
510− punpckhwd m5, m6, m1 ; m5 = 16, 17, 18, 19
511− punpcklwd m1, m6, m2 ; m1 = 8, 9, 10, 11
512− punpckhwd m6, m2 ; m6 = 20, 21, 22, 23
513− SWAP 6,2,1,0,3,4,5 ; swap registers 3,0,1,4,5,6 to 0,1,2,3,4,5
514−%endif
515− cvtdq2ps m0, m0 ; convert s32 to float
516− cvtdq2ps m1, m1
517− cvtdq2ps m2, m2
518− cvtdq2ps m3, m3
519− cvtdq2ps m4, m4
520− cvtdq2ps m5, m5
521− mulps m0, m7 ; scale float from s32 range to [-1.0,1.0]
522− mulps m1, m7
523− mulps m2, m7
524− mulps m3, m7
525− mulps m4, m7
526− mulps m5, m7
527− mova [dstq ], m0
528− mova [dstq+ mmsize], m1
529− mova [dstq+2*mmsize], m2
530− mova [dstq+3*mmsize], m3
531− mova [dstq+4*mmsize], m4
532− mova [dstq+5*mmsize], m5
533− add srcq, mmsize/2
534− add dstq, mmsize*6
535− sub lend, mmsize/4
536− jg .loop
537− REP_RET
538−%endmacro
539−
540−INIT_XMM sse2
541−CONV_S16P_TO_FLT_6CH
542−INIT_XMM ssse3
543−CONV_S16P_TO_FLT_6CH
544−%if HAVE_AVX_EXTERNAL
545−INIT_XMM avx
546−CONV_S16P_TO_FLT_6CH
547−%endif
548−
549−;------------------------------------------------------------------------------
550−; void ff_conv_fltp_to_s16_2ch(int16_t *dst, float *const *src, int len,
551−; int channels);
552−;------------------------------------------------------------------------------
553−
554−%macro CONV_FLTP_TO_S16_2CH 0
555−cglobal conv_fltp_to_s16_2ch, 3,4,3, dst, src0, len, src1
556− lea lenq, [4*lend]
557− mov src1q, [src0q+gprsize]
558− mov src0q, [src0q ]
559− add dstq, lenq
560− add src0q, lenq
561− add src1q, lenq
562− neg lenq
563− mova m2, [pf_s16_scale]
564−%if cpuflag(ssse3)
565− mova m3, [pb_interleave_words]
566−%endif
567−.loop:
568− mulps m0, m2, [src0q+lenq] ; m0 = 0, 2, 4, 6
569− mulps m1, m2, [src1q+lenq] ; m1 = 1, 3, 5, 7
570− cvtps2dq m0, m0
571− cvtps2dq m1, m1
572−%if cpuflag(ssse3)
573− packssdw m0, m1 ; m0 = 0, 2, 4, 6, 1, 3, 5, 7
574− pshufb m0, m3 ; m0 = 0, 1, 2, 3, 4, 5, 6, 7
575−%else
576− packssdw m0, m0 ; m0 = 0, 2, 4, 6, x, x, x, x
577− packssdw m1, m1 ; m1 = 1, 3, 5, 7, x, x, x, x
578− punpcklwd m0, m1 ; m0 = 0, 1, 2, 3, 4, 5, 6, 7
579−%endif
580− mova [dstq+lenq], m0
581− add lenq, mmsize
582− jl .loop
583− REP_RET
584−%endmacro
585−
586−INIT_XMM sse2
587−CONV_FLTP_TO_S16_2CH
588−INIT_XMM ssse3
589−CONV_FLTP_TO_S16_2CH
590−
591−;------------------------------------------------------------------------------
592−; void ff_conv_fltp_to_s16_6ch(int16_t *dst, float *const *src, int len,
593−; int channels);
594−;------------------------------------------------------------------------------
595−
596−%macro CONV_FLTP_TO_S16_6CH 0
597−%if ARCH_X86_64
598−cglobal conv_fltp_to_s16_6ch, 3,8,7, dst, src, len, src1, src2, src3, src4, src5
599−%else
600−cglobal conv_fltp_to_s16_6ch, 2,7,7, dst, src, src1, src2, src3, src4, src5
601−%define lend dword r2m
602−%endif
603− mov src1q, [srcq+1*gprsize]
604− mov src2q, [srcq+2*gprsize]
605− mov src3q, [srcq+3*gprsize]
606− mov src4q, [srcq+4*gprsize]
607− mov src5q, [srcq+5*gprsize]
608− mov srcq, [srcq]
609− sub src1q, srcq
610− sub src2q, srcq
611− sub src3q, srcq
612− sub src4q, srcq
613− sub src5q, srcq
614− movaps xmm6, [pf_s16_scale]
615−.loop:
616−%if cpuflag(sse2)
617− mulps m0, m6, [srcq ]
618− mulps m1, m6, [srcq+src1q]
619− mulps m2, m6, [srcq+src2q]
620− mulps m3, m6, [srcq+src3q]
621− mulps m4, m6, [srcq+src4q]
622− mulps m5, m6, [srcq+src5q]
623− cvtps2dq m0, m0
624− cvtps2dq m1, m1
625− cvtps2dq m2, m2
626− cvtps2dq m3, m3
627− cvtps2dq m4, m4
628− cvtps2dq m5, m5
629− packssdw m0, m3 ; m0 = 0, 6, 12, 18, 3, 9, 15, 21
630− packssdw m1, m4 ; m1 = 1, 7, 13, 19, 4, 10, 16, 22
631− packssdw m2, m5 ; m2 = 2, 8, 14, 20, 5, 11, 17, 23
632− ; unpack words:
633− movhlps m3, m0 ; m3 = 3, 9, 15, 21, x, x, x, x
634− punpcklwd m0, m1 ; m0 = 0, 1, 6, 7, 12, 13, 18, 19
635− punpckhwd m1, m2 ; m1 = 4, 5, 10, 11, 16, 17, 22, 23
636− punpcklwd m2, m3 ; m2 = 2, 3, 8, 9, 14, 15, 20, 21
637− ; blend dwords:
638− shufps m3, m0, m2, q2020 ; m3 = 0, 1, 12, 13, 2, 3, 14, 15
639− shufps m0, m1, q2031 ; m0 = 6, 7, 18, 19, 4, 5, 16, 17
640− shufps m2, m1, q3131 ; m2 = 8, 9, 20, 21, 10, 11, 22, 23
641− ; shuffle dwords:
642− shufps m1, m2, m3, q3120 ; m1 = 8, 9, 10, 11, 12, 13, 14, 15
643− shufps m3, m0, q0220 ; m3 = 0, 1, 2, 3, 4, 5, 6, 7
644− shufps m0, m2, q3113 ; m0 = 16, 17, 18, 19, 20, 21, 22, 23
645− mova [dstq+0*mmsize], m3
646− mova [dstq+1*mmsize], m1
647− mova [dstq+2*mmsize], m0
648−%else ; sse
649− movlps xmm0, [srcq ]
650− movlps xmm1, [srcq+src1q]
651− movlps xmm2, [srcq+src2q]
652− movlps xmm3, [srcq+src3q]
653− movlps xmm4, [srcq+src4q]
654− movlps xmm5, [srcq+src5q]
655− mulps xmm0, xmm6
656− mulps xmm1, xmm6
657− mulps xmm2, xmm6
658− mulps xmm3, xmm6
659− mulps xmm4, xmm6
660− mulps xmm5, xmm6
661− cvtps2pi mm0, xmm0
662− cvtps2pi mm1, xmm1
663− cvtps2pi mm2, xmm2
664− cvtps2pi mm3, xmm3
665− cvtps2pi mm4, xmm4
666− cvtps2pi mm5, xmm5
667− packssdw mm0, mm3 ; m0 = 0, 6, 3, 9
668− packssdw mm1, mm4 ; m1 = 1, 7, 4, 10
669− packssdw mm2, mm5 ; m2 = 2, 8, 5, 11
670− ; unpack words
671− pshufw mm3, mm0, q1032 ; m3 = 3, 9, 0, 6
672− punpcklwd mm0, mm1 ; m0 = 0, 1, 6, 7
673− punpckhwd mm1, mm2 ; m1 = 4, 5, 10, 11
674− punpcklwd mm2, mm3 ; m2 = 2, 3, 8, 9
675− ; unpack dwords
676− pshufw mm3, mm0, q1032 ; m3 = 6, 7, 0, 1
677− punpckldq mm0, mm2 ; m0 = 0, 1, 2, 3 (final)
678− punpckhdq mm2, mm1 ; m2 = 8, 9, 10, 11 (final)
679− punpckldq mm1, mm3 ; m1 = 4, 5, 6, 7 (final)
680− mova [dstq+0*mmsize], mm0
681− mova [dstq+1*mmsize], mm1
682− mova [dstq+2*mmsize], mm2
683−%endif
684− add srcq, mmsize
685− add dstq, mmsize*3
686− sub lend, mmsize/4
687− jg .loop
688−%if mmsize == 8
689− emms
690− RET
691−%else
692− REP_RET
693−%endif
694−%endmacro
695−
696−INIT_MMX sse
697−CONV_FLTP_TO_S16_6CH
698−INIT_XMM sse2
699−CONV_FLTP_TO_S16_6CH
700−%if HAVE_AVX_EXTERNAL
701−INIT_XMM avx
702−CONV_FLTP_TO_S16_6CH
703−%endif
704−
705−;------------------------------------------------------------------------------
706−; void ff_conv_fltp_to_flt_2ch(float *dst, float *const *src, int len,
707−; int channels);
708−;------------------------------------------------------------------------------
709−
710−%macro CONV_FLTP_TO_FLT_2CH 0
711−cglobal conv_fltp_to_flt_2ch, 3,4,5, dst, src0, len, src1
712− mov src1q, [src0q+gprsize]
713− mov src0q, [src0q]
714− lea lenq, [4*lend]
715− add src0q, lenq
716− add src1q, lenq
717− lea dstq, [dstq+2*lenq]
718− neg lenq
719−.loop:
720− mova m0, [src0q+lenq ]
721− mova m1, [src1q+lenq ]
722− mova m2, [src0q+lenq+mmsize]
723− mova m3, [src1q+lenq+mmsize]
724− SBUTTERFLYPS 0, 1, 4
725− SBUTTERFLYPS 2, 3, 4
726− mova [dstq+2*lenq+0*mmsize], m0
727− mova [dstq+2*lenq+1*mmsize], m1
728− mova [dstq+2*lenq+2*mmsize], m2
729− mova [dstq+2*lenq+3*mmsize], m3
730− add lenq, 2*mmsize
731− jl .loop
732− REP_RET
733−%endmacro
734−
735−INIT_XMM sse
736−CONV_FLTP_TO_FLT_2CH
737−%if HAVE_AVX_EXTERNAL
738−INIT_XMM avx
739−CONV_FLTP_TO_FLT_2CH
740−%endif
741−
742−;-----------------------------------------------------------------------------
743−; void ff_conv_fltp_to_flt_6ch(float *dst, float *const *src, int len,
744−; int channels);
745−;-----------------------------------------------------------------------------
746−
747−%macro CONV_FLTP_TO_FLT_6CH 0
748−cglobal conv_fltp_to_flt_6ch, 2,8,7, dst, src, src1, src2, src3, src4, src5, len
749−%if ARCH_X86_64
750− mov lend, r2d
751−%else
752− %define lend dword r2m
753−%endif
754− mov src1q, [srcq+1*gprsize]
755− mov src2q, [srcq+2*gprsize]
756− mov src3q, [srcq+3*gprsize]
757− mov src4q, [srcq+4*gprsize]
758− mov src5q, [srcq+5*gprsize]
759− mov srcq, [srcq]
760− sub src1q, srcq
761− sub src2q, srcq
762− sub src3q, srcq
763− sub src4q, srcq
764− sub src5q, srcq
765−.loop:
766− mova m0, [srcq ]
767− mova m1, [srcq+src1q]
768− mova m2, [srcq+src2q]
769− mova m3, [srcq+src3q]
770− mova m4, [srcq+src4q]
771− mova m5, [srcq+src5q]
772−%if cpuflag(sse4)
773− SBUTTERFLYPS 0, 1, 6
774− SBUTTERFLYPS 2, 3, 6
775− SBUTTERFLYPS 4, 5, 6
776−
777− blendps m6, m4, m0, 1100b
778− movlhps m0, m2
779− movhlps m4, m2
780− blendps m2, m5, m1, 1100b
781− movlhps m1, m3
782− movhlps m5, m3
783−
784− movaps [dstq ], m0
785− movaps [dstq+16], m6
786− movaps [dstq+32], m4
787− movaps [dstq+48], m1
788− movaps [dstq+64], m2
789− movaps [dstq+80], m5
790−%else ; mmx
791− SBUTTERFLY dq, 0, 1, 6
792− SBUTTERFLY dq, 2, 3, 6
793− SBUTTERFLY dq, 4, 5, 6
794−
795− movq [dstq ], m0
796− movq [dstq+ 8], m2
797− movq [dstq+16], m4
798− movq [dstq+24], m1
799− movq [dstq+32], m3
800− movq [dstq+40], m5
801−%endif
802− add srcq, mmsize
803− add dstq, mmsize*6
804− sub lend, mmsize/4
805− jg .loop
806−%if mmsize == 8
807− emms
808− RET
809−%else
810− REP_RET
811−%endif
812−%endmacro
813−
814−INIT_MMX mmx
815−CONV_FLTP_TO_FLT_6CH
816−INIT_XMM sse4
817−CONV_FLTP_TO_FLT_6CH
818−%if HAVE_AVX_EXTERNAL
819−INIT_XMM avx
820−CONV_FLTP_TO_FLT_6CH
821−%endif
822−
823−;------------------------------------------------------------------------------
824−; void ff_conv_s16_to_s16p_2ch(int16_t *const *dst, int16_t *src, int len,
825−; int channels);
826−;------------------------------------------------------------------------------
827−
828−%macro CONV_S16_TO_S16P_2CH 0
829−cglobal conv_s16_to_s16p_2ch, 3,4,4, dst0, src, len, dst1
830− lea lenq, [2*lend]
831− mov dst1q, [dst0q+gprsize]
832− mov dst0q, [dst0q ]
833− lea srcq, [srcq+2*lenq]
834− add dst0q, lenq
835− add dst1q, lenq
836− neg lenq
837−%if cpuflag(ssse3)
838− mova m3, [pb_deinterleave_words]
839−%endif
840−.loop:
841− mova m0, [srcq+2*lenq ] ; m0 = 0, 1, 2, 3, 4, 5, 6, 7
842− mova m1, [srcq+2*lenq+mmsize] ; m1 = 8, 9, 10, 11, 12, 13, 14, 15
843−%if cpuflag(ssse3)
844− pshufb m0, m3 ; m0 = 0, 2, 4, 6, 1, 3, 5, 7
845− pshufb m1, m3 ; m1 = 8, 10, 12, 14, 9, 11, 13, 15
846− SBUTTERFLY2 qdq, 0, 1, 2 ; m0 = 0, 2, 4, 6, 8, 10, 12, 14
847− ; m1 = 1, 3, 5, 7, 9, 11, 13, 15
848−%else ; sse2
849− pshuflw m0, m0, q3120 ; m0 = 0, 2, 1, 3, 4, 5, 6, 7
850− pshufhw m0, m0, q3120 ; m0 = 0, 2, 1, 3, 4, 6, 5, 7
851− pshuflw m1, m1, q3120 ; m1 = 8, 10, 9, 11, 12, 13, 14, 15
852− pshufhw m1, m1, q3120 ; m1 = 8, 10, 9, 11, 12, 14, 13, 15
853− DEINT2_PS 0, 1, 2 ; m0 = 0, 2, 4, 6, 8, 10, 12, 14
854− ; m1 = 1, 3, 5, 7, 9, 11, 13, 15
855−%endif
856− mova [dst0q+lenq], m0
857− mova [dst1q+lenq], m1
858− add lenq, mmsize
859− jl .loop
860− REP_RET
861−%endmacro
862−
863−INIT_XMM sse2
864−CONV_S16_TO_S16P_2CH
865−INIT_XMM ssse3
866−CONV_S16_TO_S16P_2CH
867−%if HAVE_AVX_EXTERNAL
868−INIT_XMM avx
869−CONV_S16_TO_S16P_2CH
870−%endif
871−
872−;------------------------------------------------------------------------------
873−; void ff_conv_s16_to_s16p_6ch(int16_t *const *dst, int16_t *src, int len,
874−; int channels);
875−;------------------------------------------------------------------------------
876−
877−%macro CONV_S16_TO_S16P_6CH 0
878−%if ARCH_X86_64
879−cglobal conv_s16_to_s16p_6ch, 3,8,5, dst, src, len, dst1, dst2, dst3, dst4, dst5
880−%else
881−cglobal conv_s16_to_s16p_6ch, 2,7,5, dst, src, dst1, dst2, dst3, dst4, dst5
882−%define lend dword r2m
883−%endif
884− mov dst1q, [dstq+ gprsize]
885− mov dst2q, [dstq+2*gprsize]
886− mov dst3q, [dstq+3*gprsize]
887− mov dst4q, [dstq+4*gprsize]
888− mov dst5q, [dstq+5*gprsize]
889− mov dstq, [dstq ]
890− sub dst1q, dstq
891− sub dst2q, dstq
892− sub dst3q, dstq
893− sub dst4q, dstq
894− sub dst5q, dstq
895−.loop:
896− mova m0, [srcq+0*mmsize] ; m0 = 0, 1, 2, 3, 4, 5, 6, 7
897− mova m3, [srcq+1*mmsize] ; m3 = 8, 9, 10, 11, 12, 13, 14, 15
898− mova m2, [srcq+2*mmsize] ; m2 = 16, 17, 18, 19, 20, 21, 22, 23
899− PALIGNR m1, m3, m0, 12, m4 ; m1 = 6, 7, 8, 9, 10, 11, x, x
900− shufps m3, m2, q1032 ; m3 = 12, 13, 14, 15, 16, 17, 18, 19
901− psrldq m2, 4 ; m2 = 18, 19, 20, 21, 22, 23, x, x
902− SBUTTERFLY2 wd, 0, 1, 4 ; m0 = 0, 6, 1, 7, 2, 8, 3, 9
903− ; m1 = 4, 10, 5, 11, x, x, x, x
904− SBUTTERFLY2 wd, 3, 2, 4 ; m3 = 12, 18, 13, 19, 14, 20, 15, 21
905− ; m2 = 16, 22, 17, 23, x, x, x, x
906− SBUTTERFLY2 dq, 0, 3, 4 ; m0 = 0, 6, 12, 18, 1, 7, 13, 19
907− ; m3 = 2, 8, 14, 20, 3, 9, 15, 21
908− punpckldq m1, m2 ; m1 = 4, 10, 16, 22, 5, 11, 17, 23
909− movq [dstq ], m0
910− movhps [dstq+dst1q], m0
911− movq [dstq+dst2q], m3
912− movhps [dstq+dst3q], m3
913− movq [dstq+dst4q], m1
914− movhps [dstq+dst5q], m1
915− add srcq, mmsize*3
916− add dstq, mmsize/2
917− sub lend, mmsize/4
918− jg .loop
919− REP_RET
920−%endmacro
921−
922−INIT_XMM sse2
923−CONV_S16_TO_S16P_6CH
924−INIT_XMM ssse3
925−CONV_S16_TO_S16P_6CH
926−%if HAVE_AVX_EXTERNAL
927−INIT_XMM avx
928−CONV_S16_TO_S16P_6CH
929−%endif
930−
931−;------------------------------------------------------------------------------
932−; void ff_conv_s16_to_fltp_2ch(float *const *dst, int16_t *src, int len,
933−; int channels);
934−;------------------------------------------------------------------------------
935−
936−%macro CONV_S16_TO_FLTP_2CH 0
937−cglobal conv_s16_to_fltp_2ch, 3,4,5, dst0, src, len, dst1
938− lea lenq, [4*lend]
939− mov dst1q, [dst0q+gprsize]
940− mov dst0q, [dst0q ]
941− add srcq, lenq
942− add dst0q, lenq
943− add dst1q, lenq
944− neg lenq
945− mova m3, [pf_s32_inv_scale]
946− mova m4, [pw_zero_even]
947−.loop:
948− mova m1, [srcq+lenq]
949− pslld m0, m1, 16
950− pand m1, m4
951− cvtdq2ps m0, m0
952− cvtdq2ps m1, m1
953− mulps m0, m0, m3
954− mulps m1, m1, m3
955− mova [dst0q+lenq], m0
956− mova [dst1q+lenq], m1
957− add lenq, mmsize
958− jl .loop
959− REP_RET
960−%endmacro
961−
962−INIT_XMM sse2
963−CONV_S16_TO_FLTP_2CH
964−%if HAVE_AVX_EXTERNAL
965−INIT_XMM avx
966−CONV_S16_TO_FLTP_2CH
967−%endif
968−
969−;------------------------------------------------------------------------------
970−; void ff_conv_s16_to_fltp_6ch(float *const *dst, int16_t *src, int len,
971−; int channels);
972−;------------------------------------------------------------------------------
973−
974−%macro CONV_S16_TO_FLTP_6CH 0
975−%if ARCH_X86_64
976−cglobal conv_s16_to_fltp_6ch, 3,8,7, dst, src, len, dst1, dst2, dst3, dst4, dst5
977−%else
978−cglobal conv_s16_to_fltp_6ch, 2,7,7, dst, src, dst1, dst2, dst3, dst4, dst5
979−%define lend dword r2m
980−%endif
981− mov dst1q, [dstq+ gprsize]
982− mov dst2q, [dstq+2*gprsize]
983− mov dst3q, [dstq+3*gprsize]
984− mov dst4q, [dstq+4*gprsize]
985− mov dst5q, [dstq+5*gprsize]
986− mov dstq, [dstq ]
987− sub dst1q, dstq
988− sub dst2q, dstq
989− sub dst3q, dstq
990− sub dst4q, dstq
991− sub dst5q, dstq
992− mova m6, [pf_s16_inv_scale]
993−.loop:
994− mova m0, [srcq+0*mmsize] ; m0 = 0, 1, 2, 3, 4, 5, 6, 7
995− mova m3, [srcq+1*mmsize] ; m3 = 8, 9, 10, 11, 12, 13, 14, 15
996− mova m2, [srcq+2*mmsize] ; m2 = 16, 17, 18, 19, 20, 21, 22, 23
997− PALIGNR m1, m3, m0, 12, m4 ; m1 = 6, 7, 8, 9, 10, 11, x, x
998− shufps m3, m2, q1032 ; m3 = 12, 13, 14, 15, 16, 17, 18, 19
999− psrldq m2, 4 ; m2 = 18, 19, 20, 21, 22, 23, x, x
1000− SBUTTERFLY2 wd, 0, 1, 4 ; m0 = 0, 6, 1, 7, 2, 8, 3, 9
1001− ; m1 = 4, 10, 5, 11, x, x, x, x
1002− SBUTTERFLY2 wd, 3, 2, 4 ; m3 = 12, 18, 13, 19, 14, 20, 15, 21
1003− ; m2 = 16, 22, 17, 23, x, x, x, x
1004− SBUTTERFLY2 dq, 0, 3, 4 ; m0 = 0, 6, 12, 18, 1, 7, 13, 19
1005− ; m3 = 2, 8, 14, 20, 3, 9, 15, 21
1006− punpckldq m1, m2 ; m1 = 4, 10, 16, 22, 5, 11, 17, 23
1007− S16_TO_S32_SX 0, 2 ; m0 = 0, 6, 12, 18
1008− ; m2 = 1, 7, 13, 19
1009− S16_TO_S32_SX 3, 4 ; m3 = 2, 8, 14, 20
1010− ; m4 = 3, 9, 15, 21
1011− S16_TO_S32_SX 1, 5 ; m1 = 4, 10, 16, 22
1012− ; m5 = 5, 11, 17, 23
1013− SWAP 1,2,3,4
1014− cvtdq2ps m0, m0
1015− cvtdq2ps m1, m1
1016− cvtdq2ps m2, m2
1017− cvtdq2ps m3, m3
1018− cvtdq2ps m4, m4
1019− cvtdq2ps m5, m5
1020− mulps m0, m6
1021− mulps m1, m6
1022− mulps m2, m6
1023− mulps m3, m6
1024− mulps m4, m6
1025− mulps m5, m6
1026− mova [dstq ], m0
1027− mova [dstq+dst1q], m1
1028− mova [dstq+dst2q], m2
1029− mova [dstq+dst3q], m3
1030− mova [dstq+dst4q], m4
1031− mova [dstq+dst5q], m5
1032− add srcq, mmsize*3
1033− add dstq, mmsize
1034− sub lend, mmsize/4
1035− jg .loop
1036− REP_RET
1037−%endmacro
1038−
1039−INIT_XMM sse2
1040−CONV_S16_TO_FLTP_6CH
1041−INIT_XMM ssse3
1042−CONV_S16_TO_FLTP_6CH
1043−INIT_XMM sse4
1044−CONV_S16_TO_FLTP_6CH
1045−%if HAVE_AVX_EXTERNAL
1046−INIT_XMM avx
1047−CONV_S16_TO_FLTP_6CH
1048−%endif
1049−
1050−;------------------------------------------------------------------------------
1051−; void ff_conv_flt_to_s16p_2ch(int16_t *const *dst, float *src, int len,
1052−; int channels);
1053−;------------------------------------------------------------------------------
1054−
1055−%macro CONV_FLT_TO_S16P_2CH 0
1056−cglobal conv_flt_to_s16p_2ch, 3,4,6, dst0, src, len, dst1
1057− lea lenq, [2*lend]
1058− mov dst1q, [dst0q+gprsize]
1059− mov dst0q, [dst0q ]
1060− lea srcq, [srcq+4*lenq]
1061− add dst0q, lenq
1062− add dst1q, lenq
1063− neg lenq
1064− mova m5, [pf_s16_scale]
1065−.loop:
1066− mova m0, [srcq+4*lenq ]
1067− mova m1, [srcq+4*lenq+ mmsize]
1068− mova m2, [srcq+4*lenq+2*mmsize]
1069− mova m3, [srcq+4*lenq+3*mmsize]
1070− DEINT2_PS 0, 1, 4
1071− DEINT2_PS 2, 3, 4
1072− mulps m0, m0, m5
1073− mulps m1, m1, m5
1074− mulps m2, m2, m5
1075− mulps m3, m3, m5
1076− cvtps2dq m0, m0
1077− cvtps2dq m1, m1
1078− cvtps2dq m2, m2
1079− cvtps2dq m3, m3
1080− packssdw m0, m2
1081− packssdw m1, m3
1082− mova [dst0q+lenq], m0
1083− mova [dst1q+lenq], m1
1084− add lenq, mmsize
1085− jl .loop
1086− REP_RET
1087−%endmacro
1088−
1089−INIT_XMM sse2
1090−CONV_FLT_TO_S16P_2CH
1091−%if HAVE_AVX_EXTERNAL
1092−INIT_XMM avx
1093−CONV_FLT_TO_S16P_2CH
1094−%endif
1095−
1096−;------------------------------------------------------------------------------
1097−; void ff_conv_flt_to_s16p_6ch(int16_t *const *dst, float *src, int len,
1098−; int channels);
1099−;------------------------------------------------------------------------------
1100−
1101−%macro CONV_FLT_TO_S16P_6CH 0
1102−%if ARCH_X86_64
1103−cglobal conv_flt_to_s16p_6ch, 3,8,7, dst, src, len, dst1, dst2, dst3, dst4, dst5
1104−%else
1105−cglobal conv_flt_to_s16p_6ch, 2,7,7, dst, src, dst1, dst2, dst3, dst4, dst5
1106−%define lend dword r2m
1107−%endif
1108− mov dst1q, [dstq+ gprsize]
1109− mov dst2q, [dstq+2*gprsize]
1110− mov dst3q, [dstq+3*gprsize]
1111− mov dst4q, [dstq+4*gprsize]
1112− mov dst5q, [dstq+5*gprsize]
1113− mov dstq, [dstq ]
1114− sub dst1q, dstq
1115− sub dst2q, dstq
1116− sub dst3q, dstq
1117− sub dst4q, dstq
1118− sub dst5q, dstq
1119− mova m6, [pf_s16_scale]
1120−.loop:
1121− mulps m0, m6, [srcq+0*mmsize]
1122− mulps m3, m6, [srcq+1*mmsize]
1123− mulps m1, m6, [srcq+2*mmsize]
1124− mulps m4, m6, [srcq+3*mmsize]
1125− mulps m2, m6, [srcq+4*mmsize]
1126− mulps m5, m6, [srcq+5*mmsize]
1127− cvtps2dq m0, m0
1128− cvtps2dq m1, m1
1129− cvtps2dq m2, m2
1130− cvtps2dq m3, m3
1131− cvtps2dq m4, m4
1132− cvtps2dq m5, m5
1133− packssdw m0, m3 ; m0 = 0, 1, 2, 3, 4, 5, 6, 7
1134− packssdw m1, m4 ; m1 = 8, 9, 10, 11, 12, 13, 14, 15
1135− packssdw m2, m5 ; m2 = 16, 17, 18, 19, 20, 21, 22, 23
1136− PALIGNR m3, m1, m0, 12, m4 ; m3 = 6, 7, 8, 9, 10, 11, x, x
1137− shufps m1, m2, q1032 ; m1 = 12, 13, 14, 15, 16, 17, 18, 19
1138− psrldq m2, 4 ; m2 = 18, 19, 20, 21, 22, 23, x, x
1139− SBUTTERFLY2 wd, 0, 3, 4 ; m0 = 0, 6, 1, 7, 2, 8, 3, 9
1140− ; m3 = 4, 10, 5, 11, x, x, x, x
1141− SBUTTERFLY2 wd, 1, 2, 4 ; m1 = 12, 18, 13, 19, 14, 20, 15, 21
1142− ; m2 = 16, 22, 17, 23, x, x, x, x
1143− SBUTTERFLY2 dq, 0, 1, 4 ; m0 = 0, 6, 12, 18, 1, 7, 13, 19
1144− ; m1 = 2, 8, 14, 20, 3, 9, 15, 21
1145− punpckldq m3, m2 ; m3 = 4, 10, 16, 22, 5, 11, 17, 23
1146− movq [dstq ], m0
1147− movhps [dstq+dst1q], m0
1148− movq [dstq+dst2q], m1
1149− movhps [dstq+dst3q], m1
1150− movq [dstq+dst4q], m3
1151− movhps [dstq+dst5q], m3
1152− add srcq, mmsize*6
1153− add dstq, mmsize/2
1154− sub lend, mmsize/4
1155− jg .loop
1156− REP_RET
1157−%endmacro
1158−
1159−INIT_XMM sse2
1160−CONV_FLT_TO_S16P_6CH
1161−INIT_XMM ssse3
1162−CONV_FLT_TO_S16P_6CH
1163−%if HAVE_AVX_EXTERNAL
1164−INIT_XMM avx
1165−CONV_FLT_TO_S16P_6CH
1166−%endif
1167−
1168−;------------------------------------------------------------------------------
1169−; void ff_conv_flt_to_fltp_2ch(float *const *dst, float *src, int len,
1170−; int channels);
1171−;------------------------------------------------------------------------------
1172−
1173−%macro CONV_FLT_TO_FLTP_2CH 0
1174−cglobal conv_flt_to_fltp_2ch, 3,4,3, dst0, src, len, dst1
1175− lea lenq, [4*lend]
1176− mov dst1q, [dst0q+gprsize]
1177− mov dst0q, [dst0q ]
1178− lea srcq, [srcq+2*lenq]
1179− add dst0q, lenq
1180− add dst1q, lenq
1181− neg lenq
1182−.loop:
1183− mova m0, [srcq+2*lenq ]
1184− mova m1, [srcq+2*lenq+mmsize]
1185− DEINT2_PS 0, 1, 2
1186− mova [dst0q+lenq], m0
1187− mova [dst1q+lenq], m1
1188− add lenq, mmsize
1189− jl .loop
1190− REP_RET
1191−%endmacro
1192−
1193−INIT_XMM sse
1194−CONV_FLT_TO_FLTP_2CH
1195−%if HAVE_AVX_EXTERNAL
1196−INIT_XMM avx
1197−CONV_FLT_TO_FLTP_2CH
1198−%endif
1199−
1200−;------------------------------------------------------------------------------
1201−; void ff_conv_flt_to_fltp_6ch(float *const *dst, float *src, int len,
1202−; int channels);
1203−;------------------------------------------------------------------------------
1204−
1205−%macro CONV_FLT_TO_FLTP_6CH 0
1206−%if ARCH_X86_64
1207−cglobal conv_flt_to_fltp_6ch, 3,8,7, dst, src, len, dst1, dst2, dst3, dst4, dst5
1208−%else
1209−cglobal conv_flt_to_fltp_6ch, 2,7,7, dst, src, dst1, dst2, dst3, dst4, dst5
1210−%define lend dword r2m
1211−%endif
1212− mov dst1q, [dstq+ gprsize]
1213− mov dst2q, [dstq+2*gprsize]
1214− mov dst3q, [dstq+3*gprsize]
1215− mov dst4q, [dstq+4*gprsize]
1216− mov dst5q, [dstq+5*gprsize]
1217− mov dstq, [dstq ]
1218− sub dst1q, dstq
1219− sub dst2q, dstq
1220− sub dst3q, dstq
1221− sub dst4q, dstq
1222− sub dst5q, dstq
1223−.loop:
1224− mova m0, [srcq+0*mmsize] ; m0 = 0, 1, 2, 3
1225− mova m1, [srcq+1*mmsize] ; m1 = 4, 5, 6, 7
1226− mova m2, [srcq+2*mmsize] ; m2 = 8, 9, 10, 11
1227− mova m3, [srcq+3*mmsize] ; m3 = 12, 13, 14, 15
1228− mova m4, [srcq+4*mmsize] ; m4 = 16, 17, 18, 19
1229− mova m5, [srcq+5*mmsize] ; m5 = 20, 21, 22, 23
1230−
1231− SBUTTERFLY2 dq, 0, 3, 6 ; m0 = 0, 12, 1, 13
1232− ; m3 = 2, 14, 3, 15
1233− SBUTTERFLY2 dq, 1, 4, 6 ; m1 = 4, 16, 5, 17
1234− ; m4 = 6, 18, 7, 19
1235− SBUTTERFLY2 dq, 2, 5, 6 ; m2 = 8, 20, 9, 21
1236− ; m5 = 10, 22, 11, 23
1237− SBUTTERFLY2 dq, 0, 4, 6 ; m0 = 0, 6, 12, 18
1238− ; m4 = 1, 7, 13, 19
1239− SBUTTERFLY2 dq, 3, 2, 6 ; m3 = 2, 8, 14, 20
1240− ; m2 = 3, 9, 15, 21
1241− SBUTTERFLY2 dq, 1, 5, 6 ; m1 = 4, 10, 16, 22
1242− ; m5 = 5, 11, 17, 23
1243− mova [dstq ], m0
1244− mova [dstq+dst1q], m4
1245− mova [dstq+dst2q], m3
1246− mova [dstq+dst3q], m2
1247− mova [dstq+dst4q], m1
1248− mova [dstq+dst5q], m5
1249− add srcq, mmsize*6
1250− add dstq, mmsize
1251− sub lend, mmsize/4
1252− jg .loop
1253− REP_RET
1254−%endmacro
1255−
1256−INIT_XMM sse2
1257−CONV_FLT_TO_FLTP_6CH
1258−%if HAVE_AVX_EXTERNAL
1259−INIT_XMM avx
1260−CONV_FLT_TO_FLTP_6CH
1261−%endif
libavresample/x86/audio_convert_init.c+0−265
@@ -1,265 +0,0 @@
1−/*
2− * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
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−
21−#include "config.h"
22−#include "libavutil/cpu.h"
23−#include "libavutil/x86/cpu.h"
24−#include "libavresample/audio_convert.h"
25−
26−/* flat conversions */
27−
28−void ff_conv_s16_to_s32_sse2(int16_t *dst, const int32_t *src, int len);
29−
30−void ff_conv_s16_to_flt_sse2(float *dst, const int16_t *src, int len);
31−void ff_conv_s16_to_flt_sse4(float *dst, const int16_t *src, int len);
32−
33−void ff_conv_s32_to_s16_mmx (int16_t *dst, const int32_t *src, int len);
34−void ff_conv_s32_to_s16_sse2(int16_t *dst, const int32_t *src, int len);
35−
36−void ff_conv_s32_to_flt_sse2(float *dst, const int32_t *src, int len);
37−void ff_conv_s32_to_flt_avx (float *dst, const int32_t *src, int len);
38−
39−void ff_conv_flt_to_s16_sse2(int16_t *dst, const float *src, int len);
40−
41−void ff_conv_flt_to_s32_sse2(int32_t *dst, const float *src, int len);
42−void ff_conv_flt_to_s32_avx (int32_t *dst, const float *src, int len);
43−
44−/* interleave conversions */
45−
46−void ff_conv_s16p_to_s16_2ch_sse2(int16_t *dst, int16_t *const *src,
47− int len, int channels);
48−void ff_conv_s16p_to_s16_2ch_avx (int16_t *dst, int16_t *const *src,
49− int len, int channels);
50−
51−void ff_conv_s16p_to_s16_6ch_sse2(int16_t *dst, int16_t *const *src,
52− int len, int channels);
53−void ff_conv_s16p_to_s16_6ch_sse2slow(int16_t *dst, int16_t *const *src,
54− int len, int channels);
55−void ff_conv_s16p_to_s16_6ch_avx (int16_t *dst, int16_t *const *src,
56− int len, int channels);
57−
58−void ff_conv_s16p_to_flt_2ch_sse2(float *dst, int16_t *const *src,
59− int len, int channels);
60−void ff_conv_s16p_to_flt_2ch_avx (float *dst, int16_t *const *src,
61− int len, int channels);
62−
63−void ff_conv_s16p_to_flt_6ch_sse2 (float *dst, int16_t *const *src,
64− int len, int channels);
65−void ff_conv_s16p_to_flt_6ch_ssse3(float *dst, int16_t *const *src,
66− int len, int channels);
67−void ff_conv_s16p_to_flt_6ch_avx (float *dst, int16_t *const *src,
68− int len, int channels);
69−
70−void ff_conv_fltp_to_s16_2ch_sse2 (int16_t *dst, float *const *src,
71− int len, int channels);
72−void ff_conv_fltp_to_s16_2ch_ssse3(int16_t *dst, float *const *src,
73− int len, int channels);
74−
75−void ff_conv_fltp_to_s16_6ch_sse (int16_t *dst, float *const *src,
76− int len, int channels);
77−void ff_conv_fltp_to_s16_6ch_sse2(int16_t *dst, float *const *src,
78− int len, int channels);
79−void ff_conv_fltp_to_s16_6ch_avx (int16_t *dst, float *const *src,
80− int len, int channels);
81−
82−void ff_conv_fltp_to_flt_2ch_sse(float *dst, float *const *src, int len,
83− int channels);
84−void ff_conv_fltp_to_flt_2ch_avx(float *dst, float *const *src, int len,
85− int channels);
86−
87−void ff_conv_fltp_to_flt_6ch_mmx (float *dst, float *const *src, int len,
88− int channels);
89−void ff_conv_fltp_to_flt_6ch_sse4(float *dst, float *const *src, int len,
90− int channels);
91−void ff_conv_fltp_to_flt_6ch_avx (float *dst, float *const *src, int len,
92− int channels);
93−
94−/* deinterleave conversions */
95−
96−void ff_conv_s16_to_s16p_2ch_sse2(int16_t *const *dst, int16_t *src,
97− int len, int channels);
98−void ff_conv_s16_to_s16p_2ch_ssse3(int16_t *const *dst, int16_t *src,
99− int len, int channels);
100−void ff_conv_s16_to_s16p_2ch_avx (int16_t *const *dst, int16_t *src,
101− int len, int channels);
102−
103−void ff_conv_s16_to_s16p_6ch_sse2 (int16_t *const *dst, int16_t *src,
104− int len, int channels);
105−void ff_conv_s16_to_s16p_6ch_ssse3(int16_t *const *dst, int16_t *src,
106− int len, int channels);
107−void ff_conv_s16_to_s16p_6ch_avx (int16_t *const *dst, int16_t *src,
108− int len, int channels);
109−
110−void ff_conv_s16_to_fltp_2ch_sse2(float *const *dst, int16_t *src,
111− int len, int channels);
112−void ff_conv_s16_to_fltp_2ch_avx (float *const *dst, int16_t *src,
113− int len, int channels);
114−
115−void ff_conv_s16_to_fltp_6ch_sse2 (float *const *dst, int16_t *src,
116− int len, int channels);
117−void ff_conv_s16_to_fltp_6ch_ssse3(float *const *dst, int16_t *src,
118− int len, int channels);
119−void ff_conv_s16_to_fltp_6ch_sse4 (float *const *dst, int16_t *src,
120− int len, int channels);
121−void ff_conv_s16_to_fltp_6ch_avx (float *const *dst, int16_t *src,
122− int len, int channels);
123−
124−void ff_conv_flt_to_s16p_2ch_sse2(int16_t *const *dst, float *src,
125− int len, int channels);
126−void ff_conv_flt_to_s16p_2ch_avx (int16_t *const *dst, float *src,
127− int len, int channels);
128−
129−void ff_conv_flt_to_s16p_6ch_sse2 (int16_t *const *dst, float *src,
130− int len, int channels);
131−void ff_conv_flt_to_s16p_6ch_ssse3(int16_t *const *dst, float *src,
132− int len, int channels);
133−void ff_conv_flt_to_s16p_6ch_avx (int16_t *const *dst, float *src,
134− int len, int channels);
135−
136−void ff_conv_flt_to_fltp_2ch_sse(float *const *dst, float *src, int len,
137− int channels);
138−void ff_conv_flt_to_fltp_2ch_avx(float *const *dst, float *src, int len,
139− int channels);
140−
141−void ff_conv_flt_to_fltp_6ch_sse2(float *const *dst, float *src, int len,
142− int channels);
143−void ff_conv_flt_to_fltp_6ch_avx (float *const *dst, float *src, int len,
144− int channels);
145−
146−av_cold void ff_audio_convert_init_x86(AudioConvert *ac)
147−{
148− int cpu_flags = av_get_cpu_flags();
149−
150− if (EXTERNAL_MMX(cpu_flags)) {
151− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32,
152− 0, 1, 8, "MMX", ff_conv_s32_to_s16_mmx);
153− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
154− 6, 1, 4, "MMX", ff_conv_fltp_to_flt_6ch_mmx);
155− }
156− if (EXTERNAL_SSE(cpu_flags)) {
157− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLTP,
158− 6, 1, 2, "SSE", ff_conv_fltp_to_s16_6ch_sse);
159− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
160− 2, 16, 8, "SSE", ff_conv_fltp_to_flt_2ch_sse);
161− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_FLT,
162− 2, 16, 4, "SSE", ff_conv_flt_to_fltp_2ch_sse);
163− }
164− if (EXTERNAL_SSE2(cpu_flags)) {
165− if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW)) {
166− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32,
167− 0, 16, 16, "SSE2", ff_conv_s32_to_s16_sse2);
168− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P,
169− 6, 16, 8, "SSE2", ff_conv_s16p_to_s16_6ch_sse2);
170− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLTP,
171− 6, 16, 4, "SSE2", ff_conv_fltp_to_s16_6ch_sse2);
172− } else {
173− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P,
174− 6, 1, 4, "SSE2SLOW", ff_conv_s16p_to_s16_6ch_sse2slow);
175− }
176− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16,
177− 0, 16, 8, "SSE2", ff_conv_s16_to_s32_sse2);
178− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16,
179− 0, 16, 8, "SSE2", ff_conv_s16_to_flt_sse2);
180− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32,
181− 0, 16, 8, "SSE2", ff_conv_s32_to_flt_sse2);
182− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT,
183− 0, 16, 16, "SSE2", ff_conv_flt_to_s16_sse2);
184− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT,
185− 0, 16, 16, "SSE2", ff_conv_flt_to_s32_sse2);
186− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P,
187− 2, 16, 16, "SSE2", ff_conv_s16p_to_s16_2ch_sse2);
188− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16P,
189− 2, 16, 8, "SSE2", ff_conv_s16p_to_flt_2ch_sse2);
190− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16P,
191− 6, 16, 4, "SSE2", ff_conv_s16p_to_flt_6ch_sse2);
192− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLTP,
193− 2, 16, 4, "SSE2", ff_conv_fltp_to_s16_2ch_sse2);
194− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S16,
195− 2, 16, 8, "SSE2", ff_conv_s16_to_s16p_2ch_sse2);
196− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S16,
197− 6, 16, 4, "SSE2", ff_conv_s16_to_s16p_6ch_sse2);
198− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_S16,
199− 2, 16, 8, "SSE2", ff_conv_s16_to_fltp_2ch_sse2);
200− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_S16,
201− 6, 16, 4, "SSE2", ff_conv_s16_to_fltp_6ch_sse2);
202− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_FLT,
203− 2, 16, 8, "SSE2", ff_conv_flt_to_s16p_2ch_sse2);
204− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_FLT,
205− 6, 16, 4, "SSE2", ff_conv_flt_to_s16p_6ch_sse2);
206− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_FLT,
207− 6, 16, 4, "SSE2", ff_conv_flt_to_fltp_6ch_sse2);
208− }
209− if (EXTERNAL_SSSE3(cpu_flags)) {
210− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16P,
211− 6, 16, 4, "SSSE3", ff_conv_s16p_to_flt_6ch_ssse3);
212− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLTP,
213− 2, 16, 4, "SSSE3", ff_conv_fltp_to_s16_2ch_ssse3);
214− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S16,
215− 2, 16, 8, "SSSE3", ff_conv_s16_to_s16p_2ch_ssse3);
216− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S16,
217− 6, 16, 4, "SSSE3", ff_conv_s16_to_s16p_6ch_ssse3);
218− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_S16,
219− 6, 16, 4, "SSSE3", ff_conv_s16_to_fltp_6ch_ssse3);
220− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_FLT,
221− 6, 16, 4, "SSSE3", ff_conv_flt_to_s16p_6ch_ssse3);
222− }
223− if (EXTERNAL_SSE4(cpu_flags)) {
224− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16,
225− 0, 16, 8, "SSE4", ff_conv_s16_to_flt_sse4);
226− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
227− 6, 16, 4, "SSE4", ff_conv_fltp_to_flt_6ch_sse4);
228− }
229− if (EXTERNAL_AVX_FAST(cpu_flags)) {
230− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32,
231− 0, 32, 16, "AVX", ff_conv_s32_to_flt_avx);
232− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT,
233− 0, 32, 32, "AVX", ff_conv_flt_to_s32_avx);
234− }
235− if (EXTERNAL_AVX(cpu_flags)) {
236− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P,
237− 2, 16, 16, "AVX", ff_conv_s16p_to_s16_2ch_avx);
238− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P,
239− 6, 16, 8, "AVX", ff_conv_s16p_to_s16_6ch_avx);
240− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16P,
241− 2, 16, 8, "AVX", ff_conv_s16p_to_flt_2ch_avx);
242− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16P,
243− 6, 16, 4, "AVX", ff_conv_s16p_to_flt_6ch_avx);
244− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLTP,
245− 6, 16, 4, "AVX", ff_conv_fltp_to_s16_6ch_avx);
246− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
247− 6, 16, 4, "AVX", ff_conv_fltp_to_flt_6ch_avx);
248− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S16,
249− 2, 16, 8, "AVX", ff_conv_s16_to_s16p_2ch_avx);
250− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S16,
251− 6, 16, 4, "AVX", ff_conv_s16_to_s16p_6ch_avx);
252− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_S16,
253− 2, 16, 8, "AVX", ff_conv_s16_to_fltp_2ch_avx);
254− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_S16,
255− 6, 16, 4, "AVX", ff_conv_s16_to_fltp_6ch_avx);
256− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_FLT,
257− 2, 16, 8, "AVX", ff_conv_flt_to_s16p_2ch_avx);
258− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_FLT,
259− 6, 16, 4, "AVX", ff_conv_flt_to_s16p_6ch_avx);
260− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_FLT,
261− 2, 16, 4, "AVX", ff_conv_flt_to_fltp_2ch_avx);
262− ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_FLT,
263− 6, 16, 4, "AVX", ff_conv_flt_to_fltp_6ch_avx);
264− }
265−}
libavresample/x86/audio_mix.asm+0−511
@@ -1,511 +0,0 @@
1−;******************************************************************************
2−;* x86 optimized channel mixing
3−;* Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
4−;*
5−;* This file is part of FFmpeg.
6−;*
7−;* FFmpeg is free software; you can redistribute it and/or
8−;* modify it under the terms of the GNU Lesser General Public
9−;* License as published by the Free Software Foundation; either
10−;* version 2.1 of the License, or (at your option) any later version.
11−;*
12−;* FFmpeg is distributed in the hope that it will be useful,
13−;* but WITHOUT ANY WARRANTY; without even the implied warranty of
14−;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15−;* Lesser General Public License for more details.
16−;*
17−;* You should have received a copy of the GNU Lesser General Public
18−;* License along with FFmpeg; if not, write to the Free Software
19−;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20−;******************************************************************************
21−
22−%include "libavutil/x86/x86util.asm"
23−%include "util.asm"
24−
25−SECTION .text
26−
27−;-----------------------------------------------------------------------------
28−; void ff_mix_2_to_1_fltp_flt(float **src, float **matrix, int len,
29−; int out_ch, int in_ch);
30−;-----------------------------------------------------------------------------
31−
32−%macro MIX_2_TO_1_FLTP_FLT 0
33−cglobal mix_2_to_1_fltp_flt, 3,4,6, src, matrix, len, src1
34− mov src1q, [srcq+gprsize]
35− mov srcq, [srcq ]
36− sub src1q, srcq
37− mov matrixq, [matrixq ]
38− VBROADCASTSS m4, [matrixq ]
39− VBROADCASTSS m5, [matrixq+4]
40− ALIGN 16
41−.loop:
42− mulps m0, m4, [srcq ]
43− mulps m1, m5, [srcq+src1q ]
44− mulps m2, m4, [srcq+ mmsize]
45− mulps m3, m5, [srcq+src1q+mmsize]
46− addps m0, m0, m1
47− addps m2, m2, m3
48− mova [srcq ], m0
49− mova [srcq+mmsize], m2
50− add srcq, mmsize*2
51− sub lend, mmsize*2/4
52− jg .loop
53− REP_RET
54−%endmacro
55−
56−INIT_XMM sse
57−MIX_2_TO_1_FLTP_FLT
58−%if HAVE_AVX_EXTERNAL
59−INIT_YMM avx
60−MIX_2_TO_1_FLTP_FLT
61−%endif
62−
63−;-----------------------------------------------------------------------------
64−; void ff_mix_2_to_1_s16p_flt(int16_t **src, float **matrix, int len,
65−; int out_ch, int in_ch);
66−;-----------------------------------------------------------------------------
67−
68−%macro MIX_2_TO_1_S16P_FLT 0
69−cglobal mix_2_to_1_s16p_flt, 3,4,6, src, matrix, len, src1
70− mov src1q, [srcq+gprsize]
71− mov srcq, [srcq]
72− sub src1q, srcq
73− mov matrixq, [matrixq ]
74− VBROADCASTSS m4, [matrixq ]
75− VBROADCASTSS m5, [matrixq+4]
76− ALIGN 16
77−.loop:
78− mova m0, [srcq ]
79− mova m2, [srcq+src1q]
80− S16_TO_S32_SX 0, 1
81− S16_TO_S32_SX 2, 3
82− cvtdq2ps m0, m0
83− cvtdq2ps m1, m1
84− cvtdq2ps m2, m2
85− cvtdq2ps m3, m3
86− mulps m0, m4
87− mulps m1, m4
88− mulps m2, m5
89− mulps m3, m5
90− addps m0, m2
91− addps m1, m3
92− cvtps2dq m0, m0
93− cvtps2dq m1, m1
94− packssdw m0, m1
95− mova [srcq], m0
96− add srcq, mmsize
97− sub lend, mmsize/2
98− jg .loop
99− REP_RET
100−%endmacro
101−
102−INIT_XMM sse2
103−MIX_2_TO_1_S16P_FLT
104−INIT_XMM sse4
105−MIX_2_TO_1_S16P_FLT
106−
107−;-----------------------------------------------------------------------------
108−; void ff_mix_2_to_1_s16p_q8(int16_t **src, int16_t **matrix, int len,
109−; int out_ch, int in_ch);
110−;-----------------------------------------------------------------------------
111−
112−INIT_XMM sse2
113−cglobal mix_2_to_1_s16p_q8, 3,4,6, src, matrix, len, src1
114− mov src1q, [srcq+gprsize]
115− mov srcq, [srcq]
116− sub src1q, srcq
117− mov matrixq, [matrixq]
118− movd m4, [matrixq]
119− movd m5, [matrixq]
120− SPLATW m4, m4, 0
121− SPLATW m5, m5, 1
122− pxor m0, m0
123− punpcklwd m4, m0
124− punpcklwd m5, m0
125− ALIGN 16
126−.loop:
127− mova m0, [srcq ]
128− mova m2, [srcq+src1q]
129− punpckhwd m1, m0, m0
130− punpcklwd m0, m0
131− punpckhwd m3, m2, m2
132− punpcklwd m2, m2
133− pmaddwd m0, m4
134− pmaddwd m1, m4
135− pmaddwd m2, m5
136− pmaddwd m3, m5
137− paddd m0, m2
138− paddd m1, m3
139− psrad m0, 8
140− psrad m1, 8
141− packssdw m0, m1
142− mova [srcq], m0
143− add srcq, mmsize
144− sub lend, mmsize/2
145− jg .loop
146− REP_RET
147−
148−;-----------------------------------------------------------------------------
149−; void ff_mix_1_to_2_fltp_flt(float **src, float **matrix, int len,
150−; int out_ch, int in_ch);
151−;-----------------------------------------------------------------------------
152−
153−%macro MIX_1_TO_2_FLTP_FLT 0
154−cglobal mix_1_to_2_fltp_flt, 3,5,4, src0, matrix0, len, src1, matrix1
155− mov src1q, [src0q+gprsize]
156− mov src0q, [src0q]
157− sub src1q, src0q
158− mov matrix1q, [matrix0q+gprsize]
159− mov matrix0q, [matrix0q]
160− VBROADCASTSS m2, [matrix0q]
161− VBROADCASTSS m3, [matrix1q]
162− ALIGN 16
163−.loop:
164− mova m0, [src0q]
165− mulps m1, m0, m3
166− mulps m0, m0, m2
167− mova [src0q ], m0
168− mova [src0q+src1q], m1
169− add src0q, mmsize
170− sub lend, mmsize/4
171− jg .loop
172− REP_RET
173−%endmacro
174−
175−INIT_XMM sse
176−MIX_1_TO_2_FLTP_FLT
177−%if HAVE_AVX_EXTERNAL
178−INIT_YMM avx
179−MIX_1_TO_2_FLTP_FLT
180−%endif
181−
182−;-----------------------------------------------------------------------------
183−; void ff_mix_1_to_2_s16p_flt(int16_t **src, float **matrix, int len,
184−; int out_ch, int in_ch);
185−;-----------------------------------------------------------------------------
186−
187−%macro MIX_1_TO_2_S16P_FLT 0
188−cglobal mix_1_to_2_s16p_flt, 3,5,6, src0, matrix0, len, src1, matrix1
189− mov src1q, [src0q+gprsize]
190− mov src0q, [src0q]
191− sub src1q, src0q
192− mov matrix1q, [matrix0q+gprsize]
193− mov matrix0q, [matrix0q]
194− VBROADCASTSS m4, [matrix0q]
195− VBROADCASTSS m5, [matrix1q]
196− ALIGN 16
197−.loop:
198− mova m0, [src0q]
199− S16_TO_S32_SX 0, 2
200− cvtdq2ps m0, m0
201− cvtdq2ps m2, m2
202− mulps m1, m0, m5
203− mulps m0, m0, m4
204− mulps m3, m2, m5
205− mulps m2, m2, m4
206− cvtps2dq m0, m0
207− cvtps2dq m1, m1
208− cvtps2dq m2, m2
209− cvtps2dq m3, m3
210− packssdw m0, m2
211− packssdw m1, m3
212− mova [src0q ], m0
213− mova [src0q+src1q], m1
214− add src0q, mmsize
215− sub lend, mmsize/2
216− jg .loop
217− REP_RET
218−%endmacro
219−
220−INIT_XMM sse2
221−MIX_1_TO_2_S16P_FLT
222−INIT_XMM sse4
223−MIX_1_TO_2_S16P_FLT
224−%if HAVE_AVX_EXTERNAL
225−INIT_XMM avx
226−MIX_1_TO_2_S16P_FLT
227−%endif
228−
229−;-----------------------------------------------------------------------------
230−; void ff_mix_3_8_to_1_2_fltp/s16p_flt(float/int16_t **src, float **matrix,
231−; int len, int out_ch, int in_ch);
232−;-----------------------------------------------------------------------------
233−
234−%macro MIX_3_8_TO_1_2_FLT 3 ; %1 = in channels, %2 = out channels, %3 = s16p or fltp
235−; define some names to make the code clearer
236−%assign in_channels %1
237−%assign out_channels %2
238−%assign stereo out_channels - 1
239−%ifidn %3, s16p
240− %assign is_s16 1
241−%else
242− %assign is_s16 0
243−%endif
244−
245−; determine how many matrix elements must go on the stack vs. mmregs
246−%assign matrix_elements in_channels * out_channels
247−%if is_s16
248− %if stereo
249− %assign needed_mmregs 7
250− %else
251− %assign needed_mmregs 5
252− %endif
253−%else
254− %if stereo
255− %assign needed_mmregs 4
256− %else
257− %assign needed_mmregs 3
258− %endif
259−%endif
260−%assign matrix_elements_mm num_mmregs - needed_mmregs
261−%if matrix_elements < matrix_elements_mm
262− %assign matrix_elements_mm matrix_elements
263−%endif
264−%if matrix_elements_mm < matrix_elements
265− %assign matrix_elements_stack matrix_elements - matrix_elements_mm
266−%else
267− %assign matrix_elements_stack 0
268−%endif
269−%assign matrix_stack_size matrix_elements_stack * mmsize
270−
271−%assign needed_stack_size -1 * matrix_stack_size
272−%if ARCH_X86_32 && in_channels >= 7
273−%assign needed_stack_size needed_stack_size - 16
274−%endif
275−
276−cglobal mix_%1_to_%2_%3_flt, 3,in_channels+2,needed_mmregs+matrix_elements_mm, needed_stack_size, src0, src1, len, src2, src3, src4, src5, src6, src7
277−
278−; define src pointers on stack if needed
279−%if matrix_elements_stack > 0 && ARCH_X86_32 && in_channels >= 7
280− %define src5m [rsp+matrix_stack_size+0]
281− %define src6m [rsp+matrix_stack_size+4]
282− %define src7m [rsp+matrix_stack_size+8]
283−%endif
284−
285−; load matrix pointers
286−%define matrix0q r1q
287−%define matrix1q r3q
288−%if stereo
289− mov matrix1q, [matrix0q+gprsize]
290−%endif
291− mov matrix0q, [matrix0q]
292−
293−; define matrix coeff names
294−%assign %%i 0
295−%assign %%j needed_mmregs
296−%rep in_channels
297− %if %%i >= matrix_elements_mm
298− CAT_XDEFINE mx_stack_0_, %%i, 1
299− CAT_XDEFINE mx_0_, %%i, [rsp+(%%i-matrix_elements_mm)*mmsize]
300− %else
301− CAT_XDEFINE mx_stack_0_, %%i, 0
302− CAT_XDEFINE mx_0_, %%i, m %+ %%j
303− %assign %%j %%j+1
304− %endif
305− %assign %%i %%i+1
306−%endrep
307−%if stereo
308−%assign %%i 0
309−%rep in_channels
310− %if in_channels + %%i >= matrix_elements_mm
311− CAT_XDEFINE mx_stack_1_, %%i, 1
312− CAT_XDEFINE mx_1_, %%i, [rsp+(in_channels+%%i-matrix_elements_mm)*mmsize]
313− %else
314− CAT_XDEFINE mx_stack_1_, %%i, 0
315− CAT_XDEFINE mx_1_, %%i, m %+ %%j
316− %assign %%j %%j+1
317− %endif
318− %assign %%i %%i+1
319−%endrep
320−%endif
321−
322−; load/splat matrix coeffs
323−%assign %%i 0
324−%rep in_channels
325− %if mx_stack_0_ %+ %%i
326− VBROADCASTSS m0, [matrix0q+4*%%i]
327− mova mx_0_ %+ %%i, m0
328− %else
329− VBROADCASTSS mx_0_ %+ %%i, [matrix0q+4*%%i]
330− %endif
331− %if stereo
332− %if mx_stack_1_ %+ %%i
333− VBROADCASTSS m0, [matrix1q+4*%%i]
334− mova mx_1_ %+ %%i, m0
335− %else
336− VBROADCASTSS mx_1_ %+ %%i, [matrix1q+4*%%i]
337− %endif
338− %endif
339− %assign %%i %%i+1
340−%endrep
341−
342−; load channel pointers to registers as offsets from the first channel pointer
343−%if ARCH_X86_64
344− movsxd lenq, r2d
345−%endif
346− shl lenq, 2-is_s16
347−%assign %%i 1
348−%rep (in_channels - 1)
349− %if ARCH_X86_32 && in_channels >= 7 && %%i >= 5
350− mov src5q, [src0q+%%i*gprsize]
351− add src5q, lenq
352− mov src %+ %%i %+ m, src5q
353− %else
354− mov src %+ %%i %+ q, [src0q+%%i*gprsize]
355− add src %+ %%i %+ q, lenq
356− %endif
357− %assign %%i %%i+1
358−%endrep
359− mov src0q, [src0q]
360− add src0q, lenq
361− neg lenq
362−.loop:
363−; for x86-32 with 7-8 channels we do not have enough gp registers for all src
364−; pointers, so we have to load some of them from the stack each time
365−%define copy_src_from_stack ARCH_X86_32 && in_channels >= 7 && %%i >= 5
366−%if is_s16
367− ; mix with s16p input
368− mova m0, [src0q+lenq]
369− S16_TO_S32_SX 0, 1
370− cvtdq2ps m0, m0
371− cvtdq2ps m1, m1
372− %if stereo
373− mulps m2, m0, mx_1_0
374− mulps m3, m1, mx_1_0
375− %endif
376− mulps m0, m0, mx_0_0
377− mulps m1, m1, mx_0_0
378−%assign %%i 1
379−%rep (in_channels - 1)
380− %if copy_src_from_stack
381− %define src_ptr src5q
382− %else
383− %define src_ptr src %+ %%i %+ q
384− %endif
385− %if stereo
386− %if copy_src_from_stack
387− mov src_ptr, src %+ %%i %+ m
388− %endif
389− mova m4, [src_ptr+lenq]
390− S16_TO_S32_SX 4, 5
391− cvtdq2ps m4, m4
392− cvtdq2ps m5, m5
393− FMULADD_PS m2, m4, mx_1_ %+ %%i, m2, m6
394− FMULADD_PS m3, m5, mx_1_ %+ %%i, m3, m6
395− FMULADD_PS m0, m4, mx_0_ %+ %%i, m0, m4
396− FMULADD_PS m1, m5, mx_0_ %+ %%i, m1, m5
397− %else
398− %if copy_src_from_stack
399− mov src_ptr, src %+ %%i %+ m
400− %endif
401− mova m2, [src_ptr+lenq]
402− S16_TO_S32_SX 2, 3
403− cvtdq2ps m2, m2
404− cvtdq2ps m3, m3
405− FMULADD_PS m0, m2, mx_0_ %+ %%i, m0, m4
406− FMULADD_PS m1, m3, mx_0_ %+ %%i, m1, m4
407− %endif
408− %assign %%i %%i+1
409−%endrep
410− %if stereo
411− cvtps2dq m2, m2
412− cvtps2dq m3, m3
413− packssdw m2, m3
414− mova [src1q+lenq], m2
415− %endif
416− cvtps2dq m0, m0
417− cvtps2dq m1, m1
418− packssdw m0, m1
419− mova [src0q+lenq], m0
420−%else
421− ; mix with fltp input
422− %if stereo || mx_stack_0_0
423− mova m0, [src0q+lenq]
424− %endif
425− %if stereo
426− mulps m1, m0, mx_1_0
427− %endif
428− %if stereo || mx_stack_0_0
429− mulps m0, m0, mx_0_0
430− %else
431− mulps m0, mx_0_0, [src0q+lenq]
432− %endif
433−%assign %%i 1
434−%rep (in_channels - 1)
435− %if copy_src_from_stack
436− %define src_ptr src5q
437− mov src_ptr, src %+ %%i %+ m
438− %else
439− %define src_ptr src %+ %%i %+ q
440− %endif
441− ; avoid extra load for mono if matrix is in a mm register
442− %if stereo || mx_stack_0_ %+ %%i
443− mova m2, [src_ptr+lenq]
444− %endif
445− %if stereo
446− FMULADD_PS m1, m2, mx_1_ %+ %%i, m1, m3
447− %endif
448− %if stereo || mx_stack_0_ %+ %%i
449− FMULADD_PS m0, m2, mx_0_ %+ %%i, m0, m2
450− %else
451− FMULADD_PS m0, mx_0_ %+ %%i, [src_ptr+lenq], m0, m1
452− %endif
453− %assign %%i %%i+1
454−%endrep
455− mova [src0q+lenq], m0
456− %if stereo
457− mova [src1q+lenq], m1
458− %endif
459−%endif
460−
461− add lenq, mmsize
462− jl .loop
463−; zero ymm high halves
464−%if mmsize == 32
465− vzeroupper
466−%endif
467− RET
468−%endmacro
469−
470−%macro MIX_3_8_TO_1_2_FLT_FUNCS 0
471−%assign %%i 3
472−%rep 6
473− INIT_XMM sse
474− MIX_3_8_TO_1_2_FLT %%i, 1, fltp
475− MIX_3_8_TO_1_2_FLT %%i, 2, fltp
476− INIT_XMM sse2
477− MIX_3_8_TO_1_2_FLT %%i, 1, s16p
478− MIX_3_8_TO_1_2_FLT %%i, 2, s16p
479− INIT_XMM sse4
480− MIX_3_8_TO_1_2_FLT %%i, 1, s16p
481− MIX_3_8_TO_1_2_FLT %%i, 2, s16p
482− ; do not use ymm AVX or FMA4 in x86-32 for 6 or more channels due to stack alignment issues
483− %if HAVE_AVX_EXTERNAL
484− %if ARCH_X86_64 || %%i < 6
485− INIT_YMM avx
486− %else
487− INIT_XMM avx
488− %endif
489− MIX_3_8_TO_1_2_FLT %%i, 1, fltp
490− MIX_3_8_TO_1_2_FLT %%i, 2, fltp
491− INIT_XMM avx
492− MIX_3_8_TO_1_2_FLT %%i, 1, s16p
493− MIX_3_8_TO_1_2_FLT %%i, 2, s16p
494− %endif
495− %if HAVE_FMA4_EXTERNAL
496− %if ARCH_X86_64 || %%i < 6
497− INIT_YMM fma4
498− %else
499− INIT_XMM fma4
500− %endif
501− MIX_3_8_TO_1_2_FLT %%i, 1, fltp
502− MIX_3_8_TO_1_2_FLT %%i, 2, fltp
503− INIT_XMM fma4
504− MIX_3_8_TO_1_2_FLT %%i, 1, s16p
505− MIX_3_8_TO_1_2_FLT %%i, 2, s16p
506− %endif
507− %assign %%i %%i+1
508−%endrep
509−%endmacro
510−
511−MIX_3_8_TO_1_2_FLT_FUNCS
libavresample/x86/audio_mix_init.c+0−215
@@ -1,215 +0,0 @@
1−/*
2− * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
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−
21−#include "config.h"
22−#include "libavutil/cpu.h"
23−#include "libavutil/x86/cpu.h"
24−#include "libavresample/audio_mix.h"
25−
26−void ff_mix_2_to_1_fltp_flt_sse(float **src, float **matrix, int len,
27− int out_ch, int in_ch);
28−void ff_mix_2_to_1_fltp_flt_avx(float **src, float **matrix, int len,
29− int out_ch, int in_ch);
30−
31−void ff_mix_2_to_1_s16p_flt_sse2(int16_t **src, float **matrix, int len,
32− int out_ch, int in_ch);
33−void ff_mix_2_to_1_s16p_flt_sse4(int16_t **src, float **matrix, int len,
34− int out_ch, int in_ch);
35−
36−void ff_mix_2_to_1_s16p_q8_sse2(int16_t **src, int16_t **matrix,
37− int len, int out_ch, int in_ch);
38−
39−void ff_mix_1_to_2_fltp_flt_sse(float **src, float **matrix, int len,
40− int out_ch, int in_ch);
41−void ff_mix_1_to_2_fltp_flt_avx(float **src, float **matrix, int len,
42− int out_ch, int in_ch);
43−
44−void ff_mix_1_to_2_s16p_flt_sse2(int16_t **src, float **matrix, int len,
45− int out_ch, int in_ch);
46−void ff_mix_1_to_2_s16p_flt_sse4(int16_t **src, float **matrix, int len,
47− int out_ch, int in_ch);
48−void ff_mix_1_to_2_s16p_flt_avx (int16_t **src, float **matrix, int len,
49− int out_ch, int in_ch);
50−
51−#define DEFINE_MIX_3_8_TO_1_2(chan) \
52−void ff_mix_ ## chan ## _to_1_fltp_flt_sse(float **src, \
53− float **matrix, int len, \
54− int out_ch, int in_ch); \
55−void ff_mix_ ## chan ## _to_2_fltp_flt_sse(float **src, \
56− float **matrix, int len, \
57− int out_ch, int in_ch); \
58− \
59−void ff_mix_ ## chan ## _to_1_s16p_flt_sse2(int16_t **src, \
60− float **matrix, int len, \
61− int out_ch, int in_ch); \
62−void ff_mix_ ## chan ## _to_2_s16p_flt_sse2(int16_t **src, \
63− float **matrix, int len, \
64− int out_ch, int in_ch); \
65− \
66−void ff_mix_ ## chan ## _to_1_s16p_flt_sse4(int16_t **src, \
67− float **matrix, int len, \
68− int out_ch, int in_ch); \
69−void ff_mix_ ## chan ## _to_2_s16p_flt_sse4(int16_t **src, \
70− float **matrix, int len, \
71− int out_ch, int in_ch); \
72− \
73−void ff_mix_ ## chan ## _to_1_fltp_flt_avx(float **src, \
74− float **matrix, int len, \
75− int out_ch, int in_ch); \
76−void ff_mix_ ## chan ## _to_2_fltp_flt_avx(float **src, \
77− float **matrix, int len, \
78− int out_ch, int in_ch); \
79− \
80−void ff_mix_ ## chan ## _to_1_s16p_flt_avx(int16_t **src, \
81− float **matrix, int len, \
82− int out_ch, int in_ch); \
83−void ff_mix_ ## chan ## _to_2_s16p_flt_avx(int16_t **src, \
84− float **matrix, int len, \
85− int out_ch, int in_ch); \
86− \
87−void ff_mix_ ## chan ## _to_1_fltp_flt_fma4(float **src, \
88− float **matrix, int len, \
89− int out_ch, int in_ch); \
90−void ff_mix_ ## chan ## _to_2_fltp_flt_fma4(float **src, \
91− float **matrix, int len, \
92− int out_ch, int in_ch); \
93− \
94−void ff_mix_ ## chan ## _to_1_s16p_flt_fma4(int16_t **src, \
95− float **matrix, int len, \
96− int out_ch, int in_ch); \
97−void ff_mix_ ## chan ## _to_2_s16p_flt_fma4(int16_t **src, \
98− float **matrix, int len, \
99− int out_ch, int in_ch);
100−
101−DEFINE_MIX_3_8_TO_1_2(3)
102−DEFINE_MIX_3_8_TO_1_2(4)
103−DEFINE_MIX_3_8_TO_1_2(5)
104−DEFINE_MIX_3_8_TO_1_2(6)
105−DEFINE_MIX_3_8_TO_1_2(7)
106−DEFINE_MIX_3_8_TO_1_2(8)
107−
108−#define SET_MIX_3_8_TO_1_2(chan) \
109− if (EXTERNAL_SSE(cpu_flags)) { \
110− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,\
111− chan, 1, 16, 4, "SSE", \
112− ff_mix_ ## chan ## _to_1_fltp_flt_sse); \
113− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,\
114− chan, 2, 16, 4, "SSE", \
115− ff_mix_## chan ##_to_2_fltp_flt_sse); \
116− } \
117− if (EXTERNAL_SSE2(cpu_flags)) { \
118− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,\
119− chan, 1, 16, 8, "SSE2", \
120− ff_mix_ ## chan ## _to_1_s16p_flt_sse2); \
121− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,\
122− chan, 2, 16, 8, "SSE2", \
123− ff_mix_ ## chan ## _to_2_s16p_flt_sse2); \
124− } \
125− if (EXTERNAL_SSE4(cpu_flags)) { \
126− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,\
127− chan, 1, 16, 8, "SSE4", \
128− ff_mix_ ## chan ## _to_1_s16p_flt_sse4); \
129− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,\
130− chan, 2, 16, 8, "SSE4", \
131− ff_mix_ ## chan ## _to_2_s16p_flt_sse4); \
132− } \
133− if (EXTERNAL_AVX(cpu_flags)) { \
134− int ptr_align = 32; \
135− int smp_align = 8; \
136− if (ARCH_X86_32 || chan >= 6) { \
137− ptr_align = 16; \
138− smp_align = 4; \
139− } \
140− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,\
141− chan, 1, ptr_align, smp_align, "AVX", \
142− ff_mix_ ## chan ## _to_1_fltp_flt_avx); \
143− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,\
144− chan, 2, ptr_align, smp_align, "AVX", \
145− ff_mix_ ## chan ## _to_2_fltp_flt_avx); \
146− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,\
147− chan, 1, 16, 8, "AVX", \
148− ff_mix_ ## chan ## _to_1_s16p_flt_avx); \
149− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,\
150− chan, 2, 16, 8, "AVX", \
151− ff_mix_ ## chan ## _to_2_s16p_flt_avx); \
152− } \
153− if (EXTERNAL_FMA4(cpu_flags)) { \
154− int ptr_align = 32; \
155− int smp_align = 8; \
156− if (ARCH_X86_32 || chan >= 6) { \
157− ptr_align = 16; \
158− smp_align = 4; \
159− } \
160− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,\
161− chan, 1, ptr_align, smp_align, "FMA4", \
162− ff_mix_ ## chan ## _to_1_fltp_flt_fma4); \
163− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,\
164− chan, 2, ptr_align, smp_align, "FMA4", \
165− ff_mix_ ## chan ## _to_2_fltp_flt_fma4); \
166− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,\
167− chan, 1, 16, 8, "FMA4", \
168− ff_mix_ ## chan ## _to_1_s16p_flt_fma4); \
169− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,\
170− chan, 2, 16, 8, "FMA4", \
171− ff_mix_ ## chan ## _to_2_s16p_flt_fma4); \
172− }
173−
174−av_cold void ff_audio_mix_init_x86(AudioMix *am)
175−{
176− int cpu_flags = av_get_cpu_flags();
177−
178− if (EXTERNAL_SSE(cpu_flags)) {
179− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
180− 2, 1, 16, 8, "SSE", ff_mix_2_to_1_fltp_flt_sse);
181− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
182− 1, 2, 16, 4, "SSE", ff_mix_1_to_2_fltp_flt_sse);
183− }
184− if (EXTERNAL_SSE2(cpu_flags)) {
185− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
186− 2, 1, 16, 8, "SSE2", ff_mix_2_to_1_s16p_flt_sse2);
187− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_Q8,
188− 2, 1, 16, 8, "SSE2", ff_mix_2_to_1_s16p_q8_sse2);
189− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
190− 1, 2, 16, 8, "SSE2", ff_mix_1_to_2_s16p_flt_sse2);
191− }
192− if (EXTERNAL_SSE4(cpu_flags)) {
193− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
194− 2, 1, 16, 8, "SSE4", ff_mix_2_to_1_s16p_flt_sse4);
195− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
196− 1, 2, 16, 8, "SSE4", ff_mix_1_to_2_s16p_flt_sse4);
197− }
198− if (EXTERNAL_AVX_FAST(cpu_flags)) {
199− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
200− 2, 1, 32, 16, "AVX", ff_mix_2_to_1_fltp_flt_avx);
201− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
202− 1, 2, 32, 8, "AVX", ff_mix_1_to_2_fltp_flt_avx);
203− }
204− if (EXTERNAL_AVX(cpu_flags)) {
205− ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
206− 1, 2, 16, 8, "AVX", ff_mix_1_to_2_s16p_flt_avx);
207− }
208−
209− SET_MIX_3_8_TO_1_2(3)
210− SET_MIX_3_8_TO_1_2(4)
211− SET_MIX_3_8_TO_1_2(5)
212− SET_MIX_3_8_TO_1_2(6)
213− SET_MIX_3_8_TO_1_2(7)
214− SET_MIX_3_8_TO_1_2(8)
215−}
libavresample/x86/dither.asm+0−117
@@ -1,117 +0,0 @@
1−;******************************************************************************
2−;* x86 optimized dithering format conversion
3−;* Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
4−;*
5−;* This file is part of FFmpeg.
6−;*
7−;* FFmpeg is free software; you can redistribute it and/or
8−;* modify it under the terms of the GNU Lesser General Public
9−;* License as published by the Free Software Foundation; either
10−;* version 2.1 of the License, or (at your option) any later version.
11−;*
12−;* FFmpeg is distributed in the hope that it will be useful,
13−;* but WITHOUT ANY WARRANTY; without even the implied warranty of
14−;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15−;* Lesser General Public License for more details.
16−;*
17−;* You should have received a copy of the GNU Lesser General Public
18−;* License along with FFmpeg; if not, write to the Free Software
19−;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20−;******************************************************************************
21−
22−%include "libavutil/x86/x86util.asm"
23−
24−SECTION_RODATA 32
25−
26−; 1.0f / (2.0f * INT32_MAX)
27−pf_dither_scale: times 8 dd 2.32830643762e-10
28−
29−pf_s16_scale: times 4 dd 32753.0
30−
31−SECTION .text
32−
33−;------------------------------------------------------------------------------
34−; void ff_quantize(int16_t *dst, float *src, float *dither, int len);
35−;------------------------------------------------------------------------------
36−
37−INIT_XMM sse2
38−cglobal quantize, 4,4,3, dst, src, dither, len
39− lea lenq, [2*lend]
40− add dstq, lenq
41− lea srcq, [srcq+2*lenq]
42− lea ditherq, [ditherq+2*lenq]
43− neg lenq
44− mova m2, [pf_s16_scale]
45−.loop:
46− mulps m0, m2, [srcq+2*lenq]
47− mulps m1, m2, [srcq+2*lenq+mmsize]
48− addps m0, [ditherq+2*lenq]
49− addps m1, [ditherq+2*lenq+mmsize]
50− cvtps2dq m0, m0
51− cvtps2dq m1, m1
52− packssdw m0, m1
53− mova [dstq+lenq], m0
54− add lenq, mmsize
55− jl .loop
56− REP_RET
57−
58−;------------------------------------------------------------------------------
59−; void ff_dither_int_to_float_rectangular(float *dst, int *src, int len)
60−;------------------------------------------------------------------------------
61−
62−%macro DITHER_INT_TO_FLOAT_RECTANGULAR 0
63−cglobal dither_int_to_float_rectangular, 3,3,3, dst, src, len
64− lea lenq, [4*lend]
65− add srcq, lenq
66− add dstq, lenq
67− neg lenq
68− mova m0, [pf_dither_scale]
69−.loop:
70− cvtdq2ps m1, [srcq+lenq]
71− cvtdq2ps m2, [srcq+lenq+mmsize]
72− mulps m1, m1, m0
73− mulps m2, m2, m0
74− mova [dstq+lenq], m1
75− mova [dstq+lenq+mmsize], m2
76− add lenq, 2*mmsize
77− jl .loop
78− REP_RET
79−%endmacro
80−
81−INIT_XMM sse2
82−DITHER_INT_TO_FLOAT_RECTANGULAR
83−INIT_YMM avx
84−DITHER_INT_TO_FLOAT_RECTANGULAR
85−
86−;------------------------------------------------------------------------------
87−; void ff_dither_int_to_float_triangular(float *dst, int *src0, int len)
88−;------------------------------------------------------------------------------
89−
90−%macro DITHER_INT_TO_FLOAT_TRIANGULAR 0
91−cglobal dither_int_to_float_triangular, 3,4,5, dst, src0, len, src1
92− lea lenq, [4*lend]
93− lea src1q, [src0q+2*lenq]
94− add src0q, lenq
95− add dstq, lenq
96− neg lenq
97− mova m0, [pf_dither_scale]
98−.loop:
99− cvtdq2ps m1, [src0q+lenq]
100− cvtdq2ps m2, [src0q+lenq+mmsize]
101− cvtdq2ps m3, [src1q+lenq]
102− cvtdq2ps m4, [src1q+lenq+mmsize]
103− addps m1, m1, m3
104− addps m2, m2, m4
105− mulps m1, m1, m0
106− mulps m2, m2, m0
107− mova [dstq+lenq], m1
108− mova [dstq+lenq+mmsize], m2
109− add lenq, 2*mmsize
110− jl .loop
111− REP_RET
112−%endmacro
113−
114−INIT_XMM sse2
115−DITHER_INT_TO_FLOAT_TRIANGULAR
116−INIT_YMM avx
117−DITHER_INT_TO_FLOAT_TRIANGULAR
libavresample/x86/dither_init.c+0−60
@@ -1,60 +0,0 @@
1−/*
2− * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
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−
21−#include "config.h"
22−#include "libavutil/cpu.h"
23−#include "libavutil/x86/cpu.h"
24−#include "libavresample/dither.h"
25−
26−void ff_quantize_sse2(int16_t *dst, const float *src, float *dither, int len);
27−
28−void ff_dither_int_to_float_rectangular_sse2(float *dst, int *src, int len);
29−void ff_dither_int_to_float_rectangular_avx(float *dst, int *src, int len);
30−
31−void ff_dither_int_to_float_triangular_sse2(float *dst, int *src0, int len);
32−void ff_dither_int_to_float_triangular_avx(float *dst, int *src0, int len);
33−
34−av_cold void ff_dither_init_x86(DitherDSPContext *ddsp,
35− enum AVResampleDitherMethod method)
36−{
37− int cpu_flags = av_get_cpu_flags();
38−
39− if (EXTERNAL_SSE2(cpu_flags)) {
40− ddsp->quantize = ff_quantize_sse2;
41− ddsp->ptr_align = 16;
42− ddsp->samples_align = 8;
43− }
44−
45− if (method == AV_RESAMPLE_DITHER_RECTANGULAR) {
46− if (EXTERNAL_SSE2(cpu_flags)) {
47− ddsp->dither_int_to_float = ff_dither_int_to_float_rectangular_sse2;
48− }
49− if (EXTERNAL_AVX_FAST(cpu_flags)) {
50− ddsp->dither_int_to_float = ff_dither_int_to_float_rectangular_avx;
51− }
52− } else {
53− if (EXTERNAL_SSE2(cpu_flags)) {
54− ddsp->dither_int_to_float = ff_dither_int_to_float_triangular_sse2;
55− }
56− if (EXTERNAL_AVX_FAST(cpu_flags)) {
57− ddsp->dither_int_to_float = ff_dither_int_to_float_triangular_avx;
58− }
59− }
60−}
libavresample/x86/util.asm+0−41
@@ -1,41 +0,0 @@
1−;******************************************************************************
2−;* x86 utility macros for libavresample
3−;* Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
4−;*
5−;* This file is part of FFmpeg.
6−;*
7−;* FFmpeg is free software; you can redistribute it and/or
8−;* modify it under the terms of the GNU Lesser General Public
9−;* License as published by the Free Software Foundation; either
10−;* version 2.1 of the License, or (at your option) any later version.
11−;*
12−;* FFmpeg is distributed in the hope that it will be useful,
13−;* but WITHOUT ANY WARRANTY; without even the implied warranty of
14−;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15−;* Lesser General Public License for more details.
16−;*
17−;* You should have received a copy of the GNU Lesser General Public
18−;* License along with FFmpeg; if not, write to the Free Software
19−;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20−;******************************************************************************
21−
22−%macro S16_TO_S32_SX 2 ; src/low dst, high dst
23−%if cpuflag(sse4)
24− pmovsxwd m%2, m%1
25− psrldq m%1, 8
26− pmovsxwd m%1, m%1
27− SWAP %1, %2
28−%else
29− mova m%2, m%1
30− punpckhwd m%2, m%2
31− punpcklwd m%1, m%1
32− psrad m%2, 16
33− psrad m%1, 16
34−%endif
35−%endmacro
36−
37−%macro DEINT2_PS 3 ; src0/even dst, src1/odd dst, temp
38− shufps m%3, m%1, m%2, q3131
39− shufps m%1, m%2, q2020
40− SWAP %2,%3
41−%endmacro
libavresample/x86/w64xmmtest.c+0−31
@@ -1,31 +0,0 @@
1−/*
2− * check XMM registers for clobbers on Win64
3− * Copyright (c) 2013 Martin Storsjo
4− *
5− * This file is part of FFmpeg.
6− *
7− * FFmpeg is free software; you can redistribute it and/or
8− * modify it under the terms of the GNU Lesser General Public
9− * License as published by the Free Software Foundation; either
10− * version 2.1 of the License, or (at your option) any later version.
11− *
12− * FFmpeg is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15− * Lesser General Public License for more details.
16− *
17− * You should have received a copy of the GNU Lesser General Public
18− * License along with FFmpeg; if not, write to the Free Software
19− * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20− */
21−
22−#include "libavresample/avresample.h"
23−#include "libavutil/x86/w64xmmtest.h"
24−
25−wrap(avresample_convert(AVAudioResampleContext *avr, uint8_t **output,
26− int out_plane_size, int out_samples, uint8_t **input,
27− int in_plane_size, int in_samples))
28−{
29− testxmmclobbers(avresample_convert, avr, output, out_plane_size,
30− out_samples, input, in_plane_size, in_samples);
31−}
tests/Makefile+0−1
@@ -157,7 +157,6 @@ include $(SRC_PATH)/tests/fate/indeo.mak · 156 unmodified lines
157157 include $(SRC_PATH)/tests/fate/libavcodec.mak
158158 include $(SRC_PATH)/tests/fate/libavdevice.mak
159159 include $(SRC_PATH)/tests/fate/libavformat.mak
160−include $(SRC_PATH)/tests/fate/libavresample.mak
161160 include $(SRC_PATH)/tests/fate/libavutil.mak
162161 include $(SRC_PATH)/tests/fate/libswresample.mak
163162 include $(SRC_PATH)/tests/fate/libswscale.mak
tests/fate.sh+0−1
@@ -48,7 +48,6 @@ configure()( · 47 unmodified lines
4848 --samples="${samples}" \
4949 --enable-gpl \
5050 --enable-memory-poisoning \
51− --enable-avresample \
5251 ${ignore_tests:+--ignore-tests="$ignore_tests"} \
5352 ${arch:+--arch=$arch} \
5453 ${cpu:+--cpu="$cpu"} \
tests/fate/libavresample.mak+0−68
@@ -1,68 +0,0 @@
1−CROSS_TEST = $(foreach I,$(1), \
2− $(foreach J,$(1), \
3− $(if $(filter-out $(I),$(J)), \
4− $(eval $(call $(2),$(I),$(J),$(3),$(4),$(5))), \
5− )))
6−
7−MIX_CHANNELS = 1 2 3 4 5 6 7 8
8−
9−define MIX
10−FATE_LAVR_MIX += fate-lavr-mix-$(3)-$(1)-$(2)
11−fate-lavr-mix-$(3)-$(1)-$(2): tests/data/asynth-44100-$(1).wav
12−fate-lavr-mix-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-44100-$(1).wav -ac $(2) -mix_coeff_type $(3) -internal_sample_fmt $(4) -f s16le -af atrim=end_sample=1024 -
13−fate-lavr-mix-$(3)-$(1)-$(2): CMP = oneoff
14−fate-lavr-mix-$(3)-$(1)-$(2): REF = $(SAMPLES)/lavr/lavr-mix-$(3)-$(1)-$(2)
15−endef
16−
17−$(call CROSS_TEST,$(MIX_CHANNELS),MIX,q8,s16p)
18−$(call CROSS_TEST,$(MIX_CHANNELS),MIX,q15,s16p)
19−$(call CROSS_TEST,$(MIX_CHANNELS),MIX,flt,fltp)
20−
21−# test output zeroing with skipped corresponding input
22−FATE_LAVR_MIX-$(call FILTERDEMDECENCMUX, CHANNELMAP RESAMPLE, WAV, PCM_S16LE, PCM_S16LE, WAV) += fate-lavr-mix-output-zero
23−fate-lavr-mix-output-zero: tests/data/filtergraphs/lavr_mix_output_zero tests/data/asynth-44100-4.wav
24−fate-lavr-mix-output-zero: CMP = oneoff
25−fate-lavr-mix-output-zero: CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-44100-4.wav -filter_script $(TARGET_PATH)/tests/data/filtergraphs/lavr_mix_output_zero -f s16le -
26−fate-lavr-mix-output-zero: REF = $(SAMPLES)/lavr/lavr-mix-output-zero
27−
28−FATE_LAVR_MIX-$(call FILTERDEMDECENCMUX, RESAMPLE, WAV, PCM_S16LE, PCM_S16LE, WAV) += $(FATE_LAVR_MIX)
29−fate-lavr-mix: $(FATE_LAVR_MIX-yes)
30−#FATE_LAVR += $(FATE_LAVR_MIX-yes)
31−
32−SAMPLERATES = 2626 8000 44100 48000 96000
33−
34−define RESAMPLE
35−FATE_LAVR_RESAMPLE += fate-lavr-resample-$(3)-$(1)-$(2)
36−fate-lavr-resample-$(3)-$(1)-$(2): tests/data/asynth-$(1)-1.wav
37−fate-lavr-resample-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-$(1)-1.wav -ar $(2) -internal_sample_fmt $(3) -f $(4) -af atrim=end_sample=10240 -
38−fate-lavr-resample-$(3)-$(1)-$(2): CMP = oneoff
39−fate-lavr-resample-$(3)-$(1)-$(2): CMP_UNIT = $(5)
40−fate-lavr-resample-$(3)-$(1)-$(2): FUZZ = 6
41−fate-lavr-resample-$(3)-$(1)-$(2): REF = $(SAMPLES)/lavr/lavr-resample-$(3)-$(1)-$(2)-v3
42−endef
43−
44−$(call CROSS_TEST,$(SAMPLERATES),RESAMPLE,s16p,s16le,s16)
45−$(call CROSS_TEST,$(SAMPLERATES),RESAMPLE,s32p,s32le,s16)
46−$(call CROSS_TEST,$(SAMPLERATES),RESAMPLE,fltp,f32le,f32)
47−$(call CROSS_TEST,$(SAMPLERATES),RESAMPLE,dblp,f64le,f64)
48−
49−FATE_LAVR_RESAMPLE += fate-lavr-resample-linear
50−fate-lavr-resample-linear: tests/data/asynth-44100-1.wav
51−fate-lavr-resample-linear: CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-44100-1.wav -ar 48000 -filter_size 32 -linear_interp 1 -f s16le -af atrim=end_sample=10240 -
52−fate-lavr-resample-linear: CMP = oneoff
53−fate-lavr-resample-linear: CMP_UNIT = s16
54−fate-lavr-resample-linear: REF = $(SAMPLES)/lavr/lavr-resample-linear
55−
56−FATE_LAVR_RESAMPLE += fate-lavr-resample-nearest
57−fate-lavr-resample-nearest: tests/data/asynth-48000-1.wav
58−fate-lavr-resample-nearest: CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-48000-1.wav -ar 44100 -filter_size 0 -phase_shift 0 -f s16le -af atrim=end_sample=10240 -
59−fate-lavr-resample-nearest: CMP = oneoff
60−fate-lavr-resample-nearest: CMP_UNIT = s16
61−fate-lavr-resample-nearest: REF = $(SAMPLES)/lavr/lavr-resample-nearest
62−
63−FATE_LAVR_RESAMPLE-$(call FILTERDEMDECENCMUX, RESAMPLE, WAV, PCM_S16LE, PCM_S16LE, WAV) += $(FATE_LAVR_RESAMPLE)
64−fate-lavr-resample: $(FATE_LAVR_RESAMPLE-yes)
65−#FATE_LAVR += $(FATE_LAVR_RESAMPLE-yes)
66−
67−FATE_SAMPLES_AVCONV += $(FATE_LAVR)
68−fate-lavr: $(FATE_LAVR)
tools/gen-rc+0−1
@@ -43,7 +43,6 @@ EOF · 42 unmodified lines
4343 # gen-rc libavdevice "FFmpeg device handling library"
4444 # gen-rc libavfilter "FFmpeg audio/video filtering library"
4545 # gen-rc libpostproc "FFmpeg postprocessing library"
46−# gen-rc libavresample "Libav audio resampling library"
4746 # gen-rc libswscale "FFmpeg image rescaling library"
4847 # gen-rc libswresample "FFmpeg audio resampling library"
4948
tools/target_dec_fuzzer.c+1−1
@@ -30,7 +30,7 @@ · 29 unmodified lines
3030 * build the fuzz target.
3131 Choose the value of FFMPEG_CODEC (e.g. AV_CODEC_ID_DVD_SUBTITLE) and
3232 choose one of FUZZ_FFMPEG_VIDEO, FUZZ_FFMPEG_AUDIO, FUZZ_FFMPEG_SUBTITLE.
33− clang -fsanitize=address -fsanitize-coverage=trace-pc-guard,trace-cmp tools/target_dec_fuzzer.c -o target_dec_fuzzer -I. -DFFMPEG_CODEC=AV_CODEC_ID_MPEG1VIDEO -DFUZZ_FFMPEG_VIDEO ../../libfuzzer/libFuzzer.a -Llibavcodec -Llibavdevice -Llibavfilter -Llibavformat -Llibavresample -Llibavutil -Llibpostproc -Llibswscale -Llibswresample -Wl,--as-needed -Wl,-z,noexecstack -Wl,--warn-common -Wl,-rpath-link=:libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil:libavresample -lavdevice -lavfilter -lavformat -lavcodec -lswresample -lswscale -lavutil -ldl -lxcb -lxcb-shm -lxcb -lxcb-xfixes -lxcb -lxcb-shape -lxcb -lX11 -lasound -lm -lbz2 -lz -pthread
33+ clang -fsanitize=address -fsanitize-coverage=trace-pc-guard,trace-cmp tools/target_dec_fuzzer.c -o target_dec_fuzzer -I. -DFFMPEG_CODEC=AV_CODEC_ID_MPEG1VIDEO -DFUZZ_FFMPEG_VIDEO ../../libfuzzer/libFuzzer.a -Llibavcodec -Llibavdevice -Llibavfilter -Llibavformat -Llibavutil -Llibpostproc -Llibswscale -Llibswresample -Wl,--as-needed -Wl,-z,noexecstack -Wl,--warn-common -Wl,-rpath-link=:libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil -lavdevice -lavfilter -lavformat -lavcodec -lswresample -lswscale -lavutil -ldl -lxcb -lxcb-shm -lxcb -lxcb-xfixes -lxcb -lxcb-shape -lxcb -lX11 -lasound -lm -lbz2 -lz -pthread
3434 * create a corpus directory and put some samples there (empty dir is ok too):
3535 mkdir CORPUS && cp some-files CORPUS
3636

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t