diff --git a/Telegram/SourceFiles/data/data_document.cpp b/Telegram/SourceFiles/data/data_document.cpp index 7df823b626..f97129f351 100644 --- a/Telegram/SourceFiles/data/data_document.cpp +++ b/Telegram/SourceFiles/data/data_document.cpp @@ -547,7 +547,7 @@ void DocumentData::setVideoQualities( return document->isVideoFile() && !document->dimensions.isEmpty() && !document->inappPlaybackFailed() - && document->useStreamingLoader() + && document->useStreamingLoader(nullptr) && document->canBeStreamed(nullptr); }; ranges::sort( @@ -1533,29 +1533,35 @@ bool DocumentData::hasRemoteLocation() const { return (_dc != 0 && _access != 0); } -bool DocumentData::useStreamingLoader() const { +bool DocumentData::canVideoBeStreamed(HistoryItem *item) const { + if (!isVideoFile()) { + return false; + } + // Streaming couldn't be used with external player + // Maybe someone brave will implement this once upon a time... + static const auto &ExternalVideoPlayer = base::options::lookup( + Data::kOptionExternalVideoPlayer); + return storyMedia() + || !ExternalVideoPlayer.value() + || (item && !item->allowsForward()); +} + +bool DocumentData::useStreamingLoader(HistoryItem *item) const { if (size <= 0) { return false; } else if (const auto info = sticker()) { return info->isWebm(); } return isAnimation() - || isVideoFile() + || canVideoBeStreamed(item) || isAudioFile() || isVoiceMessage(); } bool DocumentData::canBeStreamed(HistoryItem *item) const { - // Streaming couldn't be used with external player - // Maybe someone brave will implement this once upon a time... - static const auto &ExternalVideoPlayer = base::options::lookup( - Data::kOptionExternalVideoPlayer); return hasRemoteLocation() && supportsStreaming() - && (!isVideoFile() - || storyMedia() - || !ExternalVideoPlayer.value() - || (item && !item->allowsForward())); + && (!isVideoFile() || canVideoBeStreamed(item)); } void DocumentData::setInappPlaybackFailed() { @@ -1585,9 +1591,10 @@ StorageFileLocation DocumentData::videoPreloadLocation() const { auto DocumentData::createStreamingLoader( Data::FileOrigin origin, - bool forceRemoteLoader) const + bool forceRemoteLoader, + HistoryItem *item) const -> std::unique_ptr { - if (!useStreamingLoader()) { + if (!useStreamingLoader(item)) { return nullptr; } if (!forceRemoteLoader) { diff --git a/Telegram/SourceFiles/data/data_document.h b/Telegram/SourceFiles/data/data_document.h index b0918a37c8..6fd2ba0ed8 100644 --- a/Telegram/SourceFiles/data/data_document.h +++ b/Telegram/SourceFiles/data/data_document.h @@ -294,9 +294,10 @@ public: [[nodiscard]] bool canBeStreamed(HistoryItem *item) const; [[nodiscard]] auto createStreamingLoader( Data::FileOrigin origin, - bool forceRemoteLoader) const + bool forceRemoteLoader, + HistoryItem *item) const -> std::unique_ptr; - [[nodiscard]] bool useStreamingLoader() const; + [[nodiscard]] bool useStreamingLoader(HistoryItem *item) const; void setInappPlaybackFailed(); [[nodiscard]] bool inappPlaybackFailed() const; @@ -358,6 +359,7 @@ private: friend class Serialize::Document; [[nodiscard]] LocationType locationType() const; + [[nodiscard]] bool canVideoBeStreamed(HistoryItem *item) const; void validateLottieSticker(); void setMaybeSupportsStreaming(bool supports); void setLoadedInMediaCacheLocation(); diff --git a/Telegram/SourceFiles/data/data_document_media.cpp b/Telegram/SourceFiles/data/data_document_media.cpp index 6bf6bc22f1..045c894216 100644 --- a/Telegram/SourceFiles/data/data_document_media.cpp +++ b/Telegram/SourceFiles/data/data_document_media.cpp @@ -360,7 +360,7 @@ float64 DocumentMedia::progress() const { bool DocumentMedia::canBePlayed(HistoryItem *item) const { return !_owner->inappPlaybackFailed() - && _owner->useStreamingLoader() + && _owner->useStreamingLoader(item) && (loaded() || _owner->canBeStreamed(item)); } diff --git a/Telegram/SourceFiles/data/data_photo.cpp b/Telegram/SourceFiles/data/data_photo.cpp index 0a2d37f8f3..8364a3e7ff 100644 --- a/Telegram/SourceFiles/data/data_photo.cpp +++ b/Telegram/SourceFiles/data/data_photo.cpp @@ -565,7 +565,8 @@ bool PhotoData::videoCanBePlayed() const { auto PhotoData::createStreamingLoader( Data::FileOrigin origin, - bool forceRemoteLoader) const + bool forceRemoteLoader, + HistoryItem *item) const -> std::unique_ptr { if (!hasVideo()) { return nullptr; diff --git a/Telegram/SourceFiles/data/data_photo.h b/Telegram/SourceFiles/data/data_photo.h index 3cd749a715..d159364171 100644 --- a/Telegram/SourceFiles/data/data_photo.h +++ b/Telegram/SourceFiles/data/data_photo.h @@ -150,7 +150,8 @@ public: [[nodiscard]] bool videoCanBePlayed() const; [[nodiscard]] auto createStreamingLoader( Data::FileOrigin origin, - bool forceRemoteLoader) const + bool forceRemoteLoader, + HistoryItem *item) const -> std::unique_ptr; [[nodiscard]] bool hasAttachedStickers() const; diff --git a/Telegram/SourceFiles/data/data_streaming.cpp b/Telegram/SourceFiles/data/data_streaming.cpp index 658c83807e..12dcae48bd 100644 --- a/Telegram/SourceFiles/data/data_streaming.cpp +++ b/Telegram/SourceFiles/data/data_streaming.cpp @@ -78,6 +78,15 @@ bool PruneDestroyedAndSet( return {}; } +[[nodiscard]] HistoryItem *LookupContext( + not_null owner, + const FileOrigin &origin) { + if (const auto message = std::get_if(&origin.data)) { + return owner->message(*message); + } + return nullptr; +} + } // namespace Streaming::Streaming(not_null owner) @@ -92,6 +101,7 @@ template base::flat_map, std::weak_ptr> &readers, not_null data, FileOrigin origin, + HistoryItem *context, bool forceRemoteLoader) { const auto i = readers.find(data); if (i != end(readers)) { @@ -101,7 +111,10 @@ template } } } - auto loader = data->createStreamingLoader(origin, forceRemoteLoader); + auto loader = data->createStreamingLoader( + origin, + forceRemoteLoader, + context); if (!loader) { return nullptr; } @@ -133,7 +146,7 @@ template return result; } } - auto reader = sharedReader(readers, data, origin); + auto reader = sharedReader(readers, data, origin, context); if (!reader) { return nullptr; } @@ -175,18 +188,25 @@ std::shared_ptr Streaming::sharedReader( not_null document, FileOrigin origin, bool forceRemoteLoader) { - return sharedReader(_fileReaders, document, origin, forceRemoteLoader); + const auto context = LookupContext(_owner, origin); + return sharedReader( + _fileReaders, + document, + origin, + context, + forceRemoteLoader); } std::shared_ptr Streaming::sharedDocument( not_null document, FileOrigin origin) { + const auto context = LookupContext(_owner, origin); return sharedDocument( _fileDocuments, _fileReaders, document, nullptr, - nullptr, + context, origin); } @@ -208,18 +228,25 @@ std::shared_ptr Streaming::sharedReader( not_null photo, FileOrigin origin, bool forceRemoteLoader) { - return sharedReader(_photoReaders, photo, origin, forceRemoteLoader); + const auto context = LookupContext(_owner, origin); + return sharedReader( + _photoReaders, + photo, + origin, + context, + forceRemoteLoader); } std::shared_ptr Streaming::sharedDocument( not_null photo, FileOrigin origin) { + const auto context = LookupContext(_owner, origin); return sharedDocument( _photoDocuments, _photoReaders, photo, nullptr, - nullptr, + context, origin); } diff --git a/Telegram/SourceFiles/data/data_streaming.h b/Telegram/SourceFiles/data/data_streaming.h index 51a6f18549..6799b0fd79 100644 --- a/Telegram/SourceFiles/data/data_streaming.h +++ b/Telegram/SourceFiles/data/data_streaming.h @@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL class PhotoData; class DocumentData; +class HistoryItem; namespace Media::Streaming { class Reader; @@ -64,6 +65,7 @@ private: base::flat_map, std::weak_ptr> &readers, not_null data, FileOrigin origin, + HistoryItem *context, bool forceRemoteLoader = false); template diff --git a/Telegram/SourceFiles/iv/iv_instance.cpp b/Telegram/SourceFiles/iv/iv_instance.cpp index 607ab87037..1c6f6df3c9 100644 --- a/Telegram/SourceFiles/iv/iv_instance.cpp +++ b/Telegram/SourceFiles/iv/iv_instance.cpp @@ -476,7 +476,10 @@ void Shown::streamFile( requestFail(std::move(request)); return; } - auto loader = document->createStreamingLoader(fileOrigin(page), false); + auto loader = document->createStreamingLoader( + fileOrigin(page), + false, + nullptr); if (!loader) { if (document->size >= Storage::kMaxFileInMemory) { requestFail(std::move(request));