Add AudioSendStream::SetMuted() method and use it in WVoMC::MuteStream().

Removes the need to use VoEVolume::SetInputMute()/GetInputMute().

BUG=webrtc:4690
NOTRY=true

Review-Url: https://codereview.webrtc.org/2066973002
Cr-Commit-Position: refs/heads/master@{#13172}
This commit is contained in:
solenberg
2016-06-16 10:53:22 -07:00
committed by Commit bot
parent e565a04de3
commit 9421853e17
12 changed files with 65 additions and 16 deletions

View File

@ -127,6 +127,11 @@ bool AudioSendStream::SendTelephoneEvent(int payload_type, int event,
channel_proxy_->SendTelephoneEventOutband(event, duration_ms);
}
void AudioSendStream::SetMuted(bool muted) {
RTC_DCHECK(thread_checker_.CalledOnValidThread());
channel_proxy_->SetInputMute(muted);
}
webrtc::AudioSendStream::Stats AudioSendStream::GetStats() const {
RTC_DCHECK(thread_checker_.CalledOnValidThread());
webrtc::AudioSendStream::Stats stats;

View File

@ -39,6 +39,7 @@ class AudioSendStream final : public webrtc::AudioSendStream {
void Stop() override;
bool SendTelephoneEvent(int payload_type, int event,
int duration_ms) override;
void SetMuted(bool muted) override;
webrtc::AudioSendStream::Stats GetStats() const override;
void SignalNetworkState(NetworkState state);

View File

@ -110,6 +110,7 @@ struct ConfigHelper {
AudioSendStream::Config& config() { return stream_config_; }
rtc::scoped_refptr<AudioState> audio_state() { return audio_state_; }
MockVoEChannelProxy* channel_proxy() { return channel_proxy_; }
CongestionController* congestion_controller() {
return &congestion_controller_;
}
@ -200,6 +201,14 @@ TEST(AudioSendStreamTest, SendTelephoneEvent) {
kTelephoneEventCode, kTelephoneEventDuration));
}
TEST(AudioSendStreamTest, SetMuted) {
ConfigHelper helper;
internal::AudioSendStream send_stream(helper.config(), helper.audio_state(),
helper.congestion_controller());
EXPECT_CALL(*helper.channel_proxy(), SetInputMute(true));
send_stream.SetMuted(true);
}
TEST(AudioSendStreamTest, GetStats) {
ConfigHelper helper;
internal::AudioSendStream send_stream(helper.config(), helper.audio_state(),

View File

@ -100,6 +100,9 @@ class AudioSendStream {
// TODO(solenberg): Make payload_type a config property instead.
virtual bool SendTelephoneEvent(int payload_type, int event,
int duration_ms) = 0;
virtual void SetMuted(bool muted) = 0;
virtual Stats GetStats() const = 0;
protected:

View File

@ -47,6 +47,10 @@ bool FakeAudioSendStream::SendTelephoneEvent(int payload_type, int event,
return true;
}
void FakeAudioSendStream::SetMuted(bool muted) {
muted_ = muted;
}
webrtc::AudioSendStream::Stats FakeAudioSendStream::GetStats() const {
return stats_;
}

View File

@ -46,6 +46,7 @@ class FakeAudioSendStream final : public webrtc::AudioSendStream {
void SetStats(const webrtc::AudioSendStream::Stats& stats);
TelephoneEvent GetLatestTelephoneEvent() const;
bool IsSending() const { return sending_; }
bool muted() const { return muted_; }
private:
// webrtc::AudioSendStream implementation.
@ -54,12 +55,14 @@ class FakeAudioSendStream final : public webrtc::AudioSendStream {
bool SendTelephoneEvent(int payload_type, int event,
int duration_ms) override;
void SetMuted(bool muted) override;
webrtc::AudioSendStream::Stats GetStats() const override;
TelephoneEvent latest_telephone_event_;
webrtc::AudioSendStream::Config config_;
webrtc::AudioSendStream::Stats stats_;
bool sending_ = false;
bool muted_ = false;
};
class FakeAudioReceiveStream final : public webrtc::AudioReceiveStream {

View File

@ -23,7 +23,6 @@
#include "webrtc/voice_engine/include/voe_codec.h"
#include "webrtc/voice_engine/include/voe_errors.h"
#include "webrtc/voice_engine/include/voe_hardware.h"
#include "webrtc/voice_engine/include/voe_network.h"
#include "webrtc/voice_engine/include/voe_rtp_rtcp.h"
#include "webrtc/voice_engine/include/voe_volume_control.h"

View File

@ -1145,6 +1145,18 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream
UpdateSendState();
}
void SetMuted(bool muted) {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
RTC_DCHECK(stream_);
stream_->SetMuted(muted);
muted_ = muted;
}
bool muted() const {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
return muted_;
}
webrtc::AudioSendStream::Stats GetStats() const {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
RTC_DCHECK(stream_);
@ -1250,6 +1262,7 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream
// goes away.
AudioSource* source_ = nullptr;
bool send_ = false;
bool muted_ = false;
webrtc::RtpParameters rtp_parameters_;
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream);
@ -2361,29 +2374,21 @@ void WebRtcVoiceMediaChannel::OnNetworkRouteChanged(
bool WebRtcVoiceMediaChannel::MuteStream(uint32_t ssrc, bool muted) {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
int channel = GetSendChannelId(ssrc);
if (channel == -1) {
const auto it = send_streams_.find(ssrc);
if (it == send_streams_.end()) {
LOG(LS_WARNING) << "The specified ssrc " << ssrc << " is not in use.";
return false;
}
if (engine()->voe()->volume()->SetInputMute(channel, muted) == -1) {
LOG_RTCERR2(SetInputMute, channel, muted);
return false;
}
it->second->SetMuted(muted);
// TODO(solenberg):
// We set the AGC to mute state only when all the channels are muted.
// This implementation is not ideal, instead we should signal the AGC when
// the mic channel is muted/unmuted. We can't do it today because there
// is no good way to know which stream is mapping to the mic channel.
bool all_muted = muted;
for (const auto& ch : send_streams_) {
if (!all_muted) {
break;
}
if (engine()->voe()->volume()->GetInputMute(ch.second->channel(),
all_muted)) {
LOG_RTCERR1(GetInputMute, ch.second->channel());
return false;
}
for (const auto& kv : send_streams_) {
all_muted = all_muted && kv.second->muted();
}
webrtc::AudioProcessing* ap = engine()->voe()->base()->audio_processing();

View File

@ -2135,6 +2135,17 @@ TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
}
// Test that a channel is muted/unmuted.
TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
EXPECT_TRUE(SetupSendStream());
EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
EXPECT_FALSE(GetSendStream(kSsrc1).muted());
EXPECT_TRUE(channel_->SetAudioSend(kSsrc1, true, nullptr, nullptr));
EXPECT_FALSE(GetSendStream(kSsrc1).muted());
EXPECT_TRUE(channel_->SetAudioSend(kSsrc1, false, nullptr, nullptr));
EXPECT_TRUE(GetSendStream(kSsrc1).muted());
}
// Test that SetSendParameters() does not alter a stream's send state.
TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
EXPECT_TRUE(SetupSendStream());

View File

@ -45,6 +45,8 @@ class MockVoEChannelProxy : public voe::ChannelProxy {
MOCK_CONST_METHOD0(GetDelayEstimate, uint32_t());
MOCK_METHOD1(SetSendTelephoneEventPayloadType, bool(int payload_type));
MOCK_METHOD2(SendTelephoneEventOutband, bool(int event, int duration_ms));
MOCK_METHOD1(SetInputMute, void(bool muted));
MOCK_METHOD1(RegisterExternalTransport, void(Transport* transport));
MOCK_METHOD0(DeRegisterExternalTransport, void());
MOCK_METHOD3(ReceivedRTPPacket, bool(const uint8_t* packet,

View File

@ -163,6 +163,12 @@ void ChannelProxy::SetSink(std::unique_ptr<AudioSinkInterface> sink) {
channel()->SetSink(std::move(sink));
}
void ChannelProxy::SetInputMute(bool muted) {
RTC_DCHECK(thread_checker_.CalledOnValidThread());
int error = channel()->SetInputMute(muted);
RTC_DCHECK_EQ(0, error);
}
void ChannelProxy::RegisterExternalTransport(Transport* transport) {
RTC_DCHECK(thread_checker_.CalledOnValidThread());
int error = channel()->RegisterExternalTransport(transport);

View File

@ -73,6 +73,7 @@ class ChannelProxy {
virtual bool SetSendTelephoneEventPayloadType(int payload_type);
virtual bool SendTelephoneEventOutband(int event, int duration_ms);
virtual void SetSink(std::unique_ptr<AudioSinkInterface> sink);
virtual void SetInputMute(bool muted);
virtual void RegisterExternalTransport(Transport* transport);
virtual void DeRegisterExternalTransport();