diff --git a/src/output/Init.cxx b/src/output/Init.cxx
index 42af034e9..67d33f85e 100644
--- a/src/output/Init.cxx
+++ b/src/output/Init.cxx
@@ -295,7 +295,7 @@ audio_output_new(EventLoop &event_loop,
 			      plugin->name);
 	}
 
-	AudioOutput *ao = ao_plugin_init(plugin, block);
+	AudioOutput *ao = ao_plugin_init(*plugin, block);
 	assert(ao != nullptr);
 
 	try {
diff --git a/src/output/OutputPlugin.cxx b/src/output/OutputPlugin.cxx
index 7c8d5b1f3..23048167f 100644
--- a/src/output/OutputPlugin.cxx
+++ b/src/output/OutputPlugin.cxx
@@ -22,13 +22,12 @@
 #include "Internal.hxx"
 
 AudioOutput *
-ao_plugin_init(const AudioOutputPlugin *plugin,
+ao_plugin_init(const AudioOutputPlugin &plugin,
 	       const ConfigBlock &block)
 {
-	assert(plugin != nullptr);
-	assert(plugin->init != nullptr);
+	assert(plugin.init != nullptr);
 
-	return plugin->init(block);
+	return plugin.init(block);
 }
 
 void
@@ -38,68 +37,68 @@ ao_plugin_finish(AudioOutput *ao)
 }
 
 void
-ao_plugin_enable(AudioOutput *ao)
+ao_plugin_enable(AudioOutput &ao)
 {
-	if (ao->plugin.enable != nullptr)
-		ao->plugin.enable(ao);
+	if (ao.plugin.enable != nullptr)
+		ao.plugin.enable(&ao);
 }
 
 void
-ao_plugin_disable(AudioOutput *ao)
+ao_plugin_disable(AudioOutput &ao)
 {
-	if (ao->plugin.disable != nullptr)
-		ao->plugin.disable(ao);
+	if (ao.plugin.disable != nullptr)
+		ao.plugin.disable(&ao);
 }
 
 void
-ao_plugin_open(AudioOutput *ao, AudioFormat &audio_format)
+ao_plugin_open(AudioOutput &ao, AudioFormat &audio_format)
 {
-	ao->plugin.open(ao, audio_format);
+	ao.plugin.open(&ao, audio_format);
 }
 
 void
-ao_plugin_close(AudioOutput *ao)
+ao_plugin_close(AudioOutput &ao)
 {
-	ao->plugin.close(ao);
+	ao.plugin.close(&ao);
 }
 
 std::chrono::steady_clock::duration
-ao_plugin_delay(AudioOutput *ao)
+ao_plugin_delay(AudioOutput &ao)
 {
-	return ao->plugin.delay != nullptr
-		? ao->plugin.delay(ao)
+	return ao.plugin.delay != nullptr
+		? ao.plugin.delay(&ao)
 		: std::chrono::steady_clock::duration::zero();
 }
 
 void
-ao_plugin_send_tag(AudioOutput *ao, const Tag &tag)
+ao_plugin_send_tag(AudioOutput &ao, const Tag &tag)
 {
-	if (ao->plugin.send_tag != nullptr)
-		ao->plugin.send_tag(ao, tag);
+	if (ao.plugin.send_tag != nullptr)
+		ao.plugin.send_tag(&ao, tag);
 }
 
 size_t
-ao_plugin_play(AudioOutput *ao, const void *chunk, size_t size)
+ao_plugin_play(AudioOutput &ao, const void *chunk, size_t size)
 {
-	return ao->plugin.play(ao, chunk, size);
+	return ao.plugin.play(&ao, chunk, size);
 }
 
 void
-ao_plugin_drain(AudioOutput *ao)
+ao_plugin_drain(AudioOutput &ao)
 {
-	if (ao->plugin.drain != nullptr)
-		ao->plugin.drain(ao);
+	if (ao.plugin.drain != nullptr)
+		ao.plugin.drain(&ao);
 }
 
 void
-ao_plugin_cancel(AudioOutput *ao)
+ao_plugin_cancel(AudioOutput &ao)
 {
-	if (ao->plugin.cancel != nullptr)
-		ao->plugin.cancel(ao);
+	if (ao.plugin.cancel != nullptr)
+		ao.plugin.cancel(&ao);
 }
 
 bool
-ao_plugin_pause(AudioOutput *ao)
+ao_plugin_pause(AudioOutput &ao)
 {
-	return ao->plugin.pause != nullptr && ao->plugin.pause(ao);
+	return ao.plugin.pause != nullptr && ao.plugin.pause(&ao);
 }
diff --git a/src/output/OutputPlugin.hxx b/src/output/OutputPlugin.hxx
index 22c520b59..f1231bda8 100644
--- a/src/output/OutputPlugin.hxx
+++ b/src/output/OutputPlugin.hxx
@@ -162,41 +162,41 @@ ao_plugin_test_default_device(const AudioOutputPlugin *plugin)
 
 gcc_malloc
 AudioOutput *
-ao_plugin_init(const AudioOutputPlugin *plugin,
+ao_plugin_init(const AudioOutputPlugin &plugin,
 	       const ConfigBlock &block);
 
 void
 ao_plugin_finish(AudioOutput *ao);
 
 void
-ao_plugin_enable(AudioOutput *ao);
+ao_plugin_enable(AudioOutput &ao);
 
 void
-ao_plugin_disable(AudioOutput *ao);
+ao_plugin_disable(AudioOutput &ao);
 
 void
-ao_plugin_open(AudioOutput *ao, AudioFormat &audio_format);
+ao_plugin_open(AudioOutput &ao, AudioFormat &audio_format);
 
 void
-ao_plugin_close(AudioOutput *ao);
+ao_plugin_close(AudioOutput &ao);
 
 gcc_pure
 std::chrono::steady_clock::duration
-ao_plugin_delay(AudioOutput *ao);
+ao_plugin_delay(AudioOutput &ao);
 
 void
-ao_plugin_send_tag(AudioOutput *ao, const Tag &tag);
+ao_plugin_send_tag(AudioOutput &ao, const Tag &tag);
 
 size_t
-ao_plugin_play(AudioOutput *ao, const void *chunk, size_t size);
+ao_plugin_play(AudioOutput &ao, const void *chunk, size_t size);
 
 void
-ao_plugin_drain(AudioOutput *ao);
+ao_plugin_drain(AudioOutput &ao);
 
 void
-ao_plugin_cancel(AudioOutput *ao);
+ao_plugin_cancel(AudioOutput &ao);
 
 bool
-ao_plugin_pause(AudioOutput *ao);
+ao_plugin_pause(AudioOutput &ao);
 
 #endif
diff --git a/src/output/OutputThread.cxx b/src/output/OutputThread.cxx
index c2ee2ccfc..71e7c5409 100644
--- a/src/output/OutputThread.cxx
+++ b/src/output/OutputThread.cxx
@@ -64,7 +64,7 @@ AudioOutput::Enable()
 
 	try {
 		const ScopeUnlock unlock(mutex);
-		ao_plugin_enable(this);
+		ao_plugin_enable(*this);
 	} catch (const std::runtime_error &e) {
 		std::throw_with_nested(FormatRuntimeError("Failed to enable output \"%s\" [%s]",
 							  name, plugin.name));
@@ -83,7 +83,7 @@ AudioOutput::Disable()
 		really_enabled = false;
 
 		const ScopeUnlock unlock(mutex);
-		ao_plugin_disable(this);
+		ao_plugin_disable(*this);
 	}
 }
 
@@ -168,7 +168,7 @@ AudioOutput::OpenOutputAndConvert(AudioFormat desired_audio_format)
 	out_audio_format = desired_audio_format;
 
 	try {
-		ao_plugin_open(this, out_audio_format);
+		ao_plugin_open(*this, out_audio_format);
 	} catch (const std::runtime_error &e) {
 		std::throw_with_nested(FormatRuntimeError("Failed to open \"%s\" [%s]",
 							  name, plugin.name));
@@ -182,7 +182,7 @@ AudioOutput::OpenOutputAndConvert(AudioFormat desired_audio_format)
 	try {
 		convert_filter_set(convert_filter.Get(), out_audio_format);
 	} catch (const std::runtime_error &e) {
-		ao_plugin_close(this);
+		ao_plugin_close(*this);
 
 		if (out_audio_format.format == SampleFormat::DSD) {
 			/* if the audio output supports DSD, but not
@@ -224,11 +224,11 @@ inline void
 AudioOutput::CloseOutput(bool drain)
 {
 	if (drain)
-		ao_plugin_drain(this);
+		ao_plugin_drain(*this);
 	else
-		ao_plugin_cancel(this);
+		ao_plugin_cancel(*this);
 
-	ao_plugin_close(this);
+	ao_plugin_close(*this);
 }
 
 /**
@@ -241,7 +241,7 @@ inline bool
 AudioOutput::WaitForDelay()
 {
 	while (true) {
-		const auto delay = ao_plugin_delay(this);
+		const auto delay = ao_plugin_delay(*this);
 		if (delay <= std::chrono::steady_clock::duration::zero())
 			return true;
 
@@ -276,7 +276,7 @@ AudioOutput::PlayChunk()
 		if (tag != nullptr) {
 			const ScopeUnlock unlock(mutex);
 			try {
-				ao_plugin_send_tag(this, *tag);
+				ao_plugin_send_tag(*this, *tag);
 			} catch (const std::runtime_error &e) {
 				FormatError(e, "Failed to send tag to \"%s\" [%s]",
 					    name, plugin.name);
@@ -296,7 +296,7 @@ AudioOutput::PlayChunk()
 
 		try {
 			const ScopeUnlock unlock(mutex);
-			nbytes = ao_plugin_play(this, data.data, data.size);
+			nbytes = ao_plugin_play(*this, data.data, data.size);
 		} catch (const std::runtime_error &e) {
 			FormatError(e, "\"%s\" [%s] failed to play",
 				    name, plugin.name);
@@ -368,7 +368,7 @@ AudioOutput::Pause()
 {
 	{
 		const ScopeUnlock unlock(mutex);
-		ao_plugin_cancel(this);
+		ao_plugin_cancel(*this);
 	}
 
 	pause = true;
@@ -381,7 +381,7 @@ AudioOutput::Pause()
 		bool success;
 		try {
 			const ScopeUnlock unlock(mutex);
-			success = ao_plugin_pause(this);
+			success = ao_plugin_pause(*this);
 		} catch (const std::runtime_error &e) {
 			FormatError(e, "\"%s\" [%s] failed to pause",
 				    name, plugin.name);
@@ -477,7 +477,7 @@ AudioOutput::Task()
 		case Command::DRAIN:
 			if (open) {
 				const ScopeUnlock unlock(mutex);
-				ao_plugin_drain(this);
+				ao_plugin_drain(*this);
 			}
 
 			CommandFinished();
@@ -488,7 +488,7 @@ AudioOutput::Task()
 
 			if (open) {
 				const ScopeUnlock unlock(mutex);
-				ao_plugin_cancel(this);
+				ao_plugin_cancel(*this);
 			}
 
 			CommandFinished();
diff --git a/test/run_output.cxx b/test/run_output.cxx
index bf3c31205..37954378b 100644
--- a/test/run_output.cxx
+++ b/test/run_output.cxx
@@ -77,15 +77,15 @@ load_audio_output(EventLoop &event_loop, AudioOutputClient &client,
 }
 
 static void
-run_output(AudioOutput *ao, AudioFormat audio_format)
+run_output(AudioOutput &ao, AudioFormat audio_format)
 {
 	/* open the audio output */
 
 	ao_plugin_enable(ao);
-	AtScopeExit(ao) { ao_plugin_disable(ao); };
+	AtScopeExit(&ao) { ao_plugin_disable(ao); };
 
 	ao_plugin_open(ao, audio_format);
-	AtScopeExit(ao) { ao_plugin_close(ao); };
+	AtScopeExit(&ao) { ao_plugin_close(ao); };
 
 	fprintf(stderr, "audio_format=%s\n",
 		ToString(audio_format).c_str());
@@ -152,7 +152,7 @@ try {
 
 	/* do it */
 
-	run_output(ao, audio_format);
+	run_output(*ao, audio_format);
 
 	/* cleanup and exit */