Initial filter chain and filter configuration for outputs.
This commit is contained in:
		 Albin Eldstål-Damlin
					Albin Eldstål-Damlin
				
			
				
					committed by
					
						 Max Kellermann
						Max Kellermann
					
				
			
			
				
	
			
			
			 Max Kellermann
						Max Kellermann
					
				
			
						parent
						
							e28c5a0beb
						
					
				
				
					commit
					a4fbf772c1
				
			| @@ -42,6 +42,7 @@ | ||||
| #define CONF_PASSWORD                   "password" | ||||
| #define CONF_DEFAULT_PERMS              "default_permissions" | ||||
| #define CONF_AUDIO_OUTPUT               "audio_output" | ||||
| #define CONF_AUDIO_FILTER               "filter" | ||||
| #define CONF_AUDIO_OUTPUT_FORMAT        "audio_output_format" | ||||
| #define CONF_MIXER_TYPE                 "mixer_type" | ||||
| #define CONF_REPLAYGAIN                 "replaygain" | ||||
| @@ -73,6 +74,8 @@ | ||||
| #define DEFAULT_PLAYLIST_MAX_LENGTH (1024*16) | ||||
| #define DEFAULT_PLAYLIST_SAVE_ABSOLUTE_PATHS false | ||||
|  | ||||
| #define MAX_FILTER_CHAIN_LENGTH 255 | ||||
|  | ||||
| struct block_param { | ||||
| 	char *name; | ||||
| 	char *value; | ||||
|   | ||||
| @@ -18,12 +18,14 @@ | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
| #include "conf.h" | ||||
| #include "filter/chain_filter_plugin.h" | ||||
| #include "filter_plugin.h" | ||||
| #include "filter_internal.h" | ||||
| #include "filter_registry.h" | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <string.h> | ||||
|  | ||||
| struct filter_chain { | ||||
| 	/** the base class */ | ||||
| @@ -176,3 +178,100 @@ filter_chain_append(struct filter *_chain, struct filter *filter) | ||||
|  | ||||
| 	chain->children = g_slist_append(chain->children, filter); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Find the "filter" configuration block for the specified name. | ||||
|  * | ||||
|  * @param filter_template_name the name of the filter template | ||||
|  * @return the configuration block, or NULL if none was configured | ||||
|  */ | ||||
| static const struct config_param * | ||||
| filter_plugin_config(const char *filter_template_name) | ||||
| { | ||||
| 	const struct config_param *param = NULL; | ||||
|  | ||||
| 	while ((param = config_get_next_param(CONF_AUDIO_FILTER, param)) != NULL) { | ||||
| 		const char *name = | ||||
| 			config_get_block_string(param, "name", NULL); | ||||
| 		if (name == NULL) | ||||
| 			g_error("filter configuration without 'name' name in line %d", | ||||
| 				param->line); | ||||
|  | ||||
| 		if (strcmp(name, filter_template_name) == 0) | ||||
| 			return param; | ||||
| 	} | ||||
|  | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Builds a filter chain from a configuration string on the form | ||||
|  * "name1, name2, name3, ..." by looking up each name among the | ||||
|  * configured filter sections. | ||||
|  * @param chain the chain to append filters on | ||||
|  * @param spec the filter chain specification | ||||
|  * @return the number of filters which were successfully added | ||||
|  */ | ||||
| unsigned int | ||||
| filter_chain_parse(struct filter *chain, const char *spec) { | ||||
|  | ||||
| 	// Split on comma | ||||
| 	gchar** tokens = g_strsplit_set(spec, ",", 255); | ||||
|  | ||||
| 	int added_filters = 0; | ||||
|  | ||||
| 	// Add each name to the filter chain by instantiating an actual filter | ||||
| 	char **template_names = tokens; | ||||
| 	while (*template_names != NULL) { | ||||
| 		const char *plugin_name; | ||||
| 		const struct filter_plugin *fp; | ||||
| 		struct filter *f; | ||||
| 		const struct config_param *cfg; | ||||
|  | ||||
| 		// Squeeze whitespace | ||||
| 		g_strstrip(*template_names); | ||||
|  | ||||
| 		cfg = filter_plugin_config(*template_names); | ||||
| 		if (cfg == NULL) { | ||||
| 			g_error("Unable to locate filter template %s", | ||||
| 				*template_names); | ||||
| 			++template_names; | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		// Figure out what kind of a plugin that is | ||||
| 		plugin_name = config_get_block_string(cfg, "plugin", NULL); | ||||
| 		if (plugin_name == NULL) { | ||||
| 			g_error("filter configuration without 'plugin' at line %d", | ||||
| 				cfg->line); | ||||
| 			++template_names; | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		// Instantiate one of those filter plugins with the template name as a hint | ||||
| 		fp = filter_plugin_by_name(plugin_name); | ||||
| 		if (fp == NULL) { | ||||
| 			g_error("filter plugin not found: %s", | ||||
| 				plugin_name); | ||||
| 			++template_names; | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		f = filter_new(fp, cfg, NULL); | ||||
| 		if (f == NULL) { | ||||
| 			g_error("filter plugin initialization failed: %s", | ||||
| 				plugin_name); | ||||
| 			++template_names; | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		filter_chain_append(chain, f); | ||||
| 		++added_filters; | ||||
|  | ||||
| 		++template_names; | ||||
| 	} | ||||
|  | ||||
| 	g_strfreev(tokens); | ||||
|  | ||||
| 	return added_filters; | ||||
| } | ||||
|   | ||||
| @@ -45,4 +45,16 @@ filter_chain_new(void); | ||||
| void | ||||
| filter_chain_append(struct filter *chain, struct filter *filter); | ||||
|  | ||||
| /** | ||||
|  * Builds a filter chain from a configuration string on the form | ||||
|  * "name1, name2, name3, ..." by looking up each name among the | ||||
|  * configured filter sections. If no filters are specified, a | ||||
|  * null filter is automatically appended. | ||||
|  * @param chain the chain to append filters on | ||||
|  * @param spec the filter chain specification | ||||
|  * @return the number of filters which were successfully added | ||||
|  */ | ||||
| unsigned int | ||||
| filter_chain_parse(struct filter *chain, const char *spec); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -41,6 +41,7 @@ | ||||
| #define AUDIO_OUTPUT_TYPE	"type" | ||||
| #define AUDIO_OUTPUT_NAME	"name" | ||||
| #define AUDIO_OUTPUT_FORMAT	"format" | ||||
| #define AUDIO_FILTERS		"filters" | ||||
|  | ||||
| static const struct audio_output_plugin * | ||||
| audio_output_detect(GError **error) | ||||
| @@ -190,6 +191,9 @@ audio_output_init(struct audio_output *ao, const struct config_param *param, | ||||
|  | ||||
| 	ao->filter = filter_chain_new(); | ||||
| 	assert(ao->filter != NULL); | ||||
| 	filter_chain_parse(ao->filter, | ||||
| 	                   config_get_block_string(param, AUDIO_FILTERS, "") | ||||
| 	); | ||||
|  | ||||
| 	ao->thread = NULL; | ||||
| 	ao->command = AO_COMMAND_NONE; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user