diff --git a/src/mixer/basetrackplayer.cpp b/src/mixer/basetrackplayer.cpp index d7c5ecc664b..6f4247f4007 100644 --- a/src/mixer/basetrackplayer.cpp +++ b/src/mixer/basetrackplayer.cpp @@ -253,7 +253,7 @@ BaseTrackPlayerImpl::~BaseTrackPlayerImpl() { } TrackPointer BaseTrackPlayerImpl::loadFakeTrack(bool bPlay, double filebpm) { - TrackPointer pTrack(Track::newTemporary()); + TrackPointer pTrack = Track::newTemporary(); pTrack->setAudioProperties( mixxx::kEngineChannelCount, mixxx::audio::SampleRate(44100), diff --git a/src/track/globaltrackcache.cpp b/src/track/globaltrackcache.cpp index 4460dc40a11..cc42bbfb9f5 100644 --- a/src/track/globaltrackcache.cpp +++ b/src/track/globaltrackcache.cpp @@ -152,10 +152,15 @@ QSet GlobalTrackCacheLocker::getCachedTrackIds() const { } GlobalTrackCacheResolver::GlobalTrackCacheResolver( - mixxx::FileAccess fileAccess) + mixxx::FileAccess fileAccess, + bool temporary) : m_lookupResult(GlobalTrackCacheLookupResult::None) { DEBUG_ASSERT(m_pInstance); - m_pInstance->resolve(this, std::move(fileAccess), TrackId()); + if (temporary) { + m_pInstance->resolveTemporary(this, std::move(fileAccess)); + } else { + m_pInstance->resolve(this, std::move(fileAccess), TrackId()); + } m_pInstance->m_mutex.unlock(); } @@ -685,6 +690,51 @@ void GlobalTrackCache::resolve( std::move(trackRef)); } +void GlobalTrackCache::resolveTemporary( + GlobalTrackCacheResolver* /*in/out*/ pCacheResolver, + mixxx::FileAccess /*in*/ fileAccess) { + DEBUG_ASSERT(pCacheResolver); + + TrackPointer pTrack; + + auto trackRef = TrackRef::fromFileInfo(fileAccess.info()); + if (trackRef.hasCanonicalLocation()) { + pTrack = lookupByCanonicalLocation(trackRef.getCanonicalLocation()); + if (pTrack) { + // Multiple tracks may reference the same physical file on disk + auto cachedTrackRef = createTrackRef(*pTrack); + if (trackRef.getLocation() != cachedTrackRef.getLocation()) { + kLogger.warning() + << "Found a different track for the same canonical location:" + << "requested =" << trackRef + << "cached =" << cachedTrackRef; + pCacheResolver->initLookupResult( + GlobalTrackCacheLookupResult::ConflictCanonicalLocation, + TrackPointer(), + std::move(cachedTrackRef)); + } else { + pCacheResolver->initLookupResult( + GlobalTrackCacheLookupResult::Hit, + std::move(pTrack), + std::move(cachedTrackRef)); + } + return; + } + } + + pTrack = Track::newTemporary(std::move(fileAccess)); + while (m_incompletTrack) { + // Wait for completion. + m_isTrackCompleted.wait(&m_mutex); + // now the track should be empty + } + m_incompletTrack = pTrack; + pCacheResolver->initLookupResult( + GlobalTrackCacheLookupResult::Miss, + std::move(pTrack), + std::move(trackRef)); +} + TrackRef GlobalTrackCache::initTrackId( const TrackPointer& strongPtr, const TrackRef& trackRef, diff --git a/src/track/globaltrackcache.h b/src/track/globaltrackcache.h index 288e28b60a6..f3e7a0753da 100644 --- a/src/track/globaltrackcache.h +++ b/src/track/globaltrackcache.h @@ -130,7 +130,8 @@ class GlobalTrackCacheLocker { class GlobalTrackCacheResolver final: public GlobalTrackCacheLocker { public: GlobalTrackCacheResolver( - mixxx::FileAccess fileAccess); + mixxx::FileAccess fileAccess, + bool temporary = false); GlobalTrackCacheResolver( mixxx::FileAccess fileAccess, TrackId trackId); @@ -252,8 +253,12 @@ class GlobalTrackCache : public QObject { void resolve( GlobalTrackCacheResolver* /*in/out*/ pCacheResolver, - mixxx::FileAccess /*in*/ fileAccess, - TrackId /*in*/ trackId); + mixxx::FileAccess fileAccess, + TrackId trackId); + + void resolveTemporary( + GlobalTrackCacheResolver* /*in/out*/ pCacheResolver, + mixxx::FileAccess fileAccess); TrackRef initTrackId( const TrackPointer& strongPtr,