From 4eeea640f4641ec7c2b303567adf3e79855eb885 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 22 May 2014 11:10:41 +0200 Subject: DecoderAPI: add function decoder_open_uri() Move and refactor code from the Wavpack decoder plugin. --- src/decoder/DecoderAPI.cxx | 32 ++++++++++++++++++++++++++++ src/decoder/DecoderAPI.hxx | 10 +++++++++ src/decoder/plugins/WavpackDecoderPlugin.cxx | 19 +---------------- 3 files changed, 43 insertions(+), 18 deletions(-) (limited to 'src/decoder') 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. @@ -95,6 +97,14 @@ decoder_seek_where(Decoder &decoder); 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. * 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; -- cgit v1.2.3