mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Mirror my outgoing video in video chats.
This commit is contained in:
parent
e2439984ae
commit
0dfe37f998
8 changed files with 40 additions and 17 deletions
|
@ -127,12 +127,13 @@ void VideoBubble::paint() {
|
||||||
const auto inner = _content.rect().marginsRemoved(padding);
|
const auto inner = _content.rect().marginsRemoved(padding);
|
||||||
Ui::Shadow::paint(p, inner, _content.width(), st::boxRoundShadow);
|
Ui::Shadow::paint(p, inner, _content.width(), st::boxRoundShadow);
|
||||||
const auto factor = cIntRetinaFactor();
|
const auto factor = cIntRetinaFactor();
|
||||||
|
const auto left = _mirrored
|
||||||
|
? (_frame.width() - (inner.width() * factor))
|
||||||
|
: 0;
|
||||||
p.drawImage(
|
p.drawImage(
|
||||||
inner,
|
inner,
|
||||||
_frame,
|
_frame,
|
||||||
QRect(
|
QRect(QPoint(left, 0), inner.size() * factor));
|
||||||
QPoint(_frame.width() - (inner.width() * factor), 0),
|
|
||||||
inner.size() * factor));
|
|
||||||
}
|
}
|
||||||
_track->markFrameShown();
|
_track->markFrameShown();
|
||||||
}
|
}
|
||||||
|
@ -152,11 +153,10 @@ void VideoBubble::prepareFrame() {
|
||||||
.resize = size,
|
.resize = size,
|
||||||
.outer = size,
|
.outer = size,
|
||||||
};
|
};
|
||||||
const auto frame = _track->frame(request).mirrored(!_mirrored, false);
|
const auto frame = _track->frame(request);
|
||||||
if (_frame.width() < size.width() || _frame.height() < size.height()) {
|
if (_frame.width() < size.width() || _frame.height() < size.height()) {
|
||||||
_frame = QImage(
|
_frame = QImage(size, QImage::Format_ARGB32_Premultiplied);
|
||||||
size * cIntRetinaFactor(),
|
_frame.fill(Qt::transparent);
|
||||||
QImage::Format_ARGB32_Premultiplied);
|
|
||||||
}
|
}
|
||||||
Assert(_frame.width() >= frame.width()
|
Assert(_frame.width() >= frame.width()
|
||||||
&& _frame.height() >= frame.height());
|
&& _frame.height() >= frame.height());
|
||||||
|
@ -174,7 +174,7 @@ void VideoBubble::prepareFrame() {
|
||||||
ImageRoundRadius::Large,
|
ImageRoundRadius::Large,
|
||||||
RectPart::AllCorners,
|
RectPart::AllCorners,
|
||||||
QRect(QPoint(), size)
|
QRect(QPoint(), size)
|
||||||
).mirrored(true, false);
|
).mirrored(_mirrored, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoBubble::setState(Webrtc::VideoState state) {
|
void VideoBubble::setState(Webrtc::VideoState state) {
|
||||||
|
|
|
@ -1060,11 +1060,13 @@ void Panel::setupVideo(not_null<Viewport*> viewport) {
|
||||||
_call->videoEndpointLargeValue(),
|
_call->videoEndpointLargeValue(),
|
||||||
_call->videoEndpointPinnedValue()
|
_call->videoEndpointPinnedValue()
|
||||||
) | rpl::map(_1 == endpoint && _2);
|
) | rpl::map(_1 == endpoint && _2);
|
||||||
|
const auto self = (endpoint.peer == _call->joinAs());
|
||||||
viewport->add(
|
viewport->add(
|
||||||
endpoint,
|
endpoint,
|
||||||
VideoTileTrack{ GroupCall::TrackPointer(track), row },
|
VideoTileTrack{ GroupCall::TrackPointer(track), row },
|
||||||
GroupCall::TrackSizeValue(track),
|
GroupCall::TrackSizeValue(track),
|
||||||
std::move(pinned));
|
std::move(pinned),
|
||||||
|
self);
|
||||||
};
|
};
|
||||||
for (const auto &[endpoint, track] : _call->activeVideoTracks()) {
|
for (const auto &[endpoint, track] : _call->activeVideoTracks()) {
|
||||||
setupTile(endpoint, track);
|
setupTile(endpoint, track);
|
||||||
|
|
|
@ -237,13 +237,15 @@ void Viewport::add(
|
||||||
const VideoEndpoint &endpoint,
|
const VideoEndpoint &endpoint,
|
||||||
VideoTileTrack track,
|
VideoTileTrack track,
|
||||||
rpl::producer<QSize> trackSize,
|
rpl::producer<QSize> trackSize,
|
||||||
rpl::producer<bool> pinned) {
|
rpl::producer<bool> pinned,
|
||||||
|
bool self) {
|
||||||
_tiles.push_back(std::make_unique<VideoTile>(
|
_tiles.push_back(std::make_unique<VideoTile>(
|
||||||
endpoint,
|
endpoint,
|
||||||
track,
|
track,
|
||||||
std::move(trackSize),
|
std::move(trackSize),
|
||||||
std::move(pinned),
|
std::move(pinned),
|
||||||
[=] { widget()->update(); }));
|
[=] { widget()->update(); },
|
||||||
|
self));
|
||||||
|
|
||||||
_tiles.back()->trackSizeValue(
|
_tiles.back()->trackSizeValue(
|
||||||
) | rpl::filter([](QSize size) {
|
) | rpl::filter([](QSize size) {
|
||||||
|
|
|
@ -80,7 +80,8 @@ public:
|
||||||
const VideoEndpoint &endpoint,
|
const VideoEndpoint &endpoint,
|
||||||
VideoTileTrack track,
|
VideoTileTrack track,
|
||||||
rpl::producer<QSize> trackSize,
|
rpl::producer<QSize> trackSize,
|
||||||
rpl::producer<bool> pinned);
|
rpl::producer<bool> pinned,
|
||||||
|
bool self);
|
||||||
void remove(const VideoEndpoint &endpoint);
|
void remove(const VideoEndpoint &endpoint);
|
||||||
void showLarge(const VideoEndpoint &endpoint);
|
void showLarge(const VideoEndpoint &endpoint);
|
||||||
|
|
||||||
|
|
|
@ -531,6 +531,12 @@ void Viewport::RendererGL::paintTile(
|
||||||
{ { 1.f, 0.f } },
|
{ { 1.f, 0.f } },
|
||||||
{ { 0.f, 0.f } },
|
{ { 0.f, 0.f } },
|
||||||
} };
|
} };
|
||||||
|
if (tile->mirror()) {
|
||||||
|
std::swap(toBlurTexCoords[0], toBlurTexCoords[1]);
|
||||||
|
std::swap(toBlurTexCoords[2], toBlurTexCoords[3]);
|
||||||
|
std::swap(texCoords[0], texCoords[1]);
|
||||||
|
std::swap(texCoords[2], texCoords[3]);
|
||||||
|
}
|
||||||
if (const auto shift = (frameRotation / 90); shift > 0) {
|
if (const auto shift = (frameRotation / 90); shift > 0) {
|
||||||
std::rotate(
|
std::rotate(
|
||||||
toBlurTexCoords.begin(),
|
toBlurTexCoords.begin(),
|
||||||
|
|
|
@ -105,14 +105,14 @@ void Viewport::RendererSW::paintTile(
|
||||||
tileData.blurredFrame = Images::BlurLargeImage(
|
tileData.blurredFrame = Images::BlurLargeImage(
|
||||||
data.original.scaled(
|
data.original.scaled(
|
||||||
VideoTile::PausedVideoSize(),
|
VideoTile::PausedVideoSize(),
|
||||||
Qt::KeepAspectRatio),
|
Qt::KeepAspectRatio).mirrored(tile->mirror(), false),
|
||||||
kBlurRadius);
|
kBlurRadius);
|
||||||
}
|
}
|
||||||
const auto &image = _userpicFrame
|
const auto &image = _userpicFrame
|
||||||
? tileData.userpicFrame
|
? tileData.userpicFrame
|
||||||
: _pausedFrame
|
: _pausedFrame
|
||||||
? tileData.blurredFrame
|
? tileData.blurredFrame
|
||||||
: data.original;
|
: data.original.mirrored(tile->mirror(), false);
|
||||||
const auto frameRotation = _userpicFrame ? 0 : data.rotation;
|
const auto frameRotation = _userpicFrame ? 0 : data.rotation;
|
||||||
Assert(!image.isNull());
|
Assert(!image.isNull());
|
||||||
|
|
||||||
|
|
|
@ -28,12 +28,14 @@ Viewport::VideoTile::VideoTile(
|
||||||
VideoTileTrack track,
|
VideoTileTrack track,
|
||||||
rpl::producer<QSize> trackSize,
|
rpl::producer<QSize> trackSize,
|
||||||
rpl::producer<bool> pinned,
|
rpl::producer<bool> pinned,
|
||||||
Fn<void()> update)
|
Fn<void()> update,
|
||||||
|
bool self)
|
||||||
: _endpoint(endpoint)
|
: _endpoint(endpoint)
|
||||||
, _update(std::move(update))
|
, _update(std::move(update))
|
||||||
, _track(std::move(track))
|
, _track(std::move(track))
|
||||||
, _trackSize(std::move(trackSize))
|
, _trackSize(std::move(trackSize))
|
||||||
, _rtmp(endpoint.rtmp()) {
|
, _rtmp(endpoint.rtmp())
|
||||||
|
, _self(self) {
|
||||||
Expects(_track.track != nullptr);
|
Expects(_track.track != nullptr);
|
||||||
Expects(_track.row != nullptr);
|
Expects(_track.row != nullptr);
|
||||||
|
|
||||||
|
@ -48,6 +50,10 @@ Viewport::VideoTile::VideoTile(
|
||||||
setup(std::move(pinned));
|
setup(std::move(pinned));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Viewport::VideoTile::mirror() const {
|
||||||
|
return _self && (_endpoint.type == VideoEndpointType::Camera);
|
||||||
|
}
|
||||||
|
|
||||||
QRect Viewport::VideoTile::pinOuter() const {
|
QRect Viewport::VideoTile::pinOuter() const {
|
||||||
return _pinOuter;
|
return _pinOuter;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,8 @@ public:
|
||||||
VideoTileTrack track,
|
VideoTileTrack track,
|
||||||
rpl::producer<QSize> trackSize,
|
rpl::producer<QSize> trackSize,
|
||||||
rpl::producer<bool> pinned,
|
rpl::producer<bool> pinned,
|
||||||
Fn<void()> update);
|
Fn<void()> update,
|
||||||
|
bool self);
|
||||||
|
|
||||||
[[nodiscard]] not_null<Webrtc::VideoTrack*> track() const {
|
[[nodiscard]] not_null<Webrtc::VideoTrack*> track() const {
|
||||||
return _track.track;
|
return _track.track;
|
||||||
|
@ -54,6 +55,10 @@ public:
|
||||||
[[nodiscard]] bool visible() const {
|
[[nodiscard]] bool visible() const {
|
||||||
return !_hidden && !_geometry.isEmpty();
|
return !_hidden && !_geometry.isEmpty();
|
||||||
}
|
}
|
||||||
|
[[nodiscard]] bool self() const {
|
||||||
|
return _self;
|
||||||
|
}
|
||||||
|
[[nodiscard]] bool mirror() const;
|
||||||
[[nodiscard]] QRect pinOuter() const;
|
[[nodiscard]] QRect pinOuter() const;
|
||||||
[[nodiscard]] QRect pinInner() const;
|
[[nodiscard]] QRect pinInner() const;
|
||||||
[[nodiscard]] QRect backOuter() const;
|
[[nodiscard]] QRect backOuter() const;
|
||||||
|
@ -123,6 +128,7 @@ private:
|
||||||
bool _pinned = false;
|
bool _pinned = false;
|
||||||
bool _hidden = true;
|
bool _hidden = true;
|
||||||
bool _rtmp = false;
|
bool _rtmp = false;
|
||||||
|
bool _self = false;
|
||||||
std::optional<VideoQuality> _quality;
|
std::optional<VideoQuality> _quality;
|
||||||
|
|
||||||
rpl::lifetime _lifetime;
|
rpl::lifetime _lifetime;
|
||||||
|
|
Loading…
Add table
Reference in a new issue