From cb0c99acc8f9cb46a0719534b208b2b4a701b509 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 13 Jul 2016 20:34:57 +0300 Subject: [PATCH] Seek done in video player in MediaView. Some memory leaks fixed. Using pixmapFromImageInPlace() instead of QPixmap::fromImage(). --- Telegram/SourceFiles/app.cpp | 159 ++++++++++-------- Telegram/SourceFiles/application.cpp | 4 +- Telegram/SourceFiles/boxes/addcontactbox.cpp | 2 +- Telegram/SourceFiles/boxes/photocropbox.cpp | 2 +- Telegram/SourceFiles/boxes/photosendbox.cpp | 4 +- Telegram/SourceFiles/core/basic_types.cpp | 18 +- Telegram/SourceFiles/history.cpp | 33 +++- Telegram/SourceFiles/history.h | 6 +- .../history/field_autocomplete.cpp | 5 +- .../SourceFiles/history/field_autocomplete.h | 11 +- Telegram/SourceFiles/historywidget.cpp | 2 +- Telegram/SourceFiles/intro/introsignup.cpp | 2 +- Telegram/SourceFiles/localimageloader.cpp | 12 +- Telegram/SourceFiles/localstorage.cpp | 4 +- Telegram/SourceFiles/mainwidget.cpp | 4 +- Telegram/SourceFiles/mainwindow.cpp | 10 +- Telegram/SourceFiles/media/media_audio.cpp | 39 +++-- Telegram/SourceFiles/media/media_audio.h | 2 +- .../media/media_audio_ffmpeg_loader.cpp | 8 +- .../SourceFiles/media/media_audio_loaders.cpp | 2 +- .../media/media_child_ffmpeg_loader.cpp | 1 + .../SourceFiles/media/media_clip_ffmpeg.cpp | 32 +++- .../SourceFiles/media/media_clip_ffmpeg.h | 2 +- .../media/media_clip_implementation.h | 2 +- .../SourceFiles/media/media_clip_qtgif.cpp | 2 +- Telegram/SourceFiles/media/media_clip_qtgif.h | 2 +- .../SourceFiles/media/media_clip_reader.cpp | 45 +++-- .../SourceFiles/media/media_clip_reader.h | 6 +- .../media/view/media_clip_controller.cpp | 57 +++++-- .../media/view/media_clip_controller.h | 15 +- .../media/view/media_clip_playback.cpp | 20 ++- .../media/view/media_clip_playback.h | 6 +- Telegram/SourceFiles/mediaview.cpp | 55 +++--- Telegram/SourceFiles/mediaview.h | 7 +- .../SourceFiles/mtproto/file_download.cpp | 5 +- .../SourceFiles/overview/overview_layout.cpp | 4 +- .../platform/linux/main_window_linux.cpp | 4 +- .../platform/mac/main_window_mac.mm | 4 +- .../platform/win/main_window_win.cpp | 12 +- Telegram/SourceFiles/pspecific_win.cpp | 2 +- Telegram/SourceFiles/settingswidget.cpp | 2 +- Telegram/SourceFiles/structs.cpp | 7 +- Telegram/SourceFiles/structs.h | 2 +- Telegram/SourceFiles/title.cpp | 2 +- Telegram/SourceFiles/ui/boxshadow.cpp | 25 +-- Telegram/SourceFiles/ui/countryinput.cpp | 2 +- Telegram/SourceFiles/ui/images.cpp | 20 +-- Telegram/SourceFiles/ui/style/style_core.cpp | 2 + .../SourceFiles/ui/style/style_core_icon.cpp | 2 +- .../SourceFiles/ui/style/style_core_icon.h | 2 + .../SourceFiles/ui/style/style_core_types.cpp | 7 +- .../SourceFiles/ui/style/style_core_types.h | 1 + Telegram/SourceFiles/ui/text/text_block.cpp | 7 - 53 files changed, 419 insertions(+), 274 deletions(-) diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index dc0d1689c..f1f396e4e 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -2064,7 +2064,7 @@ namespace { cors[3] = rect.copy(r * 2, r * 2, r, r + (shadow ? s : 0)); if (index != SmallMaskCorners && index != LargeMaskCorners) { for (int i = 0; i < 4; ++i) { - ::corners[index].p[i] = new QPixmap(QPixmap::fromImage(cors[i], Qt::ColorOnly)); + ::corners[index].p[i] = new QPixmap(pixmapFromImageInPlace(std_::move(cors[i]))); ::corners[index].p[i]->setDevicePixelRatio(cRetinaFactor()); } } @@ -2101,12 +2101,12 @@ namespace { } QImage mask[4]; - prepareCorners(LargeMaskCorners, st::msgRadius, st::white, 0, mask); + prepareCorners(LargeMaskCorners, st::msgRadius, st::white, nullptr, mask); for (int i = 0; i < 4; ++i) { ::cornersMaskLarge[i] = new QImage(mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied)); ::cornersMaskLarge[i]->setDevicePixelRatio(cRetinaFactor()); } - prepareCorners(SmallMaskCorners, st::buttonRadius, st::white, 0, mask); + prepareCorners(SmallMaskCorners, st::buttonRadius, st::white, nullptr, mask); for (int i = 0; i < 4; ++i) { ::cornersMaskSmall[i] = new QImage(mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied)); ::cornersMaskSmall[i]->setDevicePixelRatio(cRetinaFactor()); @@ -2267,7 +2267,7 @@ namespace { p.setCompositionMode(m); emojiDraw(p, emoji, st::emojiPadding * cIntRetinaFactor(), (fontHeight * cIntRetinaFactor() - ESize) / 2); } - i = map->insert(emojiKey(emoji), QPixmap::fromImage(img, Qt::ColorOnly)); + i = map->insert(emojiKey(emoji), App::pixmapFromImageInPlace(std_::move(img))); } return i.value(); } @@ -2603,13 +2603,13 @@ namespace { if (i == cornersMap.cend()) { QImage images[4]; switch (radius) { - case ImageRoundRadius::Small: prepareCorners(SmallMaskCorners, st::buttonRadius, bg, 0, images); break; - case ImageRoundRadius::Large: prepareCorners(LargeMaskCorners, st::msgRadius, bg, 0, images); break; + case ImageRoundRadius::Small: prepareCorners(SmallMaskCorners, st::buttonRadius, bg, nullptr, images); break; + case ImageRoundRadius::Large: prepareCorners(LargeMaskCorners, st::msgRadius, bg, nullptr, images); break; } CornersPixmaps pixmaps; for (int j = 0; j < 4; ++j) { - pixmaps.p[j] = new QPixmap(QPixmap::fromImage(images[j], Qt::ColorOnly)); + pixmaps.p[j] = new QPixmap(pixmapFromImageInPlace(std_::move(images[j]))); pixmaps.p[j]->setDevicePixelRatio(cRetinaFactor()); } i = cornersMap.insert(colorKey, pixmaps); @@ -2620,46 +2620,51 @@ namespace { void initBackground(int32 id, const QImage &p, bool nowrite) { if (Local::readBackground()) return; - QImage img(p); - bool remove = false; - if (p.isNull()) { - if (id == DefaultChatBackground) { - img.load(st::msgBG); - } else { - img.load(st::msgBG0); - if (cRetina()) { - img = img.scaledToWidth(img.width() * 2, Qt::SmoothTransformation); - } else if (cScale() != dbisOne) { - img = img.scaledToWidth(convertScale(img.width()), Qt::SmoothTransformation); - } - id = 0; - } - remove = true; - } - if (img.format() != QImage::Format_ARGB32 && img.format() != QImage::Format_ARGB32_Premultiplied && img.format() != QImage::Format_RGB32) { - img = img.convertToFormat(QImage::Format_RGB32); - } - img.setDevicePixelRatio(cRetinaFactor()); - - if (!nowrite) { - Local::writeBackground(id, remove ? QImage() : img); - } - - delete cChatBackground(); - cSetChatBackground(new QPixmap(QPixmap::fromImage(img, Qt::ColorOnly))); - cSetChatBackgroundId(id); - - if (App::main()) App::main()->clearCachedBackground(); - uint64 components[3] = { 0 }, componentsScroll[3] = { 0 }, componentsPoint[3] = { 0 }; - int w = img.width(), h = img.height(), size = w * h; - const uchar *pix = img.constBits(); - if (pix) { - for (int32 i = 0, l = size * 4; i < l; i += 4) { - components[2] += pix[i + 0]; - components[1] += pix[i + 1]; - components[0] += pix[i + 2]; + int size = 0; + { + QImage img(p); + bool remove = false; + if (p.isNull()) { + if (id == DefaultChatBackground) { + img.load(st::msgBG); + } else { + img.load(st::msgBG0); + if (cRetina()) { + img = img.scaledToWidth(img.width() * 2, Qt::SmoothTransformation); + } else if (cScale() != dbisOne) { + img = img.scaledToWidth(convertScale(img.width()), Qt::SmoothTransformation); + } + id = 0; + } + remove = true; } + if (img.format() != QImage::Format_ARGB32 && img.format() != QImage::Format_ARGB32_Premultiplied && img.format() != QImage::Format_RGB32) { + img = img.convertToFormat(QImage::Format_RGB32); + } + img.setDevicePixelRatio(cRetinaFactor()); + + if (!nowrite) { + Local::writeBackground(id, remove ? QImage() : img); + } + + int w = img.width(), h = img.height(); + size = w * h; + const uchar *pix = img.constBits(); + if (pix) { + for (int32 i = 0, l = size * 4; i < l; i += 4) { + components[2] += pix[i + 0]; + components[1] += pix[i + 1]; + components[0] += pix[i + 2]; + } + } + + delete cChatBackground(); + cSetChatBackground(new QPixmap(pixmapFromImageInPlace(std_::move(img)))); + cSetChatBackgroundId(id); + + if (App::main()) App::main()->clearCachedBackground(); + } if (size) { for (int32 i = 0; i < 3; ++i) components[i] /= size; @@ -2677,41 +2682,43 @@ namespace { uint64 max = qMax(1ULL, components[maxtomin[0]]), mid = qMax(1ULL, components[maxtomin[1]]), min = qMax(1ULL, components[maxtomin[2]]); - QImage dog = App::sprite().toImage().copy(st::msgDogImg.rect()); - QImage::Format f = dog.format(); - if (f != QImage::Format_ARGB32 && f != QImage::Format_ARGB32_Premultiplied) { - dog = dog.convertToFormat(QImage::Format_ARGB32_Premultiplied); - } - uchar *dogBits = dog.bits(); - if (max != min) { - float64 coef = float64(mid - min) / float64(max - min); - for (int i = 0, s = dog.width() * dog.height() * 4; i < s; i += 4) { - int dogmaxtomin[3] = { i, i + 1, i + 2 }; - if (dogBits[dogmaxtomin[0]] < dogBits[dogmaxtomin[1]]) { - qSwap(dogmaxtomin[0], dogmaxtomin[1]); - } - if (dogBits[dogmaxtomin[1]] < dogBits[dogmaxtomin[2]]) { - qSwap(dogmaxtomin[1], dogmaxtomin[2]); + { + QImage dog = App::sprite().toImage().copy(st::msgDogImg.rect()); + QImage::Format f = dog.format(); + if (f != QImage::Format_ARGB32 && f != QImage::Format_ARGB32_Premultiplied) { + dog = dog.convertToFormat(QImage::Format_ARGB32_Premultiplied); + } + uchar *dogBits = dog.bits(); + if (max != min) { + float64 coef = float64(mid - min) / float64(max - min); + for (int i = 0, s = dog.width() * dog.height() * 4; i < s; i += 4) { + int dogmaxtomin[3] = { i, i + 1, i + 2 }; if (dogBits[dogmaxtomin[0]] < dogBits[dogmaxtomin[1]]) { qSwap(dogmaxtomin[0], dogmaxtomin[1]); } + if (dogBits[dogmaxtomin[1]] < dogBits[dogmaxtomin[2]]) { + qSwap(dogmaxtomin[1], dogmaxtomin[2]); + if (dogBits[dogmaxtomin[0]] < dogBits[dogmaxtomin[1]]) { + qSwap(dogmaxtomin[0], dogmaxtomin[1]); + } + } + uchar result[3]; + result[maxtomin[0]] = dogBits[dogmaxtomin[0]]; + result[maxtomin[2]] = dogBits[dogmaxtomin[2]]; + result[maxtomin[1]] = uchar(qRound(result[maxtomin[2]] + (result[maxtomin[0]] - result[maxtomin[2]]) * coef)); + dogBits[i] = result[2]; + dogBits[i + 1] = result[1]; + dogBits[i + 2] = result[0]; + } + } else { + for (int i = 0, s = dog.width() * dog.height() * 4; i < s; i += 4) { + uchar b = dogBits[i], g = dogBits[i + 1], r = dogBits[i + 2]; + dogBits[i] = dogBits[i + 1] = dogBits[i + 2] = (r + r + b + g + g + g) / 6; } - uchar result[3]; - result[maxtomin[0]] = dogBits[dogmaxtomin[0]]; - result[maxtomin[2]] = dogBits[dogmaxtomin[2]]; - result[maxtomin[1]] = uchar(qRound(result[maxtomin[2]] + (result[maxtomin[0]] - result[maxtomin[2]]) * coef)); - dogBits[i] = result[2]; - dogBits[i + 1] = result[1]; - dogBits[i + 2] = result[0]; - } - } else { - for (int i = 0, s = dog.width() * dog.height() * 4; i < s; i += 4) { - uchar b = dogBits[i], g = dogBits[i + 1], r = dogBits[i + 2]; - dogBits[i] = dogBits[i + 1] = dogBits[i + 2] = (r + r + b + g + g + g) / 6; } + delete cChatDogImage(); + cSetChatDogImage(new QPixmap(pixmapFromImageInPlace(std_::move(dog)))); } - delete cChatDogImage(); - cSetChatDogImage(new QPixmap(QPixmap::fromImage(dog))); memcpy(componentsScroll, components, sizeof(components)); memcpy(componentsPoint, components, sizeof(components)); @@ -2768,6 +2775,10 @@ namespace { uchar bsel = snap(qRound(((1. - alphaSel) * b + addSel) / alphaSel), 0, 0xFF); _msgServiceSelectBg = style::color(r, g, b, qRound(alphaSel * 0xFF)); + for (int i = 0; i < 4; ++i) { + delete ::corners[StickerCorners].p[i]; ::corners[StickerCorners].p[i] = nullptr; + delete ::corners[StickerSelectedCorners].p[i]; ::corners[StickerSelectedCorners].p[i] = nullptr; + } prepareCorners(StickerCorners, st::dateRadius, _msgServiceBg); prepareCorners(StickerSelectedCorners, st::dateRadius, _msgServiceSelectBg); diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index 181b3d9e6..be4e3c21c 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -1014,11 +1014,11 @@ void AppClass::uploadProfilePhoto(const QImage &tosend, const PeerId &peerId) { PreparedPhotoThumbs photoThumbs; QVector photoSizes; - QPixmap thumb = QPixmap::fromImage(tosend.scaled(160, 160, Qt::KeepAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly); + QPixmap thumb = App::pixmapFromImageInPlace(tosend.scaled(160, 160, Qt::KeepAspectRatio, Qt::SmoothTransformation)); photoThumbs.insert('a', thumb); photoSizes.push_back(MTP_photoSize(MTP_string("a"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(thumb.width()), MTP_int(thumb.height()), MTP_int(0))); - QPixmap medium = QPixmap::fromImage(tosend.scaled(320, 320, Qt::KeepAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly); + QPixmap medium = App::pixmapFromImageInPlace(tosend.scaled(320, 320, Qt::KeepAspectRatio, Qt::SmoothTransformation)); photoThumbs.insert('b', medium); photoSizes.push_back(MTP_photoSize(MTP_string("b"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(medium.width()), MTP_int(medium.height()), MTP_int(0))); diff --git a/Telegram/SourceFiles/boxes/addcontactbox.cpp b/Telegram/SourceFiles/boxes/addcontactbox.cpp index 4dae334a5..aa44ed21a 100644 --- a/Telegram/SourceFiles/boxes/addcontactbox.cpp +++ b/Telegram/SourceFiles/boxes/addcontactbox.cpp @@ -595,7 +595,7 @@ void GroupInfoBox::onPhoto() { void GroupInfoBox::onPhotoReady(const QImage &img) { _photoBig = img; - _photoSmall = QPixmap::fromImage(img.scaled(st::newGroupPhotoSize * cIntRetinaFactor(), st::newGroupPhotoSize * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly); + _photoSmall = App::pixmapFromImageInPlace(img.scaled(st::newGroupPhotoSize * cIntRetinaFactor(), st::newGroupPhotoSize * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); _photoSmall.setDevicePixelRatio(cRetinaFactor()); } diff --git a/Telegram/SourceFiles/boxes/photocropbox.cpp b/Telegram/SourceFiles/boxes/photocropbox.cpp index a0c398f44..390adc7a3 100644 --- a/Telegram/SourceFiles/boxes/photocropbox.cpp +++ b/Telegram/SourceFiles/boxes/photocropbox.cpp @@ -61,7 +61,7 @@ void PhotoCropBox::init(const QImage &img, PeerData *peer) { } int32 s = st::boxWideWidth - st::boxPhotoPadding.left() - st::boxPhotoPadding.right(); - _thumb = QPixmap::fromImage(img.scaled(s, s, Qt::KeepAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly); + _thumb = App::pixmapFromImageInPlace(img.scaled(s, s, Qt::KeepAspectRatio, Qt::SmoothTransformation)); _thumbw = _thumb.width(); _thumbh = _thumb.height(); if (_thumbw > _thumbh) { diff --git a/Telegram/SourceFiles/boxes/photosendbox.cpp b/Telegram/SourceFiles/boxes/photosendbox.cpp index 7148a89c4..08ddb2175 100644 --- a/Telegram/SourceFiles/boxes/photosendbox.cpp +++ b/Telegram/SourceFiles/boxes/photosendbox.cpp @@ -110,7 +110,7 @@ PhotoSendBox::PhotoSendBox(const FileLoadResultPtr &file) : AbstractBox(st::boxW } _thumbx = (width() - _thumbw) / 2; - _thumb = QPixmap::fromImage(_thumb.toImage().scaled(_thumbw * cIntRetinaFactor(), _thumbh * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly); + _thumb = App::pixmapFromImageInPlace(_thumb.toImage().scaled(_thumbw * cIntRetinaFactor(), _thumbh * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); _thumb.setDevicePixelRatio(cRetinaFactor()); } else { if (_file->thumb.isNull()) { @@ -483,7 +483,7 @@ EditCaptionBox::EditCaptionBox(HistoryItem *msg) : AbstractBox(st::boxWideWidth) } _thumbx = (width() - _thumbw) / 2; - _thumb = QPixmap::fromImage(_thumb.toImage().scaled(_thumbw * cIntRetinaFactor(), _thumbh * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly); + _thumb = App::pixmapFromImageInPlace(_thumb.toImage().scaled(_thumbw * cIntRetinaFactor(), _thumbh * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); _thumb.setDevicePixelRatio(cRetinaFactor()); } diff --git a/Telegram/SourceFiles/core/basic_types.cpp b/Telegram/SourceFiles/core/basic_types.cpp index 89bbd34bf..868a5d23f 100644 --- a/Telegram/SourceFiles/core/basic_types.cpp +++ b/Telegram/SourceFiles/core/basic_types.cpp @@ -24,6 +24,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include #include +#include +#include +#include +#include +#include extern "C" { #include @@ -288,10 +293,19 @@ namespace ThirdParty { } void finish() { - av_lockmgr_register(0); + av_lockmgr_register(nullptr); + + CRYPTO_cleanup_all_ex_data(); + FIPS_mode_set(0); + ENGINE_cleanup(); + CONF_modules_unload(1); + ERR_remove_state(0); + ERR_free_strings(); + ERR_remove_thread_state(nullptr); + EVP_cleanup(); delete[] _sslLocks; - _sslLocks = 0; + _sslLocks = nullptr; Platform::ThirdParty::finish(); } diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index 6c1c672c9..2813792d5 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -5857,7 +5857,7 @@ HistoryWebPage::~HistoryWebPage() { } namespace { - LocationManager manager; + LocationManager *locationManager = nullptr; } void LocationManager::init() { @@ -5869,13 +5869,16 @@ void LocationManager::init() { connect(manager, SIGNAL(sslErrors(QNetworkReply*, const QList&)), this, SLOT(onFailed(QNetworkReply*))); connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(onFinished(QNetworkReply*))); - if (black) delete black; + if (black) { + delete black->v(); + delete black; + } QImage b(cIntRetinaFactor(), cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); { QPainter p(&b); p.fillRect(QRect(0, 0, cIntRetinaFactor(), cIntRetinaFactor()), st::white->b); } - QPixmap p = QPixmap::fromImage(b, Qt::ColorOnly); + QPixmap p = App::pixmapFromImageInPlace(std_::move(b)); p.setDevicePixelRatio(cRetinaFactor()); black = new ImagePtr(p, "PNG"); } @@ -5887,26 +5890,36 @@ void LocationManager::reinit() { void LocationManager::deinit() { if (manager) { delete manager; - manager = 0; + manager = nullptr; } if (black) { + delete black->v(); delete black; - black = 0; + black = nullptr; } dataLoadings.clear(); imageLoadings.clear(); } void initImageLinkManager() { - manager.init(); + if (!locationManager) { + locationManager = new LocationManager(); + locationManager->init(); + } } void reinitImageLinkManager() { - manager.reinit(); + if (locationManager) { + locationManager->reinit(); + } } void deinitImageLinkManager() { - manager.deinit(); + if (locationManager) { + locationManager->deinit(); + delete locationManager; + locationManager = nullptr; + } } void LocationManager::getData(LocationData *data) { @@ -6046,7 +6059,9 @@ void LocationData::load() { if (loading) return; loading = true; - manager.getData(this); + if (locationManager) { + locationManager->getData(this); + } } HistoryLocation::HistoryLocation(HistoryItem *parent, const LocationCoords &coords, const QString &title, const QString &description) : HistoryMedia(parent) diff --git a/Telegram/SourceFiles/history.h b/Telegram/SourceFiles/history.h index 8f867bb09..484e67090 100644 --- a/Telegram/SourceFiles/history.h +++ b/Telegram/SourceFiles/history.h @@ -2445,8 +2445,6 @@ struct LocationData; class LocationManager : public QObject { Q_OBJECT public: - LocationManager() : manager(0), black(0) { - } void init(); void reinit(); void deinit(); @@ -2464,10 +2462,10 @@ public slots: private: void failed(LocationData *data); - QNetworkAccessManager *manager; + QNetworkAccessManager *manager = nullptr; QMap dataLoadings, imageLoadings; QMap serverRedirects; - ImagePtr *black; + ImagePtr *black = nullptr; }; class HistoryLocation : public HistoryMedia { diff --git a/Telegram/SourceFiles/history/field_autocomplete.cpp b/Telegram/SourceFiles/history/field_autocomplete.cpp index c59f1d64f..cfeffcdf0 100644 --- a/Telegram/SourceFiles/history/field_autocomplete.cpp +++ b/Telegram/SourceFiles/history/field_autocomplete.cpp @@ -53,7 +53,7 @@ FieldAutocomplete::FieldAutocomplete(QWidget *parent) : TWidget(parent) _inner->setGeometry(rect()); _scroll->setGeometry(rect()); - _scroll->setWidget(_inner); + _scroll->setOwnedWidget(_inner); _scroll->show(); _inner->show(); @@ -946,4 +946,7 @@ void FieldAutocompleteInner::onPreview() { } } +FieldAutocompleteInner::~FieldAutocompleteInner() { +} + } // namespace internal diff --git a/Telegram/SourceFiles/history/field_autocomplete.h b/Telegram/SourceFiles/history/field_autocomplete.h index 4dd85260b..71b4cba99 100644 --- a/Telegram/SourceFiles/history/field_autocomplete.h +++ b/Telegram/SourceFiles/history/field_autocomplete.h @@ -37,7 +37,6 @@ class FieldAutocomplete final : public TWidget { Q_OBJECT public: - FieldAutocomplete(QWidget *parent); void fastHide(); @@ -79,7 +78,6 @@ public: ~FieldAutocomplete(); signals: - void mentionChosen(UserData *user, FieldAutocomplete::ChooseMethod method) const; void hashtagChosen(QString hashtag, FieldAutocomplete::ChooseMethod method) const; void botCommandChosen(QString command, FieldAutocomplete::ChooseMethod method) const; @@ -88,14 +86,12 @@ signals: void moderateKeyActivate(int key, bool *outHandled) const; public slots: - void hideStart(); void hideFinish(); void showStart(); private: - void paintEvent(QPaintEvent *e) override; void updateFiltered(bool resetScroll = false); @@ -146,7 +142,6 @@ class FieldAutocompleteInner final : public TWidget { Q_OBJECT public: - FieldAutocompleteInner(FieldAutocomplete *parent, MentionRows *mrows, HashtagRows *hrows, BotCommandRows *brows, StickerPack *srows); void clearSel(bool hidden = false); @@ -155,8 +150,9 @@ public: void setRecentInlineBotsInRows(int32 bots); -signals: + ~FieldAutocompleteInner(); +signals: void mentionChosen(UserData *user, FieldAutocomplete::ChooseMethod method) const; void hashtagChosen(QString hashtag, FieldAutocomplete::ChooseMethod method) const; void botCommandChosen(QString command, FieldAutocomplete::ChooseMethod method) const; @@ -164,13 +160,11 @@ signals: void mustScrollTo(int scrollToTop, int scrollToBottom); public slots: - void onParentGeometryChanged(); void onUpdateSelected(bool force = false); void onPreview(); private: - void paintEvent(QPaintEvent *e) override; void resizeEvent(QResizeEvent *e) override; @@ -199,6 +193,7 @@ private: bool _previewShown; QTimer _previewTimer; + }; } // namespace internal diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 290eeab90..3f23f6034 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -2143,7 +2143,7 @@ int HistoryInner::itemTop(const HistoryItem *item) const { // -1 if should not b } void HistoryInner::notifyIsBotChanged() { - BotInfo *newinfo = (_history && _history->peer->isUser()) ? _history->peer->asUser()->botInfo : nullptr; + BotInfo *newinfo = (_history && _history->peer->isUser()) ? _history->peer->asUser()->botInfo.get() : nullptr; if ((!newinfo && !_botAbout) || (newinfo && _botAbout && _botAbout->info == newinfo)) { return; } diff --git a/Telegram/SourceFiles/intro/introsignup.cpp b/Telegram/SourceFiles/intro/introsignup.cpp index ab8bfc44d..7e08d5fd7 100644 --- a/Telegram/SourceFiles/intro/introsignup.cpp +++ b/Telegram/SourceFiles/intro/introsignup.cpp @@ -242,7 +242,7 @@ void IntroSignup::onCheckRequest() { void IntroSignup::onPhotoReady(const QImage &img) { _photoBig = img; - _photoSmall = QPixmap::fromImage(img.scaled(st::introPhotoSize * cIntRetinaFactor(), st::introPhotoSize * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly); + _photoSmall = App::pixmapFromImageInPlace(img.scaled(st::introPhotoSize * cIntRetinaFactor(), st::introPhotoSize * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); _photoSmall.setDevicePixelRatio(cRetinaFactor()); } diff --git a/Telegram/SourceFiles/localimageloader.cpp b/Telegram/SourceFiles/localimageloader.cpp index ce407efbe..8419f665e 100644 --- a/Telegram/SourceFiles/localimageloader.cpp +++ b/Telegram/SourceFiles/localimageloader.cpp @@ -312,7 +312,7 @@ void FileLoadTask::process() { if (!cover.isNull()) { // cover to thumb int32 cw = cover.width(), ch = cover.height(); if (cw < 20 * ch && ch < 20 * cw) { - QPixmap full = (cw > 90 || ch > 90) ? QPixmap::fromImage(cover.scaled(90, 90, Qt::KeepAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly) : QPixmap::fromImage(cover, Qt::ColorOnly); + QPixmap full = (cw > 90 || ch > 90) ? App::pixmapFromImageInPlace(cover.scaled(90, 90, Qt::KeepAspectRatio, Qt::SmoothTransformation)) : App::pixmapFromImageInPlace(std_::move(cover)); { QByteArray thumbFormat = "JPG"; int32 thumbQuality = 87; @@ -339,7 +339,7 @@ void FileLoadTask::process() { attributes.push_back(animatedAttribute); gif = true; - QPixmap full = (cw > 90 || ch > 90) ? QPixmap::fromImage(cover.scaled(90, 90, Qt::KeepAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly) : QPixmap::fromImage(cover, Qt::ColorOnly); + QPixmap full = (cw > 90 || ch > 90) ? App::pixmapFromImageInPlace(cover.scaled(90, 90, Qt::KeepAspectRatio, Qt::SmoothTransformation)) : App::pixmapFromImageInPlace(std_::move(cover)); { QByteArray thumbFormat = "JPG"; int32 thumbQuality = 87; @@ -369,15 +369,15 @@ void FileLoadTask::process() { if (animated) { attributes.push_back(MTP_documentAttributeAnimated()); } else if (_type != PrepareDocument) { - QPixmap thumb = (w > 100 || h > 100) ? QPixmap::fromImage(fullimage.scaled(100, 100, Qt::KeepAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly) : QPixmap::fromImage(fullimage); + QPixmap thumb = (w > 100 || h > 100) ? App::pixmapFromImageInPlace(fullimage.scaled(100, 100, Qt::KeepAspectRatio, Qt::SmoothTransformation)) : QPixmap::fromImage(fullimage); photoThumbs.insert('s', thumb); photoSizes.push_back(MTP_photoSize(MTP_string("s"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(thumb.width()), MTP_int(thumb.height()), MTP_int(0))); - QPixmap medium = (w > 320 || h > 320) ? QPixmap::fromImage(fullimage.scaled(320, 320, Qt::KeepAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly) : QPixmap::fromImage(fullimage); + QPixmap medium = (w > 320 || h > 320) ? App::pixmapFromImageInPlace(fullimage.scaled(320, 320, Qt::KeepAspectRatio, Qt::SmoothTransformation)) : QPixmap::fromImage(fullimage); photoThumbs.insert('m', medium); photoSizes.push_back(MTP_photoSize(MTP_string("m"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(medium.width()), MTP_int(medium.height()), MTP_int(0))); - QPixmap full = (w > 1280 || h > 1280) ? QPixmap::fromImage(fullimage.scaled(1280, 1280, Qt::KeepAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly) : QPixmap::fromImage(fullimage); + QPixmap full = (w > 1280 || h > 1280) ? App::pixmapFromImageInPlace(fullimage.scaled(1280, 1280, Qt::KeepAspectRatio, Qt::SmoothTransformation)) : QPixmap::fromImage(fullimage); photoThumbs.insert('y', full); photoSizes.push_back(MTP_photoSize(MTP_string("y"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(full.width()), MTP_int(full.height()), MTP_int(0))); @@ -397,7 +397,7 @@ void FileLoadTask::process() { thumbname = qsl("thumb.webp"); } - QPixmap full = (w > 90 || h > 90) ? QPixmap::fromImage(fullimage.scaled(90, 90, Qt::KeepAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly) : QPixmap::fromImage(fullimage, Qt::ColorOnly); + QPixmap full = (w > 90 || h > 90) ? App::pixmapFromImageInPlace(fullimage.scaled(90, 90, Qt::KeepAspectRatio, Qt::SmoothTransformation)) : QPixmap::fromImage(fullimage, Qt::ColorOnly); { QBuffer buffer(&thumbdata); diff --git a/Telegram/SourceFiles/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index 9d30c85aa..11e617c13 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -2643,7 +2643,7 @@ namespace Local { case StorageFileWebp: guessFormat = "WEBP"; break; default: guessFormat = QByteArray(); break; } - pixmap = QPixmap::fromImage(App::readImage(data, &guessFormat, false), Qt::ColorOnly); + pixmap = App::pixmapFromImageInPlace(App::readImage(data, &guessFormat, false)); if (!pixmap.isNull()) { format = guessFormat; } @@ -2910,7 +2910,7 @@ namespace Local { struct Result { Result(StorageFileType type, const QByteArray &data) : image(type, data) { QByteArray guessFormat; - pixmap = QPixmap::fromImage(App::readImage(data, &guessFormat, false), Qt::ColorOnly); + pixmap = App::pixmapFromImageInPlace(App::readImage(data, &guessFormat, false)); if (!pixmap.isNull()) { format = guessFormat; } diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index bc661a7b3..f30eb1c70 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -1019,13 +1019,13 @@ void MainWidget::onCacheBackground() { } _cachedX = 0; _cachedY = 0; - _cachedBackground = QPixmap::fromImage(result); + _cachedBackground = App::pixmapFromImageInPlace(std_::move(result)); } else { QRect to, from; backgroundParams(_willCacheFor, to, from); _cachedX = to.x(); _cachedY = to.y(); - _cachedBackground = QPixmap::fromImage(bg.toImage().copy(from).scaled(to.width() * cIntRetinaFactor(), to.height() * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + _cachedBackground = App::pixmapFromImageInPlace(bg.toImage().copy(from).scaled(to.width() * cIntRetinaFactor(), to.height() * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); _cachedBackground.setDevicePixelRatio(cRetinaFactor()); } _cachedFor = _willCacheFor; diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index ba495270d..88e49d8a0 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -174,7 +174,7 @@ void NotifyWindow::updateNotifyDisplay() { history->peer->loadUserpic(true, true); history->peer->paintUserpicLeft(p, st::notifyPhotoSize, st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), width()); } else { - static QPixmap icon = QPixmap::fromImage(App::wnd()->iconLarge().scaled(st::notifyPhotoSize, st::notifyPhotoSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly); + static QPixmap icon = App::pixmapFromImageInPlace(App::wnd()->iconLarge().scaled(st::notifyPhotoSize, st::notifyPhotoSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), icon); } @@ -234,7 +234,7 @@ void NotifyWindow::updateNotifyDisplay() { } } - pm = QPixmap::fromImage(img, Qt::ColorOnly); + pm = App::pixmapFromImageInPlace(std_::move(img)); update(); } @@ -246,7 +246,7 @@ void NotifyWindow::updatePeerPhoto() { p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), peerPhoto->pix(st::notifyPhotoSize)); } peerPhoto = ImagePtr(); - pm = QPixmap::fromImage(img, Qt::ColorOnly); + pm = App::pixmapFromImageInPlace(std_::move(img)); update(); } } @@ -1882,7 +1882,7 @@ QImage MainWindow::iconWithCounter(int size, int count, style::color bg, bool sm placeSmallCounter(img, size, count, bg, QPoint(), st::counterColor); } else { QPainter p(&img); - p.drawPixmap(size / 2, size / 2, QPixmap::fromImage(iconWithCounter(-size / 2, count, bg, false), Qt::ColorOnly)); + p.drawPixmap(size / 2, size / 2, App::pixmapFromImageInPlace(iconWithCounter(-size / 2, count, bg, false))); } return img; } @@ -1952,7 +1952,7 @@ PreLaunchWindow *PreLaunchWindowInstance = 0; PreLaunchWindow::PreLaunchWindow(QString title) : TWidget(0) { Fonts::start(); - QIcon icon(QPixmap::fromImage(QImage(cPlatform() == dbipMac ? qsl(":/gui/art/iconbig256.png") : qsl(":/gui/art/icon256.png")), Qt::ColorOnly)); + QIcon icon(App::pixmapFromImageInPlace(QImage(cPlatform() == dbipMac ? qsl(":/gui/art/iconbig256.png") : qsl(":/gui/art/icon256.png")))); if (cPlatform() == dbipLinux32 || cPlatform() == dbipLinux64) { icon = QIcon::fromTheme("telegram", icon); } diff --git a/Telegram/SourceFiles/media/media_audio.cpp b/Telegram/SourceFiles/media/media_audio.cpp index 12604b8e6..dbee88b81 100644 --- a/Telegram/SourceFiles/media/media_audio.cpp +++ b/Telegram/SourceFiles/media/media_audio.cpp @@ -484,14 +484,12 @@ void AudioPlayer::play(const AudioMsgId &audio, int64 position) { if (stopped) emit updated(stopped); } -void AudioPlayer::initFromVideo(const AudioMsgId &audio, uint64 videoPlayId, std_::unique_ptr &&data, int64 position) { - t_assert(audio.type() == AudioMsgId::Type::Video); - - auto type = audio.type(); +void AudioPlayer::initFromVideo(uint64 videoPlayId, std_::unique_ptr &&data, int64 position) { AudioMsgId stopped; { QMutexLocker lock(&playerMutex); + auto type = AudioMsgId::Type::Video; auto current = dataForType(type); t_assert(current != nullptr); @@ -503,7 +501,7 @@ void AudioPlayer::initFromVideo(const AudioMsgId &audio, uint64 videoPlayId, std } emit faderOnTimer(); current->clear(); - current->audio = audio; + current->audio = AudioMsgId(AudioMsgId::Type::Video); current->videoPlayId = videoPlayId; current->videoData = std_::move(data); { @@ -516,7 +514,7 @@ void AudioPlayer::initFromVideo(const AudioMsgId &audio, uint64 videoPlayId, std current->playbackState.state = AudioPlayerPaused; current->loading = true; - emit loaderOnStart(audio, position); + emit loaderOnStart(current->audio, position); } if (stopped) emit updated(stopped); } @@ -651,7 +649,7 @@ void AudioPlayer::videoSoundProgress(const AudioMsgId &audio) { auto current = dataForType(type); t_assert(current != nullptr); - if (current->videoPlayId == _lastVideoPlayId && current->playbackState.frequency) { + if (current->videoPlayId == _lastVideoPlayId && current->playbackState.duration && current->playbackState.frequency) { _lastVideoPlaybackWhen = getms(); _lastVideoPlaybackCorrectedMs = (current->playbackState.position * 1000ULL) / current->playbackState.frequency; } @@ -1523,15 +1521,11 @@ void AudioCaptureInner::onStop(bool needResult) { if (d->device) { alcCaptureStop(d->device); alcCaptureCloseDevice(d->device); - d->device = 0; + d->device = nullptr; - if (d->ioContext) { - av_free(d->ioContext); - d->ioContext = 0; - } if (d->codecContext) { avcodec_close(d->codecContext); - d->codecContext = 0; + d->codecContext = nullptr; } if (d->srcSamplesData) { if (d->srcSamplesData[0]) { @@ -1548,23 +1542,28 @@ void AudioCaptureInner::onStop(bool needResult) { d->fullSamples = 0; if (d->swrContext) { swr_free(&d->swrContext); - d->swrContext = 0; + d->swrContext = nullptr; } if (d->opened) { avformat_close_input(&d->fmtContext); d->opened = false; - d->ioBuffer = 0; + } + if (d->ioContext) { + av_free(d->ioContext->buffer); + av_free(d->ioContext); + d->ioContext = nullptr; + d->ioBuffer = nullptr; } else if (d->ioBuffer) { av_free(d->ioBuffer); - d->ioBuffer = 0; + d->ioBuffer = nullptr; } if (d->fmtContext) { avformat_free_context(d->fmtContext); - d->fmtContext = 0; + d->fmtContext = nullptr; } - d->fmt = 0; - d->stream = 0; - d->codec = 0; + d->fmt = nullptr; + d->stream = nullptr; + d->codec = nullptr; d->lastUpdate = 0; d->levelMax = 0; diff --git a/Telegram/SourceFiles/media/media_audio.h b/Telegram/SourceFiles/media/media_audio.h index e7a392d4f..012725cf3 100644 --- a/Telegram/SourceFiles/media/media_audio.h +++ b/Telegram/SourceFiles/media/media_audio.h @@ -67,7 +67,7 @@ public: void stop(AudioMsgId::Type type); // Video player audio stream interface. - void initFromVideo(const AudioMsgId &audio, uint64 videoPlayId, std_::unique_ptr &&data, int64 position); + void initFromVideo(uint64 videoPlayId, std_::unique_ptr &&data, int64 position); void feedFromVideo(VideoSoundPart &&part); int64 getVideoCorrectedTime(uint64 playId, uint64 systemMs); void videoSoundProgress(const AudioMsgId &audio); diff --git a/Telegram/SourceFiles/media/media_audio_ffmpeg_loader.cpp b/Telegram/SourceFiles/media/media_audio_ffmpeg_loader.cpp index 4fed50ca0..69bd99cd2 100644 --- a/Telegram/SourceFiles/media/media_audio_ffmpeg_loader.cpp +++ b/Telegram/SourceFiles/media/media_audio_ffmpeg_loader.cpp @@ -76,9 +76,12 @@ bool AbstractFFMpegLoader::open(qint64 position) { } AbstractFFMpegLoader::~AbstractFFMpegLoader() { - if (ioContext) av_free(ioContext); if (_opened) { avformat_close_input(&fmtContext); + } + if (ioContext) { + av_free(ioContext->buffer); + av_free(ioContext); } else if (ioBuffer) { av_free(ioBuffer); } @@ -221,9 +224,6 @@ bool FFMpegLoader::open(qint64 position) { if (av_seek_frame(fmtContext, streamId, ts, 0) < 0) { } } - //if (dstSamplesData) { - // position = qRound(srcRate * (position / float64(dstRate))); - //} } return true; diff --git a/Telegram/SourceFiles/media/media_audio_loaders.cpp b/Telegram/SourceFiles/media/media_audio_loaders.cpp index f635c8326..83ec07544 100644 --- a/Telegram/SourceFiles/media/media_audio_loaders.cpp +++ b/Telegram/SourceFiles/media/media_audio_loaders.cpp @@ -201,7 +201,7 @@ void AudioPlayerLoaders::loadData(AudioMsgId audio, qint64 position) { } m->skipStart = position; m->skipEnd = m->playbackState.duration - position; - m->playbackState.position = 0; + m->playbackState.position = position; m->started = 0; } if (samplesCount) { diff --git a/Telegram/SourceFiles/media/media_child_ffmpeg_loader.cpp b/Telegram/SourceFiles/media/media_child_ffmpeg_loader.cpp index c6534720b..4ec96b1c1 100644 --- a/Telegram/SourceFiles/media/media_child_ffmpeg_loader.cpp +++ b/Telegram/SourceFiles/media/media_child_ffmpeg_loader.cpp @@ -182,6 +182,7 @@ ChildFFMpegLoader::~ChildFFMpegLoader() { for (auto &packet : queue) { FFMpeg::freePacket(&packet); } + if (_swrContext) swr_free(&_swrContext); if (_dstSamplesData) { if (_dstSamplesData[0]) { av_freep(&_dstSamplesData[0]); diff --git a/Telegram/SourceFiles/media/media_clip_ffmpeg.cpp b/Telegram/SourceFiles/media/media_clip_ffmpeg.cpp index 80153b0d3..460fc689e 100644 --- a/Telegram/SourceFiles/media/media_clip_ffmpeg.cpp +++ b/Telegram/SourceFiles/media/media_clip_ffmpeg.cpp @@ -233,7 +233,7 @@ bool FFMpegReaderImplementation::renderFrame(QImage &to, bool &hasAlpha, const Q } // Read some future packets for audio stream. - if (_audioStreamId) { + if (_audioStreamId >= 0) { while (_frameMs + 5000 > _lastReadPacketMs) { auto packetResult = readPacket(); if (packetResult != PacketResult::Ok) { @@ -246,7 +246,7 @@ bool FFMpegReaderImplementation::renderFrame(QImage &to, bool &hasAlpha, const Q return true; } -bool FFMpegReaderImplementation::start(Mode mode) { +bool FFMpegReaderImplementation::start(Mode mode, int64 positionMs) { _mode = mode; initDevice(); @@ -309,6 +309,7 @@ bool FFMpegReaderImplementation::start(Mode mode) { return false; } + std_::unique_ptr soundData; if (_audioStreamId >= 0) { // Get a pointer to the codec context for the audio stream auto audioContextOriginal = _fmtContext->streams[_audioStreamId]->codec; @@ -326,7 +327,7 @@ bool FFMpegReaderImplementation::start(Mode mode) { return false; } - auto soundData = std_::make_unique(); + soundData = std_::make_unique(); soundData->context = audioContext; soundData->frequency = audioContextOriginal->sample_rate; if (_fmtContext->streams[_audioStreamId]->duration == AV_NOPTS_VALUE) { @@ -334,7 +335,20 @@ bool FFMpegReaderImplementation::start(Mode mode) { } else { soundData->length = (_fmtContext->streams[_audioStreamId]->duration * soundData->frequency * _fmtContext->streams[_audioStreamId]->time_base.num) / _fmtContext->streams[_audioStreamId]->time_base.den; } - audioPlayer()->initFromVideo(AudioMsgId(AudioMsgId::Type::Video), _playId, std_::move(soundData), 0); + } + + if (positionMs) { + int64 ts = (positionMs * _fmtContext->streams[_streamId]->time_base.den) / (1000LL * _fmtContext->streams[_streamId]->time_base.num); + if (av_seek_frame(_fmtContext, _streamId, ts, AVSEEK_FLAG_ANY) < 0) { + if (av_seek_frame(_fmtContext, _streamId, ts, 0) < 0) { + positionMs = 0; + } + } + } + + if (_audioStreamId >= 0) { + int64 position = (positionMs * soundData->frequency) / 1000LL; + audioPlayer()->initFromVideo(_playId, std_::move(soundData), position); } return true; @@ -348,22 +362,26 @@ FFMpegReaderImplementation::~FFMpegReaderImplementation() { if (_audioStreamId >= 0) { audioPlayer()->stopFromVideo(_playId); } + + clearPacketQueue(); + if (_frameRead) { av_frame_unref(_frame); _frameRead = false; } - if (_ioContext) av_free(_ioContext); if (_codecContext) avcodec_close(_codecContext); if (_swsContext) sws_freeContext(_swsContext); if (_opened) { avformat_close_input(&_fmtContext); + } + if (_ioContext) { + av_free(_ioContext->buffer); + av_free(_ioContext); } else if (_ioBuffer) { av_free(_ioBuffer); } if (_fmtContext) avformat_free_context(_fmtContext); av_frame_free(&_frame); - - clearPacketQueue(); } FFMpegReaderImplementation::PacketResult FFMpegReaderImplementation::readPacket() { diff --git a/Telegram/SourceFiles/media/media_clip_ffmpeg.h b/Telegram/SourceFiles/media/media_clip_ffmpeg.h index b048798f6..cf54258d6 100644 --- a/Telegram/SourceFiles/media/media_clip_ffmpeg.h +++ b/Telegram/SourceFiles/media/media_clip_ffmpeg.h @@ -51,7 +51,7 @@ public: void pauseAudio() override; void resumeAudio() override; - bool start(Mode mode) override; + bool start(Mode mode, int64 positionMs) override; QString logData() const; diff --git a/Telegram/SourceFiles/media/media_clip_implementation.h b/Telegram/SourceFiles/media/media_clip_implementation.h index 61e96fb0b..21d2ad53a 100644 --- a/Telegram/SourceFiles/media/media_clip_implementation.h +++ b/Telegram/SourceFiles/media/media_clip_implementation.h @@ -58,7 +58,7 @@ public: virtual void pauseAudio() = 0; virtual void resumeAudio() = 0; - virtual bool start(Mode mode) = 0; + virtual bool start(Mode mode, int64 positionMs) = 0; virtual ~ReaderImplementation() { } int64 dataSize() const { diff --git a/Telegram/SourceFiles/media/media_clip_qtgif.cpp b/Telegram/SourceFiles/media/media_clip_qtgif.cpp index 0ef2b8d96..d1216f213 100644 --- a/Telegram/SourceFiles/media/media_clip_qtgif.cpp +++ b/Telegram/SourceFiles/media/media_clip_qtgif.cpp @@ -99,7 +99,7 @@ int64 QtGifReaderImplementation::durationMs() const { return 0; // not supported } -bool QtGifReaderImplementation::start(Mode mode) { +bool QtGifReaderImplementation::start(Mode mode, int64 positionMs) { if (mode == Mode::OnlyGifv) return false; _mode = mode; return jumpToStart(); diff --git a/Telegram/SourceFiles/media/media_clip_qtgif.h b/Telegram/SourceFiles/media/media_clip_qtgif.h index 3fc704183..4384dd9e8 100644 --- a/Telegram/SourceFiles/media/media_clip_qtgif.h +++ b/Telegram/SourceFiles/media/media_clip_qtgif.h @@ -47,7 +47,7 @@ public: void resumeAudio() override { } - bool start(Mode mode) override; + bool start(Mode mode, int64 positionMs) override; ~QtGifReaderImplementation(); diff --git a/Telegram/SourceFiles/media/media_clip_reader.cpp b/Telegram/SourceFiles/media/media_clip_reader.cpp index cae75409b..5a9cea8e4 100644 --- a/Telegram/SourceFiles/media/media_clip_reader.cpp +++ b/Telegram/SourceFiles/media/media_clip_reader.cpp @@ -85,10 +85,11 @@ QPixmap _prepareFrame(const FrameRequest &request, const QImage &original, bool } // namespace -Reader::Reader(const FileLocation &location, const QByteArray &data, Callback &&callback, Mode mode) +Reader::Reader(const FileLocation &location, const QByteArray &data, Callback &&callback, Mode mode, int64 seekMs) : _callback(std_::move(callback)) , _mode(mode) -, _playId(rand_value()) { +, _playId(rand_value()) +, _seekPositionMs(seekMs) { if (threads.size() < ClipThreadsCount) { _threadIndex = threads.size(); threads.push_back(new QThread()); @@ -269,7 +270,7 @@ int64 Reader::getPositionMs() const { if (auto frame = frameToShow()) { return frame->positionMs; } - return 0; + return _seekPositionMs; } int64 Reader::getDurationMs() const { @@ -310,10 +311,12 @@ void Reader::stop() { void Reader::error() { _state = State::Error; + _private = nullptr; } void Reader::finished() { _state = State::Finished; + _private = nullptr; } Reader::~Reader() { @@ -325,6 +328,7 @@ public: ReaderPrivate(Reader *reader, const FileLocation &location, const QByteArray &data) : _interface(reader) , _mode(reader->mode()) , _playId(reader->playId()) + , _seekPositionMs(reader->seekPositionMs()) , _data(data) { if (_data.isEmpty()) { _location = std_::make_unique(location); @@ -337,7 +341,7 @@ public: } ProcessResult start(uint64 ms) { - if (!_implementation && !init()) { + if (!_implementation && !init(_seekPositionMs)) { return error(); } if (frame() && frame()->original.isNull()) { @@ -348,6 +352,8 @@ public: if (!_implementation->renderFrame(frame()->original, frame()->alpha, QSize())) { return error(); } + frame()->positionMs = _implementation->frameRealTime(); + _width = frame()->original.width(); _height = frame()->original.height(); _durationMs = _implementation->durationMs(); @@ -381,7 +387,7 @@ public: } ProcessResult finishProcess(uint64 ms) { - auto readResult = _implementation->readFramesTill(ms - _animationStarted); + auto readResult = _implementation->readFramesTill(_skippedMs + ms - _animationStarted); if (readResult == internal::ReaderImplementation::ReadResult::Eof) { stop(); _state = State::Finished; @@ -391,6 +397,11 @@ public: } _nextFramePositionMs = _implementation->frameRealTime(); _nextFrameWhen = _animationStarted + _implementation->framePresentationTime(); + if (static_cast(_nextFrameWhen) > _skippedMs) { + _nextFrameWhen -= _skippedMs; + } else { + _nextFrameWhen = 1; + } if (!renderFrame()) { return error(); @@ -411,7 +422,7 @@ public: return true; } - bool init() { + bool init(int64 positionMs) { if (_data.isEmpty() && QFileInfo(_location->name()).size() <= AnimationInMemory) { QFile f(_location->name()); if (f.open(QIODevice::ReadOnly)) { @@ -432,7 +443,8 @@ public: } return ImplementationMode::Normal; }; - return _implementation->start(implementationMode()); + _skippedMs = positionMs; + return _implementation->start(implementationMode(), positionMs); } void startedAt(uint64 ms) { @@ -485,6 +497,7 @@ private: State _state = State::Reading; Reader::Mode _mode; uint64 _playId; + int64 _seekPositionMs = 0; QByteArray _data; std_::unique_ptr _location; @@ -517,6 +530,7 @@ private: uint64 _animationStarted = 0; uint64 _nextFrameWhen = 0; int64 _nextFramePositionMs = 0; + int64 _skippedMs = 0; bool _autoPausedGif = false; bool _started = false; @@ -699,11 +713,12 @@ void Manager::process() { _timer.stop(); _processingInThread = thread(); + bool checkAllReaders = false; uint64 ms = getms(), minms = ms + 86400 * 1000ULL; { QReadLocker lock(&_readerPointersMutex); for (auto it = _readerPointers.begin(), e = _readerPointers.end(); it != e; ++it) { - if (it->v.loadAcquire()) { + if (it->v.loadAcquire() && it.key()->_private != nullptr) { auto i = _readers.find(it.key()->_private); if (i == _readers.cend()) { _readers.insert(it.key()->_private, 0); @@ -723,6 +738,7 @@ void Manager::process() { it->v.storeRelease(0); } } + checkAllReaders = (_readers.size() > _readerPointers.size()); } for (auto i = _readers.begin(), e = _readers.end(); i != e;) { @@ -744,6 +760,15 @@ void Manager::process() { } else { i.value() = (ms + 86400 * 1000ULL); } + } else if (checkAllReaders) { + QReadLocker lock(&_readerPointersMutex); + ReaderPointers::const_iterator it = constUnsafeFindReaderPointer(reader); + if (it == _readerPointers.cend()) { + _loadLevel.fetchAndAddRelaxed(-1 * (reader->_width > 0 ? reader->_width * reader->_height : AverageGifSize)); + delete reader; + i = _readers.erase(i); + continue; + } } if (!reader->_autoPausedGif && i.value() < minms) { minms = i.value(); @@ -771,7 +796,7 @@ void Manager::clear() { { QWriteLocker lock(&_readerPointersMutex); for (ReaderPointers::iterator it = _readerPointers.begin(), e = _readerPointers.end(); it != e; ++it) { - it.key()->_private = 0; + it.key()->_private = nullptr; } _readerPointers.clear(); } @@ -792,7 +817,7 @@ MTPDocumentAttribute readAttributes(const QString &fname, const QByteArray &data auto playId = 0ULL; auto reader = std_::make_unique(&localloc, &localdata, playId); - if (reader->start(internal::ReaderImplementation::Mode::OnlyGifv)) { + if (reader->start(internal::ReaderImplementation::Mode::OnlyGifv, 0)) { bool hasAlpha = false; auto readResult = reader->readFramesTill(-1); auto readFrame = (readResult == internal::ReaderImplementation::ReadResult::Success); diff --git a/Telegram/SourceFiles/media/media_clip_reader.h b/Telegram/SourceFiles/media/media_clip_reader.h index 8960ec61e..c4620a2c1 100644 --- a/Telegram/SourceFiles/media/media_clip_reader.h +++ b/Telegram/SourceFiles/media/media_clip_reader.h @@ -58,7 +58,7 @@ public: Video, }; - Reader(const FileLocation &location, const QByteArray &data, Callback &&callback, Mode mode = Mode::Gif); + Reader(const FileLocation &location, const QByteArray &data, Callback &&callback, Mode mode = Mode::Gif, int64 seekMs = 0); static void callback(Reader *reader, int threadIndex, Notification notification); // reader can be deleted void setAutoplay() { @@ -71,6 +71,9 @@ public: uint64 playId() const { return _playId; } + int64 seekPositionMs() const { + return _seekPositionMs; + } void start(int framew, int frameh, int outerw, int outerh, bool rounded); QPixmap current(int framew, int frameh, int outerw, int outerh, uint64 ms); @@ -128,6 +131,7 @@ private: uint64 _playId; bool _hasAudio = false; int64 _durationMs = 0; + int64 _seekPositionMs = 0; mutable int _width = 0; mutable int _height = 0; diff --git a/Telegram/SourceFiles/media/view/media_clip_controller.cpp b/Telegram/SourceFiles/media/view/media_clip_controller.cpp index d9cf95629..eb9f1ae3f 100644 --- a/Telegram/SourceFiles/media/view/media_clip_controller.cpp +++ b/Telegram/SourceFiles/media/view/media_clip_controller.cpp @@ -48,19 +48,29 @@ Controller::Controller(QWidget *parent) : TWidget(parent) connect(_playPauseResume, SIGNAL(clicked()), this, SIGNAL(playPressed())); connect(_fullScreenToggle, SIGNAL(clicked()), this, SIGNAL(toFullScreenPressed())); - connect(_playback, SIGNAL(seekProgress(int64)), this, SLOT(onSeekProgress(int64))); - connect(_playback, SIGNAL(seekFinished(int64)), this, SLOT(onSeekFinished(int64))); + connect(_playback, SIGNAL(seekProgress(float64)), this, SLOT(onSeekProgress(float64))); + connect(_playback, SIGNAL(seekFinished(float64)), this, SLOT(onSeekFinished(float64))); connect(_volumeController, SIGNAL(volumeChanged(float64)), this, SIGNAL(volumeChanged(float64))); } -void Controller::onSeekProgress(int64 position) { - _seekPosition = position; - emit seekProgress(position); +void Controller::onSeekProgress(float64 progress) { + if (!_lastDurationMs) return; + + auto positionMs = snap(static_cast(progress * _lastDurationMs), 0LL, _lastDurationMs); + if (_seekPositionMs != positionMs) { + _seekPositionMs = positionMs; + emit seekProgress(positionMs); + refreshTimeTexts(); + } } -void Controller::onSeekFinished(int64 position) { - _seekPosition = -1; - emit seekFinished(position); +void Controller::onSeekFinished(float64 progress) { + if (!_lastDurationMs) return; + + auto positionMs = snap(static_cast(progress * _lastDurationMs), 0LL, _lastDurationMs); + _seekPositionMs = -1; + emit seekFinished(positionMs); + refreshTimeTexts(); } void Controller::showAnimated() { @@ -89,14 +99,14 @@ void Controller::fadeUpdated(float64 opacity) { _playback->setFadeOpacity(opacity); } -void Controller::updatePlayback(const AudioPlaybackState &playbackState) { +void Controller::updatePlayback(const AudioPlaybackState &playbackState, bool reset) { updatePlayPauseResumeState(playbackState); - _playback->updateState(playbackState); + _playback->updateState(playbackState, reset); updateTimeTexts(playbackState); } void Controller::updatePlayPauseResumeState(const AudioPlaybackState &playbackState) { - bool showPause = (playbackState.state == AudioPlayerPlaying || playbackState.state == AudioPlayerResuming); + bool showPause = (playbackState.state == AudioPlayerPlaying || playbackState.state == AudioPlayerResuming || _seekPositionMs >= 0); if (showPause != _showPause) { disconnect(_playPauseResume, SIGNAL(clicked()), this, _showPause ? SIGNAL(pausePressed()) : SIGNAL(playPressed())); _showPause = showPause; @@ -120,11 +130,30 @@ void Controller::updateTimeTexts(const AudioPlaybackState &playbackState) { auto playAlready = position / playFrequency; auto playLeft = (playbackState.duration / playFrequency) - playAlready; - auto timeAlready = formatDurationText(playAlready); - auto minus = QChar(8722); - auto timeLeft = minus + formatDurationText(playLeft); + _lastDurationMs = (playbackState.duration * 1000LL) / playFrequency; + _timeAlready = formatDurationText(playAlready); + auto minus = QChar(8722); + _timeLeft = minus + formatDurationText(playLeft); + + if (_seekPositionMs < 0) { + refreshTimeTexts(); + } +} + +void Controller::refreshTimeTexts() { auto alreadyChanged = false, leftChanged = false; + auto timeAlready = _timeAlready; + auto timeLeft = _timeLeft; + if (_seekPositionMs >= 0) { + auto playAlready = _seekPositionMs / 1000LL; + auto playLeft = (_lastDurationMs / 1000LL) - playAlready; + + timeAlready = formatDurationText(playAlready); + auto minus = QChar(8722); + timeLeft = minus + formatDurationText(playLeft); + } + _playedAlready->setText(timeAlready, &alreadyChanged); _toPlayLeft->setText(timeLeft, &leftChanged); if (alreadyChanged || leftChanged) { diff --git a/Telegram/SourceFiles/media/view/media_clip_controller.h b/Telegram/SourceFiles/media/view/media_clip_controller.h index 14a5a5c13..25ebfd720 100644 --- a/Telegram/SourceFiles/media/view/media_clip_controller.h +++ b/Telegram/SourceFiles/media/view/media_clip_controller.h @@ -43,7 +43,7 @@ public: void showAnimated(); void hideAnimated(); - void updatePlayback(const AudioPlaybackState &playbackState); + void updatePlayback(const AudioPlaybackState &playbackState, bool reset); void setInFullScreen(bool inFullScreen); void grabStart() override; @@ -52,15 +52,15 @@ public: signals: void playPressed(); void pausePressed(); - void seekProgress(int64 position); - void seekFinished(int64 position); + void seekProgress(int64 positionMs); + void seekFinished(int64 positionMs); void volumeChanged(float64 volume); void toFullScreenPressed(); void fromFullScreenPressed(); private slots: - void onSeekProgress(int64 position); - void onSeekFinished(int64 position); + void onSeekProgress(float64 progress); + void onSeekFinished(float64 progress); protected: void resizeEvent(QResizeEvent *e) override; @@ -75,9 +75,12 @@ private: void updatePlayPauseResumeState(const AudioPlaybackState &playbackState); void updateTimeTexts(const AudioPlaybackState &playbackState); + void refreshTimeTexts(); bool _showPause = false; - int64 _seekPosition = -1; + QString _timeAlready, _timeLeft; + int64 _seekPositionMs = -1; + int64 _lastDurationMs = 0; ChildWidget _playPauseResume; ChildWidget _playback; diff --git a/Telegram/SourceFiles/media/view/media_clip_playback.cpp b/Telegram/SourceFiles/media/view/media_clip_playback.cpp index be628d0c8..1fccb7278 100644 --- a/Telegram/SourceFiles/media/view/media_clip_playback.cpp +++ b/Telegram/SourceFiles/media/view/media_clip_playback.cpp @@ -32,11 +32,11 @@ Playback::Playback(QWidget *parent) : TWidget(parent) setCursor(style::cur_pointer); } -void Playback::updateState(const AudioPlaybackState &playbackState) { +void Playback::updateState(const AudioPlaybackState &playbackState, bool reset) { qint64 position = 0, duration = playbackState.duration; _playing = !(playbackState.state & AudioPlayerStoppedMask); - if (_playing && playbackState.state != AudioPlayerFinishing) { + if (_playing || playbackState.state == AudioPlayerStopped) { position = playbackState.position; } else if (playbackState.state == AudioPlayerStoppedAtEnd) { position = playbackState.duration; @@ -51,7 +51,7 @@ void Playback::updateState(const AudioPlaybackState &playbackState) { progress = duration ? snap(float64(position) / duration, 0., 1.) : 0.; } if (duration != _duration || position != _position) { - if (duration && _duration && playbackState.state != AudioPlayerStopped) { + if (duration && _duration && !reset) { a_progress.start(progress); _a_progress.start(); } else { @@ -112,12 +112,26 @@ void Playback::paintEvent(QPaintEvent *e) { } void Playback::mouseMoveEvent(QMouseEvent *e) { + if (_mouseDown) { + _downProgress = snap(e->pos().x() / float64(width()), 0., 1.); + emit seekProgress(_downProgress); + update(); + } } void Playback::mousePressEvent(QMouseEvent *e) { + _mouseDown = true; + _downProgress = snap(e->pos().x() / float64(width()), 0., 1.); + emit seekProgress(_downProgress); + update(); } void Playback::mouseReleaseEvent(QMouseEvent *e) { + if (_mouseDown) { + _mouseDown = false; + emit seekFinished(_downProgress); + update(); + } } void Playback::enterEvent(QEvent *e) { diff --git a/Telegram/SourceFiles/media/view/media_clip_playback.h b/Telegram/SourceFiles/media/view/media_clip_playback.h index ad1a645f3..190358d78 100644 --- a/Telegram/SourceFiles/media/view/media_clip_playback.h +++ b/Telegram/SourceFiles/media/view/media_clip_playback.h @@ -31,12 +31,12 @@ class Playback : public TWidget { public: Playback(QWidget *parent); - void updateState(const AudioPlaybackState &playbackState); + void updateState(const AudioPlaybackState &playbackState, bool reset); void setFadeOpacity(float64 opacity); signals: - void seekProgress(int64 position); - void seekFinished(int64 position); + void seekProgress(float64 progress); + void seekFinished(float64 progress); protected: void paintEvent(QPaintEvent *e) override; diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index 54cab77d5..94a496819 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -236,6 +236,7 @@ bool MediaView::gifShown() const { void MediaView::stopGif() { _gif = nullptr; + _videoPaused = _videoIsSilent = false; _clipController.destroy(); Sandbox::removeEventFilter(this); if (audioPlayer()) { @@ -1121,7 +1122,7 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty const FileLocation &location(_doc->location(true)); if (location.accessEnable()) { if (QImageReader(location.name()).canRead()) { - _current = QPixmap::fromImage(App::readImage(location.name(), 0, false), Qt::ColorOnly); + _current = App::pixmapFromImageInPlace(App::readImage(location.name(), 0, false)); } } location.accessDisable(); @@ -1258,7 +1259,7 @@ void MediaView::createClipReader() { _gif = std_::make_unique(_doc->location(), _doc->data(), func(this, &MediaView::clipCallback), mode); // Correct values will be set when gif gets inited. - _videoIsSilent = false; + _videoPaused = _videoIsSilent = false; _videoPositionMs = 0ULL; _videoDurationMs = _doc->duration() * 1000ULL; @@ -1306,21 +1307,7 @@ void MediaView::onVideoPauseResume() { if (_gif->state() == Media::Clip::State::Error) { displayDocument(_doc, item); } else if (_gif->state() == Media::Clip::State::Finished) { - _autoplayVideoDocument = _doc; - - _current = _gif->current(_gif->width(), _gif->height(), _gif->width(), _gif->height(), getms()); - _gif = std_::make_unique(_doc->location(), _doc->data(), func(this, &MediaView::clipCallback), Media::Clip::Reader::Mode::Video); - - // Correct values will be set when gif gets inited. - _videoIsSilent = false; - _videoPositionMs = 0; - - AudioPlaybackState state; - state.state = AudioPlayerStopped; - state.position = _videoPositionMs; - state.duration = _videoDurationMs; - state.frequency = _videoFrequencyMs; - updateVideoPlaybackState(state); + restartVideoAtSeekPosition(0); } else { _gif->pauseResumeVideo(); _videoPaused = _gif->videoPaused(); @@ -1333,12 +1320,34 @@ void MediaView::onVideoPauseResume() { } } -void MediaView::onVideoSeekProgress(int64 position) { +void MediaView::restartVideoAtSeekPosition(int64 positionMs) { + _autoplayVideoDocument = _doc; + if (_current.isNull()) { + _current = _gif->current(_gif->width(), _gif->height(), _gif->width(), _gif->height(), getms()); + } + _gif = std_::make_unique(_doc->location(), _doc->data(), func(this, &MediaView::clipCallback), Media::Clip::Reader::Mode::Video, positionMs); + + // Correct values will be set when gif gets inited. + _videoPaused = _videoIsSilent = false; + _videoPositionMs = positionMs; + + AudioPlaybackState state; + state.state = AudioPlayerPlaying; + state.position = _videoPositionMs; + state.duration = _videoDurationMs; + state.frequency = _videoFrequencyMs; + updateVideoPlaybackState(state, true); } -void MediaView::onVideoSeekFinished(int64 position) { +void MediaView::onVideoSeekProgress(int64 positionMs) { + if (!_videoPaused) { + onVideoPauseResume(); + } +} +void MediaView::onVideoSeekFinished(int64 positionMs) { + restartVideoAtSeekPosition(positionMs); } void MediaView::onVideoVolumeChanged(float64 volume) { @@ -1361,12 +1370,14 @@ void MediaView::onVideoPlayProgress(const AudioMsgId &audioId) { t_assert(audioPlayer() != nullptr); auto state = audioPlayer()->currentVideoState(_gif->playId()); - updateVideoPlaybackState(state); + if (state.duration) { + updateVideoPlaybackState(state); + } } -void MediaView::updateVideoPlaybackState(const AudioPlaybackState &state) { +void MediaView::updateVideoPlaybackState(const AudioPlaybackState &state, bool reset) { if (state.frequency) { - _clipController->updatePlayback(state); + _clipController->updatePlayback(state, reset); } else { // Audio has stopped already. _videoIsSilent = true; updateSilentVideoPlaybackState(); diff --git a/Telegram/SourceFiles/mediaview.h b/Telegram/SourceFiles/mediaview.h index 582307f8c..81b7ab02a 100644 --- a/Telegram/SourceFiles/mediaview.h +++ b/Telegram/SourceFiles/mediaview.h @@ -118,8 +118,8 @@ protected: private slots: void onVideoPauseResume(); - void onVideoSeekProgress(int64 position); - void onVideoSeekFinished(int64 position); + void onVideoSeekProgress(int64 positionMs); + void onVideoSeekFinished(int64 positionMs); void onVideoVolumeChanged(float64 volume); void onVideoToFullScreen(); void onVideoFromFullScreen(); @@ -131,8 +131,9 @@ private: void findCurrent(); void loadBack(); - void updateVideoPlaybackState(const AudioPlaybackState &state); + void updateVideoPlaybackState(const AudioPlaybackState &state, bool reset = false); void updateSilentVideoPlaybackState(); + void restartVideoAtSeekPosition(int64 positionMs); void createClipController(); void setClipControllerGeometry(); diff --git a/Telegram/SourceFiles/mtproto/file_download.cpp b/Telegram/SourceFiles/mtproto/file_download.cpp index ab8a25af5..d8c588eee 100644 --- a/Telegram/SourceFiles/mtproto/file_download.cpp +++ b/Telegram/SourceFiles/mtproto/file_download.cpp @@ -105,9 +105,10 @@ void FileLoader::readImage(const QSize &shrinkBox) const { QImage image = App::readImage(_data, &format, false); if (!image.isNull()) { if (!shrinkBox.isEmpty() && (image.width() > shrinkBox.width() || image.height() > shrinkBox.height())) { - image = image.scaled(shrinkBox, Qt::KeepAspectRatio, Qt::SmoothTransformation); + _imagePixmap = App::pixmapFromImageInPlace(image.scaled(shrinkBox, Qt::KeepAspectRatio, Qt::SmoothTransformation)); + } else { + _imagePixmap = App::pixmapFromImageInPlace(std_::move(image)); } - _imagePixmap = QPixmap::fromImage(image, Qt::ColorOnly); _imageFormat = format; } } diff --git a/Telegram/SourceFiles/overview/overview_layout.cpp b/Telegram/SourceFiles/overview/overview_layout.cpp index 59bb7caa4..242d7a473 100644 --- a/Telegram/SourceFiles/overview/overview_layout.cpp +++ b/Telegram/SourceFiles/overview/overview_layout.cpp @@ -202,7 +202,7 @@ void Photo::paint(Painter &p, const QRect &clip, TextSelection selection, const img.setDevicePixelRatio(cRetinaFactor()); _data->forget(); - _pix = QPixmap::fromImage(img, Qt::ColorOnly); + _pix = App::pixmapFromImageInPlace(std_::move(img)); } else if (!_pix.isNull()) { _pix = QPixmap(); } @@ -274,7 +274,7 @@ void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const img.setDevicePixelRatio(cRetinaFactor()); _data->forget(); - _pix = QPixmap::fromImage(img, Qt::ColorOnly); + _pix = App::pixmapFromImageInPlace(std_::move(img)); } else if (!_pix.isNull()) { _pix = QPixmap(); } diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp index 8971a4976..5fe26b0fa 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp @@ -360,8 +360,8 @@ void MainWindow::psUpdateCounter() { bool muted = App::histories().unreadOnlyMuted(); style::color bg = muted ? st::counterMuteBG : st::counterBG; - icon.addPixmap(QPixmap::fromImage(iconWithCounter(16, counter, bg, true), Qt::ColorOnly)); - icon.addPixmap(QPixmap::fromImage(iconWithCounter(32, counter, bg, true), Qt::ColorOnly)); + icon.addPixmap(App::pixmapFromImageInPlace(iconWithCounter(16, counter, bg, true), Qt::ColorOnly)); + icon.addPixmap(App::pixmapFromImageInPlace(iconWithCounter(32, counter, bg, true), Qt::ColorOnly)); } trayIcon->setIcon(icon); } diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.mm b/Telegram/SourceFiles/platform/mac/main_window_mac.mm index 8738a9ffe..602816914 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.mm +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.mm @@ -212,8 +212,8 @@ void MainWindow::psUpdateCounter() { int32 size = cRetina() ? 44 : 22; _placeCounter(img, size, counter, bg, (dm && muted) ? st::counterMacInvColor : st::counterColor); _placeCounter(imgsel, size, counter, st::white, st::counterMacInvColor); - icon.addPixmap(QPixmap::fromImage(img, Qt::ColorOnly)); - icon.addPixmap(QPixmap::fromImage(imgsel, Qt::ColorOnly), QIcon::Selected); + icon.addPixmap(App::pixmapFromImageInPlace(std_::move(img))); + icon.addPixmap(App::pixmapFromImageInPlace(std_::move(imgsel)), QIcon::Selected); trayIcon->setIcon(icon); } } diff --git a/Telegram/SourceFiles/platform/win/main_window_win.cpp b/Telegram/SourceFiles/platform/win/main_window_win.cpp index d7dc77ec6..0dc587238 100644 --- a/Telegram/SourceFiles/platform/win/main_window_win.cpp +++ b/Telegram/SourceFiles/platform/win/main_window_win.cpp @@ -736,10 +736,10 @@ void MainWindow::psUpdateCounter() { style::color bg = muted ? st::counterMuteBG : st::counterBG; QIcon iconSmall, iconBig; - iconSmall.addPixmap(QPixmap::fromImage(iconWithCounter(16, counter, bg, true), Qt::ColorOnly)); - iconSmall.addPixmap(QPixmap::fromImage(iconWithCounter(32, counter, bg, true), Qt::ColorOnly)); - iconBig.addPixmap(QPixmap::fromImage(iconWithCounter(32, taskbarList.Get() ? 0 : counter, bg, false), Qt::ColorOnly)); - iconBig.addPixmap(QPixmap::fromImage(iconWithCounter(64, taskbarList.Get() ? 0 : counter, bg, false), Qt::ColorOnly)); + iconSmall.addPixmap(App::pixmapFromImageInPlace(iconWithCounter(16, counter, bg, true))); + iconSmall.addPixmap(App::pixmapFromImageInPlace(iconWithCounter(32, counter, bg, true))); + iconBig.addPixmap(App::pixmapFromImageInPlace(iconWithCounter(32, taskbarList.Get() ? 0 : counter, bg, false))); + iconBig.addPixmap(App::pixmapFromImageInPlace(iconWithCounter(64, taskbarList.Get() ? 0 : counter, bg, false))); if (trayIcon) { trayIcon->setIcon(iconSmall); } @@ -753,8 +753,8 @@ void MainWindow::psUpdateCounter() { if (taskbarList.Get()) { if (counter > 0) { QIcon iconOverlay; - iconOverlay.addPixmap(QPixmap::fromImage(iconWithCounter(-16, counter, bg, false), Qt::ColorOnly)); - iconOverlay.addPixmap(QPixmap::fromImage(iconWithCounter(-32, counter, bg, false), Qt::ColorOnly)); + iconOverlay.addPixmap(App::pixmapFromImageInPlace(iconWithCounter(-16, counter, bg, false))); + iconOverlay.addPixmap(App::pixmapFromImageInPlace(iconWithCounter(-32, counter, bg, false))); ps_iconOverlay = createHIconFromQIcon(iconOverlay, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); } QString description = counter > 0 ? QString("%1 unread messages").arg(counter) : qsl("No unread messages"); diff --git a/Telegram/SourceFiles/pspecific_win.cpp b/Telegram/SourceFiles/pspecific_win.cpp index effc56d8a..c1215a59e 100644 --- a/Telegram/SourceFiles/pspecific_win.cpp +++ b/Telegram/SourceFiles/pspecific_win.cpp @@ -585,7 +585,7 @@ namespace { if (!iconindex) { // try to read image QImage img(QString::fromWCharArray(icon)); if (!img.isNull()) { - return qt_pixmapToWinHBITMAP(QPixmap::fromImage(img.scaled(w, h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)), /* HBitmapAlpha */ 2); + return qt_pixmapToWinHBITMAP(App::pixmapFromImageInPlace(img.scaled(w, h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)), /* HBitmapAlpha */ 2); } } return 0; diff --git a/Telegram/SourceFiles/settingswidget.cpp b/Telegram/SourceFiles/settingswidget.cpp index afb3112e2..cd051bcf4 100644 --- a/Telegram/SourceFiles/settingswidget.cpp +++ b/Telegram/SourceFiles/settingswidget.cpp @@ -1753,7 +1753,7 @@ void SettingsInner::updateChatBackground() { p.setRenderHint(QPainter::SmoothPixmapTransform); p.drawPixmap(0, 0, st::setBackgroundSize, st::setBackgroundSize, pix, sx, sy, s, s); } - _background = QPixmap::fromImage(back); + _background = App::pixmapFromImageInPlace(std_::move(back)); _background.setDevicePixelRatio(cRetinaFactor()); _needBackgroundUpdate = false; diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp index 8ae66bbf0..5575db300 100644 --- a/Telegram/SourceFiles/structs.cpp +++ b/Telegram/SourceFiles/structs.cpp @@ -220,7 +220,7 @@ void UserData::setPhoto(const MTPUserProfilePhoto &p) { // see Local::readPeer a newPhotoId = 0; if (id == ServiceUserId) { if (_userpic.v() == userDefPhoto(colorIndex).v()) { - newPhoto = ImagePtr(QPixmap::fromImage(App::wnd()->iconLarge().scaledToWidth(160, Qt::SmoothTransformation), Qt::ColorOnly), "PNG"); + newPhoto = ImagePtr(App::pixmapFromImageInPlace(App::wnd()->iconLarge().scaledToWidth(160, Qt::SmoothTransformation)), "PNG"); } } else { newPhoto = userDefPhoto(colorIndex); @@ -299,12 +299,11 @@ void UserData::setBotInfoVersion(int version) { botInfo->commands.clear(); Notify::botCommandsChanged(this); } - delete botInfo; - botInfo = 0; + botInfo = nullptr; Notify::userIsBotChanged(this); } } else if (!botInfo) { - botInfo = new BotInfo(); + botInfo = std_::make_unique(); botInfo->version = version; Notify::userIsBotChanged(this); } else if (botInfo->version < version) { diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index d34e95292..4e7ed2fab 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -471,7 +471,7 @@ public: return _about; } - BotInfo *botInfo = nullptr; + std_::unique_ptr botInfo; QString restrictionReason() const override { return _restrictionReason; diff --git a/Telegram/SourceFiles/title.cpp b/Telegram/SourceFiles/title.cpp index 5aec57778..b969cd7bd 100644 --- a/Telegram/SourceFiles/title.cpp +++ b/Telegram/SourceFiles/title.cpp @@ -279,7 +279,7 @@ void TitleWidget::updateCounter() { case dbisOneAndHalf: size = -24; break; case dbisTwo: size = -32; break; } - _counter = QPixmap::fromImage(App::wnd()->iconWithCounter(size, counter, bg, false), Qt::ColorOnly); + _counter = App::pixmapFromImageInPlace(App::wnd()->iconWithCounter(size, counter, bg, false)); _counter.setDevicePixelRatio(cRetinaFactor()); update(QRect(st::titleIconPos, st::titleIconImg.pxSize())); } else { diff --git a/Telegram/SourceFiles/ui/boxshadow.cpp b/Telegram/SourceFiles/ui/boxshadow.cpp index 9e52f6229..b556d5719 100644 --- a/Telegram/SourceFiles/ui/boxshadow.cpp +++ b/Telegram/SourceFiles/ui/boxshadow.cpp @@ -56,8 +56,6 @@ BoxShadow::BoxShadow(const style::sprite &topLeft) : _size(topLeft.pxWidth()), _ m.setDevicePixelRatio(cRetinaFactor()); p.drawImage(_size, 0, m, _pixsize, 0, _pixsize, _pixsize * 2); } - _corners = QPixmap::fromImage(cornersImage, Qt::ColorOnly); - _corners.setDevicePixelRatio(cRetinaFactor()); _colors.reserve(_pixsize); uchar prev = 0; for (int i = 0; i < _pixsize; ++i) { @@ -68,15 +66,17 @@ BoxShadow::BoxShadow(const style::sprite &topLeft) : _size(topLeft.pxWidth()), _ prev = a; } if (cRetina()) { - _left = QPixmap::fromImage(cornersImage.copy(0, _pixsize - 1, _colors.size(), 1), Qt::ColorOnly); + _left = App::pixmapFromImageInPlace(cornersImage.copy(0, _pixsize - 1, _colors.size(), 1)); _left.setDevicePixelRatio(cRetinaFactor()); - _top = QPixmap::fromImage(cornersImage.copy(_pixsize - 1, 0, 1, _colors.size()), Qt::ColorOnly); + _top = App::pixmapFromImageInPlace(cornersImage.copy(_pixsize - 1, 0, 1, _colors.size())); _top.setDevicePixelRatio(cRetinaFactor()); - _right = QPixmap::fromImage(cornersImage.copy(_pixsize * 2 - _colors.size(), _pixsize, _colors.size(), 1), Qt::ColorOnly); + _right = App::pixmapFromImageInPlace(cornersImage.copy(_pixsize * 2 - _colors.size(), _pixsize, _colors.size(), 1)); _right.setDevicePixelRatio(cRetinaFactor()); - _bottom = QPixmap::fromImage(cornersImage.copy(_pixsize, _pixsize * 2 - _colors.size(), 1, _colors.size()), Qt::ColorOnly); + _bottom = App::pixmapFromImageInPlace(cornersImage.copy(_pixsize, _pixsize * 2 - _colors.size(), 1, _colors.size())); _bottom.setDevicePixelRatio(cRetinaFactor()); } + _corners = App::pixmapFromImageInPlace(std_::move(cornersImage)); + _corners.setDevicePixelRatio(cRetinaFactor()); } void BoxShadow::paint(QPainter &p, const QRect &box, int32 shifty, int32 flags) { @@ -140,8 +140,6 @@ RectShadow::RectShadow(const style::icon &topLeft) : _size(topLeft.width()), _pi m.setDevicePixelRatio(cRetinaFactor()); p.drawImage(_size, 0, m, _pixsize, 0, _pixsize, _pixsize * 2); } - _corners = QPixmap::fromImage(cornersImage, Qt::ColorOnly); - _corners.setDevicePixelRatio(cRetinaFactor()); uchar prev = 0; for (int i = 0; i < _pixsize; ++i) { @@ -152,14 +150,17 @@ RectShadow::RectShadow(const style::icon &topLeft) : _size(topLeft.width()), _pi prev = a; } - _left = QPixmap::fromImage(cornersImage.copy(0, _pixsize - 1, _thickness, 1), Qt::ColorOnly); + _left = App::pixmapFromImageInPlace(cornersImage.copy(0, _pixsize - 1, _thickness, 1)); _left.setDevicePixelRatio(cRetinaFactor()); - _top = QPixmap::fromImage(cornersImage.copy(_pixsize - 1, 0, 1, _thickness), Qt::ColorOnly); + _top = App::pixmapFromImageInPlace(cornersImage.copy(_pixsize - 1, 0, 1, _thickness)); _top.setDevicePixelRatio(cRetinaFactor()); - _right = QPixmap::fromImage(cornersImage.copy(_pixsize * 2 - _thickness, _pixsize, _thickness, 1), Qt::ColorOnly); + _right = App::pixmapFromImageInPlace(cornersImage.copy(_pixsize * 2 - _thickness, _pixsize, _thickness, 1)); _right.setDevicePixelRatio(cRetinaFactor()); - _bottom = QPixmap::fromImage(cornersImage.copy(_pixsize, _pixsize * 2 - _thickness, 1, _thickness), Qt::ColorOnly); + _bottom = App::pixmapFromImageInPlace(cornersImage.copy(_pixsize, _pixsize * 2 - _thickness, 1, _thickness)); _bottom.setDevicePixelRatio(cRetinaFactor()); + + _corners = App::pixmapFromImageInPlace(std_::move(cornersImage)); + _corners.setDevicePixelRatio(cRetinaFactor()); } void RectShadow::paint(Painter &p, const QRect &box, int shifty, Sides sides) { diff --git a/Telegram/SourceFiles/ui/countryinput.cpp b/Telegram/SourceFiles/ui/countryinput.cpp index ae979b787..bdc4d81ff 100644 --- a/Telegram/SourceFiles/ui/countryinput.cpp +++ b/Telegram/SourceFiles/ui/countryinput.cpp @@ -106,7 +106,7 @@ CountryInput::CountryInput(QWidget *parent, const style::countryInput &st) : QWi p.setBrush(_st.bgColor->b); p.drawPolygon(trPoints, 3); } - _arrow = QPixmap::fromImage(trImage, Qt::ColorOnly); + _arrow = App::pixmapFromImageInPlace(std_::move(trImage)); _inner = QRect(0, 0, _st.width, _st.height); _arrowRect = QRect((st::inpIntroCountryCode.width - _arrow.width() - 1) / 2, _st.height, _arrow.width(), _arrow.height()); } diff --git a/Telegram/SourceFiles/ui/images.cpp b/Telegram/SourceFiles/ui/images.cpp index 2cc1e8b30..a9aa79389 100644 --- a/Telegram/SourceFiles/ui/images.cpp +++ b/Telegram/SourceFiles/ui/images.cpp @@ -64,7 +64,7 @@ ImagePtr::ImagePtr(int32 width, int32 height, const MTPFileLocation &location, I } Image::Image(const QString &file, QByteArray fmt) : _forgot(false) { - _data = QPixmap::fromImage(App::readImage(file, &fmt, false, 0, &_saved), Qt::ColorOnly); + _data = App::pixmapFromImageInPlace(App::readImage(file, &fmt, false, 0, &_saved)); _format = fmt; if (!_data.isNull()) { globalAcquiredSize += int64(_data.width()) * _data.height() * 4; @@ -72,7 +72,7 @@ Image::Image(const QString &file, QByteArray fmt) : _forgot(false) { } Image::Image(const QByteArray &filecontent, QByteArray fmt) : _forgot(false) { - _data = QPixmap::fromImage(App::readImage(filecontent, &fmt, false), Qt::ColorOnly); + _data = App::pixmapFromImageInPlace(App::readImage(filecontent, &fmt, false)); _format = fmt; _saved = filecontent; if (!_data.isNull()) { @@ -420,7 +420,7 @@ const QPixmap &circleMask(int width, int height) { p.drawEllipse(0, 0, width, height); } mask.setDevicePixelRatio(cRetinaFactor()); - i = masks.insert(key, QPixmap::fromImage(mask)); + i = masks.insert(key, App::pixmapFromImageInPlace(std_::move(mask))); } return i.value(); } @@ -543,7 +543,7 @@ QPixmap imagePix(QImage img, int32 w, int32 h, ImagePixOptions options, int32 ou imageRound(img, ImageRoundRadius::Small); } img.setDevicePixelRatio(cRetinaFactor()); - return QPixmap::fromImage(img, Qt::ColorOnly); + return App::pixmapFromImageInPlace(std_::move(img)); } QPixmap Image::pixNoCache(int w, int h, ImagePixOptions options, int outerw, int outerh) const { @@ -584,7 +584,7 @@ QPixmap Image::pixNoCache(int w, int h, ImagePixOptions options, int outerw, int } else if (options.testFlag(ImagePixRoundedSmall)) { imageRound(result, ImageRoundRadius::Small); } - return QPixmap::fromImage(result, Qt::ColorOnly); + return App::pixmapFromImageInPlace(std_::move(result)); } return imagePix(_data.toImage(), w, h, options, outerw, outerh); @@ -596,11 +596,11 @@ QPixmap Image::pixColoredNoCache(const style::color &add, int32 w, int32 h, bool if (_data.isNull()) return blank()->pix(); QImage img = _data.toImage(); - if (w <= 0 || !width() || !height() || (w == width() && (h <= 0 || h == height()))) return QPixmap::fromImage(imageColored(add, img)); + if (w <= 0 || !width() || !height() || (w == width() && (h <= 0 || h == height()))) return App::pixmapFromImageInPlace(imageColored(add, img)); if (h <= 0) { - return QPixmap::fromImage(imageColored(add, img.scaledToWidth(w, smooth ? Qt::SmoothTransformation : Qt::FastTransformation)), Qt::ColorOnly); + return App::pixmapFromImageInPlace(imageColored(add, img.scaledToWidth(w, smooth ? Qt::SmoothTransformation : Qt::FastTransformation))); } - return QPixmap::fromImage(imageColored(add, img.scaled(w, h, Qt::IgnoreAspectRatio, smooth ? Qt::SmoothTransformation : Qt::FastTransformation)), Qt::ColorOnly); + return App::pixmapFromImageInPlace(imageColored(add, img.scaled(w, h, Qt::IgnoreAspectRatio, smooth ? Qt::SmoothTransformation : Qt::FastTransformation))); } QPixmap Image::pixBlurredColoredNoCache(const style::color &add, int32 w, int32 h) const { @@ -615,7 +615,7 @@ QPixmap Image::pixBlurredColoredNoCache(const style::color &add, int32 w, int32 img = img.scaled(w, h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); } - return QPixmap::fromImage(imageColored(add, img), Qt::ColorOnly); + return App::pixmapFromImageInPlace(imageColored(add, img)); } void Image::forget() const { @@ -738,7 +738,7 @@ void RemoteImage::setData(QByteArray &bytes, const QByteArray &bytesFormat) { globalAcquiredSize -= int64(_data.width()) * _data.height() * 4; } QByteArray fmt(bytesFormat); - _data = QPixmap::fromImage(App::readImage(bytes, &fmt, false), Qt::ColorOnly); + _data = App::pixmapFromImageInPlace(App::readImage(bytes, &fmt, false)); if (!_data.isNull()) { globalAcquiredSize += int64(_data.width()) * _data.height() * 4; setInformation(bytes.size(), _data.width(), _data.height()); diff --git a/Telegram/SourceFiles/ui/style/style_core.cpp b/Telegram/SourceFiles/ui/style/style_core.cpp index 253dedf45..3d490d63a 100644 --- a/Telegram/SourceFiles/ui/style/style_core.cpp +++ b/Telegram/SourceFiles/ui/style/style_core.cpp @@ -73,6 +73,8 @@ void stopManager() { internal::stopModules(); internal::destroyFonts(); internal::destroyColors(); + internal::destroyIcons(); + internal::destroySprite(); } QImage colorizeImage(const QImage &src, const color &c, const QRect &r) { diff --git a/Telegram/SourceFiles/ui/style/style_core_icon.cpp b/Telegram/SourceFiles/ui/style/style_core_icon.cpp index 83bd66a26..95445eb1b 100644 --- a/Telegram/SourceFiles/ui/style/style_core_icon.cpp +++ b/Telegram/SourceFiles/ui/style/style_core_icon.cpp @@ -64,7 +64,7 @@ QPixmap createIconPixmap(const IconMask *mask, const Color &color) { } finalImage = colorizeImage(maskImage, color, r); finalImage.setDevicePixelRatio(cRetinaFactor()); - return QPixmap::fromImage(finalImage, Qt::ColorOnly); + return App::pixmapFromImageInPlace(std_::move(finalImage)); } } // namespace diff --git a/Telegram/SourceFiles/ui/style/style_core_icon.h b/Telegram/SourceFiles/ui/style/style_core_icon.h index 446c6258c..b4c4d2a65 100644 --- a/Telegram/SourceFiles/ui/style/style_core_icon.h +++ b/Telegram/SourceFiles/ui/style/style_core_icon.h @@ -131,5 +131,7 @@ private: }; +void destroyIcons(); + } // namespace internal } // namespace style diff --git a/Telegram/SourceFiles/ui/style/style_core_types.cpp b/Telegram/SourceFiles/ui/style/style_core_types.cpp index 774de9ee2..2f0444307 100644 --- a/Telegram/SourceFiles/ui/style/style_core_types.cpp +++ b/Telegram/SourceFiles/ui/style/style_core_types.cpp @@ -41,7 +41,7 @@ void loadSprite() { } QString spriteFile = qsl(":/gui/art/sprite") + spriteFilePostfix + qsl(".png"); if (rtl()) { - spriteData = new QPixmap(QPixmap::fromImage(QImage(spriteFile).mirrored(true, false))); + spriteData = new QPixmap(App::pixmapFromImageInPlace(QImage(spriteFile).mirrored(true, false))); } else { spriteData = new QPixmap(spriteFile); } @@ -53,6 +53,11 @@ int spriteWidth() { return spriteWidthValue; } +void destroySprite() { + delete spriteData; + spriteData = nullptr; +} + } // namespace internal const QPixmap &spritePixmap() { diff --git a/Telegram/SourceFiles/ui/style/style_core_types.h b/Telegram/SourceFiles/ui/style/style_core_types.h index bb4296185..aa2fa782c 100644 --- a/Telegram/SourceFiles/ui/style/style_core_types.h +++ b/Telegram/SourceFiles/ui/style/style_core_types.h @@ -37,6 +37,7 @@ namespace internal { void loadSprite(); int spriteWidth(); +void destroySprite(); class Sprite { public: diff --git a/Telegram/SourceFiles/ui/text/text_block.cpp b/Telegram/SourceFiles/ui/text/text_block.cpp index 705d935f5..d8e7696ce 100644 --- a/Telegram/SourceFiles/ui/text/text_block.cpp +++ b/Telegram/SourceFiles/ui/text/text_block.cpp @@ -337,14 +337,7 @@ TextBlock::TextBlock(const style::font &font, const QString &str, QFixed minResi layout.beginLayout(); layout.createLine(); - bool logCrashString = (rand_value() % 4 == 1); - if (logCrashString) { - SignalHandlers::setCrashAnnotationRef("CrashString", &str); - } BlockParser parser(&engine, this, minResizeWidth, _from, part); - if (logCrashString) { - SignalHandlers::clearCrashAnnotationRef("CrashString"); - } layout.endLayout(); }