From 363c610d958827aae6af77ae55a82acc52728abc Mon Sep 17 00:00:00 2001 From: Darby Johnston Date: Sun, 25 Feb 2024 16:28:30 -0800 Subject: [PATCH] Make the read cache private --- lib/tlTimeline/CMakeLists.txt | 2 - lib/tlTimeline/ReadCache.cpp | 80 -------------------------- lib/tlTimeline/ReadCache.h | 55 ------------------ lib/tlTimeline/Timeline.cpp | 16 +++--- lib/tlTimeline/Timeline.h | 16 +++--- lib/tlTimeline/TimelineCreate.cpp | 50 +++++----------- lib/tlTimeline/TimelinePrivate.cpp | 91 +++++++++++++----------------- lib/tlTimeline/TimelinePrivate.h | 8 ++- lib/tlTimeline/Util.h | 2 + lib/tlTimelineUI/AudioClipItem.cpp | 2 + lib/tlTimelineUI/VideoClipItem.cpp | 2 + lib/tlUI/ThumbnailSystem.cpp | 6 +- 12 files changed, 83 insertions(+), 247 deletions(-) delete mode 100644 lib/tlTimeline/ReadCache.cpp delete mode 100644 lib/tlTimeline/ReadCache.h diff --git a/lib/tlTimeline/CMakeLists.txt b/lib/tlTimeline/CMakeLists.txt index 876978f47..45a3c78c8 100644 --- a/lib/tlTimeline/CMakeLists.txt +++ b/lib/tlTimeline/CMakeLists.txt @@ -21,7 +21,6 @@ set(HEADERS PlayerInline.h PlayerOptions.h PlayerOptionsInline.h - ReadCache.h RenderOptions.h RenderOptionsInline.h RenderUtil.h @@ -50,7 +49,6 @@ set(SOURCE Player.cpp PlayerOptions.cpp PlayerPrivate.cpp - ReadCache.cpp RenderUtil.cpp TimeUnits.cpp Timeline.cpp diff --git a/lib/tlTimeline/ReadCache.cpp b/lib/tlTimeline/ReadCache.cpp deleted file mode 100644 index e919a57bc..000000000 --- a/lib/tlTimeline/ReadCache.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -// Copyright (c) 2021-2024 Darby Johnston -// All rights reserved. - -#include - -#include -#include -#include - -namespace tl -{ - namespace timeline - { - namespace - { - std::string getKey(const file::Path& path) - { - std::vector out; - out.push_back(path.get()); - out.push_back(path.getNumber()); - return string::join(out, ';'); - } - } - - struct ReadCache::Private - { - memory::LRUCache cache; - }; - - void ReadCache::_init() - { - TLRENDER_P(); - } - - ReadCache::ReadCache() : - _p(new Private) - {} - - ReadCache::~ReadCache() - {} - - std::shared_ptr ReadCache::create() - { - auto out = std::shared_ptr(new ReadCache); - out->_init(); - return out; - } - - void ReadCache::add(const ReadCacheItem& read) - { - const file::Path& path = read.read->getPath(); - const std::string key = getKey(path); - _p->cache.add(key, read); - } - - bool ReadCache::get(const file::Path& path, ReadCacheItem& out) - { - return _p->cache.get(getKey(path), out); - } - - void ReadCache::setMax(size_t value) - { - _p->cache.setMax(value); - } - - size_t ReadCache::getCount() const - { - return _p->cache.getCount(); - } - - void ReadCache::cancelRequests() - { - for (auto& i : _p->cache.getValues()) - { - i.read->cancelRequests(); - } - } - } -} diff --git a/lib/tlTimeline/ReadCache.h b/lib/tlTimeline/ReadCache.h deleted file mode 100644 index 67f0eeee7..000000000 --- a/lib/tlTimeline/ReadCache.h +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -// Copyright (c) 2021-2024 Darby Johnston -// All rights reserved. - -#pragma once - -#include - -namespace tl -{ - namespace timeline - { - //! I/O read cache item. - struct ReadCacheItem - { - std::shared_ptr read; - io::Info ioInfo; - }; - - //! I/O read cache. - class ReadCache - { - TLRENDER_NON_COPYABLE(ReadCache); - - protected: - void _init(); - - ReadCache(); - - public: - ~ReadCache(); - - //! Create a new read cache. - static std::shared_ptr create(); - - //! Add an item to the cache. - void add(const ReadCacheItem&); - - //! Get an item from the cache. - bool get(const file::Path&, ReadCacheItem&); - - //! Set the maximum number of read objects. - void setMax(size_t); - - //! Get the number of read objects. - size_t getCount() const; - - //! Cancel requests. - void cancelRequests(); - - private: - TLRENDER_PRIVATE(); - }; - } -} diff --git a/lib/tlTimeline/Timeline.cpp b/lib/tlTimeline/Timeline.cpp index c7335a9b5..28cc637b5 100644 --- a/lib/tlTimeline/Timeline.cpp +++ b/lib/tlTimeline/Timeline.cpp @@ -17,6 +17,11 @@ namespace tl { namespace timeline { + namespace + { + const size_t readCacheMax = 10; + } + TLRENDER_ENUM_IMPL( FileSequenceAudio, "None", @@ -45,8 +50,7 @@ namespace tl void Timeline::_init( const otio::SerializableObject::Retainer& otioTimeline, const std::shared_ptr& context, - const Options& options, - const std::shared_ptr& readCache) + const Options& options) { TLRENDER_P(); @@ -80,8 +84,8 @@ namespace tl } p.context = context; - p.options = options; p.otioTimeline = otioTimeline; + p.timelineChanges = observer::Value::create(false); const auto i = otioTimeline->metadata().find("tlRender"); if (i != otioTimeline->metadata().end()) { @@ -102,9 +106,8 @@ namespace tl catch (const std::exception&) {} } - p.timelineChanges = observer::Value::create(false); - p.readCache = readCache ? readCache : ReadCache::create(); - p.readCache->setMax(16); + p.options = options; + p.readCache.setMax(readCacheMax); // Get information about the timeline. p.timeRange = timeline::getTimeRange(p.otioTimeline.value); @@ -324,7 +327,6 @@ namespace tl { request->promise.set_value(AudioData()); } - p.readCache->cancelRequests(); } void Timeline::tick() diff --git a/lib/tlTimeline/Timeline.h b/lib/tlTimeline/Timeline.h index f1f496f49..ebcc6e318 100644 --- a/lib/tlTimeline/Timeline.h +++ b/lib/tlTimeline/Timeline.h @@ -5,14 +5,16 @@ #pragma once #include -#include #include #include +#include #include #include +#include + namespace tl { //! Timelines. @@ -56,8 +58,7 @@ namespace tl otio::SerializableObject::Retainer create( const file::Path&, const std::shared_ptr&, - const Options& = Options(), - const std::shared_ptr& = nullptr); + const Options& = Options()); //! Create a new timeline from a path and audio path. The file name //! can point to an .otio file, .otioz file, movie file, or image @@ -66,8 +67,7 @@ namespace tl const file::Path& path, const file::Path& audioPath, const std::shared_ptr&, - const Options& = Options(), - const std::shared_ptr& = nullptr); + const Options& = Options()); //! Timeline. class Timeline : public std::enable_shared_from_this @@ -78,8 +78,7 @@ namespace tl void _init( const otio::SerializableObject::Retainer&, const std::shared_ptr&, - const Options&, - const std::shared_ptr&); + const Options&); Timeline(); @@ -90,8 +89,7 @@ namespace tl static std::shared_ptr create( const otio::SerializableObject::Retainer&, const std::shared_ptr&, - const Options& = Options(), - const std::shared_ptr& = nullptr); + const Options& = Options()); //! Create a new timeline from a file name. The file name can point //! to an .otio file, movie file, or image sequence. diff --git a/lib/tlTimeline/TimelineCreate.cpp b/lib/tlTimeline/TimelineCreate.cpp index 42596d5f7..cbec7f7fd 100644 --- a/lib/tlTimeline/TimelineCreate.cpp +++ b/lib/tlTimeline/TimelineCreate.cpp @@ -351,18 +351,16 @@ namespace tl otio::SerializableObject::Retainer create( const file::Path& path, const std::shared_ptr& context, - const Options& options, - const std::shared_ptr& readCache) + const Options& options) { - return create(path, file::Path(), context, options, readCache); + return create(path, file::Path(), context, options); } otio::SerializableObject::Retainer create( const file::Path& inputPath, const file::Path& inputAudioPath, const std::shared_ptr& context, - const Options& options, - const std::shared_ptr& readCache) + const Options& options) { otio::SerializableObject::Retainer out; std::string error; @@ -415,13 +413,6 @@ namespace tl if (auto read = ioSystem->read(path, options.ioOptions)) { const auto info = read->getInfo().get(); - if (readCache) - { - ReadCacheItem item; - item.read = read; - item.ioInfo = info; - readCache->add(item); - } otime::RationalTime startTime = time::invalidTime; otio::Track* videoTrack = nullptr; @@ -469,13 +460,6 @@ namespace tl if (auto audioRead = ioSystem->read(audioPath, options.ioOptions)) { const auto audioInfo = audioRead->getInfo().get(); - if (readCache) - { - ReadCacheItem item; - item.read = audioRead; - item.ioInfo = audioInfo; - readCache->add(item); - } auto audioClip = new otio::Clip; audioClip->set_source_range(audioInfo.audioTime); @@ -586,11 +570,10 @@ namespace tl std::shared_ptr Timeline::create( const otio::SerializableObject::Retainer& timeline, const std::shared_ptr& context, - const Options& options, - const std::shared_ptr& readCache) + const Options& options) { auto out = std::shared_ptr(new Timeline); - out->_init(timeline, context, options, readCache); + out->_init(timeline, context, options); return out; } @@ -600,13 +583,11 @@ namespace tl const Options& options) { auto out = std::shared_ptr(new Timeline); - auto readCache = ReadCache::create(); auto otioTimeline = timeline::create( file::Path(fileName, options.pathOptions), context, - options, - readCache); - out->_init(otioTimeline, context, options, readCache); + options); + out->_init(otioTimeline, context, options); return out; } @@ -616,9 +597,8 @@ namespace tl const Options& options) { auto out = std::shared_ptr(new Timeline); - auto readCache = ReadCache::create(); - auto otioTimeline = timeline::create(path, context, options, readCache); - out->_init(otioTimeline, context, options, readCache); + auto otioTimeline = timeline::create(path, context, options); + out->_init(otioTimeline, context, options); return out; } @@ -629,14 +609,12 @@ namespace tl const Options& options) { auto out = std::shared_ptr(new Timeline); - auto readCache = ReadCache::create(); auto otioTimeline = timeline::create( file::Path(fileName, options.pathOptions), file::Path(audioFileName, options.pathOptions), context, - options, - readCache); - out->_init(otioTimeline, context, options, readCache); + options); + out->_init(otioTimeline, context, options); return out; } @@ -647,14 +625,12 @@ namespace tl const Options& options) { auto out = std::shared_ptr(new Timeline); - auto readCache = ReadCache::create(); auto otioTimeline = timeline::create( path, audioPath, context, - options, - readCache); - out->_init(otioTimeline, context, options, readCache); + options); + out->_init(otioTimeline, context, options); return out; } } diff --git a/lib/tlTimeline/TimelinePrivate.cpp b/lib/tlTimeline/TimelinePrivate.cpp index a8c481535..944bf3ce0 100644 --- a/lib/tlTimeline/TimelinePrivate.cpp +++ b/lib/tlTimeline/TimelinePrivate.cpp @@ -24,12 +24,12 @@ namespace tl if (auto context = this->context.lock()) { // The first video clip defines the video information for the timeline. - auto item = getRead(clip, options.ioOptions); - if (item.read) + if (auto read = getRead(clip, options.ioOptions)) { - this->ioInfo.video = item.ioInfo.video; - this->ioInfo.videoTime = item.ioInfo.videoTime; - this->ioInfo.tags.insert(item.ioInfo.tags.begin(), item.ioInfo.tags.end()); + const io::Info& ioInfo = read->getInfo().get(); + this->ioInfo.video = ioInfo.video; + this->ioInfo.videoTime = ioInfo.videoTime; + this->ioInfo.tags.insert(ioInfo.tags.begin(), ioInfo.tags.end()); return true; } } @@ -54,12 +54,12 @@ namespace tl if (auto context = this->context.lock()) { // The first audio clip defines the audio information for the timeline. - auto item = getRead(clip, options.ioOptions); - if (item.read) + if (auto read = getRead(clip, options.ioOptions)) { - this->ioInfo.audio = item.ioInfo.audio; - this->ioInfo.audioTime = item.ioInfo.audioTime; - this->ioInfo.tags.insert(item.ioInfo.tags.begin(), item.ioInfo.tags.end()); + const io::Info& ioInfo = read->getInfo().get(); + this->ioInfo.audio = ioInfo.audio; + this->ioInfo.audioTime = ioInfo.audioTime; + this->ioInfo.tags.insert(ioInfo.tags.begin(), ioInfo.tags.end()); return true; } } @@ -108,16 +108,14 @@ namespace tl "\n" " Path: {0}\n" " Video requests: {1}, {2} in-progress, {3} max\n" - " Audio requests: {4}, {5} in-progress, {6} max\n" - " Read cache: {7}"). + " Audio requests: {4}, {5} in-progress, {6} max"). arg(path.get()). arg(videoRequestsSize). arg(thread.videoRequestsInProgress.size()). arg(options.videoRequestCount). arg(audioRequestsSize). arg(thread.audioRequestsInProgress.size()). - arg(options.audioRequestCount). - arg(readCache->getCount())); + arg(options.audioRequestCount)); } } @@ -440,50 +438,37 @@ namespace tl } } - ReadCacheItem Timeline::Private::getRead( + namespace + { + std::string getKey(const file::Path& path) + { + std::vector out; + out.push_back(path.get()); + out.push_back(path.getNumber()); + return string::join(out, ';'); + } + } + + std::shared_ptr Timeline::Private::getRead( const otio::Clip* clip, const io::Options& ioOptions) { - ReadCacheItem out; + std::shared_ptr out; const auto path = timeline::getPath( clip->media_reference(), this->path.getDirectory(), options.pathOptions); - if (!readCache->get(path, out)) + const std::string key = getKey(path); + if (!readCache.get(key, out)) { if (auto context = this->context.lock()) { - const auto path = timeline::getPath( - clip->media_reference(), - this->path.getDirectory(), - options.pathOptions); const auto memoryRead = getMemoryRead(clip->media_reference()); io::Options options = ioOptions; options["SequenceIO/DefaultSpeed"] = string::Format("{0}").arg(timeRange.duration().rate()); const auto ioSystem = context->getSystem(); - out.read = ioSystem->read(path, memoryRead, options); - if (out.read) - { - out.ioInfo = out.read->getInfo().get(); - readCache->add(out); - context->log( - string::Format("tl::timeline::Timeline {0}").arg(this), - string::Format( - "\n" - " Read: {0}\n" - " Video: {1} {2}\n" - " Video time: {3}\n" - " Audio: {4} {5} {6}\n" - " Audio time: {7}"). - arg(path.get()). - arg(!out.ioInfo.video.empty() ? out.ioInfo.video[0].size : image::Size()). - arg(!out.ioInfo.video.empty() ? out.ioInfo.video[0].pixelType : image::PixelType::None). - arg(out.ioInfo.videoTime). - arg(out.ioInfo.audio.channelCount). - arg(out.ioInfo.audio.dataType). - arg(out.ioInfo.audio.sampleRate). - arg(out.ioInfo.audioTime)); - } + out = ioSystem->read(path, memoryRead, options); + readCache.add(key, out); } } return out; @@ -497,16 +482,17 @@ namespace tl std::future out; io::Options optionsMerged = io::merge(options, this->options.ioOptions); optionsMerged["USD/cameraName"] = clip->name(); - ReadCacheItem item = getRead(clip, optionsMerged); + auto read = getRead(clip, optionsMerged); const auto timeRangeOpt = clip->trimmed_range_in_parent(); - if (item.read && timeRangeOpt.has_value()) + if (read && timeRangeOpt.has_value()) { + const io::Info& ioInfo = read->getInfo().get(); const auto mediaTime = timeline::toVideoMediaTime( time, timeRangeOpt.value(), clip->trimmed_range(), - item.ioInfo.videoTime.duration().rate()); - out = item.read->readVideo(mediaTime, optionsMerged); + ioInfo.videoTime.duration().rate()); + out = read->readVideo(mediaTime, optionsMerged); } return out; } @@ -518,16 +504,17 @@ namespace tl { std::future out; io::Options optionsMerged = io::merge(options, this->options.ioOptions); - ReadCacheItem item = getRead(clip, optionsMerged); + auto read = getRead(clip, optionsMerged); const auto timeRangeOpt = clip->trimmed_range_in_parent(); - if (item.read && timeRangeOpt.has_value()) + if (read && timeRangeOpt.has_value()) { + const io::Info& ioInfo = read->getInfo().get(); const auto mediaRange = timeline::toAudioMediaTime( timeRange, timeRangeOpt.value(), clip->trimmed_range(), - item.ioInfo.audio.sampleRate); - out = item.read->readAudio(mediaRange, optionsMerged); + ioInfo.audio.sampleRate); + out = read->readAudio(mediaRange, optionsMerged); } return out; } diff --git a/lib/tlTimeline/TimelinePrivate.h b/lib/tlTimeline/TimelinePrivate.h index b84f9f851..1ee3353f7 100644 --- a/lib/tlTimeline/TimelinePrivate.h +++ b/lib/tlTimeline/TimelinePrivate.h @@ -6,6 +6,10 @@ #include +#include + +#include + #include #include @@ -28,7 +32,7 @@ namespace tl void requests(); void finishRequests(); - ReadCacheItem getRead( + std::shared_ptr getRead( const otio::Clip*, const io::Options&); std::future readVideo( @@ -51,7 +55,7 @@ namespace tl file::Path path; file::Path audioPath; Options options; - std::shared_ptr readCache; + memory::LRUCache > readCache; otime::TimeRange timeRange = time::invalidTimeRange; io::Info ioInfo; diff --git a/lib/tlTimeline/Util.h b/lib/tlTimeline/Util.h index a5901ce5f..f7d874105 100644 --- a/lib/tlTimeline/Util.h +++ b/lib/tlTimeline/Util.h @@ -6,6 +6,8 @@ #include +#include + #include #include diff --git a/lib/tlTimelineUI/AudioClipItem.cpp b/lib/tlTimelineUI/AudioClipItem.cpp index b98db0d6d..2b8d785e8 100644 --- a/lib/tlTimelineUI/AudioClipItem.cpp +++ b/lib/tlTimelineUI/AudioClipItem.cpp @@ -9,6 +9,8 @@ #include #include +#include + #include #include diff --git a/lib/tlTimelineUI/VideoClipItem.cpp b/lib/tlTimelineUI/VideoClipItem.cpp index 5f5c61858..f0bd19f1f 100644 --- a/lib/tlTimelineUI/VideoClipItem.cpp +++ b/lib/tlTimelineUI/VideoClipItem.cpp @@ -9,6 +9,8 @@ #include #include +#include + #include #include diff --git a/lib/tlUI/ThumbnailSystem.cpp b/lib/tlUI/ThumbnailSystem.cpp index 0d59d09ce..61f49e36f 100644 --- a/lib/tlUI/ThumbnailSystem.cpp +++ b/lib/tlUI/ThumbnailSystem.cpp @@ -24,9 +24,9 @@ namespace tl { namespace { - const size_t infoRequestsMax = 3; - const size_t thumbnailRequestsMax = 3; - const size_t waveformRequestsMax = 3; + const size_t infoRequestsMax = 10; + const size_t thumbnailRequestsMax = 10; + const size_t waveformRequestsMax = 10; } struct ThumbnailCache::Private