Use simple loader for non-streamable file types.

This commit is contained in:
John Preston 2019-04-12 12:00:06 +04:00
parent e1114530ab
commit 8704f6efd0
6 changed files with 45 additions and 20 deletions

View File

@ -1196,6 +1196,13 @@ bool DocumentData::hasRemoteLocation() const {
return (_dc != 0 && _access != 0); return (_dc != 0 && _access != 0);
} }
bool DocumentData::useStreamingLoader() const {
return isAnimation()
|| isVideoFile()
|| isAudioFile()
|| isVoiceMessage();
}
bool DocumentData::canBeStreamed() const { bool DocumentData::canBeStreamed() const {
// For now video messages are not streamed. // For now video messages are not streamed.
return hasRemoteLocation() && supportsStreaming() && !isVideoMessage(); return hasRemoteLocation() && supportsStreaming() && !isVideoMessage();
@ -1203,10 +1210,7 @@ bool DocumentData::canBeStreamed() const {
bool DocumentData::canBePlayed() const { bool DocumentData::canBePlayed() const {
return !_inappPlaybackFailed return !_inappPlaybackFailed
&& (isAnimation() && useStreamingLoader()
|| isVideoFile()
|| isAudioFile()
|| isVoiceMessage())
&& (loaded() || canBeStreamed()); && (loaded() || canBeStreamed());
} }
@ -1220,6 +1224,9 @@ bool DocumentData::inappPlaybackFailed() const {
auto DocumentData::createStreamingLoader(Data::FileOrigin origin) const auto DocumentData::createStreamingLoader(Data::FileOrigin origin) const
-> std::unique_ptr<Media::Streaming::Loader> { -> std::unique_ptr<Media::Streaming::Loader> {
if (!useStreamingLoader()) {
return nullptr;
}
const auto &location = this->location(true); const auto &location = this->location(true);
if (!data().isEmpty()) { if (!data().isEmpty()) {
return Media::Streaming::MakeBytesLoader(data()); return Media::Streaming::MakeBytesLoader(data());

View File

@ -249,6 +249,7 @@ private:
void destroyLoader(FileLoader *newValue = nullptr) const; void destroyLoader(FileLoader *newValue = nullptr) const;
[[nodiscard]] bool useStreamingLoader() const;
[[nodiscard]] bool thumbnailEnoughForSticker() const; [[nodiscard]] bool thumbnailEnoughForSticker() const;
// Two types of location: from MTProto by dc+access or from web by url // Two types of location: from MTProto by dc+access or from web by url

View File

@ -473,7 +473,7 @@ auto Reader::Slices::fill(int offset, bytes::span buffer) -> FillResult {
if (_headerMode != HeaderMode::NoCache if (_headerMode != HeaderMode::NoCache
&& !(_header.flags & Flag::LoadedFromCache)) { && !(_header.flags & Flag::LoadedFromCache)) {
// Waiting for initial cache query. // Waiting for initial cache query.
Assert(_header.flags & Flag::LoadingFromCache); Assert(waitingForHeaderCache());
return {}; return {};
} else if (isFullInHeader()) { } else if (isFullInHeader()) {
return fillFromHeader(offset, buffer); return fillFromHeader(offset, buffer);
@ -587,16 +587,20 @@ QByteArray Reader::Slices::partForDownloader(int offset) const {
return (i != end(slice.parts)) ? i->second : QByteArray(); return (i != end(slice.parts)) ? i->second : QByteArray();
} }
bool Reader::Slices::waitingForHeaderCache() const {
return (_header.flags & Slice::Flag::LoadingFromCache);
}
std::optional<int> Reader::Slices::readCacheRequiredFor(int offset) { std::optional<int> Reader::Slices::readCacheRequiredFor(int offset) {
Expects(offset < _size); Expects(offset < _size);
Expects(!waitingForHeaderCache());
using Flag = Slice::Flag; if (isFullInHeader()) {
if ((_header.flags & Flag::LoadingFromCache) || isFullInHeader()) {
return std::nullopt; return std::nullopt;
} }
const auto index = offset / kInSlice; const auto index = offset / kInSlice;
auto &slice = _data[index]; auto &slice = _data[index];
return (slice.flags & Flag::LoadedFromCache) return (slice.flags & Slice::Flag::LoadedFromCache)
? std::nullopt ? std::nullopt
: std::make_optional(index + 1); : std::make_optional(index + 1);
} }
@ -923,6 +927,9 @@ void Reader::processDownloaderRequests() {
} }
bool Reader::downloaderWaitForCachedSlice(int offset) { bool Reader::downloaderWaitForCachedSlice(int offset) {
if (_slices.waitingForHeaderCache()) {
return true;
}
const auto sliceNumber = _slices.readCacheRequiredFor(offset); const auto sliceNumber = _slices.readCacheRequiredFor(offset);
if (sliceNumber.value_or(0) != _downloaderSliceNumber) { if (sliceNumber.value_or(0) != _downloaderSliceNumber) {
_downloaderSliceNumber = sliceNumber.value_or(0); _downloaderSliceNumber = sliceNumber.value_or(0);

View File

@ -131,6 +131,7 @@ private:
[[nodiscard]] bool headerModeUnknown() const; [[nodiscard]] bool headerModeUnknown() const;
[[nodiscard]] bool isFullInHeader() const; [[nodiscard]] bool isFullInHeader() const;
[[nodiscard]] bool isGoodHeader() const; [[nodiscard]] bool isGoodHeader() const;
[[nodiscard]] bool waitingForHeaderCache() const;
void processCacheResult(int sliceNumber, PartsMap &&result); void processCacheResult(int sliceNumber, PartsMap &&result);
void processPart(int offset, QByteArray &&bytes); void processPart(int offset, QByteArray &&bytes);

View File

@ -47,8 +47,9 @@ StreamedFileDownloader::StreamedFileDownloader(
, _origin(origin) , _origin(origin)
, _cacheKey(cacheKey) , _cacheKey(cacheKey)
, _fileLocationKey(fileLocationKey) , _fileLocationKey(fileLocationKey)
, _reader(std::move(reader)) { , _reader(std::move(reader))
_partIsSaved.resize((size + kPartSize - 1) / kPartSize, false); , _partsCount((size + kPartSize - 1) / kPartSize) {
_partIsSaved.resize(_partsCount, false);
_reader->partsForDownloader( _reader->partsForDownloader(
) | rpl::start_with_next([=](const LoadedPart &part) { ) | rpl::start_with_next([=](const LoadedPart &part) {
@ -87,18 +88,19 @@ std::optional<MediaKey> StreamedFileDownloader::fileLocationKey() const {
} }
void StreamedFileDownloader::cancelRequests() { void StreamedFileDownloader::cancelRequests() {
const auto requests = std::count( //_partsRequested == std::count(
begin(_partIsSaved), // begin(_partIsSaved),
begin(_partIsSaved) + _nextPartIndex, // begin(_partIsSaved) + _nextPartIndex,
false); // false);
_queue->queriesCount -= requests; _queue->queriesCount -= _partsRequested;
_partsRequested = 0;
_nextPartIndex = 0; _nextPartIndex = 0;
_reader->cancelForDownloader(); _reader->cancelForDownloader();
} }
bool StreamedFileDownloader::loadPart() { bool StreamedFileDownloader::loadPart() {
if (_finished || _nextPartIndex >= size(_partIsSaved)) { if (_finished || _nextPartIndex >= _partsCount) {
return false; return false;
} }
const auto index = std::find( const auto index = std::find(
@ -106,17 +108,19 @@ bool StreamedFileDownloader::loadPart() {
end(_partIsSaved), end(_partIsSaved),
false false
) - begin(_partIsSaved); ) - begin(_partIsSaved);
if (index == size(_partIsSaved)) { if (index == _partsCount) {
_nextPartIndex = index; _nextPartIndex = _partsCount;
return false; return false;
} }
_nextPartIndex = index + 1; _nextPartIndex = index + 1;
_reader->loadForDownloader(index * kPartSize); _reader->loadForDownloader(index * kPartSize);
AssertIsDebug(); AssertIsDebug();
//_downloader->requestedAmountIncrement( //_downloader->requestedAmountIncrement(
// requestData.dcId, // requestData.dcId,
// requestData.dcIndex, // requestData.dcIndex,
// kPartSize); // kPartSize);
++_partsRequested;
++_queue->queriesCount; ++_queue->queriesCount;
return true; return true;
@ -132,11 +136,12 @@ void StreamedFileDownloader::savePart(const LoadedPart &part) {
const auto offset = part.offset; const auto offset = part.offset;
const auto index = offset / kPartSize; const auto index = offset / kPartSize;
Assert(index >= 0 && index < _partIsSaved.size()); Assert(index >= 0 && index < _partsCount);
if (_partIsSaved[index]) { if (_partIsSaved[index]) {
return; return;
} }
_partIsSaved[index] = true; _partIsSaved[index] = true;
++_partsSaved;
if (index < _nextPartIndex) { if (index < _nextPartIndex) {
AssertIsDebug(); AssertIsDebug();
@ -144,12 +149,13 @@ void StreamedFileDownloader::savePart(const LoadedPart &part) {
// requestData.dcId, // requestData.dcId,
// requestData.dcIndex, // requestData.dcIndex,
// -kPartSize); // -kPartSize);
--_partsRequested;
--_queue->queriesCount; --_queue->queriesCount;
} }
if (!writeResultPart(offset, bytes::make_span(part.bytes))) { if (!writeResultPart(offset, bytes::make_span(part.bytes))) {
return; return;
} }
if (ranges::find(_partIsSaved, false) == end(_partIsSaved)) { if (_partsSaved == _partsCount) {
if (!finalizeResult()) { if (!finalizeResult()) {
return; return;
} }

View File

@ -59,6 +59,9 @@ private:
std::vector<bool> _partIsSaved; // vector<bool> :D std::vector<bool> _partIsSaved; // vector<bool> :D
int _nextPartIndex = 0; int _nextPartIndex = 0;
int _partsCount = 0;
int _partsRequested = 0;
int _partsSaved = 0;
rpl::lifetime _lifetime; rpl::lifetime _lifetime;