DecoderList.cxx 5.78 KB
Newer Older
1
/*
2
 * Copyright (C) 2003-2013 The Music Player Daemon Project
3
 * 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 "config.h"
21
#include "DecoderList.hxx"
22
#include "DecoderPlugin.hxx"
23 24
#include "ConfigGlobal.hxx"
#include "ConfigData.hxx"
25
#include "decoder/AudiofileDecoderPlugin.hxx"
26
#include "decoder/PcmDecoderPlugin.hxx"
27 28
#include "decoder/DsdiffDecoderPlugin.hxx"
#include "decoder/DsfDecoderPlugin.hxx"
29
#include "decoder/FlacDecoderPlugin.h"
30
#include "decoder/OpusDecoderPlugin.h"
31
#include "decoder/VorbisDecoderPlugin.h"
32
#include "decoder/AdPlugDecoderPlugin.h"
33
#include "decoder/WavpackDecoderPlugin.hxx"
34
#include "decoder/FfmpegDecoderPlugin.hxx"
35
#include "decoder/GmeDecoderPlugin.hxx"
36
#include "decoder/FaadDecoderPlugin.hxx"
37
#include "decoder/MadDecoderPlugin.hxx"
38
#include "decoder/SndfileDecoderPlugin.hxx"
39
#include "decoder/Mpg123DecoderPlugin.hxx"
40
#include "decoder/WildmidiDecoderPlugin.hxx"
41
#include "decoder/MikmodDecoderPlugin.hxx"
42
#include "decoder/ModplugDecoderPlugin.hxx"
43
#include "decoder/MpcdecDecoderPlugin.hxx"
44
#include "decoder/FluidsynthDecoderPlugin.hxx"
45
#include "system/FatalError.hxx"
46
#include "util/Macros.hxx"
47

48 49
#include <string.h>

50
extern const struct decoder_plugin sidplay_decoder_plugin;
51

52
const struct decoder_plugin *const decoder_plugins[] = {
53
#ifdef HAVE_MAD
54
	&mad_decoder_plugin,
55
#endif
56 57 58
#ifdef HAVE_MPG123
	&mpg123_decoder_plugin,
#endif
59
#ifdef ENABLE_VORBIS_DECODER
Max Kellermann's avatar
Max Kellermann committed
60
	&vorbis_decoder_plugin,
61
#endif
62
#if defined(HAVE_FLAC)
Max Kellermann's avatar
Max Kellermann committed
63
	&oggflac_decoder_plugin,
64 65
#endif
#ifdef HAVE_FLAC
Max Kellermann's avatar
Max Kellermann committed
66
	&flac_decoder_plugin,
67
#endif
68 69 70
#ifdef HAVE_OPUS
	&opus_decoder_plugin,
#endif
71 72 73
#ifdef ENABLE_SNDFILE
	&sndfile_decoder_plugin,
#endif
74
#ifdef HAVE_AUDIOFILE
75
	&audiofile_decoder_plugin,
76
#endif
77
	&dsdiff_decoder_plugin,
78
	&dsf_decoder_plugin,
79
#ifdef HAVE_FAAD
80
	&faad_decoder_plugin,
81 82
#endif
#ifdef HAVE_MPCDEC
83
	&mpcdec_decoder_plugin,
84 85
#endif
#ifdef HAVE_WAVPACK
86
	&wavpack_decoder_plugin,
87
#endif
88
#ifdef HAVE_MODPLUG
89
	&modplug_decoder_plugin,
90
#endif
91
#ifdef ENABLE_MIKMOD_DECODER
92
	&mikmod_decoder_plugin,
93
#endif
94 95 96
#ifdef ENABLE_SIDPLAY
	&sidplay_decoder_plugin,
#endif
97 98 99
#ifdef ENABLE_WILDMIDI
	&wildmidi_decoder_plugin,
#endif
100 101 102
#ifdef ENABLE_FLUIDSYNTH
	&fluidsynth_decoder_plugin,
#endif
103 104 105
#ifdef HAVE_ADPLUG
	&adplug_decoder_plugin,
#endif
106
#ifdef HAVE_FFMPEG
107
	&ffmpeg_decoder_plugin,
108 109 110
#endif
#ifdef HAVE_GME
	&gme_decoder_plugin,
111
#endif
112
	&pcm_decoder_plugin,
113
	NULL
114
};
115

116 117
static constexpr unsigned num_decoder_plugins =
	ARRAY_SIZE(decoder_plugins) - 1;
118

119
/** which plugins have been initialized successfully? */
120
bool decoder_plugins_enabled[num_decoder_plugins];
121

