Use expanding incoming frame scale if aspect is good.

This commit is contained in:
John Preston 2020-08-13 15:32:25 +04:00
parent cdc87086f3
commit 377ff2f421
2 changed files with 70 additions and 27 deletions

View file

@ -448,11 +448,11 @@ void Panel::initControls() {
_cancel->finishAnimating(); _cancel->finishAnimating();
} }
void Panel::setIncomingShown(bool shown) { void Panel::setIncomingSize(QSize size) {
if (_incomingShown == shown) { if (_incomingFrameSize == size) {
return; return;
} }
_incomingShown = shown; _incomingFrameSize = size;
showControls(); showControls();
} }
@ -501,12 +501,30 @@ void Panel::reinitWithCall(Call *call) {
stateChanged(state); stateChanged(state);
}, _callLifetime); }, _callLifetime);
rpl::merge( _call->videoIncoming()->renderNextFrame(
_call->videoIncoming()->renderNextFrame(),
_call->videoOutgoing()->renderNextFrame()
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
setIncomingShown(!_call->videoIncoming()->frame({}).isNull()); setIncomingSize(_call->videoIncoming()->frameSize());
widget()->update(); if (_incomingFrameSize.isEmpty()) {
return;
}
const auto incoming = incomingFrameGeometry();
const auto outgoing = outgoingFrameGeometry();
if (incoming.intersects(outgoing)) {
widget()->update(incoming.united(outgoing));
} else {
widget()->update(incoming);
}
}, _callLifetime);
_call->videoOutgoing()->renderNextFrame(
) | rpl::start_with_next([=] {
const auto incoming = incomingFrameGeometry();
const auto outgoing = outgoingFrameGeometry();
if (incoming.intersects(outgoing)) {
widget()->update(incoming.united(outgoing));
} else {
widget()->update(outgoing);
}
}, _callLifetime); }, _callLifetime);
rpl::combine( rpl::combine(
@ -551,9 +569,11 @@ void Panel::showControls() {
widget()->showChildren(); widget()->showChildren();
_decline->setVisible(_decline->toggled()); _decline->setVisible(_decline->toggled());
_cancel->setVisible(_cancel->toggled()); _cancel->setVisible(_cancel->toggled());
_name->setVisible(!_incomingShown);
_status->setVisible(!_incomingShown); const auto shown = !_incomingFrameSize.isEmpty();
_userpic->setVisible(!_incomingShown); _name->setVisible(!shown);
_status->setVisible(!shown);
_userpic->setVisible(!shown);
} }
void Panel::hideBeforeDestroy() { void Panel::hideBeforeDestroy() {
@ -590,6 +610,31 @@ void Panel::toggleFullScreen(bool fullscreen) {
} }
} }
QRect Panel::incomingFrameGeometry() const {
if (!_call || _incomingFrameSize.isEmpty()) {
return QRect();
}
const auto to = widget()->size();
const auto small = _incomingFrameSize.scaled(to, Qt::KeepAspectRatio);
const auto big = _incomingFrameSize.scaled(
to,
Qt::KeepAspectRatioByExpanding);
// If we cut out no more than 0.33 of the original, let's use expanding.
const auto use = ((big.width() * 3 <= to.width() * 4)
&& (big.height() * 3 <= to.height() * 4))
? big
: small;
const auto pos = QPoint(
(to.width() - use.width()) / 2,
(to.height() - use.height()) / 2);
return QRect(pos, use);
}
QRect Panel::outgoingFrameGeometry() const {
return _outgoingVideoBubble->geometry();
}
void Panel::updateFingerprintGeometry() { void Panel::updateFingerprintGeometry() {
auto realSize = Ui::Emoji::GetSizeNormal(); auto realSize = Ui::Emoji::GetSizeNormal();
auto size = realSize / cIntRetinaFactor(); auto size = realSize / cIntRetinaFactor();
@ -712,20 +757,15 @@ void Panel::paint(QRect clip) {
p.fillRect(clip, st::callBgOpaque); p.fillRect(clip, st::callBgOpaque);
const auto incomingFrame = _call const auto incoming = incomingFrameGeometry();
? _call->videoIncoming()->frame(Webrtc::FrameRequest()) if (!incoming.isEmpty()) {
: QImage(); Assert(_call != nullptr);
if (!incomingFrame.isNull()) { const auto frame = _call->videoIncoming()->frame(
const auto to = widget()->rect(); Webrtc::FrameRequest());
p.save(); if (!frame.isNull()) {
p.setClipRect(to); auto hq = PainterHighQualityEnabler(p);
const auto big = incomingFrame.size().scaled(to.size(), Qt::KeepAspectRatio); p.drawImage(incoming, frame);
const auto pos = QPoint( }
to.left() + (to.width() - big.width()) / 2,
to.top() + (to.height() - big.height()) / 2);
auto hq = PainterHighQualityEnabler(p);
p.drawImage(QRect(pos, big), incomingFrame);
p.restore();
} }
_call->videoIncoming()->markFrameShown(); _call->videoIncoming()->markFrameShown();

View file

@ -90,11 +90,14 @@ private:
void updateStatusText(State state); void updateStatusText(State state);
void startDurationUpdateTimer(crl::time currentDuration); void startDurationUpdateTimer(crl::time currentDuration);
void fillFingerprint(); void fillFingerprint();
void setIncomingShown(bool shown); void setIncomingSize(QSize size);
void refreshOutgoingPreviewInBody(State state); void refreshOutgoingPreviewInBody(State state);
void toggleFullScreen(bool fullscreen); void toggleFullScreen(bool fullscreen);
[[nodiscard]] QRect incomingFrameGeometry() const;
[[nodiscard]] QRect outgoingFrameGeometry() const;
Call *_call = nullptr; Call *_call = nullptr;
not_null<UserData*> _user; not_null<UserData*> _user;
@ -104,7 +107,7 @@ private:
std::unique_ptr<Ui::Platform::TitleControls> _controls; std::unique_ptr<Ui::Platform::TitleControls> _controls;
#endif // Q_OS_WIN #endif // Q_OS_WIN
bool _incomingShown = false; QSize _incomingFrameSize;
rpl::lifetime _callLifetime; rpl::lifetime _callLifetime;