decoder_list.c 5.75 KB
Newer Older
1 2 3
/*
 * Copyright (C) 2003-2009 The Music Player Daemon Project
 * http://www.musicpd.org
Warren Dukes's avatar
Warren Dukes committed
4 5 6 7 8 9 10 11 12 13
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
14 15 16 17
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Warren Dukes's avatar
Warren Dukes committed
18 19
 */

20
#include "decoder_list.h"
21
#include "decoder_plugin.h"
22
#include "utils.h"
23
#include "config.h"
24
#include "conf.h"
25 26

#include <glib.h>
27

28 29
#include <string.h>

30
extern const struct decoder_plugin mad_decoder_plugin;
Max Kellermann's avatar
Max Kellermann committed
31
extern const struct decoder_plugin vorbis_decoder_plugin;
Max Kellermann's avatar
Max Kellermann committed
32 33
extern const struct decoder_plugin flac_decoder_plugin;
extern const struct decoder_plugin oggflac_decoder_plugin;
34
extern const struct decoder_plugin audiofile_decoder_plugin;
35
extern const struct decoder_plugin mp4ff_decoder_plugin;
36
extern const struct decoder_plugin faad_decoder_plugin;
37
extern const struct decoder_plugin mpcdec_decoder_plugin;
38 39
extern const struct decoder_plugin wavpack_decoder_plugin;
extern const struct decoder_plugin modplug_decoder_plugin;
40
extern const struct decoder_plugin mikmod_decoder_plugin;
41
extern const struct decoder_plugin sidplay_decoder_plugin;
42
extern const struct decoder_plugin wildmidi_decoder_plugin;
43
extern const struct decoder_plugin fluidsynth_decoder_plugin;
44
extern const struct decoder_plugin ffmpeg_decoder_plugin;
45

46 47
static const struct decoder_plugin *const decoder_plugins[] = {
#ifdef HAVE_MAD
48
	&mad_decoder_plugin,
49
#endif
50
#ifdef ENABLE_VORBIS_DECODER
Max Kellermann's avatar
Max Kellermann committed
51
	&vorbis_decoder_plugin,
52
#endif
53
#if defined(HAVE_FLAC) || defined(HAVE_OGGFLAC)
Max Kellermann's avatar
Max Kellermann committed
54
	&oggflac_decoder_plugin,
55 56
#endif
#ifdef HAVE_FLAC
Max Kellermann's avatar
Max Kellermann committed
57
	&flac_decoder_plugin,
58 59
#endif
#ifdef HAVE_AUDIOFILE
60
	&audiofile_decoder_plugin,
61 62
#endif
#ifdef HAVE_FAAD
63
	&faad_decoder_plugin,
64
#endif
65
#ifdef HAVE_MP4
66
	&mp4ff_decoder_plugin,
67
#endif
68
#ifdef HAVE_MPCDEC
69
	&mpcdec_decoder_plugin,
70 71
#endif
#ifdef HAVE_WAVPACK
72
	&wavpack_decoder_plugin,
73
#endif
74
#ifdef HAVE_MODPLUG
75
	&modplug_decoder_plugin,
76
#endif
77
#ifdef ENABLE_MIKMOD_DECODER
78
	&mikmod_decoder_plugin,
79
#endif
80 81 82
#ifdef ENABLE_SIDPLAY
	&sidplay_decoder_plugin,
#endif
83 84 85
#ifdef ENABLE_WILDMIDI
	&wildmidi_decoder_plugin,
#endif
86 87 88
#ifdef ENABLE_FLUIDSYNTH
	&fluidsynth_decoder_plugin,
#endif
89
#ifdef HAVE_FFMPEG
90
	&ffmpeg_decoder_plugin,
91 92
#endif
};
93

94 95 96
enum {
	num_decoder_plugins = G_N_ELEMENTS(decoder_plugins),
};
97

98 99
/** which plugins have been initialized successfully? */
static bool decoder_plugins_enabled[num_decoder_plugins];
100

