You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	af_resample: switch to an AVOptions-based system.
This commit is contained in:
		| @@ -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, | ||||
|  | ||||
|   | ||||
| @@ -501,11 +501,12 @@ int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (filter->filter->init) { | ||||
|     if (filter->filter->init) | ||||
|         ret = filter->filter->init(filter, args); | ||||
|         if (ret < 0) | ||||
|             goto fail; | ||||
|     } | ||||
|     else if (filter->filter->init_dict) | ||||
|         ret = filter->filter->init_dict(filter, &options); | ||||
|     if (ret < 0) | ||||
|         goto fail; | ||||
|  | ||||
|     if ((e = av_dict_get(options, "", NULL, AV_DICT_IGNORE_SUFFIX))) { | ||||
|         av_log(filter, AV_LOG_ERROR, "No such option: %s.\n", e->key); | ||||
|   | ||||
| @@ -408,6 +408,13 @@ typedef struct AVFilter { | ||||
|      */ | ||||
|     int (*init)(AVFilterContext *ctx, const char *args); | ||||
|  | ||||
|     /** | ||||
|      * Should be set instead of init by the filters that want to pass a | ||||
|      * dictionary of AVOptions to nested contexts that are allocated in | ||||
|      * init. | ||||
|      */ | ||||
|     int (*init_dict)(AVFilterContext *ctx, AVDictionary **options); | ||||
|  | ||||
|     /** | ||||
|      * Filter uninitialization function. Should deallocate any memory held | ||||
|      * by the filter, release any buffer references, etc. This does not need | ||||
|   | ||||
		Reference in New Issue
	
	Block a user