af_aresample.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011 Stefano Sabatini
3  * Copyright (c) 2011 Mina Nagy Zaki
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 /**
23  * @file
24  * resampling audio filter
25  */
26 
27 #include "libavutil/avstring.h"
29 #include "libavutil/opt.h"
30 #include "libavutil/samplefmt.h"
31 #include "libavutil/avassert.h"
33 #include "avfilter.h"
34 #include "audio.h"
35 #include "internal.h"
36 
37 typedef struct {
38  const AVClass *class;
40  double ratio;
41  struct SwrContext *swr;
42  int64_t next_pts;
45 
47 {
48  AResampleContext *aresample = ctx->priv;
49  int ret = 0;
50 
51  aresample->next_pts = AV_NOPTS_VALUE;
52  aresample->swr = swr_alloc();
53  if (!aresample->swr) {
54  ret = AVERROR(ENOMEM);
55  goto end;
56  }
57 
58  if (opts) {
60 
61  while ((e = av_dict_get(*opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
62  const char *token = e->key;
63  const char *value = e->value;
64  if ((ret = av_opt_set(aresample->swr, token, value, 0)) < 0)
65  goto end;
66  }
67  av_dict_free(opts);
68  }
69  if (aresample->sample_rate_arg > 0)
70  av_opt_set_int(aresample->swr, "osr", aresample->sample_rate_arg, 0);
71 end:
72  return ret;
73 }
74 
75 static av_cold void uninit(AVFilterContext *ctx)
76 {
77  AResampleContext *aresample = ctx->priv;
78  swr_free(&aresample->swr);
79 }
80 
82 {
83  AResampleContext *aresample = ctx->priv;
84  int out_rate = av_get_int(aresample->swr, "osr", NULL);
85  uint64_t out_layout = av_get_int(aresample->swr, "ocl", NULL);
86  enum AVSampleFormat out_format = av_get_int(aresample->swr, "osf", NULL);
87 
88  AVFilterLink *inlink = ctx->inputs[0];
89  AVFilterLink *outlink = ctx->outputs[0];
90 
92  AVFilterFormats *out_formats;
93  AVFilterFormats *in_samplerates = ff_all_samplerates();
94  AVFilterFormats *out_samplerates;
96  AVFilterChannelLayouts *out_layouts;
97 
98  ff_formats_ref (in_formats, &inlink->out_formats);
99  ff_formats_ref (in_samplerates, &inlink->out_samplerates);
100  ff_channel_layouts_ref(in_layouts, &inlink->out_channel_layouts);
101 
102  if(out_rate > 0) {
103  out_samplerates = ff_make_format_list((int[]){ out_rate, -1 });
104  } else {
105  out_samplerates = ff_all_samplerates();
106  }
107  ff_formats_ref(out_samplerates, &outlink->in_samplerates);
108 
109  if(out_format != AV_SAMPLE_FMT_NONE) {
110  out_formats = ff_make_format_list((int[]){ out_format, -1 });
111  } else
112  out_formats = ff_all_formats(AVMEDIA_TYPE_AUDIO);
113  ff_formats_ref(out_formats, &outlink->in_formats);
114 
115  if(out_layout) {
116  out_layouts = avfilter_make_format64_list((int64_t[]){ out_layout, -1 });
117  } else
118  out_layouts = ff_all_channel_counts();
119  ff_channel_layouts_ref(out_layouts, &outlink->in_channel_layouts);
120 
121  return 0;
122 }
123 
124 
125 static int config_output(AVFilterLink *outlink)
126 {
127  int ret;
128  AVFilterContext *ctx = outlink->src;
129  AVFilterLink *inlink = ctx->inputs[0];
130  AResampleContext *aresample = ctx->priv;
131  int out_rate;
132  uint64_t out_layout;
133  enum AVSampleFormat out_format;
134  char inchl_buf[128], outchl_buf[128];
135 
136  aresample->swr = swr_alloc_set_opts(aresample->swr,
137  outlink->channel_layout, outlink->format, outlink->sample_rate,
138  inlink->channel_layout, inlink->format, inlink->sample_rate,
139  0, ctx);
140  if (!aresample->swr)
141  return AVERROR(ENOMEM);
142  if (!inlink->channel_layout)
143  av_opt_set_int(aresample->swr, "ich", inlink->channels, 0);
144  if (!outlink->channel_layout)
145  av_opt_set_int(aresample->swr, "och", outlink->channels, 0);
146 
147  ret = swr_init(aresample->swr);
148  if (ret < 0)
149  return ret;
150 
151  out_rate = av_get_int(aresample->swr, "osr", NULL);
152  out_layout = av_get_int(aresample->swr, "ocl", NULL);
153  out_format = av_get_int(aresample->swr, "osf", NULL);
154  outlink->time_base = (AVRational) {1, out_rate};
155 
156  av_assert0(outlink->sample_rate == out_rate);
157  av_assert0(outlink->channel_layout == out_layout || !outlink->channel_layout);
158  av_assert0(outlink->format == out_format);
159 
160  aresample->ratio = (double)outlink->sample_rate / inlink->sample_rate;
161 
162  av_get_channel_layout_string(inchl_buf, sizeof(inchl_buf), inlink ->channels, inlink ->channel_layout);
163  av_get_channel_layout_string(outchl_buf, sizeof(outchl_buf), outlink->channels, outlink->channel_layout);
164 
165  av_log(ctx, AV_LOG_VERBOSE, "ch:%d chl:%s fmt:%s r:%dHz -> ch:%d chl:%s fmt:%s r:%dHz\n",
166  inlink ->channels, inchl_buf, av_get_sample_fmt_name(inlink->format), inlink->sample_rate,
167  outlink->channels, outchl_buf, av_get_sample_fmt_name(outlink->format), outlink->sample_rate);
168  return 0;
169 }
170 
171 static int filter_frame(AVFilterLink *inlink, AVFrame *insamplesref)
172 {
173  AResampleContext *aresample = inlink->dst->priv;
174  const int n_in = insamplesref->nb_samples;
175  int n_out = n_in * aresample->ratio * 2 + 256;
176  AVFilterLink *const outlink = inlink->dst->outputs[0];
177  AVFrame *outsamplesref = ff_get_audio_buffer(outlink, n_out);
178  int ret;
179 
180  if(!outsamplesref)
181  return AVERROR(ENOMEM);
182 
183  av_frame_copy_props(outsamplesref, insamplesref);
184  outsamplesref->format = outlink->format;
185  av_frame_set_channels(outsamplesref, outlink->channels);
186  outsamplesref->channel_layout = outlink->channel_layout;
187  outsamplesref->sample_rate = outlink->sample_rate;
188 
189  if(insamplesref->pts != AV_NOPTS_VALUE) {
190  int64_t inpts = av_rescale(insamplesref->pts, inlink->time_base.num * (int64_t)outlink->sample_rate * inlink->sample_rate, inlink->time_base.den);
191  int64_t outpts= swr_next_pts(aresample->swr, inpts);
192  aresample->next_pts =
193  outsamplesref->pts = ROUNDED_DIV(outpts, inlink->sample_rate);
194  } else {
195  outsamplesref->pts = AV_NOPTS_VALUE;
196  }
197  n_out = swr_convert(aresample->swr, outsamplesref->extended_data, n_out,
198  (void *)insamplesref->extended_data, n_in);
199  if (n_out <= 0) {
200  av_frame_free(&outsamplesref);
201  av_frame_free(&insamplesref);
202  return 0;
203  }
204 
205  outsamplesref->nb_samples = n_out;
206 
207  ret = ff_filter_frame(outlink, outsamplesref);
208  aresample->req_fullfilled= 1;
209  av_frame_free(&insamplesref);
210  return ret;
211 }
212 
213 static int request_frame(AVFilterLink *outlink)
214 {
215  AVFilterContext *ctx = outlink->src;
216  AResampleContext *aresample = ctx->priv;
217  AVFilterLink *const inlink = outlink->src->inputs[0];
218  int ret;
219 
220  aresample->req_fullfilled = 0;
221  do{
222  ret = ff_request_frame(ctx->inputs[0]);
223  }while(!aresample->req_fullfilled && ret>=0);
224 
225  if (ret == AVERROR_EOF) {
226  AVFrame *outsamplesref;
227  int n_out = 4096;
228 
229  outsamplesref = ff_get_audio_buffer(outlink, n_out);
230  if (!outsamplesref)
231  return AVERROR(ENOMEM);
232  n_out = swr_convert(aresample->swr, outsamplesref->extended_data, n_out, 0, 0);
233  if (n_out <= 0) {
234  av_frame_free(&outsamplesref);
235  return (n_out == 0) ? AVERROR_EOF : n_out;
236  }
237 
238  outsamplesref->sample_rate = outlink->sample_rate;
239  outsamplesref->nb_samples = n_out;
240 #if 0
241  outsamplesref->pts = aresample->next_pts;
242  if(aresample->next_pts != AV_NOPTS_VALUE)
243  aresample->next_pts += av_rescale_q(n_out, (AVRational){1 ,outlink->sample_rate}, outlink->time_base);
244 #else
245  outsamplesref->pts = swr_next_pts(aresample->swr, INT64_MIN);
246  outsamplesref->pts = ROUNDED_DIV(outsamplesref->pts, inlink->sample_rate);
247 #endif
248 
249  return ff_filter_frame(outlink, outsamplesref);
250  }
251  return ret;
252 }
253 
254 static const AVClass *resample_child_class_next(const AVClass *prev)
255 {
256  return prev ? NULL : swr_get_class();
257 }
258 
259 static void *resample_child_next(void *obj, void *prev)
260 {
261  AResampleContext *s = obj;
262  return prev ? NULL : s->swr;
263 }
264 
265 #define OFFSET(x) offsetof(AResampleContext, x)
266 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
267 
268 static const AVOption options[] = {
269  {"sample_rate", NULL, OFFSET(sample_rate_arg), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS },
270  {NULL}
271 };
272 
273 static const AVClass aresample_class = {
274  .class_name = "aresample",
275  .item_name = av_default_item_name,
276  .option = options,
277  .version = LIBAVUTIL_VERSION_INT,
278  .child_class_next = resample_child_class_next,
280 };
281 
282 static const AVFilterPad aresample_inputs[] = {
283  {
284  .name = "default",
285  .type = AVMEDIA_TYPE_AUDIO,
286  .filter_frame = filter_frame,
287  },
288  { NULL },
289 };
290 
291 static const AVFilterPad aresample_outputs[] = {
292  {
293  .name = "default",
294  .config_props = config_output,
295  .request_frame = request_frame,
296  .type = AVMEDIA_TYPE_AUDIO,
297  },
298  { NULL },
299 };
300 
302  .name = "aresample",
303  .description = NULL_IF_CONFIG_SMALL("Resample audio data."),
304  .init_dict = init_dict,
305  .uninit = uninit,
306  .query_formats = query_formats,
307  .priv_size = sizeof(AResampleContext),
308  .priv_class = &aresample_class,
309  .inputs = aresample_inputs,
310  .outputs = aresample_outputs,
311 };
const char * s
Definition: avisynth_c.h:668
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:424
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
int swr_convert(struct SwrContext *s, uint8_t *out_arg[SWR_CH_MAX], int out_count, const uint8_t *in_arg[SWR_CH_MAX], int in_count)
Definition: swresample.c:735
AVOption.
Definition: opt.h:251
static const AVFilterPad aresample_inputs[]
Definition: af_aresample.c:282
av_default_item_name
static const AVFilterPad outputs[]
Definition: af_ashowinfo.c:117
external API header
int num
numerator
Definition: rational.h:44
int64_t swr_next_pts(struct SwrContext *s, int64_t pts)
Convert the next timestamp from input to output timestamps are in 1/(in_sample_rate * out_sample_rate...
Definition: swresample.c:900
static const AVOption options[]
Definition: af_aresample.c:268
AVDictionaryEntry * av_dict_get(AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:39
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:308
const char * name
Pad name.
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:55
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:532
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
it can be given away to ff_start_frame *A reference passed to ff_filter_frame(or the deprecated ff_start_frame) is given away and must no longer be used.*A reference created with avfilter_ref_buffer belongs to the code that created it.*A reference obtained with ff_get_video_buffer or ff_get_audio_buffer belongs to the code that requested it.*A reference given as return value by the get_video_buffer or get_audio_buffer method is given away and must no longer be used.Link reference fields---------------------The AVFilterLink structure has a few AVFilterBufferRef fields.The cur_buf and out_buf were used with the deprecated start_frame/draw_slice/end_frame API and should no longer be used.src_buf
av_cold struct SwrContext * swr_alloc(void)
Allocate SwrContext.
Definition: swresample.c:177
#define av_cold
Definition: attributes.h:78
AVOptions.
#define FLAGS
Definition: af_aresample.c:266
AVFilter avfilter_af_aresample
Definition: af_aresample.c:301
end end
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:159
void ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
Add *ref as a new reference to f.
Definition: formats.c:427
#define AVERROR_EOF
End of file.
Definition: error.h:55
AVFilterFormats * ff_all_formats(enum AVMediaType type)
Return a list of all formats supported by FFmpeg for the given media type.
Definition: formats.c:357
#define ROUNDED_DIV(a, b)
Definition: common.h:50
A filter pad used for either input or output.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:130
void *(* child_next)(void *obj, void *prev)
Return next AVOptions-enabled child or NULL.
Definition: log.h:96
libswresample public header
static void * resample_child_next(void *obj, void *prev)
Definition: af_aresample.c:259
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
Definition: audio.c:84
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
void * priv
private data for use by the filter
Definition: avfilter.h:545
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values. ...
Definition: dict.c:162
void av_frame_set_channels(AVFrame *frame, int val)
int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
Definition: opt.c:394
simple assert() macros that are a bit more flexible than ISO C assert().
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
uint64_t channel_layout
Channel layout of the audio data.
Definition: frame.h:331
#define AV_LOG_VERBOSE
Definition: log.h:157
struct AVRational AVRational
rational number numerator/denominator
audio channel layout utility functions
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:118
ret
Definition: avfilter.c:821
static const AVClass aresample_class
Definition: af_aresample.c:273
int64_t av_get_int(void *obj, const char *name, const AVOption **o_out)
Definition: opt.c:675
static av_cold int init_dict(AVFilterContext *ctx, AVDictionary **opts)
Definition: af_aresample.c:46
struct SwrContext * swr_alloc_set_opts(struct SwrContext *s, int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate, int64_t in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate, int log_offset, void *log_ctx)
Allocate SwrContext if needed and set/reset common parameters.
Definition: swresample.c:186
const AVClass * swr_get_class(void)
Get the AVClass for swrContext.
Definition: swresample.c:172
const char * av_get_sample_fmt_name(enum AVSampleFormat sample_fmt)
Return the name of sample_fmt, or NULL if sample_fmt is not recognized.
Definition: samplefmt.c:47
LIBAVUTIL_VERSION_INT
Definition: eval.c:55
A list of supported channel layouts.
Definition: formats.h:85
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_aresample.c:75
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:134
NULL
Definition: eval.c:55
int64_t outpts
output PTS
void ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:432
AVFilterChannelLayouts * avfilter_make_format64_list(const int64_t *fmts)
Definition: formats.c:317
static const AVFilterPad aresample_outputs[]
Definition: af_aresample.c:291
av_cold void swr_free(SwrContext **ss)
Free the given SwrContext and set the pointer to NULL.
Definition: swresample.c:220
double value
Definition: eval.c:82
Describe the class of an AVClass context structure.
Definition: log.h:50
int sample_rate
Sample rate of the audio data.
Definition: frame.h:326
Filter definition.
Definition: avfilter.h:436
rational number numerator/denominator
Definition: rational.h:43
struct SwrContext * swr
Definition: af_aresample.c:41
const char * name
filter name
Definition: avfilter.h:437
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:539
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:396
static int filter_frame(AVFilterLink *inlink, AVFrame *insamplesref)
Definition: af_aresample.c:171
static const AVClass * resample_child_class_next(const AVClass *prev)
Definition: af_aresample.c:254
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:108
AVSampleFormat
Audio Sample Formats.
Definition: samplefmt.h:49
char * key
Definition: dict.h:81
int den
denominator
Definition: rational.h:45
#define OFFSET(x)
Definition: af_aresample.c:265
char * value
Definition: dict.h:82
A list of supported formats for one end of a filter link.
Definition: formats.h:64
An instance of a filter.
Definition: avfilter.h:524
#define AV_DICT_IGNORE_SUFFIX
Definition: dict.h:68
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Definition: avfilter.c:319
internal API functions
AVFilterChannelLayouts * ff_all_channel_counts(void)
Construct an AVFilterChannelLayouts coding for any channel layout, with known or unknown disposition...
Definition: formats.c:411
static int query_formats(AVFilterContext *ctx)
Definition: af_aresample.c:81
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:117
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition: opt.c:252
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:127
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:190
static int request_frame(AVFilterLink *outlink)
Definition: af_aresample.c:213
av_cold int swr_init(struct SwrContext *s)
Initialize context after user parameters have been set.
Definition: swresample.c:242
static int config_output(AVFilterLink *outlink)
Definition: af_aresample.c:125
void av_get_channel_layout_string(char *buf, int buf_size, int nb_channels, uint64_t channel_layout)
Return a description of a channel layout.