diff --git a/src/TagFile.cxx b/src/TagFile.cxx
index 4c2b0d8ac..84faa848a 100644
--- a/src/TagFile.cxx
+++ b/src/TagFile.cxx
@@ -48,8 +48,7 @@ public:
 		 is(nullptr) {}
 
 	~TagFileScan() {
-		if (is != nullptr)
-			is->Close();
+		delete is;
 	}
 
 	bool ScanFile(const DecoderPlugin &plugin) {
diff --git a/src/TagStream.cxx b/src/TagStream.cxx
index 98cbe193b..639763373 100644
--- a/src/TagStream.cxx
+++ b/src/TagStream.cxx
@@ -73,6 +73,6 @@ tag_stream_scan(const char *uri, const tag_handler &handler, void *ctx)
 		return false;
 
 	bool success = tag_stream_scan(*is, handler, ctx);
-	is->Close();
+	delete is;
 	return success;
 }
diff --git a/src/archive/plugins/Bzip2ArchivePlugin.cxx b/src/archive/plugins/Bzip2ArchivePlugin.cxx
index 6940f1380..213b7d38c 100644
--- a/src/archive/plugins/Bzip2ArchivePlugin.cxx
+++ b/src/archive/plugins/Bzip2ArchivePlugin.cxx
@@ -61,7 +61,7 @@ public:
 	}
 
 	~Bzip2ArchiveFile() {
-		istream->Close();
+		delete istream;
 	}
 
 	void Ref() {
@@ -102,7 +102,6 @@ struct Bzip2InputStream final : public InputStream {
 	~Bzip2InputStream();
 
 	bool Open(Error &error);
-	void Close();
 };
 
 extern const InputPlugin bz2_inputplugin;
@@ -132,12 +131,6 @@ Bzip2InputStream::Open(Error &error)
 	return true;
 }
 
-inline void
-Bzip2InputStream::Close()
-{
-	BZ2_bzDecompressEnd(&bzstream);
-}
-
 /* archive open && listing routine */
 
 static ArchiveFile *
