aboutsummaryrefslogtreecommitdiffstats
path: root/src/DecoderThread.cxx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/DecoderThread.cxx109
1 files changed, 62 insertions, 47 deletions
diff --git a/src/DecoderThread.cxx b/src/DecoderThread.cxx
index 72fc3cfb4..7099b3bd4 100644
--- a/src/DecoderThread.cxx
+++ b/src/DecoderThread.cxx
@@ -23,13 +23,12 @@
#include "DecoderInternal.hxx"
#include "DecoderError.hxx"
#include "DecoderPlugin.hxx"
-#include "Song.hxx"
+#include "DetachedSong.hxx"
#include "system/FatalError.hxx"
#include "Mapper.hxx"
#include "fs/Traits.hxx"
#include "fs/AllocatedPath.hxx"
#include "DecoderAPI.hxx"
-#include "tag/Tag.hxx"
#include "InputStream.hxx"
#include "DecoderList.hxx"
#include "util/UriUtil.hxx"
@@ -146,7 +145,7 @@ decoder_file_decode(const DecoderPlugin &plugin,
assert(decoder.stream_tag == nullptr);
assert(decoder.decoder_tag == nullptr);
assert(path != nullptr);
- assert(PathTraits::IsAbsoluteFS(path));
+ assert(PathTraitsFS::IsAbsolute(path));
assert(decoder.dc.state == DecoderState::START);
FormatDebug(decoder_thread_domain, "probing plugin %s", plugin.name);
@@ -281,54 +280,66 @@ decoder_load_replay_gain(Decoder &decoder, const char *path_fs)
decoder_replay_gain(decoder, &info);
}
-/**
- * Try decoding a file.
- */
static bool
-decoder_run_file(Decoder &decoder, const char *path_fs)
+TryDecoderFile(Decoder &decoder, const char *path_fs, const char *suffix,
+ const DecoderPlugin &plugin)
{
+ if (!plugin.SupportsSuffix(suffix))
+ return false;
+
DecoderControl &dc = decoder.dc;
- const char *suffix = uri_get_suffix(path_fs);
- const struct DecoderPlugin *plugin = nullptr;
- if (suffix == nullptr)
- return false;
+ if (plugin.file_decode != nullptr) {
+ dc.Lock();
- dc.Unlock();
+ if (decoder_file_decode(plugin, decoder, path_fs))
+ return true;
- decoder_load_replay_gain(decoder, path_fs);
+ dc.Unlock();
+ } else if (plugin.stream_decode != nullptr) {
+ InputStream *input_stream =
+ decoder_input_stream_open(dc, path_fs);
+ if (input_stream == nullptr)
+ return false;
- while ((plugin = decoder_plugin_from_suffix(suffix, plugin)) != nullptr) {
- if (plugin->file_decode != nullptr) {
- dc.Lock();
+ dc.Lock();
- if (decoder_file_decode(*plugin, decoder, path_fs))
- return true;
+ bool success = decoder_stream_decode(plugin, decoder,
+ *input_stream);
- dc.Unlock();
- } else if (plugin->stream_decode != nullptr) {
- InputStream *input_stream;
- bool success;
+ dc.Unlock();
- input_stream = decoder_input_stream_open(dc, path_fs);
- if (input_stream == nullptr)
- continue;
+ input_stream->Close();
+ if (success) {
dc.Lock();
+ return true;
+ }
+ }
- success = decoder_stream_decode(*plugin, decoder,
- *input_stream);
+ return false;
+}
+
+/**
+ * Try decoding a file.
+ */
+static bool
+decoder_run_file(Decoder &decoder, const char *path_fs)
+{
+ const char *suffix = uri_get_suffix(path_fs);
+ if (suffix == nullptr)
+ return false;
- dc.Unlock();
+ DecoderControl &dc = decoder.dc;
+ dc.Unlock();
- input_stream->Close();
+ decoder_load_replay_gain(decoder, path_fs);
- if (success) {
- dc.Lock();
- return true;
- }
- }
- }
+ if (decoder_plugins_try([&decoder, path_fs, suffix](const DecoderPlugin &plugin){
+ return TryDecoderFile(decoder, path_fs, suffix,
+ plugin);
+ }))
+ return true;
dc.Lock();
return false;
@@ -336,18 +347,17 @@ decoder_run_file(Decoder &decoder, const char *path_fs)
static void
decoder_run_song(DecoderControl &dc,
- const Song *song, const char *uri)
+ const DetachedSong &song, const char *uri)
{
Decoder decoder(dc, dc.start_ms > 0,
- song->tag != nullptr && song->IsFile()
- ? new Tag(*song->tag) : nullptr);
+ new Tag(song.GetTag()));
int ret;
dc.state = DecoderState::START;
decoder_command_finished_locked(dc);
- ret = song->IsFile()
+ ret = song.IsFile()
? decoder_run_file(decoder, uri)
: decoder_run_stream(decoder, uri);
@@ -356,16 +366,21 @@ decoder_run_song(DecoderControl &dc,
/* flush the last chunk */
if (decoder.chunk != nullptr)
- decoder_flush_chunk(decoder);
+ decoder.FlushChunk();
dc.Lock();
- if (ret)
+ if (decoder.error.IsDefined()) {
+ /* copy the Error from sruct Decoder to
+ DecoderControl */
+ dc.state = DecoderState::ERROR;
+ dc.error = std::move(decoder.error);
+ } else if (ret)
dc.state = DecoderState::STOP;
else {
dc.state = DecoderState::ERROR;
- const char *error_uri = song->uri;
+ const char *error_uri = song.GetURI();
const std::string allocated = uri_remove_auth(error_uri);
if (!allocated.empty())
error_uri = allocated.c_str();
@@ -382,12 +397,12 @@ decoder_run(DecoderControl &dc)
{
dc.ClearError();
- const Song *song = dc.song;
- assert(song != nullptr);
+ assert(dc.song != nullptr);
+ const DetachedSong &song = *dc.song;
- const std::string uri = song->IsFile()
- ? std::string(map_song_fs(*song).c_str())
- : song->GetURI();
+ const std::string uri = song.IsFile()
+ ? map_song_fs(song).c_str()
+ : song.GetURI();
if (uri.empty()) {
dc.state = DecoderState::ERROR;