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
;
47 static av_cold
int init_dict(AVFilterContext
*ctx
, AVDictionary
**opts
)
49 AResampleContext
*aresample
= ctx
->priv
;
52 aresample
->next_pts
= AV_NOPTS_VALUE
;
53 aresample
->swr
= swr_alloc();
54 if (!aresample
->swr
) {
55 ret
= AVERROR(ENOMEM
);
60 AVDictionaryEntry
*e
= NULL
;
62 while ((e
= av_dict_get(*opts
, "", e
, AV_DICT_IGNORE_SUFFIX
))) {
63 if ((ret
= av_opt_set(aresample
->swr
, e
->key
, e
->value
, 0)) < 0)
68 if (aresample
->sample_rate_arg
> 0)
69 av_opt_set_int(aresample
->swr
, "osr", aresample
->sample_rate_arg
, 0);
74 static av_cold
void uninit(AVFilterContext
*ctx
)
76 AResampleContext
*aresample
= ctx
->priv
;
77 swr_free(&aresample
->swr
);
80 static int query_formats(AVFilterContext
*ctx
)
82 AResampleContext
*aresample
= ctx
->priv
;
83 int out_rate
= av_get_int(aresample
->swr
, "osr", NULL
);
84 uint64_t out_layout
= av_get_int(aresample
->swr
, "ocl", NULL
);
85 enum AVSampleFormat out_format
= av_get_int(aresample
->swr
, "osf", NULL
);
87 AVFilterLink
*inlink
= ctx
->inputs
[0];
88 AVFilterLink
*outlink
= ctx
->outputs
[0];
90 AVFilterFormats
*in_formats
= ff_all_formats(AVMEDIA_TYPE_AUDIO
);
91 AVFilterFormats
*out_formats
;
92 AVFilterFormats
*in_samplerates
= ff_all_samplerates();
93 AVFilterFormats
*out_samplerates
;
94 AVFilterChannelLayouts
*in_layouts
= ff_all_channel_counts();
95 AVFilterChannelLayouts
*out_layouts
;
97 ff_formats_ref (in_formats
, &inlink
->out_formats
);
98 ff_formats_ref (in_samplerates
, &inlink
->out_samplerates
);
99 ff_channel_layouts_ref(in_layouts
, &inlink
->out_channel_layouts
);
102 int ratelist
[] = { out_rate
, -1 };
103 out_samplerates
= ff_make_format_list(ratelist
);
105 out_samplerates
= ff_all_samplerates();
107 if (!out_samplerates
) {
108 av_log(ctx
, AV_LOG_ERROR
, "Cannot allocate output samplerates.\n");
109 return AVERROR(ENOMEM
);
112 ff_formats_ref(out_samplerates
, &outlink
->in_samplerates
);
114 if(out_format
!= AV_SAMPLE_FMT_NONE
) {
115 int formatlist
[] = { out_format
, -1 };
116 out_formats
= ff_make_format_list(formatlist
);
118 out_formats
= ff_all_formats(AVMEDIA_TYPE_AUDIO
);
119 ff_formats_ref(out_formats
, &outlink
->in_formats
);
122 int64_t layout_list
[] = { out_layout
, -1 };
123 out_layouts
= avfilter_make_format64_list(layout_list
);
125 out_layouts
= ff_all_channel_counts();
126 ff_channel_layouts_ref(out_layouts
, &outlink
->in_channel_layouts
);
132 static int config_output(AVFilterLink
*outlink
)
135 AVFilterContext
*ctx
= outlink
->src
;
136 AVFilterLink
*inlink
= ctx
->inputs
[0];
137 AResampleContext
*aresample
= ctx
->priv
;
140 enum AVSampleFormat out_format
;
141 char inchl_buf
[128], outchl_buf
[128];
143 aresample
->swr
= swr_alloc_set_opts(aresample
->swr
,
144 outlink
->channel_layout
, outlink
->format
, outlink
->sample_rate
,
145 inlink
->channel_layout
, inlink
->format
, inlink
->sample_rate
,
148 return AVERROR(ENOMEM
);
149 if (!inlink
->channel_layout
)
150 av_opt_set_int(aresample
->swr
, "ich", inlink
->channels
, 0);
151 if (!outlink
->channel_layout
)
152 av_opt_set_int(aresample
->swr
, "och", outlink
->channels
, 0);
154 ret
= swr_init(aresample
->swr
);
158 out_rate
= av_get_int(aresample
->swr
, "osr", NULL
);
159 out_layout
= av_get_int(aresample
->swr
, "ocl", NULL
);
160 out_format
= av_get_int(aresample
->swr
, "osf", NULL
);
161 outlink
->time_base
= (AVRational
) {1, out_rate
};
163 av_assert0(outlink
->sample_rate
== out_rate
);
164 av_assert0(outlink
->channel_layout
== out_layout
|| !outlink
->channel_layout
);
165 av_assert0(outlink
->format
== out_format
);
167 aresample
->ratio
= (double)outlink
->sample_rate
/ inlink
->sample_rate
;
169 av_get_channel_layout_string(inchl_buf
, sizeof(inchl_buf
), inlink
->channels
, inlink
->channel_layout
);
170 av_get_channel_layout_string(outchl_buf
, sizeof(outchl_buf
), outlink
->channels
, outlink
->channel_layout
);
172 av_log(ctx
, AV_LOG_VERBOSE
, "ch:%d chl:%s fmt:%s r:%dHz -> ch:%d chl:%s fmt:%s r:%dHz\n",
173 inlink
->channels
, inchl_buf
, av_get_sample_fmt_name(inlink
->format
), inlink
->sample_rate
,
174 outlink
->channels
, outchl_buf
, av_get_sample_fmt_name(outlink
->format
), outlink
->sample_rate
);
178 static int filter_frame(AVFilterLink
*inlink
, AVFrame
*insamplesref
)
180 AResampleContext
*aresample
= inlink
->dst
->priv
;
181 const int n_in
= insamplesref
->nb_samples
;
183 int n_out
= n_in
* aresample
->ratio
+ 32;
184 AVFilterLink
*const outlink
= inlink
->dst
->outputs
[0];
185 AVFrame
*outsamplesref
;
188 delay
= swr_get_delay(aresample
->swr
, outlink
->sample_rate
);
190 n_out
+= FFMIN(delay
, FFMAX(4096, n_out
));
192 outsamplesref
= ff_get_audio_buffer(outlink
, n_out
);
195 return AVERROR(ENOMEM
);
197 av_frame_copy_props(outsamplesref
, insamplesref
);
198 outsamplesref
->format
= outlink
->format
;
199 av_frame_set_channels(outsamplesref
, outlink
->channels
);
200 outsamplesref
->channel_layout
= outlink
->channel_layout
;
201 outsamplesref
->sample_rate
= outlink
->sample_rate
;
203 if(insamplesref
->pts
!= AV_NOPTS_VALUE
) {
204 int64_t inpts
= av_rescale(insamplesref
->pts
, inlink
->time_base
.num
* (int64_t)outlink
->sample_rate
* inlink
->sample_rate
, inlink
->time_base
.den
);
205 int64_t outpts
= swr_next_pts(aresample
->swr
, inpts
);
206 aresample
->next_pts
=
207 outsamplesref
->pts
= ROUNDED_DIV(outpts
, inlink
->sample_rate
);
209 outsamplesref
->pts
= AV_NOPTS_VALUE
;
211 n_out
= swr_convert(aresample
->swr
, outsamplesref
->extended_data
, n_out
,
212 (void *)insamplesref
->extended_data
, n_in
);
214 av_frame_free(&outsamplesref
);
215 av_frame_free(&insamplesref
);
219 aresample
->more_data
= outsamplesref
->nb_samples
== n_out
; // Indicate that there is probably more data in our buffers
221 outsamplesref
->nb_samples
= n_out
;
223 ret
= ff_filter_frame(outlink
, outsamplesref
);
224 aresample
->req_fullfilled
= 1;
225 av_frame_free(&insamplesref
);
229 static int flush_frame(AVFilterLink
*outlink
, int final
, AVFrame
**outsamplesref_ret
)
231 AVFilterContext
*ctx
= outlink
->src
;
232 AResampleContext
*aresample
= ctx
->priv
;
233 AVFilterLink
*const inlink
= outlink
->src
->inputs
[0];
234 AVFrame
*outsamplesref
;
238 outsamplesref
= ff_get_audio_buffer(outlink
, n_out
);
239 *outsamplesref_ret
= outsamplesref
;
241 return AVERROR(ENOMEM
);
243 pts
= swr_next_pts(aresample
->swr
, INT64_MIN
);
244 pts
= ROUNDED_DIV(pts
, inlink
->sample_rate
);
246 n_out
= swr_convert(aresample
->swr
, outsamplesref
->extended_data
, n_out
, final
? NULL
: (void*)outsamplesref
->extended_data
, 0);
248 av_frame_free(&outsamplesref
);
249 return (n_out
== 0) ? AVERROR_EOF
: n_out
;
252 outsamplesref
->sample_rate
= outlink
->sample_rate
;
253 outsamplesref
->nb_samples
= n_out
;
255 outsamplesref
->pts
= pts
;
260 static int request_frame(AVFilterLink
*outlink
)
262 AVFilterContext
*ctx
= outlink
->src
;
263 AResampleContext
*aresample
= ctx
->priv
;
266 // First try to get data from the internal buffers
267 if (aresample
->more_data
) {
268 AVFrame
*outsamplesref
;
270 if (flush_frame(outlink
, 0, &outsamplesref
) >= 0) {
271 return ff_filter_frame(outlink
, outsamplesref
);
274 aresample
->more_data
= 0;
276 // Second request more data from the input
277 aresample
->req_fullfilled
= 0;
279 ret
= ff_request_frame(ctx
->inputs
[0]);
280 }while(!aresample
->req_fullfilled
&& ret
>=0);
282 // Third if we hit the end flush
283 if (ret
== AVERROR_EOF
) {
284 AVFrame
*outsamplesref
;
286 if ((ret
= flush_frame(outlink
, 1, &outsamplesref
)) < 0)
289 return ff_filter_frame(outlink
, outsamplesref
);
294 static const AVClass
*resample_child_class_next(const AVClass
*prev
)
296 return prev
? NULL
: swr_get_class();
299 static void *resample_child_next(void *obj
, void *prev
)
301 AResampleContext
*s
= obj
;
302 return prev
? NULL
: s
->swr
;
305 #define OFFSET(x) offsetof(AResampleContext, x)
306 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
308 static const AVOption options
[] = {
309 {"sample_rate", NULL
, OFFSET(sample_rate_arg
), AV_OPT_TYPE_INT
, {.i64
=0}, 0, INT_MAX
, FLAGS
},
313 static const AVClass aresample_class
= {
314 .class_name
= "aresample",
315 .item_name
= av_default_item_name
,
317 .version
= LIBAVUTIL_VERSION_INT
,
318 .child_class_next
= resample_child_class_next
,
319 .child_next
= resample_child_next
,
322 static const AVFilterPad aresample_inputs
[] = {
325 .type
= AVMEDIA_TYPE_AUDIO
,
326 .filter_frame
= filter_frame
,
331 static const AVFilterPad aresample_outputs
[] = {
334 .config_props
= config_output
,
335 .request_frame
= request_frame
,
336 .type
= AVMEDIA_TYPE_AUDIO
,
341 AVFilter ff_af_aresample
= {
343 .description
= NULL_IF_CONFIG_SMALL("Resample audio data."),
344 .init_dict
= init_dict
,
346 .query_formats
= query_formats
,
347 .priv_size
= sizeof(AResampleContext
),
348 .priv_class
= &aresample_class
,
349 .inputs
= aresample_inputs
,
350 .outputs
= aresample_outputs
,