2 * Copyright (c) 2011 Stefano Sabatini
3 * Copyright (c) 2011 Mina Nagy Zaki
5 * This file is part of FFmpeg.
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.
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.
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
24 * resampling audio filter
27 #include "libavutil/avstring.h"
28 #include "libavutil/channel_layout.h"
29 #include "libavutil/opt.h"
30 #include "libavutil/samplefmt.h"
31 #include "libavutil/avassert.h"
32 #include "libswresample/swresample.h"
41 struct SwrContext
*swr
;
46 static av_cold
int init_dict(AVFilterContext
*ctx
, AVDictionary
**opts
)
48 AResampleContext
*aresample
= ctx
->priv
;
51 aresample
->next_pts
= AV_NOPTS_VALUE
;
52 aresample
->swr
= swr_alloc();
53 if (!aresample
->swr
) {
54 ret
= AVERROR(ENOMEM
);
59 AVDictionaryEntry
*e
= NULL
;
61 while ((e
= av_dict_get(*opts
, "", e
, AV_DICT_IGNORE_SUFFIX
))) {
62 if ((ret
= av_opt_set(aresample
->swr
, e
->key
, e
->value
, 0)) < 0)
67 if (aresample
->sample_rate_arg
> 0)
68 av_opt_set_int(aresample
->swr
, "osr", aresample
->sample_rate_arg
, 0);
73 static av_cold
void uninit(AVFilterContext
*ctx
)
75 AResampleContext
*aresample
= ctx
->priv
;
76 swr_free(&aresample
->swr
);
79 static int query_formats(AVFilterContext
*ctx
)
81 AResampleContext
*aresample
= ctx
->priv
;
82 int out_rate
= av_get_int(aresample
->swr
, "osr", NULL
);
83 uint64_t out_layout
= av_get_int(aresample
->swr
, "ocl", NULL
);
84 enum AVSampleFormat out_format
= av_get_int(aresample
->swr
, "osf", NULL
);
86 AVFilterLink
*inlink
= ctx
->inputs
[0];
87 AVFilterLink
*outlink
= ctx
->outputs
[0];
89 AVFilterFormats
*in_formats
= ff_all_formats(AVMEDIA_TYPE_AUDIO
);
90 AVFilterFormats
*out_formats
;
91 AVFilterFormats
*in_samplerates
= ff_all_samplerates();
92 AVFilterFormats
*out_samplerates
;
93 AVFilterChannelLayouts
*in_layouts
= ff_all_channel_counts();
94 AVFilterChannelLayouts
*out_layouts
;
96 ff_formats_ref (in_formats
, &inlink
->out_formats
);
97 ff_formats_ref (in_samplerates
, &inlink
->out_samplerates
);
98 ff_channel_layouts_ref(in_layouts
, &inlink
->out_channel_layouts
);
101 int ratelist
[] = { out_rate
, -1 };
102 out_samplerates
= ff_make_format_list(ratelist
);
104 out_samplerates
= ff_all_samplerates();
106 ff_formats_ref(out_samplerates
, &outlink
->in_samplerates
);
108 if(out_format
!= AV_SAMPLE_FMT_NONE
) {
109 int formatlist
[] = { out_format
, -1 };
110 out_formats
= ff_make_format_list(formatlist
);
112 out_formats
= ff_all_formats(AVMEDIA_TYPE_AUDIO
);
113 ff_formats_ref(out_formats
, &outlink
->in_formats
);
116 int64_t layout_list
[] = { out_layout
, -1 };
117 out_layouts
= avfilter_make_format64_list(layout_list
);
119 out_layouts
= ff_all_channel_counts();
120 ff_channel_layouts_ref(out_layouts
, &outlink
->in_channel_layouts
);
126 static int config_output(AVFilterLink
*outlink
)
129 AVFilterContext
*ctx
= outlink
->src
;
130 AVFilterLink
*inlink
= ctx
->inputs
[0];
131 AResampleContext
*aresample
= ctx
->priv
;
134 enum AVSampleFormat out_format
;
135 char inchl_buf
[128], outchl_buf
[128];
137 aresample
->swr
= swr_alloc_set_opts(aresample
->swr
,
138 outlink
->channel_layout
, outlink
->format
, outlink
->sample_rate
,
139 inlink
->channel_layout
, inlink
->format
, inlink
->sample_rate
,
142 return AVERROR(ENOMEM
);
143 if (!inlink
->channel_layout
)
144 av_opt_set_int(aresample
->swr
, "ich", inlink
->channels
, 0);
145 if (!outlink
->channel_layout
)
146 av_opt_set_int(aresample
->swr
, "och", outlink
->channels
, 0);
148 ret
= swr_init(aresample
->swr
);
152 out_rate
= av_get_int(aresample
->swr
, "osr", NULL
);
153 out_layout
= av_get_int(aresample
->swr
, "ocl", NULL
);
154 out_format
= av_get_int(aresample
->swr
, "osf", NULL
);
155 outlink
->time_base
= (AVRational
) {1, out_rate
};
157 av_assert0(outlink
->sample_rate
== out_rate
);
158 av_assert0(outlink
->channel_layout
== out_layout
|| !outlink
->channel_layout
);
159 av_assert0(outlink
->format
== out_format
);
161 aresample
->ratio
= (double)outlink
->sample_rate
/ inlink
->sample_rate
;
163 av_get_channel_layout_string(inchl_buf
, sizeof(inchl_buf
), inlink
->channels
, inlink
->channel_layout
);
164 av_get_channel_layout_string(outchl_buf
, sizeof(outchl_buf
), outlink
->channels
, outlink
->channel_layout
);
166 av_log(ctx
, AV_LOG_VERBOSE
, "ch:%d chl:%s fmt:%s r:%dHz -> ch:%d chl:%s fmt:%s r:%dHz\n",
167 inlink
->channels
, inchl_buf
, av_get_sample_fmt_name(inlink
->format
), inlink
->sample_rate
,
168 outlink
->channels
, outchl_buf
, av_get_sample_fmt_name(outlink
->format
), outlink
->sample_rate
);
172 static int filter_frame(AVFilterLink
*inlink
, AVFrame
*insamplesref
)
174 AResampleContext
*aresample
= inlink
->dst
->priv
;
175 const int n_in
= insamplesref
->nb_samples
;
177 int n_out
= n_in
* aresample
->ratio
+ 32;
178 AVFilterLink
*const outlink
= inlink
->dst
->outputs
[0];
179 AVFrame
*outsamplesref
;
182 delay
= swr_get_delay(aresample
->swr
, outlink
->sample_rate
);
186 outsamplesref
= ff_get_audio_buffer(outlink
, n_out
);
189 return AVERROR(ENOMEM
);
191 av_frame_copy_props(outsamplesref
, insamplesref
);
192 outsamplesref
->format
= outlink
->format
;
193 av_frame_set_channels(outsamplesref
, outlink
->channels
);
194 outsamplesref
->channel_layout
= outlink
->channel_layout
;
195 outsamplesref
->sample_rate
= outlink
->sample_rate
;
197 if(insamplesref
->pts
!= AV_NOPTS_VALUE
) {
198 int64_t inpts
= av_rescale(insamplesref
->pts
, inlink
->time_base
.num
* (int64_t)outlink
->sample_rate
* inlink
->sample_rate
, inlink
->time_base
.den
);
199 int64_t outpts
= swr_next_pts(aresample
->swr
, inpts
);
200 aresample
->next_pts
=
201 outsamplesref
->pts
= ROUNDED_DIV(outpts
, inlink
->sample_rate
);
203 outsamplesref
->pts
= AV_NOPTS_VALUE
;
205 n_out
= swr_convert(aresample
->swr
, outsamplesref
->extended_data
, n_out
,
206 (void *)insamplesref
->extended_data
, n_in
);
208 av_frame_free(&outsamplesref
);
209 av_frame_free(&insamplesref
);
213 outsamplesref
->nb_samples
= n_out
;
215 ret
= ff_filter_frame(outlink
, outsamplesref
);
216 aresample
->req_fullfilled
= 1;
217 av_frame_free(&insamplesref
);
221 static int request_frame(AVFilterLink
*outlink
)
223 AVFilterContext
*ctx
= outlink
->src
;
224 AResampleContext
*aresample
= ctx
->priv
;
225 AVFilterLink
*const inlink
= outlink
->src
->inputs
[0];
228 aresample
->req_fullfilled
= 0;
230 ret
= ff_request_frame(ctx
->inputs
[0]);
231 }while(!aresample
->req_fullfilled
&& ret
>=0);
233 if (ret
== AVERROR_EOF
) {
234 AVFrame
*outsamplesref
;
238 outsamplesref
= ff_get_audio_buffer(outlink
, n_out
);
240 return AVERROR(ENOMEM
);
242 pts
= swr_next_pts(aresample
->swr
, INT64_MIN
);
243 pts
= ROUNDED_DIV(pts
, inlink
->sample_rate
);
245 n_out
= swr_convert(aresample
->swr
, outsamplesref
->extended_data
, n_out
, 0, 0);
247 av_frame_free(&outsamplesref
);
248 return (n_out
== 0) ? AVERROR_EOF
: n_out
;
251 outsamplesref
->sample_rate
= outlink
->sample_rate
;
252 outsamplesref
->nb_samples
= n_out
;
254 outsamplesref
->pts
= pts
;
256 return ff_filter_frame(outlink
, outsamplesref
);
261 static const AVClass
*resample_child_class_next(const AVClass
*prev
)
263 return prev
? NULL
: swr_get_class();
266 static void *resample_child_next(void *obj
, void *prev
)
268 AResampleContext
*s
= obj
;
269 return prev
? NULL
: s
->swr
;
272 #define OFFSET(x) offsetof(AResampleContext, x)
273 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
275 static const AVOption options
[] = {
276 {"sample_rate", NULL
, OFFSET(sample_rate_arg
), AV_OPT_TYPE_INT
, {.i64
=0}, 0, INT_MAX
, FLAGS
},
280 static const AVClass aresample_class
= {
281 .class_name
= "aresample",
282 .item_name
= av_default_item_name
,
284 .version
= LIBAVUTIL_VERSION_INT
,
285 .child_class_next
= resample_child_class_next
,
286 .child_next
= resample_child_next
,
289 static const AVFilterPad aresample_inputs
[] = {
292 .type
= AVMEDIA_TYPE_AUDIO
,
293 .filter_frame
= filter_frame
,
298 static const AVFilterPad aresample_outputs
[] = {
301 .config_props
= config_output
,
302 .request_frame
= request_frame
,
303 .type
= AVMEDIA_TYPE_AUDIO
,
308 AVFilter ff_af_aresample
= {
310 .description
= NULL_IF_CONFIG_SMALL("Resample audio data."),
311 .init_dict
= init_dict
,
313 .query_formats
= query_formats
,
314 .priv_size
= sizeof(AResampleContext
),
315 .priv_class
= &aresample_class
,
316 .inputs
= aresample_inputs
,
317 .outputs
= aresample_outputs
,