Introduced lmscore lib to centralize services, migrated cover service

This commit is contained in:
emeric
2021-10-16 15:22:59 +02:00
parent 0dcef2e94c
commit 32a944e3d4
26 changed files with 149 additions and 106 deletions
+2 -1
View File
@@ -1,8 +1,9 @@
add_subdirectory(auth)
add_subdirectory(av)
add_subdirectory(cover)
add_subdirectory(database)
add_subdirectory(image)
add_subdirectory(lmscore)
add_subdirectory(metadata)
add_subdirectory(recommendation)
add_subdirectory(scanner)
-44
View File
@@ -1,44 +0,0 @@
add_library(lmscover SHARED
impl/CoverService.cpp
)
target_include_directories(lmscover INTERFACE
include
)
target_include_directories(lmscover PRIVATE
include
impl
)
target_link_libraries(lmscover PRIVATE
lmsav
)
target_link_libraries(lmscover PUBLIC
lmsdatabase
lmsutils
std::filesystem
)
if (IMAGE_LIBRARY STREQUAL STB)
target_sources(lmscover PRIVATE
impl/stb/JPEGImage.cpp
impl/stb/RawImage.cpp
)
target_compile_options(lmscover PRIVATE "-DLMS_SUPPORT_IMAGE_STB")
target_include_directories(lmscover PRIVATE ${STB_INCLUDE_DIR})
elseif (IMAGE_LIBRARY STREQUAL GraphicsMagick++)
target_sources(lmscover PRIVATE
impl/graphicsmagick/JPEGImage.cpp
impl/graphicsmagick/RawImage.cpp
)
target_compile_options(lmscover PRIVATE "-DLMS_SUPPORT_IMAGE_GM")
target_link_libraries(lmscover PRIVATE PkgConfig::GraphicsMagick++)
else ()
message(FATAL_ERROR "Invalid IMAGE_LIBRARY provided")
endif()
install(TARGETS lmscover DESTINATION lib)
+38
View File
@@ -0,0 +1,38 @@
add_library(lmsimage SHARED
)
target_include_directories(lmsimage INTERFACE
include
)
target_include_directories(lmsimage PRIVATE
include
impl
)
target_link_libraries(lmsimage PUBLIC
lmsutils
std::filesystem
)
if (IMAGE_LIBRARY STREQUAL STB)
target_sources(lmsimage PRIVATE
impl/stb/JPEGImage.cpp
impl/stb/RawImage.cpp
)
target_compile_options(lmsimage PRIVATE "-DLMS_SUPPORT_IMAGE_STB")
target_include_directories(lmsimage PRIVATE ${STB_INCLUDE_DIR})
elseif (IMAGE_LIBRARY STREQUAL GraphicsMagick++)
target_sources(lmsimage PRIVATE
impl/graphicsmagick/JPEGImage.cpp
impl/graphicsmagick/RawImage.cpp
)
target_compile_options(lmsimage PRIVATE "-DLMS_SUPPORT_IMAGE_GM")
target_link_libraries(lmsimage PRIVATE PkgConfig::GraphicsMagick++)
else ()
message(FATAL_ERROR "Invalid IMAGE_LIBRARY provided")
endif()
install(TARGETS lmsimage DESTINATION lib)
@@ -25,7 +25,16 @@
#include "JPEGImage.hpp"
#include "Exception.hpp"
namespace CoverArt::GraphicsMagick {
namespace Image::GraphicsMagick
{
std::unique_ptr<IRawImage> decodeImage(const std::byte* encodedData, std::size_t encodedDataSize)
{
return std::make_unique<RawImage>(encodedData, encodedDataSize);
}
std::unique_ptr<IRawImage> decodeImage(const std::filesystem::path& path)
{
void
init(const std::filesystem::path& path)
@@ -116,5 +125,5 @@ RawImage::getMagickImage() const
return _image;
}
} // namespace CoverArt::GraphicsMagick
} // namespace Image::GraphicsMagick
@@ -22,10 +22,10 @@
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include <stb/stb_image_write.h>
#include "image/Exception.hpp"
#include "RawImage.hpp"
#include "Exception.hpp"
namespace Cover::STB
namespace Image::STB
{
JPEGImage::JPEGImage(const RawImage& rawImage, unsigned quality)
{
@@ -21,9 +21,9 @@
#include <vector>
#include "cover/IEncodedImage.hpp"
#include "image/IEncodedImage.hpp"
namespace Cover::STB
namespace Image::STB
{
class RawImage;
class JPEGImage : public IEncodedImage
@@ -30,9 +30,22 @@
#include "JPEGImage.hpp"
#include "Exception.hpp"
#include "image/Exception.hpp"
namespace Cover::STB
namespace Image
{
std::unique_ptr<IRawImage> decodeImage(const std::byte* encodedData, std::size_t encodedDataSize)
{
return std::make_unique<STB::RawImage>(encodedData, encodedDataSize);
}
std::unique_ptr<IRawImage> decodeImage(const std::filesystem::path& path)
{
return std::make_unique<STB::RawImage>(path);
}
}
namespace Image::STB
{
RawImage::RawImage(const std::byte* encodedData, std::size_t encodedDataSize)
{
@@ -26,10 +26,10 @@
#include <cstddef>
#include <filesystem>
#include "cover/IEncodedImage.hpp"
#include "IRawImage.hpp"
#include "image/IEncodedImage.hpp"
#include "image/IRawImage.hpp"
namespace Cover::STB
namespace Image::STB
{
class RawImage : public IRawImage
{
@@ -21,7 +21,7 @@
#include "utils/Exception.hpp"
namespace Cover
namespace Image
{
// internal use only
class ImageException : public LmsException
@@ -22,7 +22,7 @@
#include <cstddef>
#include <string_view>
namespace Cover
namespace Image
{
using ImageSize = std::size_t;
@@ -21,9 +21,9 @@
#include <memory>
#include "cover/IEncodedImage.hpp"
#include "image/IEncodedImage.hpp"
namespace Cover
namespace Image
{
class IRawImage
{
@@ -32,5 +32,8 @@ namespace Cover
virtual void resize(ImageSize width) = 0;
virtual std::unique_ptr<IEncodedImage> encodeToJPEG(unsigned quality) const = 0;
};
std::unique_ptr<IRawImage> decodeImage(const std::byte* encodedData, std::size_t encodedDataSize);
std::unique_ptr<IRawImage> decodeImage(const std::filesystem::path& path);
}
+28
View File
@@ -0,0 +1,28 @@
add_library(lmscore SHARED
impl/CoverService.cpp
)
target_include_directories(lmscore INTERFACE
include
)
target_include_directories(lmscore PRIVATE
include
impl
)
target_link_libraries(lmscore PRIVATE
lmsav
lmsimage
)
target_link_libraries(lmscore PUBLIC
lmsdatabase
lmsimage
lmsutils
std::filesystem
)
install(TARGETS lmscore DESTINATION lib)
@@ -26,19 +26,12 @@
#include "database/Session.hpp"
#include "database/Track.hpp"
#if LMS_SUPPORT_IMAGE_STB
#include "stb/RawImage.hpp"
using RawImage = Cover::STB::RawImage;
#elif LMS_SUPPORT_IMAGE_GM
#include "graphicsmagick/RawImage.hpp"
using RawImage = Cover::GraphicsMagick::RawImage;
#endif
#include "image/Exception.hpp"
#include "image/IRawImage.hpp"
#include "utils/IConfig.hpp"
#include "utils/Logger.hpp"
#include "utils/Random.hpp"
#include "utils/Utils.hpp"
#include "Exception.hpp"
namespace
{
@@ -79,6 +72,8 @@ namespace
namespace Cover {
using namespace Image;
static
bool
isFileSupported(const std::filesystem::path& file, const std::vector<std::filesystem::path>& extensions)
@@ -117,7 +112,7 @@ CoverService::CoverService(Database::Db& db,
{
getDefault(512);
}
catch (const ImageException& e)
catch (const Image::ImageException& e)
{
throw LmsException("Cannot read default cover file '" + _defaultCoverPath.string() + "': " + e.what());
}
@@ -135,11 +130,11 @@ CoverService::getFromAvMediaFile(const Av::IAudioFile& input, ImageSize width) c
try
{
RawImage rawImage {picture.data, picture.dataSize};
rawImage.resize(width);
image = rawImage.encodeToJPEG(_jpegQuality);
std::unique_ptr<IRawImage> rawImage {decodeImage(picture.data, picture.dataSize)};
rawImage->resize(width);
image = rawImage->encodeToJPEG(_jpegQuality);
}
catch (const ImageException& e)
catch (const Image::ImageException& e)
{
LMS_LOG(COVER, ERROR) << "Cannot read embedded cover: " << e.what();
}
@@ -155,9 +150,9 @@ CoverService::getFromCoverFile(const std::filesystem::path& p, ImageSize width)
try
{
RawImage rawImage {p};
rawImage.resize(width);
image = rawImage.encodeToJPEG(_jpegQuality);
std::unique_ptr<IRawImage> rawImage {decodeImage(p)};
rawImage->resize(width);
image = rawImage->encodeToJPEG(_jpegQuality);
}
catch (const ImageException& e)
{
@@ -29,8 +29,8 @@
#include <variant>
#include <vector>
#include "cover/ICoverService.hpp"
#include "cover/IEncodedImage.hpp"
#include "lmscore/services/ICoverService.hpp"
#include "image/IEncodedImage.hpp"
#include "database/Types.hpp"
namespace Database
@@ -96,34 +96,34 @@ namespace Cover
CoverService& operator=(CoverService&&) = delete;
private:
std::shared_ptr<IEncodedImage> getFromTrack(Database::TrackId trackId, ImageSize width) override;
std::shared_ptr<IEncodedImage> getFromRelease(Database::ReleaseId releaseId, ImageSize width) override;
std::shared_ptr<Image::IEncodedImage> getFromTrack(Database::TrackId trackId, Image::ImageSize width) override;
std::shared_ptr<Image::IEncodedImage> getFromRelease(Database::ReleaseId releaseId, Image::ImageSize width) override;
void flushCache() override;
void setJpegQuality(unsigned quality) override;
std::shared_ptr<IEncodedImage> getFromTrack(Database::Session& dbSession, Database::TrackId trackId, ImageSize width, bool allowReleaseFallback);
std::unique_ptr<IEncodedImage> getFromAvMediaFile(const Av::IAudioFile& input, ImageSize width) const;
std::unique_ptr<IEncodedImage> getFromCoverFile(const std::filesystem::path& p, ImageSize width) const;
std::shared_ptr<Image::IEncodedImage> getFromTrack(Database::Session& dbSession, Database::TrackId trackId, Image::ImageSize width, bool allowReleaseFallback);
std::unique_ptr<Image::IEncodedImage> getFromAvMediaFile(const Av::IAudioFile& input, Image::ImageSize width) const;
std::unique_ptr<Image::IEncodedImage> getFromCoverFile(const std::filesystem::path& p, Image::ImageSize width) const;
std::unique_ptr<IEncodedImage> getFromTrack(const std::filesystem::path& path, ImageSize width) const;
std::unique_ptr<Image::IEncodedImage> getFromTrack(const std::filesystem::path& path, Image::ImageSize width) const;
std::multimap<std::string, std::filesystem::path> getCoverPaths(const std::filesystem::path& directoryPath) const;
std::unique_ptr<IEncodedImage> getFromDirectory(const std::filesystem::path& directory, ImageSize width) const;
std::unique_ptr<IEncodedImage> getFromSameNamedFile(const std::filesystem::path& filePath, ImageSize width) const;
std::shared_ptr<IEncodedImage> getDefault(ImageSize width);
std::unique_ptr<Image::IEncodedImage> getFromDirectory(const std::filesystem::path& directory, Image::ImageSize width) const;
std::unique_ptr<Image::IEncodedImage> getFromSameNamedFile(const std::filesystem::path& filePath, Image::ImageSize width) const;
std::shared_ptr<Image::IEncodedImage> getDefault(Image::ImageSize width);
bool checkCoverFile(const std::filesystem::path& directoryPath) const;
Database::Db& _db;
std::shared_mutex _cacheMutex;
std::unordered_map<CacheEntryDesc, std::shared_ptr<IEncodedImage>> _cache;
std::unordered_map<ImageSize, std::shared_ptr<IEncodedImage>> _defaultCoverCache;
std::unordered_map<CacheEntryDesc, std::shared_ptr<Image::IEncodedImage>> _cache;
std::unordered_map<Image::ImageSize, std::shared_ptr<Image::IEncodedImage>> _defaultCoverCache;
std::atomic<std::size_t> _cacheMisses {};
std::atomic<std::size_t> _cacheHits {};
std::size_t _cacheSize {};
void saveToCache(const CacheEntryDesc& entryDesc, std::shared_ptr<IEncodedImage> image);
std::shared_ptr<IEncodedImage> loadFromCache(const CacheEntryDesc& entryDesc);
void saveToCache(const CacheEntryDesc& entryDesc, std::shared_ptr<Image::IEncodedImage> image);
std::shared_ptr<Image::IEncodedImage> loadFromCache(const CacheEntryDesc& entryDesc);
const std::filesystem::path _defaultCoverPath;
const std::size_t _maxCacheSize;
@@ -23,7 +23,7 @@
#include <memory>
#include "database/Types.hpp"
#include "cover/IEncodedImage.hpp"
#include "image/IEncodedImage.hpp"
namespace Database
{
@@ -37,8 +37,8 @@ namespace Cover
public:
virtual ~ICoverService() = default;
virtual std::shared_ptr<IEncodedImage> getFromTrack(Database::TrackId trackId, ImageSize width) = 0;
virtual std::shared_ptr<IEncodedImage> getFromRelease(Database::ReleaseId releaseId, ImageSize width) = 0;
virtual std::shared_ptr<Image::IEncodedImage> getFromTrack(Database::TrackId trackId, Image::ImageSize width) = 0;
virtual std::shared_ptr<Image::IEncodedImage> getFromRelease(Database::ReleaseId releaseId, Image::ImageSize width) = 0;
virtual void flushCache() = 0;
+1 -1
View File
@@ -19,7 +19,7 @@ target_include_directories(lmssubsonic PRIVATE
target_link_libraries(lmssubsonic PRIVATE
lmsauth
lmsav
lmscover
lmscore
lmsdatabase
lmsrecommendation
lmsscanner
+2 -2
View File
@@ -28,7 +28,7 @@
#include "auth/IPasswordService.hpp"
#include "auth/IEnvService.hpp"
#include "cover/ICoverService.hpp"
#include "lmscore/services/ICoverService.hpp"
#include "database/Artist.hpp"
#include "database/Cluster.hpp"
#include "database/Db.hpp"
@@ -1802,7 +1802,7 @@ handleGetCoverArt(RequestContext& context, const Wt::Http::Request& /*request*/,
std::size_t size {getParameterAs<std::size_t>(context.parameters, "size").value_or(256)};
size = Utils::clamp(size, std::size_t {32}, std::size_t {1024});
std::shared_ptr<Cover::IEncodedImage> cover;
std::shared_ptr<Image::IEncodedImage> cover;
if (trackId)
cover = Service<Cover::ICoverService>::get()->getFromTrack(*trackId, size);
else if (releaseId)
+1 -1
View File
@@ -51,7 +51,7 @@ target_include_directories(lms PRIVATE
target_link_libraries(lms PRIVATE
lmsav
lmsauth
lmscover
lmscore
lmsdatabase
lmsrecommendation
lmsscanner
+1 -1
View File
@@ -28,7 +28,7 @@
#include "auth/IAuthTokenService.hpp"
#include "auth/IPasswordService.hpp"
#include "auth/IEnvService.hpp"
#include "cover/ICoverService.hpp"
#include "lmscore/services/ICoverService.hpp"
#include "database/Db.hpp"
#include "database/Session.hpp"
#include "scanner/IScanner.hpp"
+1 -1
View File
@@ -30,7 +30,7 @@
#include "auth/IEnvService.hpp"
#include "auth/IPasswordService.hpp"
#include "cover/ICoverService.hpp"
#include "lmscore/services/ICoverService.hpp"
#include "database/Artist.hpp"
#include "database/Cluster.hpp"
#include "database/Db.hpp"
+2 -2
View File
@@ -22,7 +22,7 @@
#include <Wt/WApplication.h>
#include <Wt/Http/Response.h>
#include "cover/ICoverService.hpp"
#include "lmscore/services/ICoverService.hpp"
#include "database/Track.hpp"
#include "utils/Exception.hpp"
#include "utils/Logger.hpp"
@@ -83,7 +83,7 @@ CoverResource::handleRequest(const Wt::Http::Request& request, Wt::Http::Respons
return;
}
std::shared_ptr<Cover::IEncodedImage> cover;
std::shared_ptr<Image::IEncodedImage> cover;
if (trackIdStr)
{
+1 -1
View File
@@ -4,7 +4,7 @@ add_executable(lms-cover
)
target_link_libraries(lms-cover PRIVATE
lmscover
lmscore
Boost::program_options
)
+2 -2
View File
@@ -24,7 +24,7 @@
#include <boost/program_options.hpp>
#include "cover/ICoverService.hpp"
#include "lmscore/services/ICoverService.hpp"
#include "database/Db.hpp"
#include "database/Release.hpp"
#include "database/Session.hpp"
@@ -36,7 +36,7 @@
static
void
dumpTrackCovers(Database::Session& session, Cover::ImageSize width)
dumpTrackCovers(Database::Session& session, Image::ImageSize width)
{
std::vector<Database::TrackId> trackIds;
{