encoder/Plugin: migrate from class Error to C++ exceptions
This commit is contained in:
		| @@ -28,6 +28,7 @@ | ||||
|  | ||||
| struct AudioFormat; | ||||
| struct Tag; | ||||
| class Error; | ||||
|  | ||||
| class Encoder { | ||||
| 	const bool implements_tag; | ||||
|   | ||||
| @@ -22,27 +22,27 @@ | ||||
|  | ||||
| class PreparedEncoder; | ||||
| struct ConfigBlock; | ||||
| class Error; | ||||
|  | ||||
| struct EncoderPlugin { | ||||
| 	const char *name; | ||||
|  | ||||
| 	PreparedEncoder *(*init)(const ConfigBlock &block, | ||||
| 				 Error &error); | ||||
| 	/** | ||||
| 	 * Throws #std::runtime_error on error. | ||||
| 	 */ | ||||
| 	PreparedEncoder *(*init)(const ConfigBlock &block); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Creates a new encoder object. | ||||
|  * | ||||
|  * Throws #std::runtime_error on error. | ||||
|  * | ||||
|  * @param plugin the encoder plugin | ||||
|  * @param error location to store the error occurring, or nullptr to ignore errors. | ||||
|  * @return an encoder object on success, nullptr on failure | ||||
|  */ | ||||
| static inline PreparedEncoder * | ||||
| encoder_init(const EncoderPlugin &plugin, const ConfigBlock &block, | ||||
| 	     Error &error) | ||||
| encoder_init(const EncoderPlugin &plugin, const ConfigBlock &block) | ||||
| { | ||||
| 	return plugin.init(block, error); | ||||
| 	return plugin.init(block); | ||||
| } | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -89,10 +89,10 @@ private: | ||||
| }; | ||||
|  | ||||
| class PreparedFlacEncoder final : public PreparedEncoder { | ||||
| 	unsigned compression; | ||||
| 	const unsigned compression; | ||||
|  | ||||
| public: | ||||
| 	bool Configure(const ConfigBlock &block, Error &error); | ||||
| 	PreparedFlacEncoder(const ConfigBlock &block); | ||||
|  | ||||
| 	/* virtual methods from class PreparedEncoder */ | ||||
| 	Encoder *Open(AudioFormat &audio_format, Error &) override; | ||||
| @@ -104,26 +104,15 @@ public: | ||||
|  | ||||
| static constexpr Domain flac_encoder_domain("vorbis_encoder"); | ||||
|  | ||||
| bool | ||||
| PreparedFlacEncoder::Configure(const ConfigBlock &block, Error &) | ||||
| PreparedFlacEncoder::PreparedFlacEncoder(const ConfigBlock &block) | ||||
| 	:compression(block.GetBlockValue("compression", 5u)) | ||||
| { | ||||
| 	compression = block.GetBlockValue("compression", 5u); | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| static PreparedEncoder * | ||||
| flac_encoder_init(const ConfigBlock &block, Error &error) | ||||
| flac_encoder_init(const ConfigBlock &block) | ||||
| { | ||||
| 	auto *encoder = new PreparedFlacEncoder(); | ||||
|  | ||||
| 	/* load configuration from "block" */ | ||||
| 	if (!encoder->Configure(block, error)) { | ||||
| 		/* configuration has failed, roll back and return error */ | ||||
| 		delete encoder; | ||||
| 		return nullptr; | ||||
| 	} | ||||
|  | ||||
| 	return encoder; | ||||
| 	return new PreparedFlacEncoder(block); | ||||
| } | ||||
|  | ||||
| static bool | ||||
|   | ||||
| @@ -24,6 +24,7 @@ | ||||
| #include "config/ConfigError.hxx" | ||||
| #include "util/NumberParser.hxx" | ||||
| #include "util/ReusableArray.hxx" | ||||
| #include "util/RuntimeError.hxx" | ||||
| #include "util/Error.hxx" | ||||
| #include "util/Domain.hxx" | ||||
|  | ||||
| @@ -58,7 +59,7 @@ class PreparedLameEncoder final : public PreparedEncoder { | ||||
| 	int bitrate; | ||||
|  | ||||
| public: | ||||
| 	bool Configure(const ConfigBlock &block, Error &error); | ||||
| 	PreparedLameEncoder(const ConfigBlock &block); | ||||
|  | ||||
| 	/* virtual methods from class PreparedEncoder */ | ||||
| 	Encoder *Open(AudioFormat &audio_format, Error &) override; | ||||
| @@ -70,8 +71,7 @@ public: | ||||
|  | ||||
| static constexpr Domain lame_encoder_domain("lame_encoder"); | ||||
|  | ||||
| bool | ||||
| PreparedLameEncoder::Configure(const ConfigBlock &block, Error &error) | ||||
| PreparedLameEncoder::PreparedLameEncoder(const ConfigBlock &block) | ||||
| { | ||||
| 	const char *value; | ||||
| 	char *endptr; | ||||
| @@ -82,55 +82,32 @@ PreparedLameEncoder::Configure(const ConfigBlock &block, Error &error) | ||||
|  | ||||
| 		quality = ParseDouble(value, &endptr); | ||||
|  | ||||
| 		if (*endptr != '\0' || quality < -1.0 || quality > 10.0) { | ||||
| 			error.Format(config_domain, | ||||
| 				     "quality \"%s\" is not a number in the " | ||||
| 				     "range -1 to 10", | ||||
| 				     value); | ||||
| 			return false; | ||||
| 		} | ||||
| 		if (*endptr != '\0' || quality < -1.0 || quality > 10.0) | ||||
| 			throw FormatRuntimeError("quality \"%s\" is not a number in the " | ||||
| 						 "range -1 to 10", | ||||
| 						 value); | ||||
|  | ||||
| 		if (block.GetBlockValue("bitrate") != nullptr) { | ||||
| 			error.Set(config_domain, | ||||
| 				  "quality and bitrate are both defined"); | ||||
| 			return false; | ||||
| 		} | ||||
| 		if (block.GetBlockValue("bitrate") != nullptr) | ||||
| 			throw std::runtime_error("quality and bitrate are both defined"); | ||||
| 	} else { | ||||
| 		/* a bit rate was configured */ | ||||
|  | ||||
| 		value = block.GetBlockValue("bitrate"); | ||||
| 		if (value == nullptr) { | ||||
| 			error.Set(config_domain, | ||||
| 				  "neither bitrate nor quality defined"); | ||||
| 			return false; | ||||
| 		} | ||||
| 		if (value == nullptr) | ||||
| 			throw std::runtime_error("neither bitrate nor quality defined"); | ||||
|  | ||||
| 		quality = -2.0; | ||||
| 		bitrate = ParseInt(value, &endptr); | ||||
|  | ||||
| 		if (*endptr != '\0' || bitrate <= 0) { | ||||
| 			error.Set(config_domain, | ||||
| 				  "bitrate should be a positive integer"); | ||||
| 			return false; | ||||
| 		} | ||||
| 		if (*endptr != '\0' || bitrate <= 0) | ||||
| 			throw std::runtime_error("bitrate should be a positive integer"); | ||||
| 	} | ||||
|  | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| static PreparedEncoder * | ||||
| lame_encoder_init(const ConfigBlock &block, Error &error) | ||||
| lame_encoder_init(const ConfigBlock &block) | ||||
| { | ||||
| 	auto *encoder = new PreparedLameEncoder(); | ||||
|  | ||||
| 	/* load configuration from "block" */ | ||||
| 	if (!encoder->Configure(block, error)) { | ||||
| 		/* configuration has failed, roll back and return error */ | ||||
| 		delete encoder; | ||||
| 		return nullptr; | ||||
| 	} | ||||
|  | ||||
| 	return encoder; | ||||
| 	return new PreparedLameEncoder(block); | ||||
| } | ||||
|  | ||||
| static bool | ||||
|   | ||||
| @@ -51,8 +51,7 @@ public: | ||||
| }; | ||||
|  | ||||
| static PreparedEncoder * | ||||
| null_encoder_init(gcc_unused const ConfigBlock &block, | ||||
| 		  gcc_unused Error &error) | ||||
| null_encoder_init(gcc_unused const ConfigBlock &block) | ||||
| { | ||||
| 	return new PreparedNullEncoder(); | ||||
| } | ||||
|   | ||||
| @@ -30,6 +30,8 @@ | ||||
| #include <opus.h> | ||||
| #include <ogg/ogg.h> | ||||
|  | ||||
| #include <stdexcept> | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <stdlib.h> | ||||
|  | ||||
| @@ -78,7 +80,7 @@ class PreparedOpusEncoder final : public PreparedEncoder { | ||||
| 	int signal; | ||||
|  | ||||
| public: | ||||
| 	bool Configure(const ConfigBlock &block, Error &error); | ||||
| 	PreparedOpusEncoder(const ConfigBlock &block); | ||||
|  | ||||
| 	/* virtual methods from class PreparedEncoder */ | ||||
| 	Encoder *Open(AudioFormat &audio_format, Error &) override; | ||||
| @@ -90,8 +92,7 @@ public: | ||||
|  | ||||
| static constexpr Domain opus_encoder_domain("opus_encoder"); | ||||
|  | ||||
| bool | ||||
| PreparedOpusEncoder::Configure(const ConfigBlock &block, Error &error) | ||||
| PreparedOpusEncoder::PreparedOpusEncoder(const ConfigBlock &block) | ||||
| { | ||||
| 	const char *value = block.GetBlockValue("bitrate", "auto"); | ||||
| 	if (strcmp(value, "auto") == 0) | ||||
| @@ -102,17 +103,13 @@ PreparedOpusEncoder::Configure(const ConfigBlock &block, Error &error) | ||||
| 		char *endptr; | ||||
| 		bitrate = strtoul(value, &endptr, 10); | ||||
| 		if (endptr == value || *endptr != 0 || | ||||
| 		    bitrate < 500 || bitrate > 512000) { | ||||
| 			error.Set(config_domain, "Invalid bit rate"); | ||||
| 			return false; | ||||
| 		} | ||||
| 		    bitrate < 500 || bitrate > 512000) | ||||
| 			throw std::runtime_error("Invalid bit rate"); | ||||
| 	} | ||||
|  | ||||
| 	complexity = block.GetBlockValue("complexity", 10u); | ||||
| 	if (complexity > 10) { | ||||
| 		error.Format(config_domain, "Invalid complexity"); | ||||
| 		return false; | ||||
| 	} | ||||
| 	if (complexity > 10) | ||||
| 		throw std::runtime_error("Invalid complexity"); | ||||
|  | ||||
| 	value = block.GetBlockValue("signal", "auto"); | ||||
| 	if (strcmp(value, "auto") == 0) | ||||
| @@ -121,27 +118,14 @@ PreparedOpusEncoder::Configure(const ConfigBlock &block, Error &error) | ||||
| 		signal = OPUS_SIGNAL_VOICE; | ||||
| 	else if (strcmp(value, "music") == 0) | ||||
| 		signal = OPUS_SIGNAL_MUSIC; | ||||
| 	else { | ||||
| 		error.Format(config_domain, "Invalid signal"); | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	return true; | ||||
| 	else | ||||
| 		throw std::runtime_error("Invalid signal"); | ||||
| } | ||||
|  | ||||
| static PreparedEncoder * | ||||
| opus_encoder_init(const ConfigBlock &block, Error &error) | ||||
| opus_encoder_init(const ConfigBlock &block) | ||||
| { | ||||
| 	auto *encoder = new PreparedOpusEncoder(); | ||||
|  | ||||
| 	/* load configuration from "block" */ | ||||
| 	if (!encoder->Configure(block, error)) { | ||||
| 		/* configuration has failed, roll back and return error */ | ||||
| 		delete encoder; | ||||
| 		return nullptr; | ||||
| 	} | ||||
|  | ||||
| 	return encoder; | ||||
| 	return new PreparedOpusEncoder(block); | ||||
| } | ||||
|  | ||||
| OpusEncoder::OpusEncoder(AudioFormat &_audio_format, ::OpusEncoder *_enc) | ||||
|   | ||||
| @@ -88,7 +88,7 @@ class PreparedShineEncoder final : public PreparedEncoder { | ||||
| 	shine_config_t config; | ||||
|  | ||||
| public: | ||||
| 	bool Configure(const ConfigBlock &block, Error &error); | ||||
| 	PreparedShineEncoder(const ConfigBlock &block); | ||||
|  | ||||
| 	/* virtual methods from class PreparedEncoder */ | ||||
| 	Encoder *Open(AudioFormat &audio_format, Error &) override; | ||||
| @@ -98,28 +98,16 @@ public: | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| inline bool | ||||
| PreparedShineEncoder::Configure(const ConfigBlock &block, Error &) | ||||
| PreparedShineEncoder::PreparedShineEncoder(const ConfigBlock &block) | ||||
| { | ||||
| 	shine_set_config_mpeg_defaults(&config.mpeg); | ||||
| 	config.mpeg.bitr = block.GetBlockValue("bitrate", 128); | ||||
|  | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| static PreparedEncoder * | ||||
| shine_encoder_init(const ConfigBlock &block, Error &error) | ||||
| shine_encoder_init(const ConfigBlock &block) | ||||
| { | ||||
| 	auto *encoder = new PreparedShineEncoder(); | ||||
|  | ||||
| 	/* load configuration from "block" */ | ||||
| 	if (!encoder->Configure(block, error)) { | ||||
| 		/* configuration has failed, roll back and return error */ | ||||
| 		delete encoder; | ||||
| 		return nullptr; | ||||
| 	} | ||||
|  | ||||
| 	return encoder; | ||||
| 	return new PreparedShineEncoder(block); | ||||
| } | ||||
|  | ||||
| static shine_t | ||||
|   | ||||
| @@ -23,6 +23,7 @@ | ||||
| #include "AudioFormat.hxx" | ||||
| #include "config/ConfigError.hxx" | ||||
| #include "util/NumberParser.hxx" | ||||
| #include "util/RuntimeError.hxx" | ||||
| #include "util/Error.hxx" | ||||
| #include "util/Domain.hxx" | ||||
| #include "Log.hxx" | ||||
| @@ -77,7 +78,7 @@ class PreparedTwolameEncoder final : public PreparedEncoder { | ||||
| 	int bitrate; | ||||
|  | ||||
| public: | ||||
| 	bool Configure(const ConfigBlock &block, Error &error); | ||||
| 	PreparedTwolameEncoder(const ConfigBlock &block); | ||||
|  | ||||
| 	/* virtual methods from class PreparedEncoder */ | ||||
| 	Encoder *Open(AudioFormat &audio_format, Error &) override; | ||||
| @@ -89,8 +90,7 @@ public: | ||||
|  | ||||
| static constexpr Domain twolame_encoder_domain("twolame_encoder"); | ||||
|  | ||||
| bool | ||||
| PreparedTwolameEncoder::Configure(const ConfigBlock &block, Error &error) | ||||
| PreparedTwolameEncoder::PreparedTwolameEncoder(const ConfigBlock &block) | ||||
| { | ||||
| 	const char *value; | ||||
| 	char *endptr; | ||||
| @@ -101,58 +101,35 @@ PreparedTwolameEncoder::Configure(const ConfigBlock &block, Error &error) | ||||
|  | ||||
| 		quality = ParseDouble(value, &endptr); | ||||
|  | ||||
| 		if (*endptr != '\0' || quality < -1.0 || quality > 10.0) { | ||||
| 			error.Format(config_domain, | ||||
| 				     "quality \"%s\" is not a number in the " | ||||
| 				     "range -1 to 10", | ||||
| 				     value); | ||||
| 			return false; | ||||
| 		} | ||||
| 		if (*endptr != '\0' || quality < -1.0 || quality > 10.0) | ||||
| 			throw FormatRuntimeError("quality \"%s\" is not a number in the " | ||||
| 						 "range -1 to 10", | ||||
| 						 value); | ||||
|  | ||||
| 		if (block.GetBlockValue("bitrate") != nullptr) { | ||||
| 			error.Set(config_domain, | ||||
| 				  "quality and bitrate are both defined"); | ||||
| 			return false; | ||||
| 		} | ||||
| 		if (block.GetBlockValue("bitrate") != nullptr) | ||||
| 			throw std::runtime_error("quality and bitrate are both defined"); | ||||
| 	} else { | ||||
| 		/* a bit rate was configured */ | ||||
|  | ||||
| 		value = block.GetBlockValue("bitrate"); | ||||
| 		if (value == nullptr) { | ||||
| 			error.Set(config_domain, | ||||
| 				  "neither bitrate nor quality defined"); | ||||
| 			return false; | ||||
| 		} | ||||
| 		if (value == nullptr) | ||||
| 			throw std::runtime_error("neither bitrate nor quality defined"); | ||||
|  | ||||
| 		quality = -2.0; | ||||
| 		bitrate = ParseInt(value, &endptr); | ||||
|  | ||||
| 		if (*endptr != '\0' || bitrate <= 0) { | ||||
| 			error.Set(config_domain, | ||||
| 				  "bitrate should be a positive integer"); | ||||
| 			return false; | ||||
| 		} | ||||
| 		if (*endptr != '\0' || bitrate <= 0) | ||||
| 			throw std::runtime_error("bitrate should be a positive integer"); | ||||
| 	} | ||||
|  | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| static PreparedEncoder * | ||||
| twolame_encoder_init(const ConfigBlock &block, Error &error_r) | ||||
| twolame_encoder_init(const ConfigBlock &block) | ||||
| { | ||||
| 	FormatDebug(twolame_encoder_domain, | ||||
| 		    "libtwolame version %s", get_twolame_version()); | ||||
|  | ||||
| 	auto *encoder = new PreparedTwolameEncoder(); | ||||
|  | ||||
| 	/* load configuration from "block" */ | ||||
| 	if (!encoder->Configure(block, error_r)) { | ||||
| 		/* configuration has failed, roll back and return error */ | ||||
| 		delete encoder; | ||||
| 		return nullptr; | ||||
| 	} | ||||
|  | ||||
| 	return encoder; | ||||
| 	return new PreparedTwolameEncoder(block); | ||||
| } | ||||
|  | ||||
| static bool | ||||
|   | ||||
| @@ -25,6 +25,7 @@ | ||||
| #include "config/ConfigError.hxx" | ||||
| #include "util/StringUtil.hxx" | ||||
| #include "util/NumberParser.hxx" | ||||
| #include "util/RuntimeError.hxx" | ||||
| #include "util/Error.hxx" | ||||
| #include "util/Domain.hxx" | ||||
|  | ||||
| @@ -73,7 +74,7 @@ class PreparedVorbisEncoder final : public PreparedEncoder { | ||||
| 	int bitrate; | ||||
|  | ||||
| public: | ||||
| 	bool Configure(const ConfigBlock &block, Error &error); | ||||
| 	PreparedVorbisEncoder(const ConfigBlock &block); | ||||
|  | ||||
| 	/* virtual methods from class PreparedEncoder */ | ||||
| 	Encoder *Open(AudioFormat &audio_format, Error &) override; | ||||
| @@ -85,8 +86,7 @@ public: | ||||
|  | ||||
| static constexpr Domain vorbis_encoder_domain("vorbis_encoder"); | ||||
|  | ||||
| bool | ||||
| PreparedVorbisEncoder::Configure(const ConfigBlock &block, Error &error) | ||||
| PreparedVorbisEncoder::PreparedVorbisEncoder(const ConfigBlock &block) | ||||
| { | ||||
| 	const char *value = block.GetBlockValue("quality"); | ||||
| 	if (value != nullptr) { | ||||
| @@ -95,56 +95,33 @@ PreparedVorbisEncoder::Configure(const ConfigBlock &block, Error &error) | ||||
| 		char *endptr; | ||||
| 		quality = ParseDouble(value, &endptr); | ||||
|  | ||||
| 		if (*endptr != '\0' || quality < -1.0 || quality > 10.0) { | ||||
| 			error.Format(config_domain, | ||||
| 				     "quality \"%s\" is not a number in the " | ||||
| 				     "range -1 to 10", | ||||
| 				     value); | ||||
| 			return false; | ||||
| 		} | ||||
| 		if (*endptr != '\0' || quality < -1.0 || quality > 10.0) | ||||
| 			throw FormatRuntimeError("quality \"%s\" is not a number in the " | ||||
| 						 "range -1 to 10", | ||||
| 						 value); | ||||
|  | ||||
| 		if (block.GetBlockValue("bitrate") != nullptr) { | ||||
| 			error.Set(config_domain, | ||||
| 				  "quality and bitrate are both defined"); | ||||
| 			return false; | ||||
| 		} | ||||
| 		if (block.GetBlockValue("bitrate") != nullptr) | ||||
| 			throw std::runtime_error("quality and bitrate are both defined"); | ||||
| 	} else { | ||||
| 		/* a bit rate was configured */ | ||||
|  | ||||
| 		value = block.GetBlockValue("bitrate"); | ||||
| 		if (value == nullptr) { | ||||
| 			error.Set(config_domain, | ||||
| 				  "neither bitrate nor quality defined"); | ||||
| 			return false; | ||||
| 		} | ||||
| 		if (value == nullptr) | ||||
| 			throw std::runtime_error("neither bitrate nor quality defined"); | ||||
|  | ||||
| 		quality = -2.0; | ||||
|  | ||||
| 		char *endptr; | ||||
| 		bitrate = ParseInt(value, &endptr); | ||||
| 		if (*endptr != '\0' || bitrate <= 0) { | ||||
| 			error.Set(config_domain, | ||||
| 				  "bitrate should be a positive integer"); | ||||
| 			return false; | ||||
| 		} | ||||
| 		if (*endptr != '\0' || bitrate <= 0) | ||||
| 			throw std::runtime_error("bitrate should be a positive integer"); | ||||
| 	} | ||||
|  | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| static PreparedEncoder * | ||||
| vorbis_encoder_init(const ConfigBlock &block, Error &error) | ||||
| vorbis_encoder_init(const ConfigBlock &block) | ||||
| { | ||||
| 	auto *encoder = new PreparedVorbisEncoder(); | ||||
|  | ||||
| 	/* load configuration from "block" */ | ||||
| 	if (!encoder->Configure(block, error)) { | ||||
| 		/* configuration has failed, roll back and return error */ | ||||
| 		delete encoder; | ||||
| 		return nullptr; | ||||
| 	} | ||||
|  | ||||
| 	return encoder; | ||||
| 	return new PreparedVorbisEncoder(block); | ||||
| } | ||||
|  | ||||
| bool | ||||
|   | ||||
| @@ -98,8 +98,7 @@ fill_wave_header(WaveHeader *header, int channels, int bits, | ||||
| } | ||||
|  | ||||
| static PreparedEncoder * | ||||
| wave_encoder_init(gcc_unused const ConfigBlock &block, | ||||
| 		  gcc_unused Error &error) | ||||
| wave_encoder_init(gcc_unused const ConfigBlock &block) | ||||
| { | ||||
| 	return new PreparedWaveEncoder(); | ||||
| } | ||||
|   | ||||
| @@ -148,9 +148,7 @@ RecorderOutput::Configure(const ConfigBlock &block, Error &error) | ||||
|  | ||||
| 	/* initialize encoder */ | ||||
|  | ||||
| 	prepared_encoder = encoder_init(*encoder_plugin, block, error); | ||||
| 	if (prepared_encoder == nullptr) | ||||
| 		return false; | ||||
| 	prepared_encoder = encoder_init(*encoder_plugin, block); | ||||
|  | ||||
| 	return true; | ||||
| } | ||||
| @@ -160,14 +158,19 @@ RecorderOutput::Create(const ConfigBlock &block, Error &error) | ||||
| { | ||||
| 	RecorderOutput *recorder = new RecorderOutput(); | ||||
|  | ||||
| 	if (!recorder->Initialize(block, error)) { | ||||
| 		delete recorder; | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	try { | ||||
| 		if (!recorder->Initialize(block, error)) { | ||||
| 			delete recorder; | ||||
| 			return nullptr; | ||||
| 		} | ||||
|  | ||||
| 	if (!recorder->Configure(block, error)) { | ||||
| 		if (!recorder->Configure(block, error)) { | ||||
| 			delete recorder; | ||||
| 			return nullptr; | ||||
| 		} | ||||
| 	} catch (...) { | ||||
| 		delete recorder; | ||||
| 		return nullptr; | ||||
| 		throw; | ||||
| 	} | ||||
|  | ||||
| 	return recorder; | ||||
|   | ||||
| @@ -194,9 +194,7 @@ ShoutOutput::Configure(const ConfigBlock &block, Error &error) | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	prepared_encoder = encoder_init(*encoder_plugin, block, error); | ||||
| 	if (prepared_encoder == nullptr) | ||||
| 		return false; | ||||
| 	prepared_encoder = encoder_init(*encoder_plugin, block); | ||||
|  | ||||
| 	unsigned shout_format; | ||||
| 	if (strcmp(encoding, "mp3") == 0 || strcmp(encoding, "lame") == 0) | ||||
| @@ -304,9 +302,14 @@ ShoutOutput::Create(const ConfigBlock &block, Error &error) | ||||
| 		return nullptr; | ||||
| 	} | ||||
|  | ||||
| 	if (!sd->Configure(block, error)) { | ||||
| 	try { | ||||
| 		if (!sd->Configure(block, error)) { | ||||
| 			delete sd; | ||||
| 			return nullptr; | ||||
| 		} | ||||
| 	} catch (...) { | ||||
| 		delete sd; | ||||
| 		return nullptr; | ||||
| 		throw; | ||||
| 	} | ||||
|  | ||||
| 	return sd; | ||||
|   | ||||
| @@ -117,9 +117,7 @@ HttpdOutput::Configure(const ConfigBlock &block, Error &error) | ||||
|  | ||||
| 	/* initialize encoder */ | ||||
|  | ||||
| 	prepared_encoder = encoder_init(*encoder_plugin, block, error); | ||||
| 	if (prepared_encoder == nullptr) | ||||
| 		return false; | ||||
| 	prepared_encoder = encoder_init(*encoder_plugin, block); | ||||
|  | ||||
| 	/* determine content type */ | ||||
| 	content_type = prepared_encoder->GetMimeType(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Max Kellermann
					Max Kellermann