aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2014-05-22 11:10:41 +0200
committerMax Kellermann <max@duempel.org>2014-05-22 12:35:20 +0200
commit4eeea640f4641ec7c2b303567adf3e79855eb885 (patch)
treeb56039e1576a437594230027766b7bd0c5cec9e7
parentcc6f1020d01a6f8f814a6a6a211a00d490459f66 (diff)
downloadmpd-4eeea640f4641ec7c2b303567adf3e79855eb885.tar.gz
mpd-4eeea640f4641ec7c2b303567adf3e79855eb885.tar.xz
mpd-4eeea640f4641ec7c2b303567adf3e79855eb885.zip
DecoderAPI: add function decoder_open_uri()
Move and refactor code from the Wavpack decoder plugin.
-rw-r--r--src/decoder/DecoderAPI.cxx32
-rw-r--r--src/decoder/DecoderAPI.hxx10
-rw-r--r--src/decoder/plugins/WavpackDecoderPlugin.cxx19
-rw-r--r--test/FakeDecoderAPI.cxx6
-rw-r--r--test/FakeDecoderAPI.hxx5
-rw-r--r--test/run_decoder.cxx7
6 files changed, 56 insertions, 23 deletions
diff --git a/src/decoder/DecoderAPI.cxx b/src/decoder/DecoderAPI.cxx
index 555e5c89b..5c4822804 100644
--- a/src/decoder/DecoderAPI.cxx
+++ b/src/decoder/DecoderAPI.cxx
@@ -240,6 +240,38 @@ void decoder_seek_error(Decoder & decoder)
decoder_command_finished(decoder);
}
+InputStream *
+decoder_open_uri(Decoder &decoder, const char *uri, Error &error)
+{
+ assert(decoder.dc.state == DecoderState::START ||
+ decoder.dc.state == DecoderState::DECODE);
+
+ DecoderControl &dc = decoder.dc;
+ Mutex &mutex = dc.mutex;
+ Cond &cond = dc.cond;
+
+ InputStream *is = InputStream::Open(uri, mutex, cond, error);
+ if (is == nullptr)
+ return nullptr;
+
+ mutex.lock();
+ while (true) {
+ is->Update();
+ if (is->IsReady()) {
+ mutex.unlock();
+ return is;
+ }
+
+ if (dc.command == DecoderCommand::STOP) {
+ mutex.unlock();
+ delete is;
+ return nullptr;
+ }
+
+ cond.wait(mutex);
+ }
+}
+
/**
* Should be read operation be cancelled? That is the case when the
* player thread has sent a command such as "STOP".
diff --git a/src/decoder/DecoderAPI.hxx b/src/decoder/DecoderAPI.hxx
index 0a7b84371..c57a02e01 100644
--- a/src/decoder/DecoderAPI.hxx
+++ b/src/decoder/DecoderAPI.hxx
@@ -40,6 +40,8 @@
// IWYU pragma: end_exports
+class Error;
+
/**
* Notify the player thread that it has finished initialization and
* that it has read the song's meta data.
@@ -96,6 +98,14 @@ void
decoder_seek_error(Decoder &decoder);
/**
+ * Open a new #InputStream and wait until it's ready. Can get
+ * cancelled by DecoderCommand::STOP (returns nullptr without setting
+ * #Error).
+ */
+InputStream *
+decoder_open_uri(Decoder &decoder, const char *uri, Error &error);
+
+/**
* Blocking read from the input stream.
*
* @param decoder the decoder object
diff --git a/src/decoder/plugins/WavpackDecoderPlugin.cxx b/src/decoder/plugins/WavpackDecoderPlugin.cxx
index e47bcbb30..e14d93369 100644
--- a/src/decoder/plugins/WavpackDecoderPlugin.cxx
+++ b/src/decoder/plugins/WavpackDecoderPlugin.cxx
@@ -440,7 +440,6 @@ wavpack_input_init(WavpackInput *isp, Decoder &decoder,
static InputStream *
wavpack_open_wvc(Decoder &decoder, const char *uri,
- Mutex &mutex, Cond &cond,
WavpackInput *wpi)
{
/*
@@ -452,28 +451,13 @@ wavpack_open_wvc(Decoder &decoder, const char *uri,
char *wvc_url = g_strconcat(uri, "c", nullptr);
- InputStream *is_wvc = InputStream::Open(wvc_url, mutex, cond,
- IgnoreError());
+ InputStream *is_wvc = decoder_open_uri(decoder, uri, IgnoreError());
g_free(wvc_url);
if (is_wvc == nullptr)
return nullptr;
- /*
- * And we try to buffer in order to get know
- * about a possible 404 error.
- */
- char first_byte;
- size_t nbytes = decoder_read(decoder, *is_wvc,
- &first_byte, sizeof(first_byte));
- if (nbytes == 0) {
- delete is_wvc;
- return nullptr;
- }
-
- /* push it back */
wavpack_input_init(wpi, decoder, *is_wvc);
- wpi->last_byte = first_byte;
return is_wvc;
}
@@ -488,7 +472,6 @@ wavpack_streamdecode(Decoder &decoder, InputStream &is)
WavpackInput isp_wvc;
InputStream *is_wvc = wavpack_open_wvc(decoder, is.GetURI(),
- is.mutex, is.cond,
&isp_wvc);
if (is_wvc != nullptr) {
open_flags |= OPEN_WVC;
diff --git a/test/FakeDecoderAPI.cxx b/test/FakeDecoderAPI.cxx
index 155e7d5df..7aa24c4df 100644
--- a/test/FakeDecoderAPI.cxx
+++ b/test/FakeDecoderAPI.cxx
@@ -66,6 +66,12 @@ decoder_seek_error(gcc_unused Decoder &decoder)
{
}
+InputStream *
+decoder_open_uri(Decoder &decoder, const char *uri, Error &error)
+{
+ return InputStream::OpenReady(uri, decoder.mutex, decoder.cond, error);
+}
+
size_t
decoder_read(gcc_unused Decoder *decoder,
InputStream &is,
diff --git a/test/FakeDecoderAPI.hxx b/test/FakeDecoderAPI.hxx
index 134e77117..6f1933977 100644
--- a/test/FakeDecoderAPI.hxx
+++ b/test/FakeDecoderAPI.hxx
@@ -21,8 +21,13 @@
#define FAKE_DECODER_API_HXX
#include "check.h"
+#include "thread/Mutex.hxx"
+#include "thread/Cond.hxx"
struct Decoder {
+ Mutex mutex;
+ Cond cond;
+
bool initialized;
Decoder()
diff --git a/test/run_decoder.cxx b/test/run_decoder.cxx
index b1c739405..3980340cc 100644
--- a/test/run_decoder.cxx
+++ b/test/run_decoder.cxx
@@ -27,7 +27,6 @@
#include "fs/Path.hxx"
#include "AudioFormat.hxx"
#include "util/Error.hxx"
-#include "thread/Cond.hxx"
#include "Log.hxx"
#include "stdbin.h"
@@ -77,11 +76,9 @@ int main(int argc, char **argv)
if (plugin->file_decode != nullptr) {
plugin->FileDecode(decoder, Path::FromFS(uri));
} else if (plugin->stream_decode != nullptr) {
- Mutex mutex;
- Cond cond;
-
InputStream *is =
- InputStream::OpenReady(uri, mutex, cond, error);
+ InputStream::OpenReady(uri, decoder.mutex,
+ decoder.cond, error);
if (is == NULL) {
if (error.IsDefined())
LogError(error);