@@ -166,6 +159,7 @@ Bzip2InputStream::Bzip2InputStream(Bzip2ArchiveFile &_context,
 
 Bzip2InputStream::~Bzip2InputStream()
 {
+	BZ2_bzDecompressEnd(&bzstream);
 	archive->Unref();
 }
 
@@ -183,15 +177,6 @@ Bzip2ArchiveFile::OpenStream(const char *path,
 	return bis;
 }
 
-static void
-bz2_is_close(InputStream *is)
-{
-	Bzip2InputStream *bis = (Bzip2InputStream *)is;
-
-	bis->Close();
-	delete bis;
-}
-
 static bool
 bz2_fillbuffer(Bzip2InputStream *bis, Error &error)
 {
@@ -273,7 +258,6 @@ const InputPlugin bz2_inputplugin = {
 	nullptr,
 	nullptr,
 	nullptr,
-	bz2_is_close,
 	nullptr,
 	nullptr,
 	nullptr,
diff --git a/src/archive/plugins/Iso9660ArchivePlugin.cxx b/src/archive/plugins/Iso9660ArchivePlugin.cxx
index 8390a354f..0a9cb8214 100644
--- a/src/archive/plugins/Iso9660ArchivePlugin.cxx
+++ b/src/archive/plugins/Iso9660ArchivePlugin.cxx
@@ -181,14 +181,6 @@ Iso9660ArchiveFile::OpenStream(const char *pathname,
 				      statbuf);
 }
 
-static void
-iso9660_input_close(InputStream *is)
-{
-	Iso9660InputStream *iis = (Iso9660InputStream *)is;
-
-	delete iis;
-}
-
 inline size_t
 Iso9660InputStream::Read(void *ptr, size_t read_size, Error &error)
 {
@@ -250,7 +242,6 @@ const InputPlugin iso9660_input_plugin = {
 	nullptr,
 	nullptr,
 	nullptr,
-	iso9660_input_close,
 	nullptr,
 	nullptr,
 	nullptr,
diff --git a/src/archive/plugins/ZzipArchivePlugin.cxx b/src/archive/plugins/ZzipArchivePlugin.cxx
index 69f984e5e..4eafe4aeb 100644
--- a/src/archive/plugins/ZzipArchivePlugin.cxx
+++ b/src/archive/plugins/ZzipArchivePlugin.cxx
@@ -142,14 +142,6 @@ ZzipArchiveFile::OpenStream(const char *pathname,
 				   _file);
 }
 
-static void
-zzip_input_close(InputStream *is)
-{
-	ZzipInputStream *zis = (ZzipInputStream *)is;
-
-	delete zis;
-}
-
 static size_t
 zzip_input_read(InputStream *is, void *ptr, size_t size,
 		Error &error)
@@ -202,7 +194,6 @@ const InputPlugin zzip_input_plugin = {
 	nullptr,
 	nullptr,
 	nullptr,
-	zzip_input_close,
 	nullptr,
 	nullptr,
 	nullptr,
diff --git a/src/decoder/DecoderThread.cxx b/src/decoder/DecoderThread.cxx
index 4dd3c215c..06735de83 100644
--- a/src/decoder/DecoderThread.cxx
+++ b/src/decoder/DecoderThread.cxx
@@ -271,7 +271,7 @@ decoder_run_stream(Decoder &decoder, const char *uri)
 		 decoder_run_stream_fallback(decoder, *input_stream));
 
 	dc.Unlock();
-	input_stream->Close();
+	delete input_stream;
 	dc.Lock();
 
 	return success;
@@ -318,7 +318,7 @@ TryDecoderFile(Decoder &decoder, Path path_fs, const char *suffix,
 
 		dc.Unlock();
 
-		input_stream->Close();
+		delete input_stream;
 
 		if (success) {
 			dc.Lock();
diff --git a/src/decoder/plugins/WavpackDecoderPlugin.cxx b/src/decoder/plugins/WavpackDecoderPlugin.cxx
index 070a913f2..eb15a3380 100644
--- a/src/decoder/plugins/WavpackDecoderPlugin.cxx
+++ b/src/decoder/plugins/WavpackDecoderPlugin.cxx
@@ -467,7 +467,7 @@ wavpack_open_wvc(Decoder &decoder, const char *uri,
 	size_t nbytes = decoder_read(decoder, *is_wvc,
 				     &first_byte, sizeof(first_byte));
 	if (nbytes == 0) {
-		is_wvc->Close();
+		delete is_wvc;
 		return nullptr;
 	}
 
@@ -519,7 +519,7 @@ wavpack_streamdecode(Decoder &decoder, InputStream &is)
 
 	WavpackCloseFile(wpc);
 	if (open_flags & OPEN_WVC) {
-		is_wvc->Close();
+		delete is_wvc;
 	}
 }
 
diff --git a/src/input/InputPlugin.hxx b/src/input/InputPlugin.hxx
index 412ca4cf9..449604434 100644
--- a/src/input/InputPlugin.hxx
+++ b/src/input/InputPlugin.hxx
@@ -82,7 +82,6 @@ struct InputPlugin {
 	InputStream *(*open)(const char *uri,
 			     Mutex &mutex, Cond &cond,
 			     Error &error);
-	void (*close)(InputStream *is);
 
 	/**
 	 * Check for errors that may have occurred in the I/O thread.
diff --git a/src/input/InputStream.cxx b/src/input/InputStream.cxx
index d54eca643..2e0df6856 100644
--- a/src/input/InputStream.cxx
+++ b/src/input/InputStream.cxx
@@ -31,6 +31,10 @@
 
 static constexpr Domain input_domain("input");
 
+InputStream::~InputStream()
+{
+}
+
 InputStream *
 InputStream::Open(const char *url,
 		  Mutex &mutex, Cond &cond,
@@ -41,7 +45,6 @@ InputStream::Open(const char *url,
 
 		is = plugin->open(url, mutex, cond, error);
 		if (is != nullptr) {
-			assert(is->plugin.close != nullptr);
 			assert(is->plugin.read != nullptr);
 			assert(is->plugin.eof != nullptr);
 			assert(!is->seekable || is->plugin.seek != nullptr);
@@ -72,7 +75,7 @@ InputStream::OpenReady(const char *uri,
 	mutex.unlock();
 
 	if (!success) {
-		is->Close();
+		delete is;
 		is = nullptr;
 	}
 
@@ -202,12 +205,6 @@ InputStream::LockRead(void *ptr, size_t _size, Error &error)
 	return Read(ptr, _size, error);
 }
 
-void
-InputStream::Close()
-{
-	plugin.close(this);
-}
-
 bool
 InputStream::IsEOF()
 {
diff --git a/src/input/InputStream.hxx b/src/input/InputStream.hxx
index 65840ba27..4a9d7832a 100644
--- a/src/input/InputStream.hxx
+++ b/src/input/InputStream.hxx
@@ -108,6 +108,13 @@ public:
 		assert(_uri != nullptr);
 	}
 
+	/**
+	 * Close the input stream and free resources.
+	 *
+	 * The caller must not lock the mutex.
+	 */
+	virtual ~InputStream();
+
 	/**
 	 * Opens a new input stream.  You may not access it until the "ready"
 	 * flag is set.
@@ -133,13 +140,6 @@ public:
 				      Mutex &mutex, Cond &cond,
 				      Error &error);
 
-	/**
-	 * Close the input stream and free resources.
-	 *
-	 * The caller must not lock the mutex.
-	 */
-	void Close();
-
 	const InputPlugin &GetPlugin() const {
 		return plugin;
 	}
diff --git a/src/input/ThreadInputStream.cxx b/src/input/ThreadInputStream.cxx
index 0f503be3f..408b757f9 100644
--- a/src/input/ThreadInputStream.cxx
+++ b/src/input/ThreadInputStream.cxx
@@ -29,6 +29,15 @@
 
 ThreadInputStream::~ThreadInputStream()
 {
+	Lock();
+	close = true;
+	wake_cond.signal();
+	Unlock();
+
+	Cancel();
+
+	thread.Join();
+
 	if (buffer != nullptr) {
 		buffer->Clear();
 		HugeFree(buffer->Write().data, buffer_size);
@@ -172,28 +181,6 @@ ThreadInputStream::Read(InputStream *is, void *ptr, size_t size,
 	return tis.Read2(ptr, size, error);
 }
 
-inline void
-ThreadInputStream::Close2()
-{
-	Lock();
-	close = true;
-	wake_cond.signal();
-	Unlock();
-
-	Cancel();
-
-	thread.Join();
-
-	delete this;
-}
-
-void
-ThreadInputStream::Close(InputStream *is)
-{
-	ThreadInputStream &tis = *(ThreadInputStream *)is;
-	tis.Close2();
-}
-
 inline bool
 ThreadInputStream::IsEOF2()
 {
diff --git a/src/input/ThreadInputStream.hxx b/src/input/ThreadInputStream.hxx
index 63cdd5003..2354000f6 100644
--- a/src/input/ThreadInputStream.hxx
+++ b/src/input/ThreadInputStream.hxx
@@ -134,7 +134,6 @@ private:
 	bool Check2(Error &error);
 	bool Available2();
 	size_t Read2(void *ptr, size_t size, Error &error);
-	void Close2();
 	bool IsEOF2();
 
 public:
@@ -143,7 +142,6 @@ public:
 	static bool Available(InputStream *is);
 	static size_t Read(InputStream *is, void *ptr, size_t size,
 			   Error &error);
-	static void Close(InputStream *is);
 	static bool IsEOF(InputStream *is);
 };
 
diff --git a/src/input/plugins/AlsaInputPlugin.cxx b/src/input/plugins/AlsaInputPlugin.cxx
index c1ff41d55..2049c5635 100644
--- a/src/input/plugins/AlsaInputPlugin.cxx
+++ b/src/input/plugins/AlsaInputPlugin.cxx
@@ -373,13 +373,6 @@ alsa_input_open(const char *uri, Mutex &mutex, Cond &cond, Error &error)
 	return AlsaInputStream::Create(uri, mutex, cond, error);
 }
 
-static void
-alsa_input_close(InputStream *is)
-{
-	AlsaInputStream *ais = (AlsaInputStream *)is;
-	delete ais;
-}
-
 static bool
 alsa_input_available(InputStream *is)
 {
@@ -406,7 +399,6 @@ const struct InputPlugin input_plugin_alsa = {
 	nullptr,
 	nullptr,
 	alsa_input_open,
-	alsa_input_close,
 	nullptr,
 	nullptr,
 	nullptr,
diff --git a/src/input/plugins/ArchiveInputPlugin.cxx b/src/input/plugins/ArchiveInputPlugin.cxx
index f49669674..8a8be5b2f 100644
--- a/src/input/plugins/ArchiveInputPlugin.cxx
+++ b/src/input/plugins/ArchiveInputPlugin.cxx
@@ -96,5 +96,4 @@ const InputPlugin input_plugin_archive = {
 	nullptr,
 	nullptr,
 	nullptr,
-	nullptr,
 };
diff --git a/src/input/plugins/CdioParanoiaInputPlugin.cxx b/src/input/plugins/CdioParanoiaInputPlugin.cxx
index 8e1762427..c5b238320 100644
--- a/src/input/plugins/CdioParanoiaInputPlugin.cxx
+++ b/src/input/plugins/CdioParanoiaInputPlugin.cxx
@@ -105,14 +105,6 @@ input_cdio_init(const config_param &param, Error &error)
 	return InputPlugin::InitResult::SUCCESS;
 }
 
-static void
-input_cdio_close(InputStream *is)
-{
-	CdioParanoiaInputStream *i = (CdioParanoiaInputStream *)is;
-
-	delete i;
-}
-
 struct cdio_uri {
 	char device[64];
 	int track;
@@ -394,7 +386,6 @@ const InputPlugin input_plugin_cdio_paranoia = {
 	input_cdio_init,
 	nullptr,
 	input_cdio_open,
-	input_cdio_close,
 	nullptr,
 	nullptr,
 	nullptr,
diff --git a/src/input/plugins/CurlInputPlugin.cxx b/src/input/plugins/CurlInputPlugin.cxx
index 63fb84190..fa93a1d7e 100644
--- a/src/input/plugins/CurlInputPlugin.cxx
+++ b/src/input/plugins/CurlInputPlugin.cxx
@@ -805,14 +805,6 @@ input_curl_read(InputStream *is, void *ptr, size_t size,
 	return c.Read(ptr, size, error);
 }
 
-static void
-input_curl_close(InputStream *is)
-{
-	CurlInputStream *c = (CurlInputStream *)is;
-
-	delete c;
-}
-
 static bool
 input_curl_eof(gcc_unused InputStream *is)
 {
@@ -1144,7 +1136,6 @@ const struct InputPlugin input_plugin_curl = {
 	input_curl_init,
 	input_curl_finish,
 	input_curl_open,
-	input_curl_close,
 	input_curl_check,
 	nullptr,
 	input_curl_tag,
diff --git a/src/input/plugins/DespotifyInputPlugin.cxx b/src/input/plugins/DespotifyInputPlugin.cxx
index 16ef07f0d..86fbbbad3 100644
--- a/src/input/plugins/DespotifyInputPlugin.cxx
+++ b/src/input/plugins/DespotifyInputPlugin.cxx
@@ -61,9 +61,7 @@ class DespotifyInputStream final : public InputStream {
 	}
 
 public:
-	~DespotifyInputStream() {
-		despotify_free_track(track);
-	}
+	~DespotifyInputStream();
 
 	static InputStream *Open(const char *url, Mutex &mutex, Cond &cond,
 				 Error &error);
@@ -146,6 +144,12 @@ static void callback(gcc_unused struct despotify_session* ds,
 	ctx->Callback(sig);
 }
 
+DespotifyInputStream::~DespotifyInputStream()
+{
+	mpd_despotify_unregister_callback(callback);
+	despotify_free_track(track);
+}
+
 inline InputStream *
 DespotifyInputStream::Open(const char *url,
 			   Mutex &mutex, Cond &cond,
@@ -220,15 +224,6 @@ input_despotify_read(InputStream *is, void *ptr, size_t size, Error &error)
 	return ctx->Read(ptr, size, error);
 }
 
-static void
-input_despotify_close(InputStream *is)
-{
-	DespotifyInputStream *ctx = (DespotifyInputStream *)is;
-
-	mpd_despotify_unregister_callback(callback);
-	delete ctx;
-}
-
 static bool
 input_despotify_eof(InputStream *is)
 {
@@ -250,7 +245,6 @@ const InputPlugin input_plugin_despotify = {
 	nullptr,
 	nullptr,
 	input_despotify_open,
-	input_despotify_close,
 	nullptr,
 	nullptr,
 	input_despotify_tag,
diff --git a/src/input/plugins/FfmpegInputPlugin.cxx b/src/input/plugins/FfmpegInputPlugin.cxx
index affd76718..366a99f46 100644
--- a/src/input/plugins/FfmpegInputPlugin.cxx
+++ b/src/input/plugins/FfmpegInputPlugin.cxx
@@ -125,14 +125,6 @@ input_ffmpeg_read(InputStream *is, void *ptr, size_t size,
 	return (size_t)ret;
 }
 
-static void
-input_ffmpeg_close(InputStream *is)
-{
-	FfmpegInputStream *i = (FfmpegInputStream *)is;
-
-	delete i;
-}
-
 static bool
 input_ffmpeg_eof(InputStream *is)
 {
@@ -163,7 +155,6 @@ const InputPlugin input_plugin_ffmpeg = {
 	input_ffmpeg_init,
 	nullptr,
 	input_ffmpeg_open,
-	input_ffmpeg_close,
 	nullptr,
 	nullptr,
 	nullptr,
diff --git a/src/input/plugins/FileInputPlugin.cxx b/src/input/plugins/FileInputPlugin.cxx
index 932db2150..e96347c6e 100644
--- a/src/input/plugins/FileInputPlugin.cxx
+++ b/src/input/plugins/FileInputPlugin.cxx
@@ -123,14 +123,6 @@ input_file_read(InputStream *is, void *ptr, size_t size,
 	return (size_t)nbytes;
 }
 
-static void
-input_file_close(InputStream *is)
-{
-	FileInputStream *fis = (FileInputStream *)is;
-
-	delete fis;
-}
-
 static bool
 input_file_eof(InputStream *is)
 {
@@ -142,7 +134,6 @@ const InputPlugin input_plugin_file = {
 	nullptr,
 	nullptr,
 	input_file_open,
-	input_file_close,
 	nullptr,
 	nullptr,
 	nullptr,
diff --git a/src/input/plugins/MmsInputPlugin.cxx b/src/input/plugins/MmsInputPlugin.cxx
index d4095b2cb..a5d4bc09d 100644
--- a/src/input/plugins/MmsInputPlugin.cxx
+++ b/src/input/plugins/MmsInputPlugin.cxx
@@ -106,7 +106,6 @@ const InputPlugin input_plugin_mms = {
 	nullptr,
 	nullptr,
 	input_mms_open,
-	ThreadInputStream::Close,
 	ThreadInputStream::Check,
 	nullptr,
 	nullptr,
diff --git a/src/input/plugins/NfsInputPlugin.cxx b/src/input/plugins/NfsInputPlugin.cxx
index 9b5ca5959..19eda0605 100644
--- a/src/input/plugins/NfsInputPlugin.cxx
+++ b/src/input/plugins/NfsInputPlugin.cxx
@@ -156,13 +156,6 @@ input_nfs_read(InputStream *is, void *ptr, size_t size,
 	return s.Read(ptr, size, error);
 }
 
-static void
-input_nfs_close(InputStream *is)
-{
-	NfsInputStream *s = (NfsInputStream *)is;
-	delete s;
-}
-
 static bool
 input_nfs_eof(InputStream *is)
 {
@@ -184,7 +177,6 @@ const InputPlugin input_plugin_nfs = {
 	nullptr,
 	nullptr,
 	input_nfs_open,
-	input_nfs_close,
 	nullptr,
 	nullptr,
 	nullptr,
diff --git a/src/input/plugins/RewindInputPlugin.cxx b/src/input/plugins/RewindInputPlugin.cxx
index 9665615f8..b1ec3ab62 100644
--- a/src/input/plugins/RewindInputPlugin.cxx
+++ b/src/input/plugins/RewindInputPlugin.cxx
@@ -60,7 +60,7 @@ public:
 	}
 
 	~RewindInputStream() {
-		input->Close();
+		delete input;
 	}
 
 	bool Check(Error &error) {
@@ -121,14 +121,6 @@ private:
 	}
 };
 
-static void
-input_rewind_close(InputStream *is)
-{
-	RewindInputStream *r = (RewindInputStream *)is;
-
-	delete r;
-}
-
 static bool
 input_rewind_check(InputStream *is, Error &error)
 {
@@ -263,7 +255,6 @@ const InputPlugin rewind_input_plugin = {
 	nullptr,
 	nullptr,
 	nullptr,
-	input_rewind_close,
 	input_rewind_check,
 	input_rewind_update,
 	input_rewind_tag,
diff --git a/src/input/plugins/SmbclientInputPlugin.cxx b/src/input/plugins/SmbclientInputPlugin.cxx
index c291f0608..07ffb83c4 100644
--- a/src/input/plugins/SmbclientInputPlugin.cxx
+++ b/src/input/plugins/SmbclientInputPlugin.cxx
@@ -149,13 +149,6 @@ input_smbclient_read(InputStream *is, void *ptr, size_t size,
 	return s.Read(ptr, size, error);
 }
 
-static void
-input_smbclient_close(InputStream *is)
-{
-	SmbclientInputStream *s = (SmbclientInputStream *)is;
-	delete s;
-}
-
 static bool
 input_smbclient_eof(InputStream *is)
 {
@@ -177,7 +170,6 @@ const InputPlugin input_plugin_smbclient = {
 	input_smbclient_init,
 	nullptr,
 	input_smbclient_open,
-	input_smbclient_close,
 	nullptr,
 	nullptr,
 	nullptr,
diff --git a/src/playlist/CloseSongEnumerator.cxx b/src/playlist/CloseSongEnumerator.cxx
index 6a4042395..2dddef823 100644
--- a/src/playlist/CloseSongEnumerator.cxx
+++ b/src/playlist/CloseSongEnumerator.cxx
@@ -24,7 +24,7 @@
 CloseSongEnumerator::~CloseSongEnumerator()
 {
 	delete other;
-	is->Close();
+	delete is;
 }
 
 DetachedSong *
diff --git a/src/playlist/PlaylistStream.cxx b/src/playlist/PlaylistStream.cxx
index 6222a768d..5855c598b 100644
--- a/src/playlist/PlaylistStream.cxx
+++ b/src/playlist/PlaylistStream.cxx
@@ -50,7 +50,7 @@ playlist_open_path_suffix(const char *path_fs, Mutex &mutex, Cond &cond)
 	if (playlist != nullptr)
 		playlist = new CloseSongEnumerator(playlist, is);
 	else
-		is->Close();
+		delete is;
 
 	return playlist;
 }
@@ -85,7 +85,7 @@ playlist_open_remote(const char *uri, Mutex &mutex, Cond &cond)
 
 	playlist = playlist_list_open_stream(*is, uri);
 	if (playlist == nullptr) {
-		is->Close();
+		delete is;
 		return nullptr;
 	}
 
diff --git a/src/playlist/plugins/SoundCloudPlaylistPlugin.cxx b/src/playlist/plugins/SoundCloudPlaylistPlugin.cxx
index 8f378ac9d..d9f62300b 100644
--- a/src/playlist/plugins/SoundCloudPlaylistPlugin.cxx
+++ b/src/playlist/plugins/SoundCloudPlaylistPlugin.cxx
@@ -276,7 +276,7 @@ soundcloud_parse_json(const char *url, yajl_handle hand,
 				done = true;
 			} else {
 				mutex.unlock();
-				input_stream->Close();
+				delete input_stream;
 				return -1;
 			}
 		}
@@ -304,7 +304,7 @@ soundcloud_parse_json(const char *url, yajl_handle hand,
 	}
 
 	mutex.unlock();
-	input_stream->Close();
+	delete input_stream;
 
 	return 0;
 }
diff --git a/test/dump_playlist.cxx b/test/dump_playlist.cxx
index 5f7fad993..5928c8eb4 100644
--- a/test/dump_playlist.cxx
+++ b/test/dump_playlist.cxx
@@ -105,7 +105,7 @@ int main(int argc, char **argv)
 
 		playlist = playlist_list_open_stream(*is, uri);
 		if (playlist == NULL) {
-			is->Close();
+			delete is;
 			fprintf(stderr, "Failed to open playlist\n");
 			return 2;
 		}
@@ -139,8 +139,7 @@ int main(int argc, char **argv)
 	/* deinitialize everything */
 
 	delete playlist;
-	if (is != NULL)
-		is->Close();
+	delete is;
 
 	decoder_plugin_deinit_all();
 	playlist_list_global_finish();
diff --git a/test/dump_text_file.cxx b/test/dump_text_file.cxx
index a2fc10b3f..79b402b5a 100644
--- a/test/dump_text_file.cxx
+++ b/test/dump_text_file.cxx
@@ -112,7 +112,7 @@ int main(int argc, char **argv)
 	InputStream *is = InputStream::OpenReady(argv[1], mutex, cond, error);
 	if (is != NULL) {
 		ret = dump_input_stream(*is);
-		is->Close();
+		delete is;
 	} else {
 		if (error.IsDefined())
 			LogError(error);
diff --git a/test/read_tags.cxx b/test/read_tags.cxx
index c525c8064..f11b04f7a 100644
--- a/test/read_tags.cxx
+++ b/test/read_tags.cxx
@@ -127,7 +127,7 @@ int main(int argc, char **argv)
 		}
 
 		success = plugin->ScanStream(*is, print_handler, nullptr);
-		is->Close();
+		delete is;
 	}
 
 	decoder_plugin_deinit_all();
diff --git a/test/run_decoder.cxx b/test/run_decoder.cxx
index 58731d5a5..c6f25b3fc 100644
--- a/test/run_decoder.cxx
+++ b/test/run_decoder.cxx
@@ -230,7 +230,7 @@ int main(int argc, char **argv)
 
 		decoder.plugin->StreamDecode(decoder, *is);
 
-		is->Close();
+		delete is;
 	} else {
 		fprintf(stderr, "Decoder plugin is not usable\n");
 		return EXIT_FAILURE;
diff --git a/test/run_input.cxx b/test/run_input.cxx
index 4a35e1479..130d0f031 100644
--- a/test/run_input.cxx
+++ b/test/run_input.cxx
@@ -132,7 +132,7 @@ int main(int argc, char **argv)
 	is = InputStream::OpenReady(argv[1], mutex, cond, error);
 	if (is != NULL) {
 		ret = dump_input_stream(is);
-		is->Close();
+		delete is;
 	} else {
 		if (error.IsDefined())
 			LogError(error);