122 123
static unsigned
decoder_plugin_index(const struct decoder_plugin *plugin)
Avuton Olrich's avatar
Avuton Olrich committed
124
{
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
	unsigned i = 0;

	while (decoder_plugins[i] != plugin)
		++i;

	return i;
}

static unsigned
decoder_plugin_next_index(const struct decoder_plugin *plugin)
{
	return plugin == 0
		? 0 /* start with first plugin */
		: decoder_plugin_index(plugin) + 1;
}
Avuton Olrich's avatar
Avuton Olrich committed
140

141 142 143 144
const struct decoder_plugin *
decoder_plugin_from_suffix(const char *suffix,
			   const struct decoder_plugin *plugin)
{
Avuton Olrich's avatar
Avuton Olrich committed
145 146
	if (suffix == NULL)
		return NULL;
147

148 149 150
	for (unsigned i = decoder_plugin_next_index(plugin);
	     decoder_plugins[i] != NULL; ++i) {
		plugin = decoder_plugins[i];
151
		if (decoder_plugins_enabled[i] &&
152
		    decoder_plugin_supports_suffix(plugin, suffix))
153 154 155 156 157 158
			return plugin;
	}

	return NULL;
}

159 160
const struct decoder_plugin *
decoder_plugin_from_mime_type(const char *mimeType, unsigned int next)
Avuton Olrich's avatar
Avuton Olrich committed
161
{
162
	static unsigned i = num_decoder_plugins;
Avuton Olrich's avatar
Avuton Olrich committed
163 164 165

	if (mimeType == NULL)
		return NULL;
166

167 168
	if (!next)
		i = 0;
169
	for (; decoder_plugins[i] != NULL; ++i) {
170
		const struct decoder_plugin *plugin = decoder_plugins[i];
171
		if (decoder_plugins_enabled[i] &&
172
		    decoder_plugin_supports_mime_type(plugin, mimeType)) {
173
			++i;
174 175 176 177 178 179 180
			return plugin;
		}
	}

	return NULL;
}

181 182
const struct decoder_plugin *
decoder_plugin_from_name(const char *name)
Avuton Olrich's avatar
Avuton Olrich committed
183
{
184 185
	decoder_plugins_for_each_enabled(plugin)
		if (strcmp(plugin->name, name) == 0)
186
			return plugin;
187

188
	return NULL;
189 190
}

191 192 193 194 195 196 197 198 199 200 201 202
/**
 * 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) {
203
		const char *name = param->GetBlockValue("plugin");
204
		if (name == NULL)
205 206
			FormatFatalError("decoder configuration without 'plugin' name in line %d",
					 param->line);
207 208 209 210 211 212 213 214

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

	return NULL;
}

215
void decoder_plugin_init_all(void)
Avuton Olrich's avatar
Avuton Olrich committed
216
{
217 218
	struct config_param empty;

219
	for (unsigned i = 0; decoder_plugins[i] != NULL; ++i) {
220
		const struct decoder_plugin *plugin = decoder_plugins[i];
221 222
		const struct config_param *param =
			decoder_plugin_config(plugin->name);
223

224 225 226
		if (param == nullptr)
			param = &empty;
		else if (!param->GetBlockValue("enabled", true))
227 228 229
			/* the plugin is disabled in mpd.conf */
			continue;

230
		if (decoder_plugin_init(plugin, *param))
231 232
			decoder_plugins_enabled[i] = true;
	}
233 234
}

235
void decoder_plugin_deinit_all(void)
Avuton Olrich's avatar
Avuton Olrich committed
236
{
237 238
	decoder_plugins_for_each_enabled(plugin)
		decoder_plugin_finish(plugin);
239
}