diff --git a/Makefile.am b/Makefile.am
index 13834dc10..8cd35b9a1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -55,8 +55,6 @@ mpd_headers = \
 	src/filter_internal.h \
 	src/command.h \
 	src/conf.h \
-	src/encoder_plugin.h \
-	src/encoder_api.h \
 	src/fd_util.h \
 	src/gerror.h \
 	src/glib_compat.h \
@@ -639,6 +637,8 @@ ENCODER_LIBS = \
 	$(VORBISENC_LIBS)
 
 libencoder_plugins_a_SOURCES = \
+	src/EncoderAPI.hxx \
+	src/EncoderPlugin.hxx \
 	src/encoder/OggStream.hxx \
 	src/encoder/NullEncoderPlugin.cxx src/encoder/NullEncoderPlugin.hxx \
 	src/EncoderList.cxx src/EncoderList.hxx
diff --git a/src/CommandLine.cxx b/src/CommandLine.cxx
index 194bf3e2b..1e0e028ec 100644
--- a/src/CommandLine.cxx
+++ b/src/CommandLine.cxx
@@ -36,7 +36,7 @@
 
 #ifdef ENABLE_ENCODER
 #include "EncoderList.hxx"
-#include "encoder_plugin.h"
+#include "EncoderPlugin.hxx"
 #endif
 
 #ifdef ENABLE_ARCHIVE
diff --git a/src/encoder_api.h b/src/EncoderAPI.hxx
similarity index 85%
rename from src/encoder_api.h
rename to src/EncoderAPI.hxx
index 46c8d10c8..bd874fa41 100644
--- a/src/encoder_api.h
+++ b/src/EncoderAPI.hxx
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
  * http://www.musicpd.org
  *
  * This program is free software; you can redistribute it and/or modify
@@ -22,10 +22,10 @@
  *
  */
 
-#ifndef MPD_ENCODER_API_H
-#define MPD_ENCODER_API_H
+#ifndef MPD_ENCODER_API_HXX
+#define MPD_ENCODER_API_HXX
 
-#include "encoder_plugin.h"
+#include "EncoderPlugin.hxx"
 #include "audio_format.h"
 #include "tag.h"
 #include "conf.h"
diff --git a/src/EncoderList.cxx b/src/EncoderList.cxx
index e89140f47..2305548b9 100644
--- a/src/EncoderList.cxx
+++ b/src/EncoderList.cxx
@@ -19,7 +19,7 @@
 
 #include "config.h"
 #include "EncoderList.hxx"
-#include "encoder_plugin.h"
+#include "EncoderPlugin.hxx"
 #include "encoder/NullEncoderPlugin.hxx"
 #include "encoder/WaveEncoderPlugin.hxx"
 #include "encoder/VorbisEncoderPlugin.hxx"
@@ -30,7 +30,7 @@
 
 #include <string.h>
 
