-
Notifications
You must be signed in to change notification settings - Fork 18
[qtAliceVision] Improve the Sequence Player #76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
6bac381
00c98c2
1dc75c5
a82c3ae
2f0537f
d304d86
62030e1
02206d4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,253 @@ | ||||||||||
| #include "AsyncFetcher.hpp" | ||||||||||
|
|
||||||||||
| #include <QMutexLocker> | ||||||||||
| #include <QPoint> | ||||||||||
|
|
||||||||||
| #include <thread> | ||||||||||
| #include <chrono> | ||||||||||
|
|
||||||||||
| using namespace aliceVision; | ||||||||||
|
|
||||||||||
| namespace qtAliceVision { | ||||||||||
| namespace imgserve { | ||||||||||
|
|
||||||||||
| AsyncFetcher::AsyncFetcher() | ||||||||||
| { | ||||||||||
| _resizeRatio = 0.001; | ||||||||||
| _isAsynchroneous = false; | ||||||||||
| _requestSynchroneous = false; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| AsyncFetcher::~AsyncFetcher() | ||||||||||
| { | ||||||||||
|
|
||||||||||
| } | ||||||||||
|
|
||||||||||
| void AsyncFetcher::setSequence(const std::vector<std::string> & paths) | ||||||||||
| { | ||||||||||
| //Sequence can't be changed while thread is running | ||||||||||
| if (_isAsynchroneous) | ||||||||||
servantftransperfect marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
| { | ||||||||||
| return; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| _sequence = paths; | ||||||||||
| _currentIndex = 0; | ||||||||||
|
|
||||||||||
| for (unsigned idx = 0; idx < _sequence.size(); idx++) | ||||||||||
| { | ||||||||||
| _pathToSeqId[_sequence[idx]] = idx; | ||||||||||
| } | ||||||||||
| } | ||||||||||
|
|
||||||||||
| void AsyncFetcher::setResizeRatio(double ratio) | ||||||||||
| { | ||||||||||
| QMutexLocker locker(&_mutexResizeRatio); | ||||||||||
| _resizeRatio = ratio; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| void AsyncFetcher::setCache(ImageCache::uptr && cache) | ||||||||||
| { | ||||||||||
| //Cache can't be changed while thread is running | ||||||||||
| if (_isAsynchroneous) | ||||||||||
| { | ||||||||||
| return; | ||||||||||
| } | ||||||||||
| _cache = std::move(cache); | ||||||||||
| } | ||||||||||
|
|
||||||||||
|
|
||||||||||
| void AsyncFetcher::run() | ||||||||||
| { | ||||||||||
| using namespace std::chrono_literals; | ||||||||||
|
|
||||||||||
| _isAsynchroneous = true; | ||||||||||
| _requestSynchroneous = false; | ||||||||||
servantftransperfect marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| int previousCacheSize = getDiskLoads(); | ||||||||||
|
|
||||||||||
| while (1) | ||||||||||
| { | ||||||||||
| if (_requestSynchroneous) | ||||||||||
| { | ||||||||||
| _requestSynchroneous = false; | ||||||||||
| break; | ||||||||||
| } | ||||||||||
servantftransperfect marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| if (_sequence.size() == 0) | ||||||||||
| { | ||||||||||
| std::this_thread::sleep_for(100ms); | ||||||||||
| } | ||||||||||
| else | ||||||||||
| { | ||||||||||
| const std::string & lpath = _sequence[_currentIndex]; | ||||||||||
|
|
||||||||||
| //Load in cache | ||||||||||
| if (_cache) | ||||||||||
| { | ||||||||||
| double ratio; | ||||||||||
| { | ||||||||||
| QMutexLocker locker(&_mutexResizeRatio); | ||||||||||
| ratio = _resizeRatio; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| _cache->get<image::RGBAfColor>(lpath, _currentIndex, ratio, false); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| _currentIndex++; | ||||||||||
|
|
||||||||||
| int size = _sequence.size(); | ||||||||||
| if (_currentIndex >= size) | ||||||||||
| { | ||||||||||
| _currentIndex = 0; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| std::this_thread::sleep_for(1ms); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| int cacheSize = getDiskLoads(); | ||||||||||
| if (cacheSize != previousCacheSize) | ||||||||||
| { | ||||||||||
| previousCacheSize = cacheSize; | ||||||||||
| Q_EMIT onAsyncFetchProgressed(); | ||||||||||
| } | ||||||||||
| } | ||||||||||
|
|
||||||||||
| _requestSynchroneous = false; | ||||||||||
| _isAsynchroneous = false; | ||||||||||
|
||||||||||
| _requestSynchroneous = false; | |
| _isAsynchroneous = false; | |
| _requestSynchronous = false; | |
| _isAsynchronous = false; |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| _requestSynchroneous = true; | |
| _requestSynchronous = true; |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return (_cache)?_cache->info().getContentSize():0.0f; | |
| return (_cache) ? _cache->info().getContentSize() : 0.0f; |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return (_cache)?_cache->info().getLoadFromDisk():0.0f; | |
| return (_cache) ? _cache->info().getLoadFromDisk() : 0.0f; |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| bool onlyCache = _isAsynchroneous; | |
| bool onlyCache = _isAsynchronous; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| #pragma once | ||
|
|
||
| #include <QObject> | ||
| #include <QRunnable> | ||
| #include <QMutex> | ||
| #include <QVariantList> | ||
|
|
||
|
|
||
| #include "ImageCache.hpp" | ||
|
|
||
| namespace qtAliceVision { | ||
| namespace imgserve { | ||
|
|
||
| class AsyncFetcher : public QObject, public QRunnable | ||
| { | ||
| Q_OBJECT | ||
|
|
||
| public: | ||
| AsyncFetcher(); | ||
| ~AsyncFetcher(); | ||
|
|
||
| /** | ||
| * @brief Cache object is created externally. | ||
| * Pass it to the Fetcher for use (Fetcher get ownership) | ||
| * @param cache the cache object to store | ||
| */ | ||
| void setCache(ImageCache::uptr && cache); | ||
|
|
||
| /** | ||
| * @brief set the image sequence | ||
| * The image sequence is a list of image paths which is ordered | ||
| * The Fetcher must not be in asynchroneous mode for this function to work | ||
servantftransperfect marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| * As such, the _sequence object is only used in read mode during async mode. | ||
| */ | ||
| void setSequence(const std::vector<std::string> & paths); | ||
|
|
||
| /** | ||
| * @brief update the resize ratio of the image | ||
| * @param ratio the coefficient of resize of the loaded images | ||
| */ | ||
| void setResizeRatio(double ratio); | ||
|
|
||
| /** | ||
| * @brief retrieve a frame from the cache in both sync and async mode | ||
| * @param path the image path which should be contained in _sequence. | ||
| * @param image the result image pointer | ||
| * @param metadatas the image metadatas found in the file | ||
| * @param originalWidth the image width before the resize | ||
| * @param originalHeight the image height before the resize | ||
| * @return true if the image was succesfully found in the cache | ||
| */ | ||
| bool getFrame(const std::string & path, | ||
| std::shared_ptr<aliceVision::image::Image<aliceVision::image::RGBAfColor>> & image, | ||
| oiio::ParamValueList & metadatas, | ||
| size_t & originalWidth, | ||
| size_t & originalHeight); | ||
|
|
||
|
|
||
| /** | ||
| * @brief Internal function for QT to start the asynchroneous mode | ||
| */ | ||
| Q_SLOT void run() override; | ||
|
|
||
| /** | ||
| * @brief stop asynchroneous mode | ||
servantftransperfect marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| * The caller have to wait on the thread pool to guarantee the effective end | ||
| */ | ||
| void stopAsync(); | ||
|
|
||
| bool isAsync() const | ||
| { | ||
| return _isAsynchroneous; | ||
servantftransperfect marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| /** | ||
| * @brief get the cache content size in bytes | ||
| * @return the cache content size in bytes | ||
| */ | ||
| size_t getCacheSize() const; | ||
|
|
||
| /** | ||
| * @brief get the number of images loaded | ||
| * @return the count of images loaded since the creation of the cache object | ||
| */ | ||
| size_t getDiskLoads() const; | ||
|
|
||
| /** | ||
| * @brief update maxMemory for the cache | ||
| * @param maxMemory the number of bytes allowed in the cache | ||
| */ | ||
| void updateCacheMemory(size_t maxMemory); | ||
|
|
||
| /** | ||
| * @brief get a list of regions containing the image frames | ||
| * @return a list of two values (begin, end) | ||
| */ | ||
| QVariantList getCachedFrames() const; | ||
|
|
||
| public: | ||
| Q_SIGNAL void onAsyncFetchProgressed(); | ||
|
|
||
| private: | ||
| ImageCache::uptr _cache; | ||
|
|
||
| std::vector<std::string> _sequence; | ||
| std::unordered_map<std::string, unsigned> _pathToSeqId; | ||
|
|
||
| QAtomicInt _currentIndex; | ||
| QAtomicInt _isAsynchroneous; | ||
| QAtomicInt _requestSynchroneous; | ||
servantftransperfect marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| double _resizeRatio; | ||
| QMutex _mutexResizeRatio; | ||
| }; | ||
|
|
||
| } // namespace imgserve | ||
| } // namespace qtAliceVision | ||
Uh oh!
There was an error while loading. Please reload this page.