From c2f58d3ab5a59c2ddd432ff8f4a9d6dc3657db2c Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 24 Feb 2020 17:48:23 +0400 Subject: [PATCH] Fix GIFs with alpha display. --- .../streaming/media_streaming_utility.cpp | 37 +++++++++++++------ .../media/streaming/media_streaming_utility.h | 1 + .../streaming/media_streaming_video_track.cpp | 9 ++++- .../streaming/media_streaming_video_track.h | 2 + .../SourceFiles/media/view/media_view_pip.cpp | 1 + 5 files changed, 37 insertions(+), 13 deletions(-) diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_utility.cpp b/Telegram/SourceFiles/media/streaming/media_streaming_utility.cpp index 297475c955..44fe63b8ab 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_utility.cpp +++ b/Telegram/SourceFiles/media/streaming/media_streaming_utility.cpp @@ -212,6 +212,7 @@ void PaintFrameInner( QPainter &p, QRect to, const QImage &original, + bool alpha, int rotation) { const auto rotated = [](QRect rect, int rotation) { switch (rotation) { @@ -239,22 +240,32 @@ void PaintFrameInner( if (rotation) { p.rotate(rotation); } - p.drawImage(rotated(to, rotation), original); + const auto rect = rotated(to, rotation); + if (alpha) { + p.fillRect(rect, Qt::white); + } + p.drawImage(rect, original); } void PaintFrameContent( QPainter &p, const QImage &original, + bool alpha, int rotation, const FrameRequest &request) { - const auto full = request.outer; + const auto full = request.outer.isEmpty() + ? original.size() + : request.outer; + const auto size = request.resize.isEmpty() + ? original.size() + : request.resize; const auto to = QRect( - (full.width() - request.resize.width()) / 2, - (full.height() - request.resize.height()) / 2, - request.resize.width(), - request.resize.height()); + (full.width() - size.width()) / 2, + (full.height() - size.height()) / 2, + size.width(), + size.height()); PaintFrameOuter(p, to, full); - PaintFrameInner(p, to, original, rotation); + PaintFrameInner(p, to, original, alpha, rotation); } void ApplyFrameRounding(QImage &storage, const FrameRequest &request) { @@ -267,17 +278,21 @@ void ApplyFrameRounding(QImage &storage, const FrameRequest &request) { QImage PrepareByRequest( const QImage &original, + bool alpha, int rotation, const FrameRequest &request, QImage storage) { - Expects(!request.outer.isEmpty()); + Expects(!request.outer.isEmpty() || alpha); - if (!FFmpeg::GoodStorageForFrame(storage, request.outer)) { - storage = FFmpeg::CreateFrameStorage(request.outer); + const auto outer = request.outer.isEmpty() + ? original.size() + : request.outer; + if (!FFmpeg::GoodStorageForFrame(storage, outer)) { + storage = FFmpeg::CreateFrameStorage(outer); } QPainter p(&storage); - PaintFrameContent(p, original, rotation, request); + PaintFrameContent(p, original, alpha, rotation, request); p.end(); ApplyFrameRounding(storage, request); diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_utility.h b/Telegram/SourceFiles/media/streaming/media_streaming_utility.h index 0b28584e2b..3a39eb7f92 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_utility.h +++ b/Telegram/SourceFiles/media/streaming/media_streaming_utility.h @@ -60,6 +60,7 @@ struct Stream { QImage storage); [[nodiscard]] QImage PrepareByRequest( const QImage &original, + bool alpha, int rotation, const FrameRequest &request, QImage storage); diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_video_track.cpp b/Telegram/SourceFiles/media/streaming/media_streaming_video_track.cpp index 1feaa68525..b2cc6ff001 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_video_track.cpp +++ b/Telegram/SourceFiles/media/streaming/media_streaming_video_track.cpp @@ -361,6 +361,7 @@ void VideoTrackObject::presentFrameIfNeeded() { Expects(frame->position != kFinishedPosition); fillRequests(frame); + frame->alpha = (frame->decoded->format == AV_PIX_FMT_BGRA); frame->original = ConvertFrame( _stream, frame->decoded.get(), @@ -982,7 +983,8 @@ QImage VideoTrack::frame( unwrapped.updateFrameRequest(instance, useRequest); }); } - if (GoodForRequest(frame->original, _streamRotation, useRequest)) { + if (!frame->alpha + && GoodForRequest(frame->original, _streamRotation, useRequest)) { return frame->original; } else if (changed || none || i->second.image.isNull()) { const auto j = none @@ -1002,6 +1004,7 @@ QImage VideoTrack::frame( } j->second.image = PrepareByRequest( frame->original, + frame->alpha, _streamRotation, useRequest, std::move(j->second.image)); @@ -1025,7 +1028,8 @@ void VideoTrack::PrepareFrameByRequests( const auto end = frame->prepared.end(); for (auto i = begin; i != end; ++i) { auto &prepared = i->second; - if (!GoodForRequest(frame->original, rotation, prepared.request)) { + if (frame->alpha + || !GoodForRequest(frame->original, rotation, prepared.request)) { auto j = begin; for (; j != i; ++j) { if (j->second.request == prepared.request) { @@ -1036,6 +1040,7 @@ void VideoTrack::PrepareFrameByRequests( if (j == i) { prepared.image = PrepareByRequest( frame->original, + frame->alpha, rotation, prepared.request, std::move(prepared.image)); diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_video_track.h b/Telegram/SourceFiles/media/streaming/media_streaming_video_track.h index 434e061ee7..e92ddc5661 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_video_track.h +++ b/Telegram/SourceFiles/media/streaming/media_streaming_video_track.h @@ -83,6 +83,8 @@ private: crl::time display = kTimeUnknown; base::flat_map prepared; + + bool alpha = false; }; class Shared { diff --git a/Telegram/SourceFiles/media/view/media_view_pip.cpp b/Telegram/SourceFiles/media/view/media_view_pip.cpp index cba1ecf924..639f47f372 100644 --- a/Telegram/SourceFiles/media/view/media_view_pip.cpp +++ b/Telegram/SourceFiles/media/view/media_view_pip.cpp @@ -1391,6 +1391,7 @@ QImage Pip::videoFrame(const FrameRequest &request) const { if (state == ThumbState::Cover) { _preparedCoverStorage = Streaming::PrepareByRequest( _instance.info().video.cover, + false, _instance.info().video.rotation, request, std::move(_preparedCoverStorage));