|
|
|
@ -37,6 +37,7 @@ |
|
|
|
|
#include "internal.h" |
|
|
|
|
|
|
|
|
|
typedef struct ResampleContext { |
|
|
|
|
const AVClass *class; |
|
|
|
|
AVAudioResampleContext *avr; |
|
|
|
|
AVDictionary *options; |
|
|
|
|
|
|
|
|
@ -46,26 +47,30 @@ typedef struct ResampleContext { |
|
|
|
|
int got_output; |
|
|
|
|
} ResampleContext; |
|
|
|
|
|
|
|
|
|
static av_cold int init(AVFilterContext *ctx, const char *args) |
|
|
|
|
static av_cold int init(AVFilterContext *ctx, AVDictionary **opts) |
|
|
|
|
{ |
|
|
|
|
ResampleContext *s = ctx->priv; |
|
|
|
|
const AVClass *avr_class = avresample_get_class(); |
|
|
|
|
AVDictionaryEntry *e = NULL; |
|
|
|
|
|
|
|
|
|
if (args) { |
|
|
|
|
int ret = av_dict_parse_string(&s->options, args, "=", ":", 0); |
|
|
|
|
if (ret < 0) { |
|
|
|
|
av_log(ctx, AV_LOG_ERROR, "error setting option string: %s\n", args); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* do not allow the user to override basic format options */ |
|
|
|
|
av_dict_set(&s->options, "in_channel_layout", NULL, 0); |
|
|
|
|
av_dict_set(&s->options, "out_channel_layout", NULL, 0); |
|
|
|
|
av_dict_set(&s->options, "in_sample_fmt", NULL, 0); |
|
|
|
|
av_dict_set(&s->options, "out_sample_fmt", NULL, 0); |
|
|
|
|
av_dict_set(&s->options, "in_sample_rate", NULL, 0); |
|
|
|
|
av_dict_set(&s->options, "out_sample_rate", NULL, 0); |
|
|
|
|
while ((e = av_dict_get(*opts, "", e, AV_DICT_IGNORE_SUFFIX))) { |
|
|
|
|
if (av_opt_find(&avr_class, e->key, NULL, 0, |
|
|
|
|
AV_OPT_SEARCH_FAKE_OBJ | AV_OPT_SEARCH_CHILDREN)) |
|
|
|
|
av_dict_set(&s->options, e->key, e->value, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
e = NULL; |
|
|
|
|
while ((e = av_dict_get(s->options, "", e, AV_DICT_IGNORE_SUFFIX))) |
|
|
|
|
av_dict_set(opts, e->key, NULL, 0); |
|
|
|
|
|
|
|
|
|
/* do not allow the user to override basic format options */ |
|
|
|
|
av_dict_set(&s->options, "in_channel_layout", NULL, 0); |
|
|
|
|
av_dict_set(&s->options, "out_channel_layout", NULL, 0); |
|
|
|
|
av_dict_set(&s->options, "in_sample_fmt", NULL, 0); |
|
|
|
|
av_dict_set(&s->options, "out_sample_fmt", NULL, 0); |
|
|
|
|
av_dict_set(&s->options, "in_sample_rate", NULL, 0); |
|
|
|
|
av_dict_set(&s->options, "out_sample_rate", NULL, 0); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -272,6 +277,25 @@ fail: |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static const AVClass *resample_child_class_next(const AVClass *prev) |
|
|
|
|
{ |
|
|
|
|
return prev ? NULL : avresample_get_class(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void *resample_child_next(void *obj, void *prev) |
|
|
|
|
{ |
|
|
|
|
ResampleContext *s = obj; |
|
|
|
|
return prev ? NULL : s->avr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static const AVClass resample_class = { |
|
|
|
|
.class_name = "resample", |
|
|
|
|
.item_name = av_default_item_name, |
|
|
|
|
.version = LIBAVUTIL_VERSION_INT, |
|
|
|
|
.child_class_next = resample_child_class_next, |
|
|
|
|
.child_next = resample_child_next, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static const AVFilterPad avfilter_af_resample_inputs[] = { |
|
|
|
|
{ |
|
|
|
|
.name = "default", |
|
|
|
@ -295,8 +319,9 @@ AVFilter avfilter_af_resample = { |
|
|
|
|
.name = "resample", |
|
|
|
|
.description = NULL_IF_CONFIG_SMALL("Audio resampling and conversion."), |
|
|
|
|
.priv_size = sizeof(ResampleContext), |
|
|
|
|
.priv_class = &resample_class, |
|
|
|
|
|
|
|
|
|
.init = init, |
|
|
|
|
.init_dict = init, |
|
|
|
|
.uninit = uninit, |
|
|
|
|
.query_formats = query_formats, |
|
|
|
|
|
|
|
|
|