Mirror my outgoing video in video chats.

This commit is contained in:
John Preston 2024-01-10 08:28:39 -08:00
parent e2439984ae
commit 0dfe37f998
8 changed files with 40 additions and 17 deletions

View file

@ -127,12 +127,13 @@ void VideoBubble::paint() {
const auto inner = _content.rect().marginsRemoved(padding);
Ui::Shadow::paint(p, inner, _content.width(), st::boxRoundShadow);
const auto factor = cIntRetinaFactor();
const auto left = _mirrored
? (_frame.width() - (inner.width() * factor))
: 0;
p.drawImage(
inner,
_frame,
QRect(
QPoint(_frame.width() - (inner.width() * factor), 0),
inner.size() * factor));
QRect(QPoint(left, 0), inner.size() * factor));
}
_track->markFrameShown();
}
@ -152,11 +153,10 @@ void VideoBubble::prepareFrame() {
.resize = 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()) {
_frame = QImage(
size * cIntRetinaFactor(),
QImage::Format_ARGB32_Premultiplied);
_frame = QImage(size, QImage::Format_ARGB32_Premultiplied);
_frame.fill(Qt::transparent);
}
Assert(_frame.width() >= frame.width()
&& _frame.height() >= frame.height());
@ -174,7 +174,7 @@ void VideoBubble::prepareFrame() {
ImageRoundRadius::Large,
RectPart::AllCorners,
QRect(QPoint(), size)
).mirrored(true, false);
).mirrored(_mirrored, false);
}
void VideoBubble::setState(Webrtc::VideoState state) {

View file

@ -1060,11 +1060,13 @@ void Panel::setupVideo(not_null<Viewport*> viewport) {
_call->videoEndpointLargeValue(),
_call->videoEndpointPinnedValue()
) | rpl::map(_1 == endpoint && _2);
const auto self = (endpoint.peer == _call->joinAs());
viewport->add(
endpoint,
VideoTileTrack{ GroupCall::TrackPointer(track), row },
GroupCall::TrackSizeValue(track),
std::move(pinned));
std::move(pinned),
self);
};
for (const auto &[endpoint, track] : _call->activeVideoTracks()) {
setupTile(endpoint, track);

View file

@ -237,13 +237,15 @@ void Viewport::add(
const VideoEndpoint &endpoint,
VideoTileTrack track,
rpl::producer<QSize> trackSize,
rpl::producer<bool> pinned) {
rpl::producer<bool> pinned,
bool self) {
_tiles.push_back(std::make_unique<VideoTile>(
endpoint,
track,
std::move(trackSize),
std::move(pinned),
[=] { widget()->update(); }));
[=] { widget()->update(); },
self));
_tiles.back()->trackSizeValue(
) | rpl::filter([](QSize size) {

View file

@ -80,7 +80,8 @@ public:
const VideoEndpoint &endpoint,
VideoTileTrack track,
rpl::producer<QSize> trackSize,
rpl::producer<bool> pinned);
rpl::producer<bool> pinned,
bool self);
void remove(const VideoEndpoint &endpoint);
void showLarge(const VideoEndpoint &endpoint);

View file

@ -531,6 +531,12 @@ void Viewport::RendererGL::paintTile(
{ { 1.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) {
std::rotate(
toBlurTexCoords.begin(),

View file

@ -105,14 +105,14 @@ void Viewport::RendererSW::paintTile(
tileData.blurredFrame = Images::BlurLargeImage(
data.original.scaled(
VideoTile::PausedVideoSize(),
Qt::KeepAspectRatio),
Qt::KeepAspectRatio).mirrored(tile->mirror(), false),
kBlurRadius);
}
const auto &image = _userpicFrame
? tileData.userpicFrame
: _pausedFrame
? tileData.blurredFrame
: data.original;
: data.original.mirrored(tile->mirror(), false);
const auto frameRotation = _userpicFrame ? 0 : data.rotation;
Assert(!image.isNull());

View file

@ -28,12 +28,14 @@ Viewport::VideoTile::VideoTile(
VideoTileTrack track,
rpl::producer<QSize> trackSize,
rpl::producer<bool> pinned,
Fn<void()> update)
Fn<void()> update,
bool self)
: _endpoint(endpoint)
, _update(std::move(update))
, _track(std::move(track))
, _trackSize(std::move(trackSize))
, _rtmp(endpoint.rtmp()) {
, _rtmp(endpoint.rtmp())
, _self(self) {
Expects(_track.track != nullptr);
Expects(_track.row != nullptr);
@ -48,6 +50,10 @@ Viewport::VideoTile::VideoTile(
setup(std::move(pinned));
}
bool Viewport::VideoTile::mirror() const {
return _self && (_endpoint.type == VideoEndpointType::Camera);
}
QRect Viewport::VideoTile::pinOuter() const {
return _pinOuter;
}

View file

@ -28,7 +28,8 @@ public:
VideoTileTrack track,
rpl::producer<QSize> trackSize,
rpl::producer<bool> pinned,
Fn<void()> update);
Fn<void()> update,
bool self);
[[nodiscard]] not_null<Webrtc::VideoTrack*> track() const {
return _track.track;
@ -54,6 +55,10 @@ public:
[[nodiscard]] bool visible() const {
return !_hidden && !_geometry.isEmpty();
}
[[nodiscard]] bool self() const {
return _self;
}
[[nodiscard]] bool mirror() const;
[[nodiscard]] QRect pinOuter() const;
[[nodiscard]] QRect pinInner() const;
[[nodiscard]] QRect backOuter() const;
@ -123,6 +128,7 @@ private:
bool _pinned = false;
bool _hidden = true;
bool _rtmp = false;
bool _self = false;
std::optional<VideoQuality> _quality;
rpl::lifetime _lifetime;