diff options
author | Max Kellermann <max@musicpd.org> | 2016-11-22 12:25:52 +0100 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2016-11-22 16:49:31 +0100 |
commit | 95e2bec215b17e11601edf5456eaf0e73ccc944d (patch) | |
tree | 7b1471f36e519ec9a0ff2970401b08ada677cf46 /src | |
parent | 72c96052b4f4c18959fe0fb374bc8c17cb9c19fe (diff) |
decoder/DecoderPlugin: container_scan() returns forward_list<DetachedSong>
Speed up container_scan() again, by eliminating the need to call
scan_file() for each item.
Diffstat (limited to 'src')
-rw-r--r-- | src/db/update/Container.cxx | 31 | ||||
-rw-r--r-- | src/decoder/DecoderPlugin.hxx | 4 | ||||
-rw-r--r-- | src/decoder/plugins/GmeDecoderPlugin.cxx | 17 | ||||
-rw-r--r-- | src/decoder/plugins/SidplayDecoderPlugin.cxx | 22 |
4 files changed, 40 insertions, 34 deletions
diff --git a/src/db/update/Container.cxx b/src/db/update/Container.cxx index c56ed1eb8..b21c4adb4 100644 --- a/src/db/update/Container.cxx +++ b/src/db/update/Container.cxx @@ -20,6 +20,7 @@ #include "config.h" /* must be first for large file support */ #include "Walk.hxx" #include "UpdateDomain.hxx" +#include "DetachedSong.hxx" #include "db/DatabaseLock.hxx" #include "db/plugins/simple/Directory.hxx" #include "db/plugins/simple/Song.hxx" @@ -28,8 +29,6 @@ #include "decoder/DecoderList.hxx" #include "fs/AllocatedPath.hxx" #include "storage/FileInfo.hxx" -#include "tag/TagHandler.hxx" -#include "tag/TagBuilder.hxx" #include "Log.hxx" #include "util/AllocatedString.hxx" @@ -97,34 +96,21 @@ UpdateWalk::UpdateContainerFile(Directory &directory, } try { - const auto v = plugin.container_scan(pathname); + auto v = plugin.container_scan(pathname); if (v.empty()) { editor.LockDeleteDirectory(contdir); return false; } - TagBuilder tag_builder; - for (const auto &vtrack : v) { - Song *song = Song::NewFile(vtrack.c_str(), *contdir); + for (auto &vtrack : v) { + Song *song = Song::NewFrom(std::move(vtrack), + *contdir); // shouldn't be necessary but it's there.. song->mtime = info.mtime; - try { - const auto vtrack_fs = - AllocatedPath::FromUTF8Throw(vtrack.c_str()); - - const auto child_path_fs = AllocatedPath::Build(pathname, - vtrack_fs); - plugin.ScanFile(child_path_fs, - add_tag_handler, &tag_builder); - } catch (const std::runtime_error &e) { - song->Free(); - LogError(e); - continue; - } - - tag_builder.Commit(song->tag); + FormatDefault(update_domain, "added %s/%s", + contdir->GetPath(), song->uri); { const ScopeDatabaseLock protect; @@ -132,9 +118,6 @@ UpdateWalk::UpdateContainerFile(Directory &directory, } modified = true; - - FormatDefault(update_domain, "added %s/%s", - directory.GetPath(), vtrack.c_str()); } } catch (const std::runtime_error &e) { editor.LockDeleteDirectory(contdir); diff --git a/src/decoder/DecoderPlugin.hxx b/src/decoder/DecoderPlugin.hxx index ec24a115f..d36bb4002 100644 --- a/src/decoder/DecoderPlugin.hxx +++ b/src/decoder/DecoderPlugin.hxx @@ -23,13 +23,13 @@ #include "Compiler.h" #include <forward_list> -#include <string> struct ConfigBlock; class InputStream; struct TagHandler; class Path; class DecoderClient; +class DetachedSong; struct DecoderPlugin { const char *name; @@ -93,7 +93,7 @@ struct DecoderPlugin { * a filename for every single track; * do not include full pathname here, just the "virtual" file */ - std::forward_list<std::string> (*container_scan)(Path path_fs); + std::forward_list<DetachedSong> (*container_scan)(Path path_fs); /* last element in these arrays must always be a nullptr: */ const char *const*suffixes; diff --git a/src/decoder/plugins/GmeDecoderPlugin.cxx b/src/decoder/plugins/GmeDecoderPlugin.cxx index f3813d475..cd58bc06a 100644 --- a/src/decoder/plugins/GmeDecoderPlugin.cxx +++ b/src/decoder/plugins/GmeDecoderPlugin.cxx @@ -22,7 +22,9 @@ #include "../DecoderAPI.hxx" #include "config/Block.cxx" #include "CheckAudioFormat.hxx" +#include "DetachedSong.hxx" #include "tag/TagHandler.hxx" +#include "tag/TagBuilder.hxx" #include "fs/Path.hxx" #include "fs/AllocatedPath.hxx" #include "util/ScopeExit.hxx" @@ -266,10 +268,10 @@ gme_scan_file(Path path_fs, return ScanMusicEmu(emu, container.track, handler, handler_ctx); } -static std::forward_list<std::string> +static std::forward_list<DetachedSong> gme_container_scan(Path path_fs) { - std::forward_list<std::string> list; + std::forward_list<DetachedSong> list; Music_Emu *emu; const char *gme_err = gme_open_file(path_fs.c_str(), &emu, @@ -279,20 +281,27 @@ gme_container_scan(Path path_fs) return list; } + AtScopeExit(emu) { gme_delete(emu); }; + const unsigned num_songs = gme_track_count(emu); - gme_delete(emu); /* if it only contains a single tune, don't treat as container */ if (num_songs < 2) return list; const char *subtune_suffix = uri_get_suffix(path_fs.c_str()); + TagBuilder tag_builder; + auto tail = list.before_begin(); for (unsigned i = 1; i <= num_songs; ++i) { + ScanMusicEmu(emu, i, + add_tag_handler, &tag_builder); + char track_name[64]; snprintf(track_name, sizeof(track_name), SUBTUNE_PREFIX "%03u.%s", i, subtune_suffix); - tail = list.emplace_after(tail, track_name); + tail = list.emplace_after(tail, track_name, + tag_builder.Commit()); } return list; diff --git a/src/decoder/plugins/SidplayDecoderPlugin.cxx b/src/decoder/plugins/SidplayDecoderPlugin.cxx index 151a73914..b7edd9a95 100644 --- a/src/decoder/plugins/SidplayDecoderPlugin.cxx +++ b/src/decoder/plugins/SidplayDecoderPlugin.cxx @@ -21,6 +21,8 @@ #include "SidplayDecoderPlugin.hxx" #include "../DecoderAPI.hxx" #include "tag/TagHandler.hxx" +#include "tag/TagBuilder.hxx" +#include "DetachedSong.hxx" #include "fs/Path.hxx" #include "fs/AllocatedPath.hxx" #include "util/Macros.hxx" @@ -467,12 +469,16 @@ sidplay_scan_file(Path path_fs, return true; } -static std::forward_list<std::string> +static std::forward_list<DetachedSong> sidplay_container_scan(Path path_fs) { - std::forward_list<std::string> list; + std::forward_list<DetachedSong> list; - SidTune tune(path_fs.c_str(), nullptr, true); +#ifdef HAVE_SIDPLAYFP + SidTune tune(path_fs.c_str()); +#else + SidTuneMod tune(path_fs.c_str()); +#endif if (!tune.getStatus()) return list; @@ -489,13 +495,21 @@ sidplay_container_scan(Path path_fs) if(!all_files_are_containers && n_tracks < 2) return list; + TagBuilder tag_builder; + auto tail = list.before_begin(); for (unsigned i = 1; i <= n_tracks; ++i) { + tune.selectSong(i); + + ScanSidTuneInfo(info, i, n_tracks, + add_tag_handler, &tag_builder); + char track_name[32]; /* Construct container/tune path names, eg. Delta.sid/tune_001.sid */ sprintf(track_name, SUBTUNE_PREFIX "%03u.sid", i); - tail = list.emplace_after(tail, track_name); + tail = list.emplace_after(tail, track_name, + tag_builder.Commit()); } return list; |