-const struct encoder_plugin *const encoder_plugins[] = {
+const EncoderPlugin *const encoder_plugins[] = {
 	&null_encoder_plugin,
 #ifdef ENABLE_VORBIS_ENCODER
 	&vorbis_encoder_plugin,
@@ -53,7 +53,7 @@ const struct encoder_plugin *const encoder_plugins[] = {
 	NULL
 };
 
-const struct encoder_plugin *
+const EncoderPlugin *
 encoder_plugin_get(const char *name)
 {
 	encoder_plugins_for_each(plugin)
diff --git a/src/EncoderList.hxx b/src/EncoderList.hxx
index 69ee8e2bc..feaf7a6d1 100644
--- a/src/EncoderList.hxx
+++ b/src/EncoderList.hxx
@@ -20,12 +20,12 @@
 #ifndef MPD_ENCODER_LIST_HXX
 #define MPD_ENCODER_LIST_HXX
 
-struct encoder_plugin;
+struct EncoderPlugin;
 
-extern const struct encoder_plugin *const encoder_plugins[];
+extern const EncoderPlugin *const encoder_plugins[];
 
 #define encoder_plugins_for_each(plugin) \
-	for (const struct encoder_plugin *plugin, \
+	for (const EncoderPlugin *plugin, \
 		*const*encoder_plugin_iterator = &encoder_plugins[0]; \
 		(plugin = *encoder_plugin_iterator) != NULL; \
 		++encoder_plugin_iterator)
@@ -37,7 +37,7 @@ extern const struct encoder_plugin *const encoder_plugins[];
  * @return the encoder plugin with the specified name, or NULL if none
  * was found
  */
-const struct encoder_plugin *
+const EncoderPlugin *
 encoder_plugin_get(const char *name);
 
 #endif
diff --git a/src/encoder_plugin.h b/src/EncoderPlugin.hxx
similarity index 69%
rename from src/encoder_plugin.h
rename to src/EncoderPlugin.hxx
index e0748a136..9336b2693 100644
--- a/src/encoder_plugin.h
+++ b/src/EncoderPlugin.hxx
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
  * http://www.musicpd.org
  *
  * This program is free software; you can redistribute it and/or modify
@@ -17,8 +17,8 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#ifndef MPD_ENCODER_PLUGIN_H
-#define MPD_ENCODER_PLUGIN_H
+#ifndef MPD_ENCODER_PLUGIN_HXX
+#define MPD_ENCODER_PLUGIN_HXX
 
 #include "gerror.h"
 
@@ -26,66 +26,58 @@
 #include <stdbool.h>
 #include <stddef.h>
 
-struct encoder_plugin;
+struct EncoderPlugin;
 struct audio_format;
 struct config_param;
 struct tag;
 
-struct encoder {
-	const struct encoder_plugin *plugin;
+struct Encoder {
+	const EncoderPlugin &plugin;
 
 #ifndef NDEBUG
 	bool open, pre_tag, tag, end;
 #endif
+
+	explicit Encoder(const EncoderPlugin &_plugin)
+		:plugin(_plugin)
+#ifndef NDEBUG
+		, open(false)
+#endif
+	{}
 };
 
-struct encoder_plugin {
+struct EncoderPlugin {
 	const char *name;
 
-	struct encoder *(*init)(const struct config_param *param,
-				GError **error);
+	Encoder *(*init)(const struct config_param *param,
+			 GError **error);
 
-	void (*finish)(struct encoder *encoder);
+	void (*finish)(Encoder *encoder);
 
-	bool (*open)(struct encoder *encoder,
+	bool (*open)(Encoder *encoder,
 		     struct audio_format *audio_format,
 		     GError **error);
 
-	void (*close)(struct encoder *encoder);
+	void (*close)(Encoder *encoder);
 
-	bool (*end)(struct encoder *encoder, GError **error);
+	bool (*end)(Encoder *encoder, GError **error);
 
-	bool (*flush)(struct encoder *encoder, GError **error);
+	bool (*flush)(Encoder *encoder, GError **error);
 
-	bool (*pre_tag)(struct encoder *encoder, GError **error);
+	bool (*pre_tag)(Encoder *encoder, GError **error);
 
-	bool (*tag)(struct encoder *encoder, const struct tag *tag,
+	bool (*tag)(Encoder *encoder, const struct tag *tag,
 		    GError **error);
 
-	bool (*write)(struct encoder *encoder,
+	bool (*write)(Encoder *encoder,
 		      const void *data, size_t length,
 		      GError **error);
 
-	size_t (*read)(struct encoder *encoder, void *dest, size_t length);
+	size_t (*read)(Encoder *encoder, void *dest, size_t length);
 
-	const char *(*get_mime_type)(struct encoder *encoder);
+	const char *(*get_mime_type)(Encoder *encoder);
 };
 
-/**
- * Initializes an encoder object.  This should be used by encoder
- * plugins to initialize their base class.
- */
-static inline void
-encoder_struct_init(struct encoder *encoder,
-		    const struct encoder_plugin *plugin)
-{
-	encoder->plugin = plugin;
-
-#ifndef NDEBUG
-	encoder->open = false;
-#endif
-}
-
 /**
  * Creates a new encoder object.
  *
@@ -94,11 +86,11 @@ encoder_struct_init(struct encoder *encoder,
  * @param error location to store the error occurring, or NULL to ignore errors.
  * @return an encoder object on success, NULL on failure
  */
-static inline struct encoder *
-encoder_init(const struct encoder_plugin *plugin,
-	     const struct config_param *param, GError **error)
+static inline Encoder *
+encoder_init(const EncoderPlugin &plugin, const config_param *param,
+	     GError **error_r)
 {
-	return plugin->init(param, error);
+	return plugin.init(param, error_r);
 }
 
 /**
@@ -107,11 +99,11 @@ encoder_init(const struct encoder_plugin *plugin,
  * @param encoder the encoder
  */
 static inline void
-encoder_finish(struct encoder *encoder)
+encoder_finish(Encoder *encoder)
 {
 	assert(!encoder->open);
 
-	encoder->plugin->finish(encoder);
+	encoder->plugin.finish(encoder);
 }
 
 /**
@@ -130,12 +122,12 @@ encoder_finish(struct encoder *encoder)
  * @return true on success
  */
 static inline bool
-encoder_open(struct encoder *encoder, struct audio_format *audio_format,
+encoder_open(Encoder *encoder, struct audio_format *audio_format,
 	     GError **error)
 {
 	assert(!encoder->open);
 
-	bool success = encoder->plugin->open(encoder, audio_format, error);
+	bool success = encoder->plugin.open(encoder, audio_format, error);
 #ifndef NDEBUG
 	encoder->open = success;
 	encoder->pre_tag = encoder->tag = encoder->end = false;
@@ -150,12 +142,12 @@ encoder_open(struct encoder *encoder, struct audio_format *audio_format,
  * @param encoder the encoder
  */
 static inline void
-encoder_close(struct encoder *encoder)
+encoder_close(Encoder *encoder)
 {
 	assert(encoder->open);
 
-	if (encoder->plugin->close != NULL)
-		encoder->plugin->close(encoder);
+	if (encoder->plugin.close != NULL)
+		encoder->plugin.close(encoder);
 
 #ifndef NDEBUG
 	encoder->open = false;
@@ -176,7 +168,7 @@ encoder_close(struct encoder *encoder)
  * @return true on success
  */
 static inline bool
-encoder_end(struct encoder *encoder, GError **error)
+encoder_end(Encoder *encoder, GError **error)
 {
 	assert(encoder->open);
 	assert(!encoder->end);
@@ -186,8 +178,8 @@ encoder_end(struct encoder *encoder, GError **error)
 #endif
 
 	/* this method is optional */
-	return encoder->plugin->end != NULL
-		? encoder->plugin->end(encoder, error)
+	return encoder->plugin.end != NULL
+		? encoder->plugin.end(encoder, error)
 		: true;
 }
 
@@ -200,7 +192,7 @@ encoder_end(struct encoder *encoder, GError **error)
  * @return true on success
  */
 static inline bool
-encoder_flush(struct encoder *encoder, GError **error)
+encoder_flush(Encoder *encoder, GError **error)
 {
 	assert(encoder->open);
 	assert(!encoder->pre_tag);
@@ -208,8 +200,8 @@ encoder_flush(struct encoder *encoder, GError **error)
 	assert(!encoder->end);
 
 	/* this method is optional */
-	return encoder->plugin->flush != NULL
-		? encoder->plugin->flush(encoder, error)
+	return encoder->plugin.flush != NULL
+		? encoder->plugin.flush(encoder, error)
 		: true;
 }
 
@@ -224,7 +216,7 @@ encoder_flush(struct encoder *encoder, GError **error)
  * @return true on success
  */
 static inline bool
-encoder_pre_tag(struct encoder *encoder, GError **error)
+encoder_pre_tag(Encoder *encoder, GError **error)
 {
 	assert(encoder->open);
 	assert(!encoder->pre_tag);
@@ -232,8 +224,8 @@ encoder_pre_tag(struct encoder *encoder, GError **error)
 	assert(!encoder->end);
 
 	/* this method is optional */
-	bool success = encoder->plugin->pre_tag != NULL
-		? encoder->plugin->pre_tag(encoder, error)
+	bool success = encoder->plugin.pre_tag != NULL
+		? encoder->plugin.pre_tag(encoder, error)
 		: true;
 
 #ifndef NDEBUG
@@ -254,7 +246,7 @@ encoder_pre_tag(struct encoder *encoder, GError **error)
  * @return true on success
  */
 static inline bool
-encoder_tag(struct encoder *encoder, const struct tag *tag, GError **error)
+encoder_tag(Encoder *encoder, const struct tag *tag, GError **error)
 {
 	assert(encoder->open);
 	assert(!encoder->pre_tag);
@@ -266,8 +258,8 @@ encoder_tag(struct encoder *encoder, const struct tag *tag, GError **error)
 #endif
 
 	/* this method is optional */
-	return encoder->plugin->tag != NULL
-		? encoder->plugin->tag(encoder, tag, error)
+	return encoder->plugin.tag != NULL
+		? encoder->plugin.tag(encoder, tag, error)
 		: true;
 }
 
@@ -281,7 +273,7 @@ encoder_tag(struct encoder *encoder, const struct tag *tag, GError **error)
  * @return true on success
  */
 static inline bool
-encoder_write(struct encoder *encoder, const void *data, size_t length,
+encoder_write(Encoder *encoder, const void *data, size_t length,
 	      GError **error)
 {
 	assert(encoder->open);
@@ -289,7 +281,7 @@ encoder_write(struct encoder *encoder, const void *data, size_t length,
 	assert(!encoder->tag);
 	assert(!encoder->end);
 
-	return encoder->plugin->write(encoder, data, length, error);
+	return encoder->plugin.write(encoder, data, length, error);
 }
 
 /**
@@ -303,7 +295,7 @@ encoder_write(struct encoder *encoder, const void *data, size_t length,
  * @return the number of bytes written to #dest
  */
 static inline size_t
-encoder_read(struct encoder *encoder, void *dest, size_t length)
+encoder_read(Encoder *encoder, void *dest, size_t length)
 {
 	assert(encoder->open);
 	assert(!encoder->pre_tag || !encoder->tag);
@@ -315,7 +307,7 @@ encoder_read(struct encoder *encoder, void *dest, size_t length)
 	}
 #endif
 
-	return encoder->plugin->read(encoder, dest, length);
+	return encoder->plugin.read(encoder, dest, length);
 }
 
 /**
@@ -325,11 +317,11 @@ encoder_read(struct encoder *encoder, void *dest, size_t length)
  * @return an constant string, NULL on failure
  */
 static inline const char *
-encoder_get_mime_type(struct encoder *encoder)
+encoder_get_mime_type(Encoder *encoder)
 {
 	/* this method is optional */
-	return encoder->plugin->get_mime_type != NULL
-		? encoder->plugin->get_mime_type(encoder)
+	return encoder->plugin.get_mime_type != NULL
+		? encoder->plugin.get_mime_type(encoder)
 		: NULL;
 }
 
diff --git a/src/encoder/FlacEncoderPlugin.cxx b/src/encoder/FlacEncoderPlugin.cxx
index a7f551422..3aeb96cf7 100644
--- a/src/encoder/FlacEncoderPlugin.cxx
+++ b/src/encoder/FlacEncoderPlugin.cxx
@@ -19,8 +19,7 @@
 
 #include "config.h"
 #include "FlacEncoderPlugin.hxx"
-#include "encoder_api.h"
-#include "encoder_plugin.h"
+#include "EncoderAPI.hxx"
 #include "audio_format.h"
 #include "pcm/PcmBuffer.hxx"
 #include "util/fifo_buffer.h"
@@ -39,7 +38,7 @@ extern "C" {
 #endif
 
 struct flac_encoder {
-	struct encoder encoder;
+	Encoder encoder;
 
 	struct audio_format audio_format;
 	unsigned compression;
@@ -53,11 +52,10 @@ struct flac_encoder {
 	 * picked up with flac_encoder_read().
 	 */
 	struct fifo_buffer *output_buffer;
+
+	flac_encoder():encoder(flac_encoder_plugin) {}
 };
 
-extern const struct encoder_plugin flac_encoder_plugin;
-
-
 static inline GQuark
 flac_encoder_quark(void)
 {
@@ -74,18 +72,15 @@ flac_encoder_configure(struct flac_encoder *encoder,
 	return true;
 }
 
-static struct encoder *
+static Encoder *
 flac_encoder_init(const struct config_param *param, GError **error)
 {
-	struct flac_encoder *encoder;
-
-	encoder = g_new(struct flac_encoder, 1);
-	encoder_struct_init(&encoder->encoder, &flac_encoder_plugin);
+	flac_encoder *encoder = new flac_encoder();
 
 	/* load configuration from "param" */
 	if (!flac_encoder_configure(encoder, param, error)) {
 		/* configuration has failed, roll back and return error */
-		g_free(encoder);
+		delete encoder;
 		return nullptr;
 	}
 
@@ -93,13 +88,13 @@ flac_encoder_init(const struct config_param *param, GError **error)
 }
 
 static void
-flac_encoder_finish(struct encoder *_encoder)
+flac_encoder_finish(Encoder *_encoder)
 {
 	struct flac_encoder *encoder = (struct flac_encoder *)_encoder;
 
 	/* the real libFLAC cleanup was already performed by
 	   flac_encoder_close(), so no real work here */
-	g_free(encoder);
+	delete encoder;
 }
 
 static bool
@@ -154,7 +149,7 @@ flac_write_callback(G_GNUC_UNUSED const FLAC__StreamEncoder *fse,
 }
 
 static void
-flac_encoder_close(struct encoder *_encoder)
+flac_encoder_close(Encoder *_encoder)
 {
 	struct flac_encoder *encoder = (struct flac_encoder *)_encoder;
 
@@ -165,7 +160,7 @@ flac_encoder_close(struct encoder *_encoder)
 }
 
 static bool
-flac_encoder_open(struct encoder *_encoder, struct audio_format *audio_format,
+flac_encoder_open(Encoder *_encoder, struct audio_format *audio_format,
 		     GError **error)
 {
 	struct flac_encoder *encoder = (struct flac_encoder *)_encoder;
@@ -230,7 +225,7 @@ flac_encoder_open(struct encoder *_encoder, struct audio_format *audio_format,
 
 
 static bool
-flac_encoder_flush(struct encoder *_encoder, G_GNUC_UNUSED GError **error)
+flac_encoder_flush(Encoder *_encoder, G_GNUC_UNUSED GError **error)
 {
 	struct flac_encoder *encoder = (struct flac_encoder *)_encoder;
 
@@ -257,7 +252,7 @@ pcm16_to_flac(int32_t *out, const int16_t *in, unsigned num_samples)
 }
 
 static bool
-flac_encoder_write(struct encoder *_encoder,
+flac_encoder_write(Encoder *_encoder,
 		      const void *data, size_t length,
 		      G_GNUC_UNUSED GError **error)
 {
@@ -308,7 +303,7 @@ flac_encoder_write(struct encoder *_encoder,
 }
 
 static size_t
-flac_encoder_read(struct encoder *_encoder, void *dest, size_t length)
+flac_encoder_read(Encoder *_encoder, void *dest, size_t length)
 {
 	struct flac_encoder *encoder = (struct flac_encoder *)_encoder;
 
@@ -327,12 +322,12 @@ flac_encoder_read(struct encoder *_encoder, void *dest, size_t length)
 }
 
 static const char *
-flac_encoder_get_mime_type(G_GNUC_UNUSED struct encoder *_encoder)
+flac_encoder_get_mime_type(G_GNUC_UNUSED Encoder *_encoder)
 {
 	return "audio/flac";
 }
 
-const struct encoder_plugin flac_encoder_plugin = {
+const EncoderPlugin flac_encoder_plugin = {
 	"flac",
 	flac_encoder_init,
 	flac_encoder_finish,
diff --git a/src/encoder/FlacEncoderPlugin.hxx b/src/encoder/FlacEncoderPlugin.hxx
index da2d91a9a..928a7f93e 100644
--- a/src/encoder/FlacEncoderPlugin.hxx
+++ b/src/encoder/FlacEncoderPlugin.hxx
@@ -20,6 +20,6 @@
 #ifndef MPD_ENCODER_FLAC_HXX
 #define MPD_ENCODER_FLAC_HXX
 
-extern const struct encoder_plugin flac_encoder_plugin;
+extern const struct EncoderPlugin flac_encoder_plugin;
 
 #endif
diff --git a/src/encoder/LameEncoderPlugin.cxx b/src/encoder/LameEncoderPlugin.cxx
index 32fa7a323..933fa3ff2 100644
--- a/src/encoder/LameEncoderPlugin.cxx
+++ b/src/encoder/LameEncoderPlugin.cxx
@@ -19,8 +19,7 @@
 
 #include "config.h"
 #include "LameEncoderPlugin.hxx"
-#include "encoder_api.h"
-#include "encoder_plugin.h"
+#include "EncoderAPI.hxx"
 #include "audio_format.h"
 
 #include <lame/lame.h>
@@ -31,7 +30,7 @@
 #include <string.h>
 
 struct LameEncoder final {
-	struct encoder encoder;
+	Encoder encoder;
 
 	struct audio_format audio_format;
 	float quality;
@@ -42,9 +41,7 @@ struct LameEncoder final {
 	unsigned char buffer[32768];
 	size_t buffer_length;
 
-	LameEncoder() {
-		encoder_struct_init(&encoder, &lame_encoder_plugin);
-	}
+	LameEncoder():encoder(lame_encoder_plugin) {}
 
 	bool Configure(const config_param *param, GError **error);
 };
@@ -108,7 +105,7 @@ LameEncoder::Configure(const config_param *param, GError **error)
 	return true;
 }
 
-static struct encoder *
+static Encoder *
 lame_encoder_init(const struct config_param *param, GError **error_r)
 {
 	LameEncoder *encoder = new LameEncoder();
@@ -124,7 +121,7 @@ lame_encoder_init(const struct config_param *param, GError **error_r)
 }
 
 static void
-lame_encoder_finish(struct encoder *_encoder)
+lame_encoder_finish(Encoder *_encoder)
 {
 	LameEncoder *encoder = (LameEncoder *)_encoder;
 
@@ -190,7 +187,7 @@ lame_encoder_setup(LameEncoder *encoder, GError **error)
 }
 
 static bool
-lame_encoder_open(struct encoder *_encoder, struct audio_format *audio_format,
+lame_encoder_open(Encoder *_encoder, struct audio_format *audio_format,
 		  GError **error)
 {
 	LameEncoder *encoder = (LameEncoder *)_encoder;
@@ -218,7 +215,7 @@ lame_encoder_open(struct encoder *_encoder, struct audio_format *audio_format,
 }
 
 static void
-lame_encoder_close(struct encoder *_encoder)
+lame_encoder_close(Encoder *_encoder)
 {
 	LameEncoder *encoder = (LameEncoder *)_encoder;
 
@@ -226,7 +223,7 @@ lame_encoder_close(struct encoder *_encoder)
 }
 
 static bool
-lame_encoder_write(struct encoder *_encoder,
+lame_encoder_write(Encoder *_encoder,
 		   const void *data, size_t length,
 		   gcc_unused GError **error)
 {
@@ -265,7 +262,7 @@ lame_encoder_write(struct encoder *_encoder,
 }
 
 static size_t
-lame_encoder_read(struct encoder *_encoder, void *dest, size_t length)
+lame_encoder_read(Encoder *_encoder, void *dest, size_t length)
 {
 	LameEncoder *encoder = (LameEncoder *)_encoder;
 
@@ -282,12 +279,12 @@ lame_encoder_read(struct encoder *_encoder, void *dest, size_t length)
 }
 
 static const char *
-lame_encoder_get_mime_type(gcc_unused struct encoder *_encoder)
+lame_encoder_get_mime_type(gcc_unused Encoder *_encoder)
 {
 	return "audio/mpeg";
 }
 
-const struct encoder_plugin lame_encoder_plugin = {
+const EncoderPlugin lame_encoder_plugin = {
 	"lame",
 	lame_encoder_init,
 	lame_encoder_finish,
diff --git a/src/encoder/LameEncoderPlugin.hxx b/src/encoder/LameEncoderPlugin.hxx
index 3037ab4ec..49832baee 100644
--- a/src/encoder/LameEncoderPlugin.hxx
+++ b/src/encoder/LameEncoderPlugin.hxx
@@ -20,6 +20,6 @@
 #ifndef MPD_ENCODER_LAME_HXX
 #define MPD_ENCODER_LAME_HXX
 
-extern const struct encoder_plugin lame_encoder_plugin;
+extern const struct EncoderPlugin lame_encoder_plugin;
 
 #endif
diff --git a/src/encoder/NullEncoderPlugin.cxx b/src/encoder/NullEncoderPlugin.cxx
index bdfab1563..39e391063 100644
--- a/src/encoder/NullEncoderPlugin.cxx
+++ b/src/encoder/NullEncoderPlugin.cxx
@@ -19,8 +19,7 @@
 
 #include "config.h"
 #include "NullEncoderPlugin.hxx"
-#include "encoder_api.h"
-#include "encoder_plugin.h"
+#include "EncoderAPI.hxx"
 #include "util/fifo_buffer.h"
 extern "C" {
 #include "util/growing_fifo.h"
@@ -33,16 +32,14 @@ extern "C" {
 #include <string.h>
 
 struct NullEncoder final {
-	struct encoder encoder;
+	Encoder encoder;
 
 	struct fifo_buffer *buffer;
 
-	NullEncoder() {
-		encoder_struct_init(&encoder, &null_encoder_plugin);
-	}
+	NullEncoder():encoder(null_encoder_plugin) {}
 };
 
-static struct encoder *
+static Encoder *
 null_encoder_init(gcc_unused const struct config_param *param,
 		  gcc_unused GError **error)
 {
@@ -51,7 +48,7 @@ null_encoder_init(gcc_unused const struct config_param *param,
 }
 
 static void
-null_encoder_finish(struct encoder *_encoder)
+null_encoder_finish(Encoder *_encoder)
 {
 	NullEncoder *encoder = (NullEncoder *)_encoder;
 
@@ -59,7 +56,7 @@ null_encoder_finish(struct encoder *_encoder)
 }
 
 static void
-null_encoder_close(struct encoder *_encoder)
+null_encoder_close(Encoder *_encoder)
 {
 	NullEncoder *encoder = (NullEncoder *)_encoder;
 
@@ -68,7 +65,7 @@ null_encoder_close(struct encoder *_encoder)
 
 
 static bool
-null_encoder_open(struct encoder *_encoder,
+null_encoder_open(Encoder *_encoder,
 		  gcc_unused struct audio_format *audio_format,
 		  gcc_unused GError **error)
 {
@@ -78,7 +75,7 @@ null_encoder_open(struct encoder *_encoder,
 }
 
 static bool
-null_encoder_write(struct encoder *_encoder,
+null_encoder_write(Encoder *_encoder,
 		   const void *data, size_t length,
 		   gcc_unused GError **error)
 {
@@ -89,7 +86,7 @@ null_encoder_write(struct encoder *_encoder,
 }
 
 static size_t
-null_encoder_read(struct encoder *_encoder, void *dest, size_t length)
+null_encoder_read(Encoder *_encoder, void *dest, size_t length)
 {
 	NullEncoder *encoder = (NullEncoder *)_encoder;
 
@@ -106,7 +103,7 @@ null_encoder_read(struct encoder *_encoder, void *dest, size_t length)
 	return length;
 }
 
-const struct encoder_plugin null_encoder_plugin = {
+const EncoderPlugin null_encoder_plugin = {
 	"null",
 	null_encoder_init,
 	null_encoder_finish,
diff --git a/src/encoder/NullEncoderPlugin.hxx b/src/encoder/NullEncoderPlugin.hxx
index bf2cfee60..b741a2f6d 100644
--- a/src/encoder/NullEncoderPlugin.hxx
+++ b/src/encoder/NullEncoderPlugin.hxx
@@ -20,6 +20,6 @@
 #ifndef MPD_ENCODER_NULL_HXX
 #define MPD_ENCODER_NULL_HXX
 
-extern const struct encoder_plugin null_encoder_plugin;
+extern const struct EncoderPlugin null_encoder_plugin;
 
 #endif
diff --git a/src/encoder/OpusEncoderPlugin.cxx b/src/encoder/OpusEncoderPlugin.cxx
index 7167473e5..a5947e4b8 100644
--- a/src/encoder/OpusEncoderPlugin.cxx
+++ b/src/encoder/OpusEncoderPlugin.cxx
@@ -20,8 +20,7 @@
 #include "config.h"
 #include "OpusEncoderPlugin.hxx"
 #include "OggStream.hxx"
-#include "encoder_api.h"
-#include "encoder_plugin.h"
+#include "EncoderAPI.hxx"
 #include "audio_format.h"
 #include "mpd_error.h"
 
@@ -35,7 +34,7 @@
 
 struct opus_encoder {
 	/** the base class */
-	struct encoder encoder;
+	Encoder encoder;
 
 	/* configuration */
 
@@ -64,9 +63,7 @@ struct opus_encoder {
 
 	ogg_int64_t granulepos;
 
-	opus_encoder() {
-		encoder_struct_init(&encoder, &opus_encoder_plugin);
-	}
+	opus_encoder():encoder(opus_encoder_plugin) {}
 };
 
 gcc_const
@@ -120,7 +117,7 @@ opus_encoder_configure(struct opus_encoder *encoder,
 	return true;
 }
 
-static struct encoder *
+static Encoder *
 opus_encoder_init(const struct config_param *param, GError **error)
 {
 	opus_encoder *encoder = new opus_encoder();
@@ -136,7 +133,7 @@ opus_encoder_init(const struct config_param *param, GError **error)
 }
 
 static void
-opus_encoder_finish(struct encoder *_encoder)
+opus_encoder_finish(Encoder *_encoder)
 {
 	struct opus_encoder *encoder = (struct opus_encoder *)_encoder;
 
@@ -146,7 +143,7 @@ opus_encoder_finish(struct encoder *_encoder)
 }
 
 static bool
-opus_encoder_open(struct encoder *_encoder,
+opus_encoder_open(Encoder *_encoder,
 		  struct audio_format *audio_format,
 		  GError **error_r)
 {
@@ -205,7 +202,7 @@ opus_encoder_open(struct encoder *_encoder,
 }
 
 static void
-opus_encoder_close(struct encoder *_encoder)
+opus_encoder_close(Encoder *_encoder)
 {
 	struct opus_encoder *encoder = (struct opus_encoder *)_encoder;
 
@@ -255,7 +252,7 @@ opus_encoder_do_encode(struct opus_encoder *encoder, bool eos,
 }
 
 static bool
-opus_encoder_end(struct encoder *_encoder, GError **error_r)
+opus_encoder_end(Encoder *_encoder, GError **error_r)
 {
 	struct opus_encoder *encoder = (struct opus_encoder *)_encoder;
 
@@ -269,7 +266,7 @@ opus_encoder_end(struct encoder *_encoder, GError **error_r)
 }
 
 static bool
-opus_encoder_flush(struct encoder *_encoder, G_GNUC_UNUSED GError **error)
+opus_encoder_flush(Encoder *_encoder, G_GNUC_UNUSED GError **error)
 {
 	struct opus_encoder *encoder = (struct opus_encoder *)_encoder;
 
@@ -303,7 +300,7 @@ opus_encoder_write_silence(struct opus_encoder *encoder, unsigned fill_frames,
 }
 
 static bool
-opus_encoder_write(struct encoder *_encoder,
+opus_encoder_write(Encoder *_encoder,
 		   const void *_data, size_t length,
 		   GError **error_r)
 {
@@ -395,7 +392,7 @@ opus_encoder_generate_tags(struct opus_encoder *encoder)
 }
 
 static size_t
-opus_encoder_read(struct encoder *_encoder, void *dest, size_t length)
+opus_encoder_read(Encoder *_encoder, void *dest, size_t length)
 {
 	struct opus_encoder *encoder = (struct opus_encoder *)_encoder;
 
@@ -408,12 +405,12 @@ opus_encoder_read(struct encoder *_encoder, void *dest, size_t length)
 }
 
 static const char *
-opus_encoder_get_mime_type(G_GNUC_UNUSED struct encoder *_encoder)
+opus_encoder_get_mime_type(G_GNUC_UNUSED Encoder *_encoder)
 {
 	return  "audio/ogg";
 }
 
-const struct encoder_plugin opus_encoder_plugin = {
+const EncoderPlugin opus_encoder_plugin = {
 	"opus",
 	opus_encoder_init,
 	opus_encoder_finish,
diff --git a/src/encoder/OpusEncoderPlugin.hxx b/src/encoder/OpusEncoderPlugin.hxx
index f54377202..d6da0e960 100644
--- a/src/encoder/OpusEncoderPlugin.hxx
+++ b/src/encoder/OpusEncoderPlugin.hxx
@@ -20,6 +20,6 @@
 #ifndef MPD_ENCODER_OPUS_H
 #define MPD_ENCODER_OPUS_H
 
-extern const struct encoder_plugin opus_encoder_plugin;
+extern const struct EncoderPlugin opus_encoder_plugin;
 
 #endif
diff --git a/src/encoder/TwolameEncoderPlugin.cxx b/src/encoder/TwolameEncoderPlugin.cxx
index a61426170..c307b7b4f 100644
--- a/src/encoder/TwolameEncoderPlugin.cxx
+++ b/src/encoder/TwolameEncoderPlugin.cxx
@@ -19,8 +19,7 @@
 
 #include "config.h"
 #include "TwolameEncoderPlugin.hxx"
-#include "encoder_api.h"
-#include "encoder_plugin.h"
+#include "EncoderAPI.hxx"
 #include "audio_format.h"
 
 #include <twolame.h>
@@ -31,7 +30,7 @@
 #include <string.h>
 
 struct TwolameEncoder final {
-	struct encoder encoder;
+	Encoder encoder;
 
 	struct audio_format audio_format;
 	float quality;
@@ -47,9 +46,7 @@ struct TwolameEncoder final {
 	 */
 	bool flush;
 
-	TwolameEncoder() {
-		encoder_struct_init(&encoder, &twolame_encoder_plugin);
-	}
+	TwolameEncoder():encoder(twolame_encoder_plugin) {}
 
 	bool Configure(const config_param *param, GError **error);
 };
@@ -113,7 +110,7 @@ TwolameEncoder::Configure(const config_param *param, GError **error)
 	return true;
 }
 
-static struct encoder *
+static Encoder *
 twolame_encoder_init(const struct config_param *param, GError **error_r)
 {
 	g_debug("libtwolame version %s", get_twolame_version());
@@ -131,7 +128,7 @@ twolame_encoder_init(const struct config_param *param, GError **error_r)
 }
 
 static void
-twolame_encoder_finish(struct encoder *_encoder)
+twolame_encoder_finish(Encoder *_encoder)
 {
 	TwolameEncoder *encoder = (TwolameEncoder *)_encoder;
 
@@ -190,7 +187,7 @@ twolame_encoder_setup(TwolameEncoder *encoder, GError **error)
 }
 
 static bool
-twolame_encoder_open(struct encoder *_encoder, struct audio_format *audio_format,
+twolame_encoder_open(Encoder *_encoder, struct audio_format *audio_format,
 		     GError **error)
 {
 	TwolameEncoder *encoder = (TwolameEncoder *)_encoder;
@@ -219,7 +216,7 @@ twolame_encoder_open(struct encoder *_encoder, struct audio_format *audio_format
 }
 
 static void
-twolame_encoder_close(struct encoder *_encoder)
+twolame_encoder_close(Encoder *_encoder)
 {
 	TwolameEncoder *encoder = (TwolameEncoder *)_encoder;
 
@@ -227,7 +224,7 @@ twolame_encoder_close(struct encoder *_encoder)
 }
 
 static bool
-twolame_encoder_flush(struct encoder *_encoder, gcc_unused GError **error)
+twolame_encoder_flush(Encoder *_encoder, gcc_unused GError **error)
 {
 	TwolameEncoder *encoder = (TwolameEncoder *)_encoder;
 
@@ -236,7 +233,7 @@ twolame_encoder_flush(struct encoder *_encoder, gcc_unused GError **error)
 }
 
 static bool
-twolame_encoder_write(struct encoder *_encoder,
+twolame_encoder_write(Encoder *_encoder,
 		      const void *data, size_t length,
 		      gcc_unused GError **error)
 {
@@ -263,7 +260,7 @@ twolame_encoder_write(struct encoder *_encoder,
 }
 
 static size_t
-twolame_encoder_read(struct encoder *_encoder, void *dest, size_t length)
+twolame_encoder_read(Encoder *_encoder, void *dest, size_t length)
 {
 	TwolameEncoder *encoder = (TwolameEncoder *)_encoder;
 
@@ -290,12 +287,12 @@ twolame_encoder_read(struct encoder *_encoder, void *dest, size_t length)
 }
 
 static const char *
-twolame_encoder_get_mime_type(gcc_unused struct encoder *_encoder)
+twolame_encoder_get_mime_type(gcc_unused Encoder *_encoder)
 {
 	return "audio/mpeg";
 }
 
-const struct encoder_plugin twolame_encoder_plugin = {
+const EncoderPlugin twolame_encoder_plugin = {
 	"twolame",
 	twolame_encoder_init,
 	twolame_encoder_finish,
diff --git a/src/encoder/TwolameEncoderPlugin.hxx b/src/encoder/TwolameEncoderPlugin.hxx
index 585345172..dd8a536f6 100644
--- a/src/encoder/TwolameEncoderPlugin.hxx
+++ b/src/encoder/TwolameEncoderPlugin.hxx
@@ -20,6 +20,6 @@
 #ifndef MPD_ENCODER_TWOLAME_HXX
 #define MPD_ENCODER_TWOLAME_HXX
 
-extern const struct encoder_plugin twolame_encoder_plugin;
+extern const struct EncoderPlugin twolame_encoder_plugin;
 
 #endif
diff --git a/src/encoder/VorbisEncoderPlugin.cxx b/src/encoder/VorbisEncoderPlugin.cxx
index dc7ef0d5e..8996a57d6 100644
--- a/src/encoder/VorbisEncoderPlugin.cxx
+++ b/src/encoder/VorbisEncoderPlugin.cxx
@@ -20,8 +20,7 @@
 #include "config.h"
 #include "VorbisEncoderPlugin.hxx"
 #include "OggStream.hxx"
-#include "encoder_api.h"
-#include "encoder_plugin.h"
+#include "EncoderAPI.hxx"
 #include "tag.h"
 #include "audio_format.h"
 #include "mpd_error.h"
@@ -35,7 +34,7 @@
 
 struct vorbis_encoder {
 	/** the base class */
-	struct encoder encoder;
+	Encoder encoder;
 
 	/* configuration */
 
@@ -52,9 +51,7 @@ struct vorbis_encoder {
 
 	OggStream stream;
 
-	vorbis_encoder() {
-		encoder_struct_init(&encoder, &vorbis_encoder_plugin);
-	}
+	vorbis_encoder():encoder(vorbis_encoder_plugin) {}
 };
 
 static inline GQuark
@@ -117,7 +114,7 @@ vorbis_encoder_configure(struct vorbis_encoder *encoder,
 	return true;
 }
 
-static struct encoder *
+static Encoder *
 vorbis_encoder_init(const struct config_param *param, GError **error)
 {
 	vorbis_encoder *encoder = new vorbis_encoder();
@@ -133,7 +130,7 @@ vorbis_encoder_init(const struct config_param *param, GError **error)
 }
 
 static void
-vorbis_encoder_finish(struct encoder *_encoder)
+vorbis_encoder_finish(Encoder *_encoder)
 {
 	struct vorbis_encoder *encoder = (struct vorbis_encoder *)_encoder;
 
@@ -204,7 +201,7 @@ vorbis_encoder_send_header(struct vorbis_encoder *encoder)
 }
 
 static bool
-vorbis_encoder_open(struct encoder *_encoder,
+vorbis_encoder_open(Encoder *_encoder,
 		    struct audio_format *audio_format,
 		    GError **error)
 {
@@ -232,7 +229,7 @@ vorbis_encoder_clear(struct vorbis_encoder *encoder)
 }
 
 static void
-vorbis_encoder_close(struct encoder *_encoder)
+vorbis_encoder_close(Encoder *_encoder)
 {
 	struct vorbis_encoder *encoder = (struct vorbis_encoder *)_encoder;
 
@@ -253,7 +250,7 @@ vorbis_encoder_blockout(struct vorbis_encoder *encoder)
 }
 
 static bool
-vorbis_encoder_flush(struct encoder *_encoder, G_GNUC_UNUSED GError **error)
+vorbis_encoder_flush(Encoder *_encoder, G_GNUC_UNUSED GError **error)
 {
 	struct vorbis_encoder *encoder = (struct vorbis_encoder *)_encoder;
 
@@ -262,7 +259,7 @@ vorbis_encoder_flush(struct encoder *_encoder, G_GNUC_UNUSED GError **error)
 }
 
 static bool
-vorbis_encoder_pre_tag(struct encoder *_encoder, G_GNUC_UNUSED GError **error)
+vorbis_encoder_pre_tag(Encoder *_encoder, G_GNUC_UNUSED GError **error)
 {
 	struct vorbis_encoder *encoder = (struct vorbis_encoder *)_encoder;
 
@@ -292,7 +289,7 @@ copy_tag_to_vorbis_comment(vorbis_comment *vc, const struct tag *tag)
 }
 
 static bool
-vorbis_encoder_tag(struct encoder *_encoder, const struct tag *tag,
+vorbis_encoder_tag(Encoder *_encoder, const struct tag *tag,
 		   G_GNUC_UNUSED GError **error)
 {
 	struct vorbis_encoder *encoder = (struct vorbis_encoder *)_encoder;
@@ -325,7 +322,7 @@ interleaved_to_vorbis_buffer(float **dest, const float *src,
 }
 
 static bool
-vorbis_encoder_write(struct encoder *_encoder,
+vorbis_encoder_write(Encoder *_encoder,
 		     const void *data, size_t length,
 		     G_GNUC_UNUSED GError **error)
 {
@@ -348,7 +345,7 @@ vorbis_encoder_write(struct encoder *_encoder,
 }
 
 static size_t
-vorbis_encoder_read(struct encoder *_encoder, void *dest, size_t length)
+vorbis_encoder_read(Encoder *_encoder, void *dest, size_t length)
 {
 	struct vorbis_encoder *encoder = (struct vorbis_encoder *)_encoder;
 
@@ -356,12 +353,12 @@ vorbis_encoder_read(struct encoder *_encoder, void *dest, size_t length)
 }
 
 static const char *
-vorbis_encoder_get_mime_type(G_GNUC_UNUSED struct encoder *_encoder)
+vorbis_encoder_get_mime_type(G_GNUC_UNUSED Encoder *_encoder)
 {
 	return  "audio/ogg";
 }
 
-const struct encoder_plugin vorbis_encoder_plugin = {
+const EncoderPlugin vorbis_encoder_plugin = {
 	"vorbis",
 	vorbis_encoder_init,
 	vorbis_encoder_finish,
diff --git a/src/encoder/VorbisEncoderPlugin.hxx b/src/encoder/VorbisEncoderPlugin.hxx
index 4cddf1b11..72cc44f5c 100644
--- a/src/encoder/VorbisEncoderPlugin.hxx
+++ b/src/encoder/VorbisEncoderPlugin.hxx
@@ -20,6 +20,6 @@
 #ifndef MPD_ENCODER_VORBIS_H
 #define MPD_ENCODER_VORBIS_H
 
-extern const struct encoder_plugin vorbis_encoder_plugin;
+extern const struct EncoderPlugin vorbis_encoder_plugin;
 
 #endif
diff --git a/src/encoder/WaveEncoderPlugin.cxx b/src/encoder/WaveEncoderPlugin.cxx
index fb52d7906..939012d89 100644
--- a/src/encoder/WaveEncoderPlugin.cxx
+++ b/src/encoder/WaveEncoderPlugin.cxx
@@ -19,8 +19,7 @@
 
 #include "config.h"
 #include "WaveEncoderPlugin.hxx"
-#include "encoder_api.h"
-#include "encoder_plugin.h"
+#include "EncoderAPI.hxx"
 #include "util/fifo_buffer.h"
 extern "C" {
 #include "util/growing_fifo.h"
@@ -32,14 +31,12 @@ extern "C" {
 #include <string.h>
 
 struct WaveEncoder {
-	struct encoder encoder;
+	Encoder encoder;
 	unsigned bits;
 
 	struct fifo_buffer *buffer;
 
-	WaveEncoder() {
-		encoder_struct_init(&encoder, &wave_encoder_plugin);
-	}
+	WaveEncoder():encoder(wave_encoder_plugin) {}
 };
 
 struct wave_header {
@@ -58,8 +55,6 @@ struct wave_header {
 	uint32_t data_size;
 };
 
-extern const struct encoder_plugin wave_encoder_plugin;
-
 static void
 fill_wave_header(struct wave_header *header, int channels, int bits,
 		int freq, int block_size)
@@ -87,7 +82,7 @@ fill_wave_header(struct wave_header *header, int channels, int bits,
 					 (8 + data_size));
 }
 
-static struct encoder *
+static Encoder *
 wave_encoder_init(gcc_unused const struct config_param *param,
 		  gcc_unused GError **error)
 {
@@ -96,7 +91,7 @@ wave_encoder_init(gcc_unused const struct config_param *param,
 }
 
 static void
-wave_encoder_finish(struct encoder *_encoder)
+wave_encoder_finish(Encoder *_encoder)
 {
 	WaveEncoder *encoder = (WaveEncoder *)_encoder;
 
@@ -104,7 +99,7 @@ wave_encoder_finish(struct encoder *_encoder)
 }
 
 static bool
-wave_encoder_open(struct encoder *_encoder,
+wave_encoder_open(Encoder *_encoder,
 		  gcc_unused struct audio_format *audio_format,
 		  gcc_unused GError **error)
 {
@@ -151,7 +146,7 @@ wave_encoder_open(struct encoder *_encoder,
 }
 
 static void
-wave_encoder_close(struct encoder *_encoder)
+wave_encoder_close(Encoder *_encoder)
 {
 	WaveEncoder *encoder = (WaveEncoder *)_encoder;
 
@@ -199,7 +194,7 @@ pcm24_to_wave(uint8_t *dst8, const uint32_t *src32, size_t length)
 }
 
 static bool
-wave_encoder_write(struct encoder *_encoder,
+wave_encoder_write(Encoder *_encoder,
 		   const void *src, size_t length,
 		   gcc_unused GError **error)
 {
@@ -242,7 +237,7 @@ wave_encoder_write(struct encoder *_encoder,
 }
 
 static size_t
-wave_encoder_read(struct encoder *_encoder, void *dest, size_t length)
+wave_encoder_read(Encoder *_encoder, void *dest, size_t length)
 {
 	WaveEncoder *encoder = (WaveEncoder *)_encoder;
 
@@ -260,12 +255,12 @@ wave_encoder_read(struct encoder *_encoder, void *dest, size_t length)
 }
 
 static const char *
-wave_encoder_get_mime_type(gcc_unused struct encoder *_encoder)
+wave_encoder_get_mime_type(gcc_unused Encoder *_encoder)
 {
 	return "audio/wav";
 }
 
-const struct encoder_plugin wave_encoder_plugin = {
+const EncoderPlugin wave_encoder_plugin = {
 	"wave",
 	wave_encoder_init,
 	wave_encoder_finish,
diff --git a/src/encoder/WaveEncoderPlugin.hxx b/src/encoder/WaveEncoderPlugin.hxx
index b50fe5514..190ee131e 100644
--- a/src/encoder/WaveEncoderPlugin.hxx
+++ b/src/encoder/WaveEncoderPlugin.hxx
@@ -20,6 +20,6 @@
 #ifndef MPD_ENCODER_WAVE_HXX
 #define MPD_ENCODER_WAVE_HXX
 
-extern const struct encoder_plugin wave_encoder_plugin;
+extern const struct EncoderPlugin wave_encoder_plugin;
 
 #endif
diff --git a/src/output/HttpdInternal.hxx b/src/output/HttpdInternal.hxx
index b79a22905..d7394d051 100644
--- a/src/output/HttpdInternal.hxx
+++ b/src/output/HttpdInternal.hxx
@@ -37,6 +37,7 @@ class EventLoop;
 class ServerSocket;
 class HttpdClient;
 class Page;
+struct Encoder;
 
 struct HttpdOutput final : private ServerSocket {
 	struct audio_output base;
@@ -50,7 +51,7 @@ struct HttpdOutput final : private ServerSocket {
 	/**
 	 * The configured encoder plugin.
 	 */
-	struct encoder *encoder;
+	Encoder *encoder;
 
 	/**
 	 * Number of bytes which were fed into the encoder, without
diff --git a/src/output/HttpdOutputPlugin.cxx b/src/output/HttpdOutputPlugin.cxx
index 8c0b5f8be..2ac462842 100644
--- a/src/output/HttpdOutputPlugin.cxx
+++ b/src/output/HttpdOutputPlugin.cxx
@@ -22,7 +22,7 @@
 #include "HttpdInternal.hxx"
 #include "HttpdClient.hxx"
 #include "OutputAPI.hxx"
-#include "encoder_plugin.h"
+#include "EncoderPlugin.hxx"
 #include "EncoderList.hxx"
 #include "resolver.h"
 #include "Page.hxx"
@@ -102,8 +102,7 @@ HttpdOutput::Configure(const config_param *param, GError **error_r)
 
 	const char *encoder_name =
 		config_get_block_string(param, "encoder", "vorbis");
-	const struct encoder_plugin *encoder_plugin =
-		encoder_plugin_get(encoder_name);
+	const auto encoder_plugin = encoder_plugin_get(encoder_name);
 	if (encoder_plugin == NULL) {
 		g_set_error(error_r, httpd_output_quark(), 0,
 			    "No such encoder: %s", encoder_name);
@@ -125,7 +124,7 @@ HttpdOutput::Configure(const config_param *param, GError **error_r)
 
 	/* initialize encoder */
 
-	encoder = encoder_init(encoder_plugin, param, error_r);
+	encoder = encoder_init(*encoder_plugin, param, error_r);
 	if (encoder == nullptr)
 		return false;
 
@@ -190,7 +189,7 @@ inline void
 HttpdOutput::AddClient(int fd)
 {
 	clients.emplace_front(this, fd, GetEventLoop(),
-			      encoder->plugin->tag == NULL);
+			      encoder->plugin.tag == nullptr);
 	++clients_cnt;
 
 	/* pass metadata to client */
@@ -489,7 +488,7 @@ HttpdOutput::SendTag(const struct tag *tag)
 {
 	assert(tag != NULL);
 
-	if (encoder->plugin->tag != NULL) {
+	if (encoder->plugin.tag != nullptr) {
 		/* embed encoder tags */
 
 		/* flush the current stream, and end it */
diff --git a/src/output/RecorderOutputPlugin.cxx b/src/output/RecorderOutputPlugin.cxx
index b9874debb..6b31fcbc6 100644
--- a/src/output/RecorderOutputPlugin.cxx
+++ b/src/output/RecorderOutputPlugin.cxx
@@ -20,7 +20,7 @@
 #include "config.h"
 #include "RecorderOutputPlugin.hxx"
 #include "OutputAPI.hxx"
-#include "encoder_plugin.h"
+#include "EncoderPlugin.hxx"
 #include "EncoderList.hxx"
 #include "fd_util.h"
 #include "open.h"
@@ -40,7 +40,7 @@ struct RecorderOutput {
 	/**
 	 * The configured encoder plugin.
 	 */
-	struct encoder *encoder;
+	Encoder *encoder;
 
 	/**
 	 * The destination file name.
@@ -92,8 +92,7 @@ RecorderOutput::Configure(const config_param *param, GError **error_r)
 
 	const char *encoder_name =
 		config_get_block_string(param, "encoder", "vorbis");
-	const struct encoder_plugin *encoder_plugin =
-		encoder_plugin_get(encoder_name);
+	const auto encoder_plugin = encoder_plugin_get(encoder_name);
 	if (encoder_plugin == nullptr) {
 		g_set_error(error_r, recorder_output_quark(), 0,
 			    "No such encoder: %s", encoder_name);
@@ -109,7 +108,7 @@ RecorderOutput::Configure(const config_param *param, GError **error_r)
 
 	/* initialize encoder */
 
-	encoder = encoder_init(encoder_plugin, param, error_r);
+	encoder = encoder_init(*encoder_plugin, param, error_r);
 	if (encoder == nullptr)
 		return false;
 
diff --git a/src/output/ShoutOutputPlugin.cxx b/src/output/ShoutOutputPlugin.cxx
index 912b57dc8..0a46d8bee 100644
--- a/src/output/ShoutOutputPlugin.cxx
+++ b/src/output/ShoutOutputPlugin.cxx
@@ -20,7 +20,7 @@
 #include "config.h"
 #include "ShoutOutputPlugin.hxx"
 #include "OutputAPI.hxx"
-#include "encoder_plugin.h"
+#include "EncoderPlugin.hxx"
 #include "EncoderList.hxx"
 #include "mpd_error.h"
 
@@ -42,7 +42,7 @@ struct ShoutOutput final {
 	shout_t *shout_conn;
 	shout_metadata_t *shout_meta;
 
-	struct encoder *encoder;
+	Encoder *encoder;
 
 	float quality;
 	int bitrate;
@@ -88,7 +88,7 @@ shout_output_quark(void)
 	return g_quark_from_static_string("shout_output");
 }
 
-static const struct encoder_plugin *
+static const EncoderPlugin *
 shout_encoder_plugin_get(const char *name)
 {
 	if (strcmp(name, "ogg") == 0)
@@ -179,8 +179,7 @@ ShoutOutput::Configure(const config_param *param, GError **error_r)
 
 	const char *encoding = config_get_block_string(param, "encoding",
 						       "ogg");
-	const struct encoder_plugin *encoder_plugin =
-		shout_encoder_plugin_get(encoding);
+	const auto encoder_plugin = shout_encoder_plugin_get(encoding);
 	if (encoder_plugin == nullptr) {
 		g_set_error(error_r, shout_output_quark(), 0,
 			    "couldn't find shout encoder plugin \"%s\"",
@@ -188,7 +187,7 @@ ShoutOutput::Configure(const config_param *param, GError **error_r)
 		return false;
 	}
 
-	encoder = encoder_init(encoder_plugin, param, error_r);
+	encoder = encoder_init(*encoder_plugin, param, error_r);
 	if (encoder == nullptr)
 		return false;
 
@@ -514,7 +513,7 @@ static void my_shout_set_tag(struct audio_output *ao,
 	ShoutOutput *sd = (ShoutOutput *)ao;
 	GError *error = nullptr;
 
-	if (sd->encoder->plugin->tag != nullptr) {
+	if (sd->encoder->plugin.tag != nullptr) {
 		/* encoder plugin supports stream tags */
 
 		if (!encoder_pre_tag(sd->encoder, &error)) {
diff --git a/test/run_encoder.cxx b/test/run_encoder.cxx
index 91993c95a..1beb434df 100644
--- a/test/run_encoder.cxx
+++ b/test/run_encoder.cxx
@@ -19,7 +19,7 @@
 
 #include "config.h"
 #include "EncoderList.hxx"
-#include "encoder_plugin.h"
+#include "EncoderPlugin.hxx"
 #include "audio_format.h"
 #include "AudioParser.hxx"
 #include "conf.h"
@@ -31,12 +31,12 @@
 #include <unistd.h>
 
 static void
-encoder_to_stdout(struct encoder *encoder)
+encoder_to_stdout(Encoder &encoder)
 {
 	size_t length;
 	static char buffer[32768];
 
-	while ((length = encoder_read(encoder, buffer, sizeof(buffer))) > 0) {
+	while ((length = encoder_read(&encoder, buffer, sizeof(buffer))) > 0) {
 		G_GNUC_UNUSED ssize_t ignored = write(1, buffer, length);
 	}
 }
@@ -47,8 +47,6 @@ int main(int argc, char **argv)
 	struct audio_format audio_format;
 	bool ret;
 	const char *encoder_name;
-	const struct encoder_plugin *plugin;
-	struct encoder *encoder;
 	static char buffer[32768];
 
 	/* parse command line */
@@ -67,7 +65,7 @@ int main(int argc, char **argv)
 
 	/* create the encoder */
 
-	plugin = encoder_plugin_get(encoder_name);
+	const auto plugin = encoder_plugin_get(encoder_name);
 	if (plugin == NULL) {
 		g_printerr("No such encoder: %s\n", encoder_name);
 		return 1;
@@ -76,7 +74,7 @@ int main(int argc, char **argv)
 	config_param param;
 	param.AddBlockParam("quality", "5.0", -1);
 
-	encoder = encoder_init(plugin, &param, &error);
+	const auto encoder = encoder_init(*plugin, &param, &error);
 	if (encoder == NULL) {
 		g_printerr("Failed to initialize encoder: %s\n",
 			   error->message);
@@ -104,7 +102,7 @@ int main(int argc, char **argv)
 		return 1;
 	}
 
-	encoder_to_stdout(encoder);
+	encoder_to_stdout(*encoder);
 
 	/* do it */
 
@@ -118,7 +116,7 @@ int main(int argc, char **argv)
 			return 1;
 		}
 
-		encoder_to_stdout(encoder);
+		encoder_to_stdout(*encoder);
 	}
 
 	ret = encoder_end(encoder, &error);
@@ -129,5 +127,5 @@ int main(int argc, char **argv)
 		return 1;
 	}
 
-	encoder_to_stdout(encoder);
+	encoder_to_stdout(*encoder);
 }
diff --git a/test/test_vorbis_encoder.cxx b/test/test_vorbis_encoder.cxx
index 7ac36e3ec..1e3b78065 100644
--- a/test/test_vorbis_encoder.cxx
+++ b/test/test_vorbis_encoder.cxx
@@ -19,7 +19,7 @@
 
 #include "config.h"
 #include "EncoderList.hxx"
-#include "encoder_plugin.h"
+#include "EncoderPlugin.hxx"
 #include "audio_format.h"
 #include "conf.h"
 #include "stdbin.h"
@@ -33,12 +33,12 @@
 static uint8_t zero[256];
 
 static void
-encoder_to_stdout(struct encoder *encoder)
+encoder_to_stdout(Encoder &encoder)
 {
 	size_t length;
 	static char buffer[32768];
 
-	while ((length = encoder_read(encoder, buffer, sizeof(buffer))) > 0) {
+	while ((length = encoder_read(&encoder, buffer, sizeof(buffer))) > 0) {
 		G_GNUC_UNUSED ssize_t ignored = write(1, buffer, length);
 	}
 }
@@ -50,13 +50,13 @@ main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
 
 	/* create the encoder */
 
-	const struct encoder_plugin *plugin = encoder_plugin_get("vorbis");
+	const auto plugin = encoder_plugin_get("vorbis");
 	assert(plugin != NULL);
 
 	config_param param;
 	param.AddBlockParam("quality", "5.0", -1);
 
-	struct encoder *encoder = encoder_init(plugin, &param, NULL);
+	const auto encoder = encoder_init(*plugin, &param, NULL);
 	assert(encoder != NULL);
 
 	/* open the encoder */
@@ -67,21 +67,21 @@ main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
 	success = encoder_open(encoder, &audio_format, NULL);
 	assert(success);
 
-	encoder_to_stdout(encoder);
+	encoder_to_stdout(*encoder);
 
 	/* write a block of data */
 
 	success = encoder_write(encoder, zero, sizeof(zero), NULL);
 	assert(success);
 
-	encoder_to_stdout(encoder);
+	encoder_to_stdout(*encoder);
 
 	/* write a tag */
 
 	success = encoder_pre_tag(encoder, NULL);
 	assert(success);
 
-	encoder_to_stdout(encoder);
+	encoder_to_stdout(*encoder);
 
 	struct tag *tag = tag_new();
 	tag_add_item(tag, TAG_ARTIST, "Foo");
@@ -92,7 +92,7 @@ main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
 
 	tag_free(tag);
 
-	encoder_to_stdout(encoder);
+	encoder_to_stdout(*encoder);
 
 	/* write another block of data */
 
@@ -104,7 +104,7 @@ main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
 	success = encoder_end(encoder, NULL);
 	assert(success);
 
-	encoder_to_stdout(encoder);
+	encoder_to_stdout(*encoder);
 
 	encoder_close(encoder);
 	encoder_finish(encoder);