Add AudioReceiveStream::SetGain() method and use that in WVoMC::SetOutputVolume().
Removes the need to use VoEVolume::SetChannelOutputVolumeScaling().
BUG=webrtc:4690
Review-Url: https://codereview.webrtc.org/2062193002
Cr-Commit-Position: refs/heads/master@{#13194}
diff --git a/webrtc/audio/audio_receive_stream.cc b/webrtc/audio/audio_receive_stream.cc
index 15e4f61..c933f78 100644
--- a/webrtc/audio/audio_receive_stream.cc
+++ b/webrtc/audio/audio_receive_stream.cc
@@ -210,6 +210,11 @@
channel_proxy_->SetSink(std::move(sink));
}
+void AudioReceiveStream::SetGain(float gain) {
+ RTC_DCHECK(thread_checker_.CalledOnValidThread());
+ channel_proxy_->SetChannelOutputVolumeScaling(gain);
+}
+
const webrtc::AudioReceiveStream::Config& AudioReceiveStream::config() const {
RTC_DCHECK(thread_checker_.CalledOnValidThread());
return config_;
diff --git a/webrtc/audio/audio_receive_stream.h b/webrtc/audio/audio_receive_stream.h
index d99956c..284f98e 100644
--- a/webrtc/audio/audio_receive_stream.h
+++ b/webrtc/audio/audio_receive_stream.h
@@ -41,6 +41,7 @@
void Stop() override;
webrtc::AudioReceiveStream::Stats GetStats() const override;
void SetSink(std::unique_ptr<AudioSinkInterface> sink) override;
+ void SetGain(float gain) override;
void SignalNetworkState(NetworkState state);
bool DeliverRtcp(const uint8_t* packet, size_t length);
diff --git a/webrtc/audio/audio_receive_stream_unittest.cc b/webrtc/audio/audio_receive_stream_unittest.cc
index 2e789f9..8e26dd9 100644
--- a/webrtc/audio/audio_receive_stream_unittest.cc
+++ b/webrtc/audio/audio_receive_stream_unittest.cc
@@ -30,6 +30,7 @@
namespace {
using testing::_;
+using testing::FloatEq;
using testing::Return;
using testing::ReturnRef;
@@ -92,12 +93,12 @@
EXPECT_CALL(*channel_proxy_,
SetReceiveAudioLevelIndicationStatus(true, kAudioLevelId))
.Times(1);
- EXPECT_CALL(*channel_proxy_, EnableReceiveTransportSequenceNumber(
- kTransportSequenceNumberId))
- .Times(1);
EXPECT_CALL(*channel_proxy_,
- RegisterReceiverCongestionControlObjects(&packet_router_))
- .Times(1);
+ EnableReceiveTransportSequenceNumber(kTransportSequenceNumberId))
+ .Times(1);
+ EXPECT_CALL(*channel_proxy_,
+ RegisterReceiverCongestionControlObjects(&packet_router_))
+ .Times(1);
EXPECT_CALL(congestion_controller_, packet_router())
.WillOnce(Return(&packet_router_));
EXPECT_CALL(*channel_proxy_, ResetCongestionControlObjects())
@@ -303,7 +304,6 @@
EXPECT_TRUE(recv_stream.DeliverRtcp(&rtcp_packet[0], rtcp_packet.size()));
}
-
TEST(AudioReceiveStreamTest, GetStats) {
ConfigHelper helper;
internal::AudioReceiveStream recv_stream(
@@ -345,5 +345,14 @@
EXPECT_EQ(kCallStats.capture_start_ntp_time_ms_,
stats.capture_start_ntp_time_ms);
}
+
+TEST(AudioReceiveStreamTest, SetGain) {
+ ConfigHelper helper;
+ internal::AudioReceiveStream recv_stream(
+ helper.congestion_controller(), helper.config(), helper.audio_state());
+ EXPECT_CALL(*helper.channel_proxy(),
+ SetChannelOutputVolumeScaling(FloatEq(0.765f)));
+ recv_stream.SetGain(0.765f);
+}
} // namespace test
} // namespace webrtc
diff --git a/webrtc/audio_receive_stream.h b/webrtc/audio_receive_stream.h
index 16ed769..e0e9536 100644
--- a/webrtc/audio_receive_stream.h
+++ b/webrtc/audio_receive_stream.h
@@ -127,6 +127,10 @@
// of feeding to the AEC.
virtual void SetSink(std::unique_ptr<AudioSinkInterface> sink) = 0;
+ // Sets playback gain of the stream, applied when mixing, and thus after it
+ // is potentially forwarded to any attached AudioSinkInterface implementation.
+ virtual void SetGain(float gain) = 0;
+
protected:
virtual ~AudioReceiveStream() {}
};
diff --git a/webrtc/media/engine/fakewebrtccall.cc b/webrtc/media/engine/fakewebrtccall.cc
index fd020d4..914a403 100644
--- a/webrtc/media/engine/fakewebrtccall.cc
+++ b/webrtc/media/engine/fakewebrtccall.cc
@@ -57,7 +57,7 @@
FakeAudioReceiveStream::FakeAudioReceiveStream(
const webrtc::AudioReceiveStream::Config& config)
- : config_(config), received_packets_(0) {
+ : config_(config) {
RTC_DCHECK(config.voe_channel_id != -1);
}
@@ -93,6 +93,10 @@
sink_ = std::move(sink);
}
+void FakeAudioReceiveStream::SetGain(float gain) {
+ gain_ = gain;
+}
+
FakeVideoSendStream::FakeVideoSendStream(
const webrtc::VideoSendStream::Config& config,
const webrtc::VideoEncoderConfig& encoder_config)
diff --git a/webrtc/media/engine/fakewebrtccall.h b/webrtc/media/engine/fakewebrtccall.h
index 4a0e41c..f703b15 100644
--- a/webrtc/media/engine/fakewebrtccall.h
+++ b/webrtc/media/engine/fakewebrtccall.h
@@ -75,6 +75,7 @@
int received_packets() const { return received_packets_; }
bool VerifyLastPacket(const uint8_t* data, size_t length) const;
const webrtc::AudioSinkInterface* sink() const { return sink_.get(); }
+ float gain() const { return gain_; }
bool DeliverRtp(const uint8_t* packet,
size_t length,
const webrtc::PacketTime& packet_time);
@@ -86,11 +87,13 @@
webrtc::AudioReceiveStream::Stats GetStats() const override;
void SetSink(std::unique_ptr<webrtc::AudioSinkInterface> sink) override;
+ void SetGain(float gain) override;
webrtc::AudioReceiveStream::Config config_;
webrtc::AudioReceiveStream::Stats stats_;
- int received_packets_;
+ int received_packets_ = 0;
std::unique_ptr<webrtc::AudioSinkInterface> sink_;
+ float gain_ = 1.0f;
rtc::Buffer last_packet_;
};
diff --git a/webrtc/media/engine/fakewebrtcvoiceengine.h b/webrtc/media/engine/fakewebrtcvoiceengine.h
index 8d15f52..4e3ced6 100644
--- a/webrtc/media/engine/fakewebrtcvoiceengine.h
+++ b/webrtc/media/engine/fakewebrtcvoiceengine.h
@@ -129,7 +129,6 @@
memset(&send_codec, 0, sizeof(send_codec));
}
bool playout = false;
- float volume_scale = 1.0f;
bool vad = false;
bool codec_fec = false;
int max_encoding_bandwidth = 0;
@@ -441,16 +440,8 @@
WEBRTC_STUB(GetSpeechOutputLevel, (int, unsigned int&));
WEBRTC_STUB(GetSpeechInputLevelFullRange, (unsigned int&));
WEBRTC_STUB(GetSpeechOutputLevelFullRange, (int, unsigned int&));
- WEBRTC_FUNC(SetChannelOutputVolumeScaling, (int channel, float scale)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->volume_scale= scale;
- return 0;
- }
- WEBRTC_FUNC(GetChannelOutputVolumeScaling, (int channel, float& scale)) {
- WEBRTC_CHECK_CHANNEL(channel);
- scale = channels_[channel]->volume_scale;
- return 0;
- }
+ WEBRTC_STUB(SetChannelOutputVolumeScaling, (int channel, float scale));
+ WEBRTC_STUB(GetChannelOutputVolumeScaling, (int channel, float& scale));
WEBRTC_STUB(SetOutputVolumePan, (int channel, float left, float right));
WEBRTC_STUB(GetOutputVolumePan, (int channel, float& left, float& right));
diff --git a/webrtc/media/engine/webrtcvoiceengine.cc b/webrtc/media/engine/webrtcvoiceengine.cc
index eb9b4bb..2ddf67d 100644
--- a/webrtc/media/engine/webrtcvoiceengine.cc
+++ b/webrtc/media/engine/webrtcvoiceengine.cc
@@ -1341,6 +1341,11 @@
stream_->SetSink(std::move(sink));
}
+ void SetOutputVolume(double volume) {
+ RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
+ stream_->SetGain(volume);
+ }
+
private:
void RecreateAudioReceiveStream(
uint32_t local_ssrc,
@@ -2270,19 +2275,14 @@
}
ssrc = static_cast<uint32_t>(default_recv_ssrc_);
}
- int ch_id = GetReceiveChannelId(ssrc);
- if (ch_id < 0) {
- LOG(LS_WARNING) << "Cannot find channel for ssrc:" << ssrc;
+ const auto it = recv_streams_.find(ssrc);
+ if (it == recv_streams_.end()) {
+ LOG(LS_WARNING) << "SetOutputVolume: no recv stream" << ssrc;
return false;
}
-
- if (-1 == engine()->voe()->volume()->SetChannelOutputVolumeScaling(ch_id,
- volume)) {
- LOG_RTCERR2(SetChannelOutputVolumeScaling, ch_id, volume);
- return false;
- }
- LOG(LS_INFO) << "SetOutputVolume to " << volume
- << " for channel " << ch_id << " and ssrc " << ssrc;
+ it->second->SetOutputVolume(volume);
+ LOG(LS_INFO) << "SetOutputVolume() to " << volume
+ << " for recv stream with ssrc " << ssrc;
return true;
}
diff --git a/webrtc/media/engine/webrtcvoiceengine_unittest.cc b/webrtc/media/engine/webrtcvoiceengine_unittest.cc
index 167ec89..2db70d1 100644
--- a/webrtc/media/engine/webrtcvoiceengine_unittest.cc
+++ b/webrtc/media/engine/webrtcvoiceengine_unittest.cc
@@ -3130,24 +3130,20 @@
cricket::StreamParams stream;
stream.ssrcs.push_back(kSsrc2);
EXPECT_TRUE(channel_->AddRecvStream(stream));
- int channel_id = voe_.GetLastChannel();
+ EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc2).gain());
EXPECT_TRUE(channel_->SetOutputVolume(kSsrc2, 3));
- float scale = 0;
- EXPECT_EQ(0, voe_.GetChannelOutputVolumeScaling(channel_id, scale));
- EXPECT_DOUBLE_EQ(3, scale);
+ EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc2).gain());
}
TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeDefaultRecvStream) {
EXPECT_TRUE(SetupChannel());
EXPECT_TRUE(channel_->SetOutputVolume(0, 2));
DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
- int channel_id = voe_.GetLastChannel();
- float scale = 0;
- EXPECT_EQ(0, voe_.GetChannelOutputVolumeScaling(channel_id, scale));
- EXPECT_DOUBLE_EQ(2, scale);
+ EXPECT_DOUBLE_EQ(2, GetRecvStream(1).gain());
EXPECT_TRUE(channel_->SetOutputVolume(0, 3));
- EXPECT_EQ(0, voe_.GetChannelOutputVolumeScaling(channel_id, scale));
- EXPECT_DOUBLE_EQ(3, scale);
+ EXPECT_DOUBLE_EQ(3, GetRecvStream(1).gain());
+ EXPECT_TRUE(channel_->SetOutputVolume(1, 4));
+ EXPECT_DOUBLE_EQ(4, GetRecvStream(1).gain());
}
TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
diff --git a/webrtc/test/mock_voe_channel_proxy.h b/webrtc/test/mock_voe_channel_proxy.h
index da215d6..dc2a961 100644
--- a/webrtc/test/mock_voe_channel_proxy.h
+++ b/webrtc/test/mock_voe_channel_proxy.h
@@ -46,7 +46,8 @@
MOCK_METHOD1(SetSendTelephoneEventPayloadType, bool(int payload_type));
MOCK_METHOD2(SendTelephoneEventOutband, bool(int event, int duration_ms));
MOCK_METHOD1(SetInputMute, void(bool muted));
-
+ // TODO(solenberg): Talk the compiler into accepting this mock method:
+ // MOCK_METHOD1(SetSink, void(std::unique_ptr<AudioSinkInterface> sink));
MOCK_METHOD1(RegisterExternalTransport, void(Transport* transport));
MOCK_METHOD0(DeRegisterExternalTransport, void());
MOCK_METHOD3(ReceivedRTPPacket, bool(const uint8_t* packet,
@@ -55,6 +56,7 @@
MOCK_METHOD2(ReceivedRTCPPacket, bool(const uint8_t* packet, size_t length));
MOCK_CONST_METHOD0(GetAudioDecoderFactory,
const rtc::scoped_refptr<AudioDecoderFactory>&());
+ MOCK_METHOD1(SetChannelOutputVolumeScaling, void(float scaling));
};
} // namespace test
} // namespace webrtc
diff --git a/webrtc/voice_engine/channel_proxy.cc b/webrtc/voice_engine/channel_proxy.cc
index 46288e9..f60728a 100644
--- a/webrtc/voice_engine/channel_proxy.cc
+++ b/webrtc/voice_engine/channel_proxy.cc
@@ -193,10 +193,17 @@
}
const rtc::scoped_refptr<AudioDecoderFactory>&
-ChannelProxy::GetAudioDecoderFactory() const {
+ ChannelProxy::GetAudioDecoderFactory() const {
+ RTC_DCHECK(thread_checker_.CalledOnValidThread());
return channel()->GetAudioDecoderFactory();
}
+void ChannelProxy::SetChannelOutputVolumeScaling(float scaling) {
+ RTC_DCHECK(thread_checker_.CalledOnValidThread());
+ int error = channel()->SetChannelOutputVolumeScaling(scaling);
+ RTC_DCHECK_EQ(0, error);
+}
+
Channel* ChannelProxy::channel() const {
RTC_DCHECK(channel_owner_.channel());
return channel_owner_.channel();
diff --git a/webrtc/voice_engine/channel_proxy.h b/webrtc/voice_engine/channel_proxy.h
index 93b8a58..39eed67 100644
--- a/webrtc/voice_engine/channel_proxy.h
+++ b/webrtc/voice_engine/channel_proxy.h
@@ -83,7 +83,9 @@
virtual bool ReceivedRTCPPacket(const uint8_t* packet, size_t length);
virtual const rtc::scoped_refptr<AudioDecoderFactory>&
- GetAudioDecoderFactory() const;
+ GetAudioDecoderFactory() const;
+
+ virtual void SetChannelOutputVolumeScaling(float scaling);
private:
Channel* channel() const;