diff --git a/Telegram/SourceFiles/calls/calls_call.cpp b/Telegram/SourceFiles/calls/calls_call.cpp index ba59556d9..486d5af2a 100644 --- a/Telegram/SourceFiles/calls/calls_call.cpp +++ b/Telegram/SourceFiles/calls/calls_call.cpp @@ -420,6 +420,14 @@ void Call::actuallyAnswer() { }).send(); } +void Call::captureMuteChanged(bool mute) { + setMuted(mute); +} + +rpl::producer Call::captureMuteDeviceId() { + return _captureDeviceId.value(); +} + void Call::setMuted(bool mute) { _muted = mute; if (_instance) { @@ -1033,6 +1041,20 @@ void Call::createAndStartController(const MTPDphoneCall &call) { raw->setIncomingVideoOutput(_videoIncoming->sink()); raw->setAudioOutputDuckingEnabled(settings.callAudioDuckingEnabled()); + + _state.value() | rpl::start_with_next([=](State state) { + const auto track = (state != State::FailedHangingUp) + && (state != State::Failed) + && (state != State::HangingUp) + && (state != State::Ended) + && (state != State::EndedByOtherDevice) + && (state != State::Busy); + Core::App().mediaDevices().setCaptureMuteTracker(this, track); + }, _instanceLifetime); + + _muted.value() | rpl::start_with_next([=](bool muted) { + Core::App().mediaDevices().setCaptureMuted(muted); + }, _instanceLifetime); } void Call::handleControllerStateChange(tgcalls::State state) { @@ -1375,6 +1397,9 @@ void Call::handleControllerError(const QString &error) { } void Call::destroyController() { + _instanceLifetime.destroy(); + Core::App().mediaDevices().setCaptureMuteTracker(this, false); + if (_instance) { _instance->stop([](tgcalls::FinalState) { }); diff --git a/Telegram/SourceFiles/calls/calls_call.h b/Telegram/SourceFiles/calls/calls_call.h index 4be689831..69c2d94da 100644 --- a/Telegram/SourceFiles/calls/calls_call.h +++ b/Telegram/SourceFiles/calls/calls_call.h @@ -59,7 +59,9 @@ enum class CallType { Outgoing, }; -class Call : public base::has_weak_ptr { +class Call final + : public base::has_weak_ptr + , private Webrtc::CaptureMuteTracker { public: class Delegate { public: @@ -249,6 +251,9 @@ private: void setSignalBarCount(int count); void destroyController(); + void captureMuteChanged(bool mute) override; + rpl::producer captureMuteDeviceId() override; + void setupMediaDevices(); void setupOutgoingVideo(); void updateRemoteMediaState( @@ -298,6 +303,7 @@ private: std::unique_ptr _waitingTrack; + rpl::lifetime _instanceLifetime; rpl::lifetime _lifetime; }; diff --git a/Telegram/SourceFiles/calls/group/calls_group_call.cpp b/Telegram/SourceFiles/calls/group/calls_group_call.cpp index 8617aef85..5f7346913 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_call.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_call.cpp @@ -30,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/random.h" #include "webrtc/webrtc_video_track.h" #include "webrtc/webrtc_create_adm.h" +#include "webrtc/webrtc_environment.h" #include #include @@ -667,6 +668,8 @@ GroupCall::GroupCall( GroupCall::~GroupCall() { destroyScreencast(); destroyController(); + + Core::App().mediaDevices().setCaptureMuteTracker(this, false); } bool GroupCall::isSharingScreen() const { @@ -2087,6 +2090,32 @@ void GroupCall::setupMediaDevices() { }) | rpl::start_with_next([=](const Webrtc::DeviceResolvedId &deviceId) { _cameraCapture->switchToDevice(deviceId.value.toStdString(), false); }, _lifetime); + + _muted.value() | rpl::start_with_next([=](MuteState state) { + const auto devices = &Core::App().mediaDevices(); + const auto muted = (state != MuteState::Active) + && (state != MuteState::PushToTalk); + const auto track = !muted || (state == MuteState::Muted); + devices->setCaptureMuteTracker(this, track); + devices->setCaptureMuted(muted); + }, _lifetime); +} + +void GroupCall::captureMuteChanged(bool mute) { + const auto oldState = muted(); + if (mute + && (oldState == MuteState::ForceMuted + || oldState == MuteState::RaisedHand + || oldState == MuteState::Muted)) { + return; + } else if (!mute && oldState != MuteState::Muted) { + return; + } + setMutedAndUpdate(mute ? MuteState::Muted : MuteState::Active); +} + +rpl::producer GroupCall::captureMuteDeviceId() { + return _captureDeviceId.value(); } int GroupCall::activeVideoSendersCount() const { diff --git a/Telegram/SourceFiles/calls/group/calls_group_call.h b/Telegram/SourceFiles/calls/group/calls_group_call.h index fd2cd88a0..8f93793bd 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_call.h +++ b/Telegram/SourceFiles/calls/group/calls_group_call.h @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/bytes.h" #include "mtproto/sender.h" #include "mtproto/mtproto_auth_key.h" +#include "webrtc/webrtc_device_common.h" #include "webrtc/webrtc_device_resolver.h" class History; @@ -175,7 +176,9 @@ struct ParticipantVideoParams; [[nodiscard]] uint32 GetAdditionalAudioSsrc( const std::shared_ptr ¶ms); -class GroupCall final : public base::has_weak_ptr { +class GroupCall final + : public base::has_weak_ptr + , private Webrtc::CaptureMuteTracker { public: class Delegate { public: @@ -550,6 +553,9 @@ private: void applySelfUpdate(const MTPDgroupCallParticipant &data); void applyOtherParticipantUpdate(const MTPDgroupCallParticipant &data); + void captureMuteChanged(bool mute) override; + rpl::producer captureMuteDeviceId() override; + void setupMediaDevices(); void setupOutgoingVideo(); void setScreenEndpoint(std::string endpoint); diff --git a/Telegram/lib_webrtc b/Telegram/lib_webrtc index 5493af61d..1cbf5fa7d 160000 --- a/Telegram/lib_webrtc +++ b/Telegram/lib_webrtc @@ -1 +1 @@ -Subproject commit 5493af61df5cb90a30b686296521961763a009e0 +Subproject commit 1cbf5fa7d875074c40e76216a3047bd7c59996d7