By using preinit, the AVDCT already exists directly after allocating the filter, so that the filter's AVClass's child_next becomes usable for setting options with the AV_OPT_SEARCH_CHILDREN search flag. This means that it is no longer necessary to use the init_dict callback for this filter. Furthermore, the earlier code did not abide by the documentation of the init_dict callback at all: Instead of only returning the options that have not been recognized it always returned all options on any av_opt_set() error and errored out in this case, even if it is just an unrecognized option. This behaviour has been inherited by avfilter_init_dict(), contradicting its documentation. This is also fixed in this commit.
Unified · Split
| @@ -338,6 +338,12 @@ static int config_input(AVFilterLink *inlink) · 337 unmodified lines | |||
| 338 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); | 338 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); |
| 339 | const int bps = desc->comp[0].depth; | 339 | const int bps = desc->comp[0].depth; |
| 340 | 340 | ||
| 341 | s->store_slice = store_slice_c; | ||
| 342 | switch (s->mode) { | ||
| 343 | case MODE_HARD: s->requantize = hardthresh_c; break; | ||
| 344 | case MODE_SOFT: s->requantize = softthresh_c; break; | ||
| 345 | } | ||
| 346 | |||
| 341 | av_opt_set_int(s->dct, "bits_per_sample", bps, 0); | 347 | av_opt_set_int(s->dct, "bits_per_sample", bps, 0); |
| 342 | avcodec_dct_init(s->dct); | 348 | avcodec_dct_init(s->dct); |
| 343 | 349 | ||
| @@ -451,30 +457,14 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar · 107 unmodified lines | |||
| 451 | return AVERROR(ENOSYS); | 457 | return AVERROR(ENOSYS); |
| 452 | } | 458 | } |
| 453 | 459 | ||
| 454 | static av_cold int init_dict(AVFilterContext *ctx, AVDictionary **opts) | 460 | static av_cold int preinit(AVFilterContext *ctx) |
| 455 | { | 461 | { |
| 456 | SPPContext *s = ctx->priv; | 462 | SPPContext *s = ctx->priv; |
| 457 | int ret; | ||
| 458 | 463 | ||
| 459 | s->dct = avcodec_dct_alloc(); | 464 | s->dct = avcodec_dct_alloc(); |
| 460 | if (!s->dct) | 465 | if (!s->dct) |
| 461 | return AVERROR(ENOMEM); | 466 | return AVERROR(ENOMEM); |
| 462 | 467 | ||
| 463 | if (opts) { | ||
| 464 | AVDictionaryEntry *e = NULL; | ||
| 465 | |||
| 466 | while ((e = av_dict_get(*opts, "", e, AV_DICT_IGNORE_SUFFIX))) { | ||
| 467 | if ((ret = av_opt_set(s->dct, e->key, e->value, 0)) < 0) | ||
| 468 | return ret; | ||
| 469 | } | ||
| 470 | av_dict_free(opts); | ||
| 471 | } | ||
| 472 | |||
| 473 | s->store_slice = store_slice_c; | ||
| 474 | switch (s->mode) { | ||
| 475 | case MODE_HARD: s->requantize = hardthresh_c; break; | ||
| 476 | case MODE_SOFT: s->requantize = softthresh_c; break; | ||
| 477 | } | ||
| 478 | return 0; | 468 | return 0; |
| 479 | } | 469 | } |
| 480 | 470 | ||
| @@ -508,7 +498,7 @@ const AVFilter ff_vf_spp = { · 27 unmodified lines | |||
| 508 | .name = "spp", | 498 | .name = "spp", |
| 509 | .description = NULL_IF_CONFIG_SMALL("Apply a simple post processing filter."), | 499 | .description = NULL_IF_CONFIG_SMALL("Apply a simple post processing filter."), |
| 510 | .priv_size = sizeof(SPPContext), | 500 | .priv_size = sizeof(SPPContext), |
| 511 | .init_dict = init_dict, | 501 | .preinit = preinit, |
| 512 | .uninit = uninit, | 502 | .uninit = uninit, |
| 513 | .query_formats = query_formats, | 503 | .query_formats = query_formats, |
| 514 | FILTER_INPUTS(spp_inputs), | 504 | FILTER_INPUTS(spp_inputs), |