diff --git a/src/encoder/EncoderInterface.hxx b/src/encoder/EncoderInterface.hxx
index 165c5eeca..8ee723a63 100644
--- a/src/encoder/EncoderInterface.hxx
+++ b/src/encoder/EncoderInterface.hxx
@@ -37,75 +37,65 @@ struct Encoder {
 		, open(false)
 #endif
 	{}
+
+
+	/**
+	 * Frees an #Encoder object.
+	 */
+	void Dispose() {
+		assert(!open);
+
+		plugin.finish(this);
+	}
+
+	/**
+	 * Opens the object.  You must call this prior to using it.
+	 * Before you free it, you must call Close().  You may open
+	 * and close (reuse) one encoder any number of times.
+	 *
+	 * After this function returns successfully and before the
+	 * first encoder_write() call, you should invoke
+	 * encoder_read() to obtain the file header.
+	 *
+	 * @param audio_format the encoder's input audio format; the plugin
+	 * may modify the struct to adapt it to its abilities
+	 * @return true on success
+	 */
+	bool Open(AudioFormat &audio_format, Error &error) {
+		assert(!open);
+
+		bool success = plugin.open(this, audio_format, error);
+#ifndef NDEBUG
+		open = success;
+		pre_tag = tag = end = false;
+#endif
+		return success;
+	}
+
+
+	/**
+	 * Closes the object.  This disables the encoder, and readies
+	 * it for reusal by calling Open() again.
+	 */
+	void Close() {
+		assert(open);
+
+		if (plugin.close != nullptr)
+			plugin.close(this);
+
+#ifndef NDEBUG
+		open = false;
+#endif
+	}
 };
 
-/**
- * Frees an encoder object.
- *
- * @param encoder the encoder
- */
-static inline void
-encoder_finish(Encoder *encoder)
-{
-	assert(!encoder->open);
-
-	encoder->plugin.finish(encoder);
-}
-
-/**
- * Opens an encoder object.  You must call this prior to using it.
- * Before you free it, you must call encoder_close().  You may open
- * and close (reuse) one encoder any number of times.
- *
- * After this function returns successfully and before the first
- * encoder_write() call, you should invoke encoder_read() to obtain
- * the file header.
- *
- * @param encoder the encoder
- * @param audio_format the encoder's input audio format; the plugin
- * may modify the struct to adapt it to its abilities
- * @return true on success
- */
-static inline bool
-encoder_open(Encoder *encoder, AudioFormat &audio_format,
-	     Error &error)
-{
-	assert(!encoder->open);
-
-	bool success = encoder->plugin.open(encoder, audio_format, error);
-#ifndef NDEBUG
-	encoder->open = success;
-	encoder->pre_tag = encoder->tag = encoder->end = false;
-#endif
-	return success;
-}
-
-/**
- * Closes an encoder object.  This disables the encoder, and readies
- * it for reusal by calling encoder_open() again.
- *
- * @param encoder the encoder
- */
-static inline void
-encoder_close(Encoder *encoder)
-{
-	assert(encoder->open);
-
-	if (encoder->plugin.close != nullptr)
-		encoder->plugin.close(encoder);
-
-#ifndef NDEBUG
-	encoder->open = false;
-#endif
-}
-
 /**
  * Ends the stream: flushes the encoder object, generate an
  * end-of-stream marker (if applicable), make everything which might
  * currently be buffered available by encoder_read().
  *
  * After this function has been called, the encoder may not be usable
- * for more data, and only encoder_read() and encoder_close() can be
+ * for more data, and only encoder_read() and Encoder::Close() can be
  * called.
  *
  * @param encoder the encoder
diff --git a/src/output/plugins/RecorderOutputPlugin.cxx b/src/output/plugins/RecorderOutputPlugin.cxx
index fb73f7b6f..f6508e33c 100644
--- a/src/output/plugins/RecorderOutputPlugin.cxx
+++ b/src/output/plugins/RecorderOutputPlugin.cxx
@@ -64,7 +64,7 @@ class RecorderOutput {
 
 	~RecorderOutput() {
 		if (encoder != nullptr)
-			encoder_finish(encoder);
+			encoder->Dispose();
 	}
 
 	bool Initialize(const config_param &param, Error &error_r) {
@@ -175,13 +175,13 @@ RecorderOutput::Open(AudioFormat &audio_format, Error &error)
 
 	/* open the encoder */
 
