| @@ -37,6 +37,7 @@ · 36 unmodified lines |
| 37 | 37 | #include "internal.h" |
| 38 | 38 | |
| 39 | 39 | typedef struct ResampleContext { |
| 40 | + const AVClass *class; |
| 40 | 41 | AVAudioResampleContext *avr; |
| 41 | 42 | AVDictionary *options; |
| 42 | 43 | |
| @@ -46,26 +47,30 @@ typedef struct ResampleContext { · 3 unmodified lines |
| 46 | 47 | int got_output; |
| 47 | 48 | } ResampleContext; |
| 48 | 49 | |
| 49 | | −static av_cold int init(AVFilterContext *ctx, const char *args) |
| 50 | +static av_cold int init(AVFilterContext *ctx, AVDictionary **opts) |
| 50 | 51 | { |
| 51 | 52 | ResampleContext *s = ctx->priv; |
| 53 | + const AVClass *avr_class = avresample_get_class(); |
| 54 | + AVDictionaryEntry *e = NULL; |
| 52 | 55 | |
| 53 | | − if (args) { |
| 54 | | − int ret = av_dict_parse_string(&s->options, args, "=", ":", 0); |
| 55 | | − if (ret < 0) { |
| 56 | | − av_log(ctx, AV_LOG_ERROR, "error setting option string: %s\n", args); |
| 57 | | − return ret; |
| 58 | | − } |
| 59 | | − |
| 60 | | − /* do not allow the user to override basic format options */ |
| 61 | | − av_dict_set(&s->options, "in_channel_layout", NULL, 0); |
| 62 | | − av_dict_set(&s->options, "out_channel_layout", NULL, 0); |
| 63 | | − av_dict_set(&s->options, "in_sample_fmt", NULL, 0); |
| 64 | | − av_dict_set(&s->options, "out_sample_fmt", NULL, 0); |
| 65 | | − av_dict_set(&s->options, "in_sample_rate", NULL, 0); |
| 66 | | − av_dict_set(&s->options, "out_sample_rate", NULL, 0); |
| 56 | + while ((e = av_dict_get(*opts, "", e, AV_DICT_IGNORE_SUFFIX))) { |
| 57 | + if (av_opt_find(&avr_class, e->key, NULL, 0, |
| 58 | + AV_OPT_SEARCH_FAKE_OBJ | AV_OPT_SEARCH_CHILDREN)) |
| 59 | + av_dict_set(&s->options, e->key, e->value, 0); |
| 67 | 60 | } |
| 68 | 61 | |
| 62 | + e = NULL; |
| 63 | + while ((e = av_dict_get(s->options, "", e, AV_DICT_IGNORE_SUFFIX))) |
| 64 | + av_dict_set(opts, e->key, NULL, 0); |
| 65 | + |
| 66 | + /* do not allow the user to override basic format options */ |
| 67 | + av_dict_set(&s->options, "in_channel_layout", NULL, 0); |
| 68 | + av_dict_set(&s->options, "out_channel_layout", NULL, 0); |
| 69 | + av_dict_set(&s->options, "in_sample_fmt", NULL, 0); |
| 70 | + av_dict_set(&s->options, "out_sample_fmt", NULL, 0); |
| 71 | + av_dict_set(&s->options, "in_sample_rate", NULL, 0); |
| 72 | + av_dict_set(&s->options, "out_sample_rate", NULL, 0); |
| 73 | + |
| 69 | 74 | return 0; |
| 70 | 75 | } |
| 71 | 76 | |
| @@ -272,6 +277,25 @@ fail: · 200 unmodified lines |
| 272 | 277 | return ret; |
| 273 | 278 | } |
| 274 | 279 | |
| 280 | +static const AVClass *resample_child_class_next(const AVClass *prev) |
| 281 | +{ |
| 282 | + return prev ? NULL : avresample_get_class(); |
| 283 | +} |
| 284 | + |
| 285 | +static void *resample_child_next(void *obj, void *prev) |
| 286 | +{ |
| 287 | + ResampleContext *s = obj; |
| 288 | + return prev ? NULL : s->avr; |
| 289 | +} |
| 290 | + |
| 291 | +static const AVClass resample_class = { |
| 292 | + .class_name = "resample", |
| 293 | + .item_name = av_default_item_name, |
| 294 | + .version = LIBAVUTIL_VERSION_INT, |
| 295 | + .child_class_next = resample_child_class_next, |
| 296 | + .child_next = resample_child_next, |
| 297 | +}; |
| 298 | + |
| 275 | 299 | static const AVFilterPad avfilter_af_resample_inputs[] = { |
| 276 | 300 | { |
| 277 | 301 | .name = "default", |
| @@ -295,8 +319,9 @@ AVFilter avfilter_af_resample = { · 17 unmodified lines |
| 295 | 319 | .name = "resample", |
| 296 | 320 | .description = NULL_IF_CONFIG_SMALL("Audio resampling and conversion."), |
| 297 | 321 | .priv_size = sizeof(ResampleContext), |
| 322 | + .priv_class = &resample_class, |
| 298 | 323 | |
| 299 | | − .init = init, |
| 324 | + .init_dict = init, |
| 300 | 325 | .uninit = uninit, |
| 301 | 326 | .query_formats = query_formats, |
| 302 | 327 | |