Handle "video_joined" flag in self participant.

This commit is contained in:
John Preston 2021-06-08 19:27:26 +04:00
parent 054223efe0
commit 84f6a5f957
6 changed files with 66 additions and 39 deletions

View file

@ -636,17 +636,17 @@ void GroupCall::subscribeToReal(not_null<Data::GroupCall*> real) {
// If we joined before you could start video and then you can,
// you have to rejoin so that the server knows your video params.
real->canStartVideoValue(
) | rpl::combine_previous(
) | rpl::start_with_next([=](bool could, bool can) {
if (could || !can) {
return;
} if (_joinState.action == JoinAction::None) {
rejoin();
} else {
_joinState.nextActionPending = true;
}
}, _lifetime);
//real->canStartVideoValue( // ignore can_start_video after call start.
//) | rpl::combine_previous(
//) | rpl::start_with_next([=](bool could, bool can) {
// if (could || !can) {
// return;
// } if (_joinState.action == JoinAction::None) {
// rejoin();
// } else {
// _joinState.nextActionPending = true;
// }
//}, _lifetime);
// Postpone creating video tracks, so that we know if Panel
// supports OpenGL and we don't need ARGB32 frames at all.
@ -674,6 +674,10 @@ void GroupCall::subscribeToReal(not_null<Data::GroupCall*> real) {
const auto peer = data.was ? data.was->peer : data.now->peer;
if (peer == _joinAs) {
const auto working = data.now && data.now->videoJoined;
if (videoIsWorking() != working) {
fillActiveVideoEndpoints();
}
return;
}
const auto &wasCameraEndpoint = data.was
@ -1401,6 +1405,7 @@ void GroupCall::applyMeInCallLocally() {
const auto flags = (canSelfUnmute ? Flag::f_can_self_unmute : Flag(0))
| (lastActive ? Flag::f_active_date : Flag(0))
| (_joinState.ssrc ? Flag(0) : Flag::f_left)
| (_videoIsWorking.current() ? Flag::f_video_joined : Flag(0))
| Flag::f_self
| Flag::f_volume // Without flag the volume is reset to 100%.
| Flag::f_volume_by_admin // Self volume can only be set by admin.
@ -1446,6 +1451,7 @@ void GroupCall::applyParticipantLocally(
| ((participant->applyVolumeFromMin && !volume)
? Flag::f_volume_by_admin
: Flag(0))
| (participant->videoJoined ? Flag::f_video_joined : Flag(0))
| (participant->lastActive ? Flag::f_active_date : Flag(0))
| (isMuted ? Flag::f_muted : Flag(0))
| (isMutedByYou ? Flag::f_muted_by_you : Flag(0))
@ -1884,7 +1890,9 @@ bool GroupCall::emitShareCameraError() {
emitShareCameraError(error);
return true;
};
if (const auto real = lookupReal(); real && !real->canStartVideo()) {
/*if (const auto real = lookupReal(); real && !real->canStartVideo()) {
return emitError(Error::DisabledNoCamera);
} else */if (!videoIsWorking()) {
return emitError(Error::DisabledNoCamera);
} else if (mutedByAdmin()) {
return emitError(Error::MutedNoCamera);
@ -1906,7 +1914,9 @@ bool GroupCall::emitShareScreenError() {
emitShareScreenError(error);
return true;
};
if (const auto real = lookupReal(); real && !real->canStartVideo()) {
/*if (const auto real = lookupReal(); real && !real->canStartVideo()) {
return emitError(Error::DisabledNoScreen);
} else */if (!videoIsWorking()) {
return emitError(Error::DisabledNoScreen);
} else if (mutedByAdmin()) {
return emitError(Error::MutedNoScreen);
@ -2377,6 +2387,16 @@ void GroupCall::fillActiveVideoEndpoints() {
const auto real = lookupReal();
Assert(real != nullptr);
if (const auto participant = real->participantByPeer(_joinAs)) {
_videoIsWorking = participant->videoJoined;
} else {
_videoIsWorking = false;
}
if (!videoIsWorking()) {
toggleVideo(false);
toggleScreenSharing(std::nullopt);
}
const auto &participants = real->participants();
const auto &large = _videoEndpointLarge.current();
auto largeFound = false;
@ -2400,24 +2420,26 @@ void GroupCall::fillActiveVideoEndpoints() {
}
};
using Type = VideoEndpointType;
for (const auto &participant : participants) {
const auto camera = GetCameraEndpoint(participant.videoParams);
if (camera != _cameraEndpoint
&& camera != _screenEndpoint
&& participant.peer != _joinAs) {
const auto paused = IsCameraPaused(participant.videoParams);
feedOne({ Type::Camera, participant.peer, camera }, paused);
}
const auto screen = GetScreenEndpoint(participant.videoParams);
if (screen != _cameraEndpoint
&& screen != _screenEndpoint
&& participant.peer != _joinAs) {
const auto paused = IsScreenPaused(participant.videoParams);
feedOne({ Type::Screen, participant.peer, screen }, paused);
if (_videoIsWorking.current()) {
for (const auto &participant : participants) {
const auto camera = GetCameraEndpoint(participant.videoParams);
if (camera != _cameraEndpoint
&& camera != _screenEndpoint
&& participant.peer != _joinAs) {
const auto paused = IsCameraPaused(participant.videoParams);
feedOne({ Type::Camera, participant.peer, camera }, paused);
}
const auto screen = GetScreenEndpoint(participant.videoParams);
if (screen != _cameraEndpoint
&& screen != _screenEndpoint
&& participant.peer != _joinAs) {
const auto paused = IsScreenPaused(participant.videoParams);
feedOne({ Type::Screen, participant.peer, screen }, paused);
}
}
feedOne({ Type::Camera, _joinAs, cameraSharingEndpoint() }, false);
feedOne({ Type::Screen, _joinAs, screenSharingEndpoint() }, false);
}
feedOne({ Type::Camera, _joinAs, cameraSharingEndpoint() }, false);
feedOne({ Type::Screen, _joinAs, screenSharingEndpoint() }, false);
if (large && !largeFound) {
setVideoEndpointLarge({});
}

View file

@ -358,6 +358,12 @@ public:
[[nodiscard]] bool mutedByAdmin() const;
[[nodiscard]] bool canManage() const;
[[nodiscard]] rpl::producer<bool> canManageValue() const;
[[nodiscard]] bool videoIsWorking() const {
return _videoIsWorking.current();
}
[[nodiscard]] rpl::producer<bool> videoIsWorkingValue() const {
return _videoIsWorking.value();
}
void setCurrentAudioDevice(bool input, const QString &deviceId);
void setCurrentVideoDevice(const QString &deviceId);
@ -552,6 +558,7 @@ private:
rpl::variable<MuteState> _muted = MuteState::Muted;
rpl::variable<bool> _canManage = false;
rpl::variable<bool> _videoIsWorking = false;
bool _initialMuteStateSent = false;
bool _acceptFields = false;

View file

@ -607,7 +607,7 @@ void FillMenu(
const auto addEditTitle = call->canManage();
const auto addEditRecording = call->canManage() && !real->scheduleDate();
const auto addScreenCast = !wide
&& (real->canStartVideo() || call->isSharingScreen())
&& call->videoIsWorking()
&& !real->scheduleDate();
if (addEditJoinAs) {
menu->addAction(MakeJoinAsAction(

View file

@ -468,12 +468,8 @@ void Panel::refreshLeftButton() {
void Panel::refreshVideoButtons(std::optional<bool> overrideWideMode) {
const auto real = _call->lookupReal();
const auto canStartVideo = !_call->scheduleDate()
&& real
&& real->canStartVideo();
const auto create = overrideWideMode.value_or(mode() == PanelMode::Wide)
|| canStartVideo
|| _call->isSharingCamera();
|| (!_call->scheduleDate() && _call->videoIsWorking());
const auto created = _video && _screenShare;
if (created == create) {
return;
@ -987,14 +983,14 @@ void Panel::subscribeToChanges(not_null<Data::GroupCall*> real) {
validateRecordingMark(real->recordStartDate() != 0);
rpl::combine(
real->canStartVideoValue(),
_call->videoIsWorkingValue(),
_call->isSharingCameraValue()
) | rpl::start_with_next([=] {
refreshVideoButtons();
}, widget()->lifetime());
rpl::combine(
real->canStartVideoValue(),
_call->videoIsWorkingValue(),
_call->isSharingScreenValue()
) | rpl::start_with_next([=] {
refreshTopButton();
@ -1014,8 +1010,7 @@ void Panel::refreshTopButton() {
const auto hasJoinAs = _call->showChooseJoinAs();
const auto wide = (_mode.current() == PanelMode::Wide);
const auto showNarrowMenu = _call->canManage()
|| (real && real->canStartVideo())
|| _call->isSharingScreen();
|| _call->videoIsWorking();
const auto showNarrowUserpic = !showNarrowMenu && hasJoinAs;
if (showNarrowMenu) {
_joinAsToggle.destroy();

View file

@ -590,6 +590,7 @@ void GroupCall::applyParticipantsSlice(
: data.is_muted_by_you();
const auto onlyMinLoaded = data.is_min()
&& (!was || was->onlyMinLoaded);
const auto videoJoined = data.is_video_joined();
const auto raisedHandRating
= data.vraise_hand_rating().value_or_empty();
const auto localUpdate = (sliceSource
@ -617,6 +618,7 @@ void GroupCall::applyParticipantsSlice(
.mutedByMe = mutedByMe,
.canSelfUnmute = canSelfUnmute,
.onlyMinLoaded = onlyMinLoaded,
.videoJoined = videoJoined,
};
if (i == end(_participants)) {
_participantPeerByAudioSsrc.emplace(

View file

@ -39,6 +39,7 @@ struct GroupCallParticipant {
bool mutedByMe = false;
bool canSelfUnmute = false;
bool onlyMinLoaded = false;
bool videoJoined = false;
[[nodiscard]] const std::string &cameraEndpoint() const;
[[nodiscard]] const std::string &screenEndpoint() const;