-	if (!encoder_open(encoder, audio_format, error)) {
+	if (!encoder->Open(audio_format, error)) {
 		delete file;
 		return false;
 	}
 
 	if (!EncoderToFile(error)) {
-		encoder_close(encoder);
+		encoder->Close();
 		delete file;
 		return false;
 	}
@@ -199,7 +199,7 @@ RecorderOutput::Commit(Error &error)
 
 	/* now really close everything */
 
-	encoder_close(encoder);
+	encoder->Close();
 
 	if (success && !file->Commit(error))
 		success = false;
diff --git a/src/output/plugins/ShoutOutputPlugin.cxx b/src/output/plugins/ShoutOutputPlugin.cxx
index e5d8b23a4..f9070026e 100644
--- a/src/output/plugins/ShoutOutputPlugin.cxx
+++ b/src/output/plugins/ShoutOutputPlugin.cxx
@@ -346,7 +346,7 @@ static void close_shout_conn(ShoutOutput * sd)
 		if (encoder_end(sd->encoder, IgnoreError()))
 			write_page(sd, IgnoreError());
 
-		encoder_close(sd->encoder);
+		sd->encoder->Close();
 	}
 
 	if (shout_get_connected(sd->shout_conn) != SHOUTERR_UNCONNECTED &&
@@ -362,7 +362,7 @@ my_shout_finish_driver(AudioOutput *ao)
 {
 	ShoutOutput *sd = (ShoutOutput *)ao;
 
-	encoder_finish(sd->encoder);
+	sd->encoder->Dispose();
 
 	delete sd;
 
@@ -416,13 +416,13 @@ my_shout_open_device(AudioOutput *ao, AudioFormat &audio_format,
 	if (!shout_connect(sd, error))
 		return false;
 
-	if (!encoder_open(sd->encoder, audio_format, error)) {
+	if (!sd->encoder->Open(audio_format, error)) {
 		shout_close(sd->shout_conn);
 		return false;
 	}
 
 	if (!write_page(sd, error)) {
-		encoder_close(sd->encoder);
+		sd->encoder->Close();
 		shout_close(sd->shout_conn);
 		return false;
 	}
diff --git a/src/output/plugins/httpd/HttpdOutputPlugin.cxx b/src/output/plugins/httpd/HttpdOutputPlugin.cxx
index 811cdaaff..19ee38cd2 100644
--- a/src/output/plugins/httpd/HttpdOutputPlugin.cxx
+++ b/src/output/plugins/httpd/HttpdOutputPlugin.cxx
@@ -64,7 +64,7 @@ HttpdOutput::~HttpdOutput()
 		metadata->Unref();
 
 	if (encoder != nullptr)
-		encoder_finish(encoder);
+		encoder->Dispose();
 
 }
 
@@ -295,7 +295,7 @@ httpd_output_disable(AudioOutput *ao)
 inline bool
 HttpdOutput::OpenEncoder(AudioFormat &audio_format, Error &error)
 {
-	if (!encoder_open(encoder, audio_format, error))
+	if (!encoder->Open(audio_format, error))
 		return false;
 
 	/* we have to remember the encoder header, i.e. the first
@@ -355,7 +355,7 @@ HttpdOutput::Close()
 	if (header != nullptr)
 		header->Unref();
 
-	encoder_close(encoder);
+	encoder->Close();
 }
 
 static void
diff --git a/test/run_encoder.cxx b/test/run_encoder.cxx
index c500b8e1f..42d934dbd 100644
--- a/test/run_encoder.cxx
+++ b/test/run_encoder.cxx
@@ -90,7 +90,7 @@ int main(int argc, char **argv)
 		}
 	}
 
-	if (!encoder_open(encoder, audio_format, error)) {
+	if (!encoder->Open(audio_format, error)) {
 		LogError(error, "Failed to open encoder");
 		return EXIT_FAILURE;
 	}
@@ -116,6 +116,6 @@ int main(int argc, char **argv)
 
 	encoder_to_stdout(*encoder);
 
-	encoder_close(encoder);
-	encoder_finish(encoder);
+	encoder->Close();
+	encoder->Dispose();
 }
diff --git a/test/test_vorbis_encoder.cxx b/test/test_vorbis_encoder.cxx
index f01331ee5..8e6b62739 100644
--- a/test/test_vorbis_encoder.cxx
+++ b/test/test_vorbis_encoder.cxx
@@ -63,7 +63,7 @@ main(gcc_unused int argc, gcc_unused char **argv)
 	/* open the encoder */
 
 	AudioFormat audio_format(44100, SampleFormat::S16, 2);
-	success = encoder_open(encoder, audio_format, IgnoreError());
+	success = encoder->Open(audio_format, IgnoreError());
 	assert(success);
 
 	encoder_to_stdout(*encoder);
@@ -108,6 +108,6 @@ main(gcc_unused int argc, gcc_unused char **argv)
 
 	encoder_to_stdout(*encoder);
 
-	encoder_close(encoder);
-	encoder_finish(encoder);
+	encoder->Close();
+	encoder->Dispose();
 }