Collect local DocumentMedia data.

This commit is contained in:
John Preston 2020-05-22 22:01:04 +04:00
parent 3f26fc9f55
commit 9ce59730ff
5 changed files with 77 additions and 7 deletions

View File

@ -1621,11 +1621,14 @@ void DocumentData::collectLocalData(not_null<DocumentData*> local) {
}
_owner->cache().copyIfEmpty(local->cacheKey(), cacheKey());
const auto localMedia = local->activeMediaView();
if (!localMedia->bytes().isEmpty()) {
if (const auto media = activeMediaView()) {
media->setBytes(localMedia->bytes());
}
if (const auto localMedia = local->activeMediaView()) {
const auto media = createMediaView();
media->collectLocalData(localMedia.get());
// Keep DocumentMedia alive for some more time.
// NB! This allows DocumentMedia to outlive Main::Session!
// In case this is a problem this code should be rewritten.
crl::on_main(&session(), [media] {});
}
if (!local->_location.inMediaCache() && !local->_location.isEmpty()) {
_location = local->_location;

View File

@ -139,6 +139,9 @@ DocumentMedia::DocumentMedia(not_null<DocumentData*> owner)
: _owner(owner) {
}
// NB! Right now DocumentMedia can outlive Main::Session!
// In DocumentData::collectLocalData a shared_ptr is sent on_main.
// In case this is a problem the ~Gif code should be rewritten.
DocumentMedia::~DocumentMedia() = default;
not_null<DocumentData*> DocumentMedia::owner() const {
@ -291,6 +294,28 @@ void DocumentMedia::automaticLoad(
true);
}
void DocumentMedia::collectLocalData(not_null<DocumentMedia*> local) {
if (const auto image = local->_goodThumbnail.get()) {
_goodThumbnail = std::make_unique<Image>(
std::make_unique<Images::ImageSource>(image->original(), "PNG"));
}
if (const auto image = local->_inlineThumbnail.get()) {
_inlineThumbnail = std::make_unique<Image>(
std::make_unique<Images::ImageSource>(image->original(), "PNG"));
}
if (const auto image = local->_thumbnail.get()) {
_thumbnail = std::make_unique<Image>(
std::make_unique<Images::ImageSource>(image->original(), "PNG"));
}
if (const auto image = local->_sticker.get()) {
_sticker = std::make_unique<Image>(
std::make_unique<Images::ImageSource>(image->original(), "PNG"));
}
_bytes = local->_bytes;
_videoThumbnailBytes = local->_videoThumbnailBytes;
_flags = local->_flags;
}
void DocumentMedia::setBytes(const QByteArray &bytes) {
if (!bytes.isEmpty()) {
_bytes = bytes;

View File

@ -76,6 +76,8 @@ public:
void automaticLoad(Data::FileOrigin origin, const HistoryItem *item);
void collectLocalData(not_null<DocumentMedia*> local);
// For DocumentData.
static void CheckGoodThumbnail(not_null<DocumentData*> document);
@ -93,6 +95,9 @@ private:
[[nodiscard]] bool thumbnailEnoughForSticker() const;
// NB! Right now DocumentMedia can outlive Main::Session!
// In DocumentData::collectLocalData a shared_ptr is sent on_main.
// In case this is a problem the ~Gif code should be rewritten.
const not_null<DocumentData*> _owner;
std::unique_ptr<Image> _goodThumbnail;
mutable std::unique_ptr<Image> _inlineThumbnail;

View File

@ -85,7 +85,14 @@ Gif::Gif(
setStatusSize(FileStatusSizeReady);
refreshCaption();
_data->loadThumbnail(realParent->fullId());
if ((_dataMedia = _data->activeMediaView())) {
dataMediaCreated();
} else {
_data->loadThumbnail(realParent->fullId());
if (!autoplayEnabled()) {
_data->loadVideoThumbnail(realParent->fullId());
}
}
}
Gif::~Gif() {
@ -427,7 +434,10 @@ void Gif::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms
}
} else {
_data->loadThumbnail(_realParent->fullId());
if (const auto blurred = _dataMedia->thumbnailInline()) {
validateVideoThumbnail();
if (_videoThumbnailFrame) {
p.drawPixmap(rthumb.topLeft(), _videoThumbnailFrame->pixSingle(_realParent->fullId(), _thumbw, _thumbh, usew, painth, roundRadius, roundCorners));
} else if (const auto blurred = _dataMedia->thumbnailInline()) {
p.drawPixmap(rthumb.topLeft(), blurred->pixBlurredSingle(_realParent->fullId(), _thumbw, _thumbh, usew, painth, roundRadius, roundCorners));
} else if (!isRound) {
const auto roundTop = (roundCorners & RectPart::TopLeft);
@ -632,6 +642,20 @@ void Gif::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms
}
}
void Gif::validateVideoThumbnail() const {
const auto content = _dataMedia->videoThumbnailContent();
if (_videoThumbnailFrame || content.isEmpty()) {
return;
}
auto info = ::Media::Clip::PrepareForSending(QString(), content);
_videoThumbnailFrame = std::make_unique<Image>(
std::make_unique<Images::ImageSource>(
(info.thumbnail.isNull()
? Image::BlankMedia()->original()
: info.thumbnail),
"PNG"));
}
void Gif::drawCornerStatus(Painter &p, bool selected, QPoint position) const {
if (!needCornerStatusDisplay()) {
return;
@ -1086,8 +1110,17 @@ void Gif::ensureDataMediaCreated() const {
return;
}
_dataMedia = _data->createMediaView();
dataMediaCreated();
}
void Gif::dataMediaCreated() const {
Expects(_dataMedia != nullptr);
_dataMedia->goodThumbnailWanted();
_dataMedia->thumbnailWanted(_realParent->fullId());
if (!autoplayEnabled()) {
_dataMedia->videoThumbnailWanted(_realParent->fullId());
}
history()->owner().registerHeavyViewPart(_parent);
}

View File

@ -112,11 +112,14 @@ public:
private:
struct Streamed;
void validateVideoThumbnail() const;
float64 dataProgress() const override;
bool dataFinished() const override;
bool dataLoaded() const override;
void ensureDataMediaCreated() const;
void dataMediaCreated() const;
void refreshCaption();
[[nodiscard]] bool autoplayEnabled() const;
@ -171,6 +174,7 @@ private:
Ui::Text::String _caption;
std::unique_ptr<Streamed> _streamed;
mutable std::shared_ptr<Data::DocumentMedia> _dataMedia;
mutable std::unique_ptr<Image> _videoThumbnailFrame;
QString _downloadSize;