From 85545dba643fdde779cd12ab7115d0c75e46867f Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 23 Dec 2019 13:27:20 +0300 Subject: [PATCH] Set higher streaming priority in media overlay. --- .../streaming/media_streaming_document.cpp | 12 ++++++++++ .../streaming/media_streaming_document.h | 1 + .../media/streaming/media_streaming_file.cpp | 4 ++++ .../media/streaming/media_streaming_file.h | 1 + .../streaming/media_streaming_instance.cpp | 14 ++++++++++++ .../streaming/media_streaming_instance.h | 4 ++++ .../streaming/media_streaming_loader.cpp | 2 +- .../media/streaming/media_streaming_loader.h | 5 +++-- .../media_streaming_loader_local.cpp | 5 ++++- .../streaming/media_streaming_loader_local.h | 3 ++- .../media_streaming_loader_mtproto.cpp | 22 ++++++++++++++----- .../media_streaming_loader_mtproto.h | 4 +++- .../streaming/media_streaming_player.cpp | 4 ++++ .../media/streaming/media_streaming_player.h | 2 ++ .../streaming/media_streaming_reader.cpp | 18 +++++++++++++-- .../media/streaming/media_streaming_reader.h | 5 +++++ .../media/view/media_view_overlay_widget.cpp | 3 +++ 17 files changed, 95 insertions(+), 14 deletions(-) diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_document.cpp b/Telegram/SourceFiles/media/streaming/media_streaming_document.cpp index addf3251da..9435819651 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_document.cpp +++ b/Telegram/SourceFiles/media/streaming/media_streaming_document.cpp @@ -85,6 +85,18 @@ void Document::registerInstance(not_null instance) { void Document::unregisterInstance(not_null instance) { _instances.remove(instance); _player.unregisterInstance(instance); + refreshPlayerPriority(); +} + +void Document::refreshPlayerPriority() { + if (_instances.empty()) { + return; + } + const auto max = ranges::max_element( + _instances, + ranges::less(), + &Instance::priority); + _player.setLoaderPriority((*max)->priority()); } bool Document::waitingShown() const { diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_document.h b/Telegram/SourceFiles/media/streaming/media_streaming_document.h index 9a3d9b8085..348ae18f7f 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_document.h +++ b/Telegram/SourceFiles/media/streaming/media_streaming_document.h @@ -41,6 +41,7 @@ private: void registerInstance(not_null instance); void unregisterInstance(not_null instance); + void refreshPlayerPriority(); void waitingCallback(); diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_file.cpp b/Telegram/SourceFiles/media/streaming/media_streaming_file.cpp index dc50f0036c..76eca72e5b 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_file.cpp +++ b/Telegram/SourceFiles/media/streaming/media_streaming_file.cpp @@ -421,6 +421,10 @@ bool File::isRemoteLoader() const { return _reader->isRemoteLoader(); } +void File::setLoaderPriority(int priority) { + _reader->setLoaderPriority(priority); +} + File::~File() { stop(); } diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_file.h b/Telegram/SourceFiles/media/streaming/media_streaming_file.h index 63450e89ee..e6992021a2 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_file.h +++ b/Telegram/SourceFiles/media/streaming/media_streaming_file.h @@ -37,6 +37,7 @@ public: void stop(bool stillActive = false); [[nodiscard]] bool isRemoteLoader() const; + void setLoaderPriority(int priority); ~File(); diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_instance.cpp b/Telegram/SourceFiles/media/streaming/media_streaming_instance.cpp index 92848a9c1a..a6082e86e2 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_instance.cpp +++ b/Telegram/SourceFiles/media/streaming/media_streaming_instance.cpp @@ -187,6 +187,20 @@ bool Instance::playerLocked() const { return _shared->player().locked(); } +void Instance::setPriority(int priority) { + Expects(_shared != nullptr); + + if (_priority == priority) { + return; + } + _priority = priority; + _shared->refreshPlayerPriority(); +} + +int Instance::priority() const { + return _priority; +} + rpl::lifetime &Instance::lifetime() { return _lifetime; } diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_instance.h b/Telegram/SourceFiles/media/streaming/media_streaming_instance.h index a52f6ba3be..b070171ff9 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_instance.h +++ b/Telegram/SourceFiles/media/streaming/media_streaming_instance.h @@ -70,11 +70,15 @@ public: void unlockPlayer(); [[nodiscard]] bool playerLocked() const; + void setPriority(int priority); + [[nodiscard]] int priority() const; + [[nodiscard]] rpl::lifetime &lifetime(); private: const std::shared_ptr _shared; Fn _waitingCallback; + int _priority = 1; bool _playerLocked = false; rpl::lifetime _lifetime; diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_loader.cpp b/Telegram/SourceFiles/media/streaming/media_streaming_loader.cpp index aaa79ffaad..c8bb54871b 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_loader.cpp +++ b/Telegram/SourceFiles/media/streaming/media_streaming_loader.cpp @@ -86,7 +86,7 @@ void PriorityQueue::clear() { _data.clear(); } -void PriorityQueue::increasePriority() { +void PriorityQueue::resetPriorities() { ++_priority; } diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_loader.h b/Telegram/SourceFiles/media/streaming/media_streaming_loader.h index cfe19238e6..6b315b6929 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_loader.h +++ b/Telegram/SourceFiles/media/streaming/media_streaming_loader.h @@ -33,7 +33,8 @@ public: virtual void load(int offset) = 0; virtual void cancel(int offset) = 0; - virtual void increasePriority() = 0; + virtual void resetPriorities() = 0; + virtual void setPriority(int priority) = 0; virtual void stop() = 0; // Parts will be sent from the main thread. @@ -51,7 +52,7 @@ class PriorityQueue { public: bool add(int value); bool remove(int value); - void increasePriority(); + void resetPriorities(); [[nodiscard]] bool empty() const; [[nodiscard]] std::optional front() const; [[nodiscard]] std::optional take(); diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_loader_local.cpp b/Telegram/SourceFiles/media/streaming/media_streaming_loader_local.cpp index 00cef555dd..a8b462a9d7 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_loader_local.cpp +++ b/Telegram/SourceFiles/media/streaming/media_streaming_loader_local.cpp @@ -68,7 +68,10 @@ void LoaderLocal::fail() { void LoaderLocal::cancel(int offset) { } -void LoaderLocal::increasePriority() { +void LoaderLocal::resetPriorities() { +} + +void LoaderLocal::setPriority(int priority) { } void LoaderLocal::stop() { diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_loader_local.h b/Telegram/SourceFiles/media/streaming/media_streaming_loader_local.h index b7436e2a5a..5b8b80e9b5 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_loader_local.h +++ b/Telegram/SourceFiles/media/streaming/media_streaming_loader_local.h @@ -26,7 +26,8 @@ public: void load(int offset) override; void cancel(int offset) override; - void increasePriority() override; + void resetPriorities() override; + void setPriority(int priority) override; void stop() override; // Parts will be sent from the main thread. diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_loader_mtproto.cpp b/Telegram/SourceFiles/media/streaming/media_streaming_loader_mtproto.cpp index 1b49998c2f..137ddbf6f8 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_loader_mtproto.cpp +++ b/Telegram/SourceFiles/media/streaming/media_streaming_loader_mtproto.cpp @@ -57,9 +57,7 @@ void LoaderMtproto::load(int offset) { } void LoaderMtproto::addToQueueWithPriority() { - addToQueue([&] { - return 1; - }()); + addToQueue(_priority); } void LoaderMtproto::stop() { @@ -79,7 +77,9 @@ void LoaderMtproto::cancel(int offset) { void LoaderMtproto::cancelForOffset(int offset) { if (haveSentRequestForOffset(offset)) { cancelRequestForOffset(offset); - addToQueueWithPriority(); + if (!_requested.empty()) { + addToQueueWithPriority(); + } } else { _requested.remove(offset); } @@ -94,12 +94,22 @@ void LoaderMtproto::clearAttachedDownloader() { _downloader = nullptr; } -void LoaderMtproto::increasePriority() { +void LoaderMtproto::resetPriorities() { crl::on_main(this, [=] { - _requested.increasePriority(); + _requested.resetPriorities(); }); } +void LoaderMtproto::setPriority(int priority) { + if (_priority == priority) { + return; + } + _priority = priority; + if (haveSentRequests()) { + addToQueueWithPriority(); + } +} + bool LoaderMtproto::readyToRequest() const { return !_requested.empty(); } diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_loader_mtproto.h b/Telegram/SourceFiles/media/streaming/media_streaming_loader_mtproto.h index 1b301e810d..15b5b628cc 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_loader_mtproto.h +++ b/Telegram/SourceFiles/media/streaming/media_streaming_loader_mtproto.h @@ -29,7 +29,8 @@ public: void load(int offset) override; void cancel(int offset) override; - void increasePriority() override; + void resetPriorities() override; + void setPriority(int priority) override; void stop() override; // Parts will be sent from the main thread. @@ -49,6 +50,7 @@ private: void addToQueueWithPriority(); const int _size = 0; + int _priority = 0; MTP::Sender _api; diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_player.cpp b/Telegram/SourceFiles/media/streaming/media_streaming_player.cpp index 542cf8e80f..6f550a49f7 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_player.cpp +++ b/Telegram/SourceFiles/media/streaming/media_streaming_player.cpp @@ -143,6 +143,10 @@ bool Player::markFrameShown() { return _video->markFrameShown(); } +void Player::setLoaderPriority(int priority) { + _file->setLoaderPriority(priority); +} + template void Player::trackReceivedTill( const Track &track, diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_player.h b/Telegram/SourceFiles/media/streaming/media_streaming_player.h index 3ac0fc2eeb..28e6d3ab13 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_player.h +++ b/Telegram/SourceFiles/media/streaming/media_streaming_player.h @@ -71,6 +71,8 @@ public: void unregisterInstance(not_null instance); bool markFrameShown(); + void setLoaderPriority(int priority); + [[nodiscard]] Media::Player::TrackState prepareLegacyState() const; void lock(); diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_reader.cpp b/Telegram/SourceFiles/media/streaming/media_streaming_reader.cpp index 15d41aad88..c6e24e62c1 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_reader.cpp +++ b/Telegram/SourceFiles/media/streaming/media_streaming_reader.cpp @@ -888,6 +888,7 @@ void Reader::stopSleep() { void Reader::startStreaming() { _streamingActive = true; + refreshLoaderPriority(); } void Reader::stopStreaming(bool stillActive) { @@ -896,6 +897,7 @@ void Reader::stopStreaming(bool stillActive) { _waiting.store(nullptr, std::memory_order_release); if (!stillActive) { _streamingActive = false; + refreshLoaderPriority(); _loadingOffsets.clear(); processDownloaderRequests(); } @@ -1080,6 +1082,18 @@ void Reader::checkCacheResultsForDownloader() { processDownloaderRequests(); } +void Reader::setLoaderPriority(int priority) { + if (_realPriority == priority) { + return; + } + _realPriority = priority; + refreshLoaderPriority(); +} + +void Reader::refreshLoaderPriority() { + _loader->setPriority(_streamingActive ? _realPriority : 0); +} + bool Reader::isRemoteLoader() const { return _loader->baseCacheKey().has_value(); } @@ -1269,8 +1283,8 @@ void Reader::cancelLoadInRange(int from, int till) { void Reader::checkLoadWillBeFirst(int offset) { if (_loadingOffsets.front().value_or(offset) != offset) { - _loadingOffsets.increasePriority(); - _loader->increasePriority(); + _loadingOffsets.resetPriorities(); + _loader->resetPriorities(); } } diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_reader.h b/Telegram/SourceFiles/media/streaming/media_streaming_reader.h index 45f24187c2..126fade259 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_reader.h +++ b/Telegram/SourceFiles/media/streaming/media_streaming_reader.h @@ -37,6 +37,8 @@ public: not_null cache, std::unique_ptr loader); + void setLoaderPriority(int priority); + // Any thread. [[nodiscard]] int size() const; [[nodiscard]] bool isRemoteLoader() const; @@ -219,6 +221,8 @@ private: void checkForDownloaderChange(int checkItemsCount); void checkForDownloaderReadyOffsets(); + void refreshLoaderPriority(); + static std::shared_ptr InitCacheHelper( std::optional baseKey); @@ -242,6 +246,7 @@ private: // Main thread. Storage::StreamedFileDownloader *_attachedDownloader = nullptr; rpl::event_stream _partsForDownloader; + int _realPriority = 1; bool _streamingActive = false; // Streaming thread. diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index 50671d477b..d0c95d5666 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -68,6 +68,8 @@ namespace { constexpr auto kPreloadCount = 4; +constexpr auto kOverlayLoaderPriority = 2; + // macOS OpenGL renderer fails to render larger texture // even though it reports that max texture size is 16384. constexpr auto kMaxDisplayImageSize = 4096; @@ -2081,6 +2083,7 @@ bool OverlayWidget::createStreamingObjects() { _streamed = nullptr; return false; } + _streamed->instance.setPriority(kOverlayLoaderPriority); _streamed->instance.lockPlayer(); _streamed->withSound = _doc->isAudioFile() || _doc->isVideoFile()