101 102
const struct decoder_plugin *
decoder_plugin_from_suffix(const char *suffix, unsigned int next)
Avuton Olrich's avatar
Avuton Olrich committed
103
{
104
	static unsigned i = num_decoder_plugins;
Avuton Olrich's avatar
Avuton Olrich committed
105 106 107

	if (suffix == NULL)
		return NULL;
108

109 110 111 112 113 114 115
	if (!next)
		i = 0;
	for (; i < num_decoder_plugins; ++i) {
		const struct decoder_plugin *plugin = decoder_plugins[i];
		if (decoder_plugins_enabled[i] &&
		    stringFoundInStringArray(plugin->suffixes, suffix)) {
			++i;
116 117 118 119 120 121 122
			return plugin;
		}
	}

	return NULL;
}

123 124
const struct decoder_plugin *
decoder_plugin_from_mime_type(const char *mimeType, unsigned int next)
Avuton Olrich's avatar
Avuton Olrich committed
125
{
126
	static unsigned i = num_decoder_plugins;
Avuton Olrich's avatar
Avuton Olrich committed
127 128 129

	if (mimeType == NULL)
		return NULL;
130

131 132 133 134 135 136 137
	if (!next)
		i = 0;
	for (; i < num_decoder_plugins; ++i) {
		const struct decoder_plugin *plugin = decoder_plugins[i];
		if (decoder_plugins_enabled[i] &&
		    stringFoundInStringArray(plugin->mime_types, mimeType)) {
			++i;
138 139 140 141 142 143 144
			return plugin;
		}
	}

	return NULL;
}

145 146
const struct decoder_plugin *
decoder_plugin_from_name(const char *name)
Avuton Olrich's avatar
Avuton Olrich committed
147
{
148 149 150 151 152 153
	for (unsigned i = 0; i < num_decoder_plugins; ++i) {
		const struct decoder_plugin *plugin = decoder_plugins[i];
		if (decoder_plugins_enabled[i] &&
		    strcmp(plugin->name, name) == 0)
			return plugin;
	}
154

155
	return NULL;
156 157
}

158
void decoder_plugin_print_all_decoders(FILE * fp)
Avuton Olrich's avatar
Avuton Olrich committed
159
{
160 161
	for (unsigned i = 0; i < num_decoder_plugins; ++i) {
		const struct decoder_plugin *plugin = decoder_plugins[i];
162 163
		const char *const*suffixes;

164 165 166
		if (!decoder_plugins_enabled[i])
			continue;

167
		fprintf(fp, "[%s]", plugin->name);
168

169 170 171 172 173
		for (suffixes = plugin->suffixes;
		     suffixes != NULL && *suffixes != NULL;
		     ++suffixes) {
			fprintf(fp, " %s", *suffixes);
		}
174

175
		fprintf(fp, "\n");
176 177 178
	}
}

179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
/**
 * Find the "decoder" configuration block for the specified plugin.
 *
 * @param plugin_name the name of the decoder plugin
 * @return the configuration block, or NULL if none was configured
 */
static const struct config_param *
decoder_plugin_config(const char *plugin_name)
{
	const struct config_param *param = NULL;

	while ((param = config_get_next_param(CONF_DECODER, param)) != NULL) {
		const char *name =
			config_get_block_string(param, "plugin", NULL);
		if (name == NULL)
			g_error("decoder configuration without 'plugin' name in line %d",
				param->line);

		if (strcmp(name, plugin_name) == 0)
			return param;
	}

	return NULL;
}

204
void decoder_plugin_init_all(void)
Avuton Olrich's avatar
Avuton Olrich committed
205
{
206 207
	for (unsigned i = 0; i < num_decoder_plugins; ++i) {
		const struct decoder_plugin *plugin = decoder_plugins[i];
208 209
		const struct config_param *param =
			decoder_plugin_config(plugin->name);
210

211 212 213 214
		if (!config_get_block_bool(param, "enabled", true))
			/* the plugin is disabled in mpd.conf */
			continue;

215
		if (decoder_plugin_init(plugin, param))
216 217
			decoder_plugins_enabled[i] = true;
	}
218 219
}

220
void decoder_plugin_deinit_all(void)
Avuton Olrich's avatar
Avuton Olrich committed
221
{
222 223
	for (unsigned i = 0; i < num_decoder_plugins; ++i) {
		const struct decoder_plugin *plugin = decoder_plugins[i];
224 225 226

		if (decoder_plugins_enabled[i])
			decoder_plugin_finish(plugin);
227
	}
228
}