diff --git a/src/output/Control.cxx b/src/output/Control.cxx
index 4b062a1a5..8a91f22c7 100644
--- a/src/output/Control.cxx
+++ b/src/output/Control.cxx
@@ -37,13 +37,21 @@ static constexpr PeriodClock::Duration REOPEN_AFTER = std::chrono::seconds(10);
 
 struct notify audio_output_client_notify;
 
-AudioOutputControl::AudioOutputControl(FilteredAudioOutput *_output,
+AudioOutputControl::AudioOutputControl(std::unique_ptr<FilteredAudioOutput> _output,
 				       AudioOutputClient &_client) noexcept
-	:output(_output), client(_client),
+	:output(std::move(_output)), client(_client),
 	 thread(BIND_THIS_METHOD(Task))
 {
 }
 
+AudioOutputControl::~AudioOutputControl() noexcept
+{
+	assert(!fail_timer.IsDefined());
+	assert(!thread.IsDefined());
+	assert(output == nullptr);
+	assert(!open);
+}
+
 void
 AudioOutputControl::Configure(const ConfigBlock &block)
 {
@@ -377,6 +385,5 @@ AudioOutputControl::FinishDestroy() noexcept
 	if (thread.IsDefined())
 		thread.Join();
 
-	delete output;
-	output = nullptr;
+	output.reset();
 }
diff --git a/src/output/Control.hxx b/src/output/Control.hxx
index ecf9388f1..8e8226f37 100644
--- a/src/output/Control.hxx
+++ b/src/output/Control.hxx
@@ -30,6 +30,7 @@
 
 #include <utility>
 #include <exception>
+#include <memory>
 #include <string>
 #include <map>
 
@@ -52,7 +53,7 @@ class AudioOutputClient;
  * Controller for an #AudioOutput and its output thread.
  */
 class AudioOutputControl {
-	FilteredAudioOutput *output;
+	std::unique_ptr<FilteredAudioOutput> output;
 
 	/**
 	 * The PlayerControl object which "owns" this output.  This
@@ -211,17 +212,10 @@ public:
 	 */
 	mutable Mutex mutex;
 
-	AudioOutputControl(FilteredAudioOutput *_output,
+	AudioOutputControl(std::unique_ptr<FilteredAudioOutput> _output,
 			   AudioOutputClient &_client) noexcept;
 
-#ifndef NDEBUG
-	~AudioOutputControl() noexcept {
-		assert(!fail_timer.IsDefined());
-		assert(!thread.IsDefined());
-		assert(output == nullptr);
-		assert(!open);
-	}
-#endif
+	~AudioOutputControl() noexcept;
 
 	AudioOutputControl(const AudioOutputControl &) = delete;
 	AudioOutputControl &operator=(const AudioOutputControl &) = delete;
diff --git a/src/output/Filtered.hxx b/src/output/Filtered.hxx
index 0bf96a824..1d20bad17 100644
--- a/src/output/Filtered.hxx
+++ b/src/output/Filtered.hxx
@@ -239,7 +239,7 @@ extern struct notify audio_output_client_notify;
 /**
  * Throws #std::runtime_error on error.
  */
-FilteredAudioOutput *
+std::unique_ptr<FilteredAudioOutput>
 audio_output_new(EventLoop &event_loop,
 		 const ReplayGainConfig &replay_gain_config,
 		 const ConfigBlock &block,
diff --git a/src/output/Init.cxx b/src/output/Init.cxx
index 57f8b21d5..f2a441330 100644
--- a/src/output/Init.cxx
+++ b/src/output/Init.cxx
@@ -259,7 +259,7 @@ FilteredAudioOutput::Setup(EventLoop &event_loop,
 			    convert_filter.Set(convert_filter_prepare()));
 }
 
-FilteredAudioOutput *
+std::unique_ptr<FilteredAudioOutput>
 audio_output_new(EventLoop &event_loop,
 		 const ReplayGainConfig &replay_gain_config,
 		 const ConfigBlock &block,
@@ -292,16 +292,10 @@ audio_output_new(EventLoop &event_loop,
 						       block));
 	assert(ao != nullptr);
 
-	auto *f = new FilteredAudioOutput(plugin->name, std::move(ao), block);
-
-	try {
-		f->Setup(event_loop, replay_gain_config,
-			 plugin->mixer_plugin,
-			 mixer_listener, block);
-	} catch (...) {
-		delete f;
-		throw;
-	}
-
+	auto f = std::make_unique<FilteredAudioOutput>(plugin->name,
+						       std::move(ao), block);
+	f->Setup(event_loop, replay_gain_config,
+		 plugin->mixer_plugin,
+		 mixer_listener, block);
 	return f;
 }
diff --git a/src/output/MultipleOutputs.cxx b/src/output/MultipleOutputs.cxx
index 0b84c3ca3..e31309427 100644
--- a/src/output/MultipleOutputs.cxx
+++ b/src/output/MultipleOutputs.cxx
@@ -51,7 +51,7 @@ MultipleOutputs::~MultipleOutputs() noexcept
 		delete i;
 }
 
-static FilteredAudioOutput *
+static std::unique_ptr<FilteredAudioOutput>
 LoadOutput(EventLoop &event_loop,
 	   const ReplayGainConfig &replay_gain_config,
 	   MixerListener &mixer_listener,
@@ -73,10 +73,10 @@ LoadOutputControl(EventLoop &event_loop,
 		  MixerListener &mixer_listener,
 		  AudioOutputClient &client, const ConfigBlock &block)
 {
-	auto *output = LoadOutput(event_loop, replay_gain_config,
-				  mixer_listener,
-				  block);
-	auto *control = new AudioOutputControl(output, client);
+	auto output = LoadOutput(event_loop, replay_gain_config,
+				 mixer_listener,
+				 block);
+	auto *control = new AudioOutputControl(std::move(output), client);
 
 	try {
 		control->Configure(block);