diff --git a/Telegram/SourceFiles/calls/calls.style b/Telegram/SourceFiles/calls/calls.style index 3124fb61e9..075662184f 100644 --- a/Telegram/SourceFiles/calls/calls.style +++ b/Telegram/SourceFiles/calls/calls.style @@ -34,7 +34,7 @@ callShadow: Shadow { callWidthMin: 380px; callHeightMin: 440px; -callWidth: 960px; +callWidth: 720px; callHeight: 540px; callBottomControlsHeight: 85px; diff --git a/Telegram/SourceFiles/calls/calls_video_bubble.cpp b/Telegram/SourceFiles/calls/calls_video_bubble.cpp index 7d66a6420b..35d50e5598 100644 --- a/Telegram/SourceFiles/calls/calls_video_bubble.cpp +++ b/Telegram/SourceFiles/calls/calls_video_bubble.cpp @@ -9,7 +9,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "webrtc/webrtc_video_track.h" #include "ui/image/image_prepare.h" +#include "ui/widgets/shadow.h" #include "styles/style_calls.h" +#include "styles/style_widgets.h" +#include "styles/style_layers.h" namespace Calls { @@ -110,11 +113,58 @@ void VideoBubble::applySizeConstraints(QSize min, QSize max) { void VideoBubble::paint() { Painter p(&_content); - auto hq = PainterHighQualityEnabler(p); - p.drawImage(_content.rect(), _track->frame({})); + prepareFrame(); + if (!_frame.isNull()) { + const auto padding = st::boxRoundShadow.extend; + const auto inner = _content.rect().marginsRemoved(padding); + Ui::Shadow::paint(p, inner, _content.width(), st::boxRoundShadow); + p.drawImage( + inner, + _frame, + QRect(QPoint(), inner.size() * cIntRetinaFactor())); + } _track->markFrameShown(); } +void VideoBubble::prepareFrame() { + const auto original = _track->frameSize(); + if (original.isEmpty()) { + _frame = QImage(); + return; + } + const auto padding = st::boxRoundShadow.extend; + const auto size = _content.rect().marginsRemoved(padding).size() + * cIntRetinaFactor(); + + // Should we check 'original' and 'size' aspect ratios?.. + const auto request = webrtc::FrameRequest{ + .resize = size, + .outer = size, + }; + const auto frame = _track->frame(request); + if (_frame.width() < size.width() || _frame.height() < size.height()) { + _frame = QImage( + _max * cIntRetinaFactor(), + QImage::Format_ARGB32_Premultiplied); + } + Assert(_frame.width() >= frame.width() + && _frame.height() >= frame.height()); + const auto toPerLine = _frame.bytesPerLine(); + const auto fromPerLine = frame.bytesPerLine(); + const auto lineSize = frame.width() * 4; + auto to = _frame.bits(); + auto from = frame.bits(); + const auto till = from + frame.height() * fromPerLine; + for (; from != till; from += fromPerLine, to += toPerLine) { + memcpy(to, from, lineSize); + } + Images::prepareRound( + _frame, + ImageRoundRadius::Large, + RectPart::AllCorners, + QRect(QPoint(), size)); +} + void VideoBubble::setState(webrtc::VideoState state) { if (state == webrtc::VideoState::Paused) { using namespace Images; @@ -161,7 +211,7 @@ void VideoBubble::setInnerSize(QSize size) { } _geometryDirty = false; _size = size; - _content.setGeometry(QRect([&] { + const auto topLeft = [&] { switch (_corner) { case RectPart::None: return _boundingRect.topLeft() + QPoint( @@ -183,7 +233,9 @@ void VideoBubble::setInnerSize(QSize size) { _boundingRect.y() + _boundingRect.height() - size.height()); } Unexpected("Corner value in VideoBubble::setInnerSize."); - }(), size)); + }(); + const auto inner = QRect(topLeft, size); + _content.setGeometry(inner.marginsAdded(st::boxRoundShadow.extend)); } void VideoBubble::updateVisibility() { diff --git a/Telegram/SourceFiles/calls/calls_video_bubble.h b/Telegram/SourceFiles/calls/calls_video_bubble.h index b9d99d3739..a8682c6e8b 100644 --- a/Telegram/SourceFiles/calls/calls_video_bubble.h +++ b/Telegram/SourceFiles/calls/calls_video_bubble.h @@ -46,11 +46,12 @@ private: void updateSizeToFrame(QSize frame); void updateVisibility(); void setInnerSize(QSize size); + void prepareFrame(); Ui::RpWidget _content; const not_null _track; webrtc::VideoState _state = webrtc::VideoState(); - QImage _pausedFrame; + QImage _frame, _pausedFrame; QSize _min, _max, _size, _lastDraggableSize, _lastFrameSize; QRect _boundingRect; DragMode _dragMode = DragMode::None;