Implement screencast pause in TDesktop.
This commit is contained in:
		
							parent
							
								
									8d72026cbd
								
							
						
					
					
						commit
						4543656aa3
					
				
					 3 changed files with 145 additions and 40 deletions
				
			
		| 
						 | 
					@ -544,6 +544,11 @@ rpl::producer<bool> GroupCall::isSharingScreenValue() const {
 | 
				
			||||||
	return _isSharingScreen.value();
 | 
						return _isSharingScreen.value();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool GroupCall::isScreenPaused() const {
 | 
				
			||||||
 | 
						return _screenOutgoing
 | 
				
			||||||
 | 
							&& (_screenOutgoing->state() == Webrtc::VideoState::Paused);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const std::string &GroupCall::screenSharingEndpoint() const {
 | 
					const std::string &GroupCall::screenSharingEndpoint() const {
 | 
				
			||||||
	return isSharingScreen() ? _screenEndpoint : EmptyString();
 | 
						return isSharingScreen() ? _screenEndpoint : EmptyString();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -556,6 +561,11 @@ rpl::producer<bool> GroupCall::isSharingCameraValue() const {
 | 
				
			||||||
	return _isSharingCamera.value();
 | 
						return _isSharingCamera.value();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool GroupCall::isCameraPaused() const {
 | 
				
			||||||
 | 
						return _cameraOutgoing
 | 
				
			||||||
 | 
							&& (_cameraOutgoing->state() == Webrtc::VideoState::Paused);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const std::string &GroupCall::cameraSharingEndpoint() const {
 | 
					const std::string &GroupCall::cameraSharingEndpoint() const {
 | 
				
			||||||
	return isSharingCamera() ? _cameraEndpoint : EmptyString();
 | 
						return isSharingCamera() ? _cameraEndpoint : EmptyString();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -700,7 +710,7 @@ void GroupCall::subscribeToReal(not_null<Data::GroupCall*> real) {
 | 
				
			||||||
				VideoEndpointType::Camera,
 | 
									VideoEndpointType::Camera,
 | 
				
			||||||
				peer,
 | 
									peer,
 | 
				
			||||||
				wasCameraEndpoint,
 | 
									wasCameraEndpoint,
 | 
				
			||||||
			}, false, wasCameraPaused);
 | 
								}, false, false);
 | 
				
			||||||
		} else if (wasCameraPaused != nowCameraPaused) {
 | 
							} else if (wasCameraPaused != nowCameraPaused) {
 | 
				
			||||||
			markTrackPaused({
 | 
								markTrackPaused({
 | 
				
			||||||
				VideoEndpointType::Camera,
 | 
									VideoEndpointType::Camera,
 | 
				
			||||||
| 
						 | 
					@ -728,7 +738,7 @@ void GroupCall::subscribeToReal(not_null<Data::GroupCall*> real) {
 | 
				
			||||||
				VideoEndpointType::Screen,
 | 
									VideoEndpointType::Screen,
 | 
				
			||||||
				peer,
 | 
									peer,
 | 
				
			||||||
				wasScreenEndpoint,
 | 
									wasScreenEndpoint,
 | 
				
			||||||
			}, false, wasScreenPaused);
 | 
								}, false, false);
 | 
				
			||||||
		} else if (wasScreenPaused != nowScreenPaused) {
 | 
							} else if (wasScreenPaused != nowScreenPaused) {
 | 
				
			||||||
			markTrackPaused({
 | 
								markTrackPaused({
 | 
				
			||||||
				VideoEndpointType::Screen,
 | 
									VideoEndpointType::Screen,
 | 
				
			||||||
| 
						 | 
					@ -988,7 +998,7 @@ void GroupCall::setScreenEndpoint(std::string endpoint) {
 | 
				
			||||||
			VideoEndpointType::Screen,
 | 
								VideoEndpointType::Screen,
 | 
				
			||||||
			_joinAs,
 | 
								_joinAs,
 | 
				
			||||||
			_screenEndpoint
 | 
								_screenEndpoint
 | 
				
			||||||
		}, true, false);
 | 
							}, true, isScreenPaused());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1012,7 +1022,7 @@ void GroupCall::setCameraEndpoint(std::string endpoint) {
 | 
				
			||||||
			VideoEndpointType::Camera,
 | 
								VideoEndpointType::Camera,
 | 
				
			||||||
			_joinAs,
 | 
								_joinAs,
 | 
				
			||||||
			_cameraEndpoint
 | 
								_cameraEndpoint
 | 
				
			||||||
		}, true, false);
 | 
							}, true, isCameraPaused());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1225,11 +1235,15 @@ void GroupCall::rejoin(not_null<PeerData*> as) {
 | 
				
			||||||
				_peer->session().api().applyUpdates(updates);
 | 
									_peer->session().api().applyUpdates(updates);
 | 
				
			||||||
				applyQueuedSelfUpdates();
 | 
									applyQueuedSelfUpdates();
 | 
				
			||||||
				checkFirstTimeJoined();
 | 
									checkFirstTimeJoined();
 | 
				
			||||||
				if (wasVideoStopped == isSharingCamera()) {
 | 
					 | 
				
			||||||
					sendSelfUpdate(SendUpdateType::VideoStopped);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				_screenJoinState.nextActionPending = true;
 | 
									_screenJoinState.nextActionPending = true;
 | 
				
			||||||
				checkNextJoinAction();
 | 
									checkNextJoinAction();
 | 
				
			||||||
 | 
									if (wasVideoStopped == isSharingCamera()) {
 | 
				
			||||||
 | 
										sendSelfUpdate(SendUpdateType::CameraStopped);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if (isCameraPaused()) {
 | 
				
			||||||
 | 
										sendSelfUpdate(SendUpdateType::CameraPaused);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									sendPendingSelfUpdates();
 | 
				
			||||||
			}).fail([=](const MTP::Error &error) {
 | 
								}).fail([=](const MTP::Error &error) {
 | 
				
			||||||
				_joinState.finish();
 | 
									_joinState.finish();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1323,6 +1337,10 @@ void GroupCall::rejoinPresentation() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				_peer->session().api().applyUpdates(updates);
 | 
									_peer->session().api().applyUpdates(updates);
 | 
				
			||||||
				checkNextJoinAction();
 | 
									checkNextJoinAction();
 | 
				
			||||||
 | 
									if (isScreenPaused()) {
 | 
				
			||||||
 | 
										sendSelfUpdate(SendUpdateType::ScreenPaused);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									sendPendingSelfUpdates();
 | 
				
			||||||
			}).fail([=](const MTP::Error &error) {
 | 
								}).fail([=](const MTP::Error &error) {
 | 
				
			||||||
				_screenJoinState.finish();
 | 
									_screenJoinState.finish();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1934,22 +1952,35 @@ void GroupCall::emitShareScreenError(Error error) {
 | 
				
			||||||
void GroupCall::ensureOutgoingVideo() {
 | 
					void GroupCall::ensureOutgoingVideo() {
 | 
				
			||||||
	Expects(_id != 0);
 | 
						Expects(_id != 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						using Webrtc::VideoState;
 | 
				
			||||||
	if (_cameraOutgoing) {
 | 
						if (_cameraOutgoing) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	_cameraOutgoing = std::make_unique<Webrtc::VideoTrack>(
 | 
						_cameraOutgoing = std::make_unique<Webrtc::VideoTrack>(
 | 
				
			||||||
		Webrtc::VideoState::Inactive,
 | 
							VideoState::Inactive,
 | 
				
			||||||
		_requireARGB32);
 | 
							_requireARGB32);
 | 
				
			||||||
	_screenOutgoing = std::make_unique<Webrtc::VideoTrack>(
 | 
						_screenOutgoing = std::make_unique<Webrtc::VideoTrack>(
 | 
				
			||||||
		Webrtc::VideoState::Inactive,
 | 
							VideoState::Inactive,
 | 
				
			||||||
		_requireARGB32);
 | 
							_requireARGB32);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_cameraOutgoing->stateValue(
 | 
						_cameraOutgoing->stateValue(
 | 
				
			||||||
	) | rpl::start_with_next([=](Webrtc::VideoState state) {
 | 
						) | rpl::combine_previous(
 | 
				
			||||||
		const auto active = (state != Webrtc::VideoState::Inactive);
 | 
						) | rpl::start_with_next([=](VideoState previous, VideoState state) {
 | 
				
			||||||
		if (active) {
 | 
							const auto wasPaused = (previous == VideoState::Paused);
 | 
				
			||||||
			// Paused not supported right now.
 | 
							const auto wasActive = (previous != VideoState::Inactive);
 | 
				
			||||||
			Assert(state == Webrtc::VideoState::Active);
 | 
							const auto nowPaused = (state == VideoState::Paused);
 | 
				
			||||||
 | 
							const auto nowActive = (state != VideoState::Inactive);
 | 
				
			||||||
 | 
							if (wasActive == nowActive) {
 | 
				
			||||||
 | 
								Assert(wasActive && nowActive);
 | 
				
			||||||
 | 
								sendSelfUpdate(SendUpdateType::CameraPaused);
 | 
				
			||||||
 | 
								markTrackPaused({
 | 
				
			||||||
 | 
									VideoEndpointType::Camera,
 | 
				
			||||||
 | 
									_joinAs,
 | 
				
			||||||
 | 
									_cameraEndpoint
 | 
				
			||||||
 | 
								}, nowPaused);
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (nowActive) {
 | 
				
			||||||
			if (emitShareCameraError()) {
 | 
								if (emitShareCameraError()) {
 | 
				
			||||||
				return;
 | 
									return;
 | 
				
			||||||
			} else if (!_cameraCapture) {
 | 
								} else if (!_cameraCapture) {
 | 
				
			||||||
| 
						 | 
					@ -1957,7 +1988,7 @@ void GroupCall::ensureOutgoingVideo() {
 | 
				
			||||||
					_cameraInputId);
 | 
										_cameraInputId);
 | 
				
			||||||
				if (!_cameraCapture) {
 | 
									if (!_cameraCapture) {
 | 
				
			||||||
					return emitShareCameraError(Error::NoCamera);
 | 
										return emitShareCameraError(Error::NoCamera);
 | 
				
			||||||
					_cameraOutgoing->setState(Webrtc::VideoState::Inactive);
 | 
										_cameraOutgoing->setState(VideoState::Inactive);
 | 
				
			||||||
					_errors.fire_copy(Error::NoCamera);
 | 
										_errors.fire_copy(Error::NoCamera);
 | 
				
			||||||
					return;
 | 
										return;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
| 
						 | 
					@ -1971,22 +2002,34 @@ void GroupCall::ensureOutgoingVideo() {
 | 
				
			||||||
		} else if (_cameraCapture) {
 | 
							} else if (_cameraCapture) {
 | 
				
			||||||
			_cameraCapture->setState(tgcalls::VideoState::Inactive);
 | 
								_cameraCapture->setState(tgcalls::VideoState::Inactive);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		_isSharingCamera = active;
 | 
							_isSharingCamera = nowActive;
 | 
				
			||||||
		markEndpointActive({
 | 
							markEndpointActive({
 | 
				
			||||||
			VideoEndpointType::Camera,
 | 
								VideoEndpointType::Camera,
 | 
				
			||||||
			_joinAs,
 | 
								_joinAs,
 | 
				
			||||||
			_cameraEndpoint
 | 
								_cameraEndpoint
 | 
				
			||||||
		}, active, false);
 | 
							}, nowActive, nowPaused);
 | 
				
			||||||
		sendSelfUpdate(SendUpdateType::VideoStopped);
 | 
							sendSelfUpdate(SendUpdateType::CameraStopped);
 | 
				
			||||||
		applyMeInCallLocally();
 | 
							applyMeInCallLocally();
 | 
				
			||||||
	}, _lifetime);
 | 
						}, _lifetime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_screenOutgoing->stateValue(
 | 
						_screenOutgoing->stateValue(
 | 
				
			||||||
	) | rpl::start_with_next([=](Webrtc::VideoState state) {
 | 
						) | rpl::combine_previous(
 | 
				
			||||||
		const auto active = (state != Webrtc::VideoState::Inactive);
 | 
						) | rpl::start_with_next([=](VideoState previous, VideoState state) {
 | 
				
			||||||
		if (active) {
 | 
							const auto wasPaused = (previous == VideoState::Paused);
 | 
				
			||||||
			// Paused not supported right now.
 | 
							const auto wasActive = (previous != VideoState::Inactive);
 | 
				
			||||||
			Assert(state == Webrtc::VideoState::Active);
 | 
							const auto nowPaused = (state == VideoState::Paused);
 | 
				
			||||||
 | 
							const auto nowActive = (state != VideoState::Inactive);
 | 
				
			||||||
 | 
							if (wasActive == nowActive) {
 | 
				
			||||||
 | 
								Assert(wasActive && nowActive);
 | 
				
			||||||
 | 
								sendSelfUpdate(SendUpdateType::ScreenPaused);
 | 
				
			||||||
 | 
								markTrackPaused({
 | 
				
			||||||
 | 
									VideoEndpointType::Screen,
 | 
				
			||||||
 | 
									_joinAs,
 | 
				
			||||||
 | 
									_screenEndpoint
 | 
				
			||||||
 | 
								}, nowPaused);
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (nowActive) {
 | 
				
			||||||
			if (emitShareScreenError()) {
 | 
								if (emitShareScreenError()) {
 | 
				
			||||||
				return;
 | 
									return;
 | 
				
			||||||
			} else if (!_screenCapture) {
 | 
								} else if (!_screenCapture) {
 | 
				
			||||||
| 
						 | 
					@ -2004,6 +2047,15 @@ void GroupCall::ensureOutgoingVideo() {
 | 
				
			||||||
						emitShareScreenError(Error::ScreenFailed);
 | 
											emitShareScreenError(Error::ScreenFailed);
 | 
				
			||||||
					});
 | 
										});
 | 
				
			||||||
				});
 | 
									});
 | 
				
			||||||
 | 
									_screenCapture->setOnPause([=](bool paused) {
 | 
				
			||||||
 | 
										crl::on_main(weak, [=] {
 | 
				
			||||||
 | 
											if (isSharingScreen()) {
 | 
				
			||||||
 | 
												_screenOutgoing->setState(paused
 | 
				
			||||||
 | 
													? VideoState::Paused
 | 
				
			||||||
 | 
													: VideoState::Active);
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										});
 | 
				
			||||||
 | 
									});
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				_screenCapture->switchToDevice(_screenDeviceId.toStdString());
 | 
									_screenCapture->switchToDevice(_screenDeviceId.toStdString());
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -2014,12 +2066,12 @@ void GroupCall::ensureOutgoingVideo() {
 | 
				
			||||||
		} else if (_screenCapture) {
 | 
							} else if (_screenCapture) {
 | 
				
			||||||
			_screenCapture->setState(tgcalls::VideoState::Inactive);
 | 
								_screenCapture->setState(tgcalls::VideoState::Inactive);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		_isSharingScreen = active;
 | 
							_isSharingScreen = nowActive;
 | 
				
			||||||
		markEndpointActive({
 | 
							markEndpointActive({
 | 
				
			||||||
			VideoEndpointType::Screen,
 | 
								VideoEndpointType::Screen,
 | 
				
			||||||
			_joinAs,
 | 
								_joinAs,
 | 
				
			||||||
			_screenEndpoint
 | 
								_screenEndpoint
 | 
				
			||||||
		}, active, false);
 | 
							}, nowActive, nowPaused);
 | 
				
			||||||
		_screenJoinState.nextActionPending = true;
 | 
							_screenJoinState.nextActionPending = true;
 | 
				
			||||||
		checkNextJoinAction();
 | 
							checkNextJoinAction();
 | 
				
			||||||
	}, _lifetime);
 | 
						}, _lifetime);
 | 
				
			||||||
| 
						 | 
					@ -2361,7 +2413,11 @@ void GroupCall::updateRequestedVideoChannels() {
 | 
				
			||||||
			.ssrcGroups = (params->camera.endpointId == endpointId
 | 
								.ssrcGroups = (params->camera.endpointId == endpointId
 | 
				
			||||||
				? params->camera.ssrcGroups
 | 
									? params->camera.ssrcGroups
 | 
				
			||||||
				: params->screen.ssrcGroups),
 | 
									: params->screen.ssrcGroups),
 | 
				
			||||||
			.quality = (video.quality == Group::VideoQuality::Full
 | 
								.minQuality = ((video.quality == Group::VideoQuality::Full
 | 
				
			||||||
 | 
									&& endpoint.type == VideoEndpointType::Screen)
 | 
				
			||||||
 | 
									? Quality::Full
 | 
				
			||||||
 | 
									: Quality::Thumbnail),
 | 
				
			||||||
 | 
								.maxQuality = (video.quality == Group::VideoQuality::Full
 | 
				
			||||||
				? Quality::Full
 | 
									? Quality::Full
 | 
				
			||||||
				: video.quality == Group::VideoQuality::Medium
 | 
									: video.quality == Group::VideoQuality::Medium
 | 
				
			||||||
				? Quality::Medium
 | 
									? Quality::Medium
 | 
				
			||||||
| 
						 | 
					@ -2437,8 +2493,13 @@ void GroupCall::fillActiveVideoEndpoints() {
 | 
				
			||||||
				feedOne({ Type::Screen, participant.peer, screen }, paused);
 | 
									feedOne({ Type::Screen, participant.peer, screen }, paused);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		feedOne({ Type::Camera, _joinAs, cameraSharingEndpoint() }, false);
 | 
							const auto pausedState = Webrtc::VideoState::Paused;
 | 
				
			||||||
		feedOne({ Type::Screen, _joinAs, screenSharingEndpoint() }, false);
 | 
							feedOne(
 | 
				
			||||||
 | 
								{ Type::Camera, _joinAs, cameraSharingEndpoint() },
 | 
				
			||||||
 | 
								(_cameraOutgoing && _cameraOutgoing->state() == pausedState));
 | 
				
			||||||
 | 
							feedOne(
 | 
				
			||||||
 | 
								{ Type::Screen, _joinAs, screenSharingEndpoint() },
 | 
				
			||||||
 | 
								(_screenOutgoing && _screenOutgoing->state() == pausedState));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (large && !largeFound) {
 | 
						if (large && !largeFound) {
 | 
				
			||||||
		setVideoEndpointLarge({});
 | 
							setVideoEndpointLarge({});
 | 
				
			||||||
| 
						 | 
					@ -2726,14 +2787,47 @@ void GroupCall::maybeSendMutedUpdate(MuteState previous) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GroupCall::sendPendingSelfUpdates() {
 | 
				
			||||||
 | 
						if ((state() != State::Connecting && state() != State::Joined)
 | 
				
			||||||
 | 
							|| _selfUpdateRequestId) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						const auto updates = {
 | 
				
			||||||
 | 
							SendUpdateType::Mute,
 | 
				
			||||||
 | 
							SendUpdateType::RaiseHand,
 | 
				
			||||||
 | 
							SendUpdateType::CameraStopped,
 | 
				
			||||||
 | 
							SendUpdateType::CameraPaused,
 | 
				
			||||||
 | 
							SendUpdateType::ScreenPaused,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						for (const auto type : updates) {
 | 
				
			||||||
 | 
							if (type == SendUpdateType::ScreenPaused
 | 
				
			||||||
 | 
								&& _screenJoinState.action != JoinAction::None) {
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (_pendingSelfUpdates & type) {
 | 
				
			||||||
 | 
								_pendingSelfUpdates &= ~type;
 | 
				
			||||||
 | 
								sendSelfUpdate(type);
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void GroupCall::sendSelfUpdate(SendUpdateType type) {
 | 
					void GroupCall::sendSelfUpdate(SendUpdateType type) {
 | 
				
			||||||
	_api.request(_updateMuteRequestId).cancel();
 | 
						if ((state() != State::Connecting && state() != State::Joined)
 | 
				
			||||||
 | 
							|| _selfUpdateRequestId) {
 | 
				
			||||||
 | 
							_pendingSelfUpdates |= type;
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	using Flag = MTPphone_EditGroupCallParticipant::Flag;
 | 
						using Flag = MTPphone_EditGroupCallParticipant::Flag;
 | 
				
			||||||
	_updateMuteRequestId = _api.request(MTPphone_EditGroupCallParticipant(
 | 
						_selfUpdateRequestId = _api.request(MTPphone_EditGroupCallParticipant(
 | 
				
			||||||
		MTP_flags((type == SendUpdateType::RaiseHand)
 | 
							MTP_flags((type == SendUpdateType::RaiseHand)
 | 
				
			||||||
			? Flag::f_raise_hand
 | 
								? Flag::f_raise_hand
 | 
				
			||||||
			: (type == SendUpdateType::VideoStopped)
 | 
								: (type == SendUpdateType::CameraStopped)
 | 
				
			||||||
			? Flag::f_video_stopped
 | 
								? Flag::f_video_stopped
 | 
				
			||||||
 | 
								: (type == SendUpdateType::CameraPaused)
 | 
				
			||||||
 | 
								? Flag::f_video_paused
 | 
				
			||||||
 | 
								: (type == SendUpdateType::ScreenPaused)
 | 
				
			||||||
 | 
								? Flag::f_presentation_paused
 | 
				
			||||||
			: Flag::f_muted),
 | 
								: Flag::f_muted),
 | 
				
			||||||
		inputCall(),
 | 
							inputCall(),
 | 
				
			||||||
		_joinAs->input,
 | 
							_joinAs->input,
 | 
				
			||||||
| 
						 | 
					@ -2741,13 +2835,14 @@ void GroupCall::sendSelfUpdate(SendUpdateType type) {
 | 
				
			||||||
		MTP_int(100000), // volume
 | 
							MTP_int(100000), // volume
 | 
				
			||||||
		MTP_bool(muted() == MuteState::RaisedHand),
 | 
							MTP_bool(muted() == MuteState::RaisedHand),
 | 
				
			||||||
		MTP_bool(!isSharingCamera()),
 | 
							MTP_bool(!isSharingCamera()),
 | 
				
			||||||
		MTP_bool(false), // video_paused
 | 
							MTP_bool(_cameraOutgoing->state() == Webrtc::VideoState::Paused),
 | 
				
			||||||
		MTP_bool(false) // presentation_paused
 | 
							MTP_bool(_screenOutgoing->state() == Webrtc::VideoState::Paused)
 | 
				
			||||||
	)).done([=](const MTPUpdates &result) {
 | 
						)).done([=](const MTPUpdates &result) {
 | 
				
			||||||
		_updateMuteRequestId = 0;
 | 
							_selfUpdateRequestId = 0;
 | 
				
			||||||
		_peer->session().api().applyUpdates(result);
 | 
							_peer->session().api().applyUpdates(result);
 | 
				
			||||||
 | 
							sendPendingSelfUpdates();
 | 
				
			||||||
	}).fail([=](const MTP::Error &error) {
 | 
						}).fail([=](const MTP::Error &error) {
 | 
				
			||||||
		_updateMuteRequestId = 0;
 | 
							_selfUpdateRequestId = 0;
 | 
				
			||||||
		if (error.type() == u"GROUPCALL_FORBIDDEN"_q) {
 | 
							if (error.type() == u"GROUPCALL_FORBIDDEN"_q) {
 | 
				
			||||||
			LOG(("Call Info: Rejoin after error '%1' in editGroupCallMember."
 | 
								LOG(("Call Info: Rejoin after error '%1' in editGroupCallMember."
 | 
				
			||||||
				).arg(error.type()));
 | 
									).arg(error.type()));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -369,9 +369,11 @@ public:
 | 
				
			||||||
	void setCurrentVideoDevice(const QString &deviceId);
 | 
						void setCurrentVideoDevice(const QString &deviceId);
 | 
				
			||||||
	[[nodiscard]] bool isSharingScreen() const;
 | 
						[[nodiscard]] bool isSharingScreen() const;
 | 
				
			||||||
	[[nodiscard]] rpl::producer<bool> isSharingScreenValue() const;
 | 
						[[nodiscard]] rpl::producer<bool> isSharingScreenValue() const;
 | 
				
			||||||
 | 
						[[nodiscard]] bool isScreenPaused() const;
 | 
				
			||||||
	[[nodiscard]] const std::string &screenSharingEndpoint() const;
 | 
						[[nodiscard]] const std::string &screenSharingEndpoint() const;
 | 
				
			||||||
	[[nodiscard]] bool isSharingCamera() const;
 | 
						[[nodiscard]] bool isSharingCamera() const;
 | 
				
			||||||
	[[nodiscard]] rpl::producer<bool> isSharingCameraValue() const;
 | 
						[[nodiscard]] rpl::producer<bool> isSharingCameraValue() const;
 | 
				
			||||||
 | 
						[[nodiscard]] bool isCameraPaused() const;
 | 
				
			||||||
	[[nodiscard]] const std::string &cameraSharingEndpoint() const;
 | 
						[[nodiscard]] const std::string &cameraSharingEndpoint() const;
 | 
				
			||||||
	[[nodiscard]] QString screenSharingDeviceId() const;
 | 
						[[nodiscard]] QString screenSharingDeviceId() const;
 | 
				
			||||||
	void toggleVideo(bool active);
 | 
						void toggleVideo(bool active);
 | 
				
			||||||
| 
						 | 
					@ -429,9 +431,11 @@ private:
 | 
				
			||||||
		Stream,
 | 
							Stream,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	enum class SendUpdateType {
 | 
						enum class SendUpdateType {
 | 
				
			||||||
		Mute,
 | 
							Mute          = 0x01,
 | 
				
			||||||
		RaiseHand,
 | 
							RaiseHand     = 0x02,
 | 
				
			||||||
		VideoStopped,
 | 
							CameraStopped = 0x04,
 | 
				
			||||||
 | 
							CameraPaused  = 0x08,
 | 
				
			||||||
 | 
							ScreenPaused  = 0x10,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	enum class JoinAction {
 | 
						enum class JoinAction {
 | 
				
			||||||
		None,
 | 
							None,
 | 
				
			||||||
| 
						 | 
					@ -449,6 +453,10 @@ private:
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						friend inline constexpr bool is_flag_type(SendUpdateType) {
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] bool mediaChannelDescriptionsFill(
 | 
						[[nodiscard]] bool mediaChannelDescriptionsFill(
 | 
				
			||||||
		not_null<MediaChannelDescriptionsTask*> task,
 | 
							not_null<MediaChannelDescriptionsTask*> task,
 | 
				
			||||||
		Fn<bool(uint32)> resolved = nullptr);
 | 
							Fn<bool(uint32)> resolved = nullptr);
 | 
				
			||||||
| 
						 | 
					@ -514,6 +522,7 @@ private:
 | 
				
			||||||
		bool mute,
 | 
							bool mute,
 | 
				
			||||||
		std::optional<int> volume);
 | 
							std::optional<int> volume);
 | 
				
			||||||
	void applyQueuedSelfUpdates();
 | 
						void applyQueuedSelfUpdates();
 | 
				
			||||||
 | 
						void sendPendingSelfUpdates();
 | 
				
			||||||
	void applySelfUpdate(const MTPDgroupCallParticipant &data);
 | 
						void applySelfUpdate(const MTPDgroupCallParticipant &data);
 | 
				
			||||||
	void applyOtherParticipantUpdate(const MTPDgroupCallParticipant &data);
 | 
						void applyOtherParticipantUpdate(const MTPDgroupCallParticipant &data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -574,7 +583,7 @@ private:
 | 
				
			||||||
	TimeId _scheduleDate = 0;
 | 
						TimeId _scheduleDate = 0;
 | 
				
			||||||
	base::flat_set<uint32> _mySsrcs;
 | 
						base::flat_set<uint32> _mySsrcs;
 | 
				
			||||||
	mtpRequestId _createRequestId = 0;
 | 
						mtpRequestId _createRequestId = 0;
 | 
				
			||||||
	mtpRequestId _updateMuteRequestId = 0;
 | 
						mtpRequestId _selfUpdateRequestId = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rpl::variable<InstanceState> _instanceState
 | 
						rpl::variable<InstanceState> _instanceState
 | 
				
			||||||
		= InstanceState::Disconnected;
 | 
							= InstanceState::Disconnected;
 | 
				
			||||||
| 
						 | 
					@ -597,6 +606,7 @@ private:
 | 
				
			||||||
	rpl::variable<bool> _isSharingScreen = false;
 | 
						rpl::variable<bool> _isSharingScreen = false;
 | 
				
			||||||
	QString _screenDeviceId;
 | 
						QString _screenDeviceId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						base::flags<SendUpdateType> _pendingSelfUpdates;
 | 
				
			||||||
	bool _requireARGB32 = true;
 | 
						bool _requireARGB32 = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rpl::event_stream<LevelUpdate> _levelUpdates;
 | 
						rpl::event_stream<LevelUpdate> _levelUpdates;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								Telegram/ThirdParty/tgcalls
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								Telegram/ThirdParty/tgcalls
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -1 +1 @@
 | 
				
			||||||
Subproject commit 99c951b9c7c014666f67e1e972dfc43538a47ff7
 | 
					Subproject commit 9adb220f798cadc0848d3e1efbf32fb2a98a3bcb
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue