diff options
Diffstat (limited to 'src/DecoderThread.cxx')
-rw-r--r-- | src/DecoderThread.cxx | 109 |
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; |