Commit 4eeea640 authored by Max Kellermann's avatar Max Kellermann

DecoderAPI: add function decoder_open_uri()

Move and refactor code from the Wavpack decoder plugin.
parent cc6f1020
......@@ -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".
......
......@@ -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
......
......@@ -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;
......
......@@ -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,
......
......@@ -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()
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment