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}
This commit is contained in:
solenberg 2016-06-17 08:30:54 -07:00 committed by Commit bot
parent 387000114d
commit 217fb66e16
12 changed files with 67 additions and 43 deletions

View File

@ -210,6 +210,11 @@ void AudioReceiveStream::SetSink(std::unique_ptr<AudioSinkInterface> sink) {
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_;

View File

@ -41,6 +41,7 @@ class AudioReceiveStream final : public webrtc::AudioReceiveStream {
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);

View File

@ -30,6 +30,7 @@ namespace test {
namespace {
using testing::_;
using testing::FloatEq;
using testing::Return;
using testing::ReturnRef;
@ -92,8 +93,8 @@ struct ConfigHelper {
EXPECT_CALL(*channel_proxy_,
SetReceiveAudioLevelIndicationStatus(true, kAudioLevelId))
.Times(1);
EXPECT_CALL(*channel_proxy_, EnableReceiveTransportSequenceNumber(
kTransportSequenceNumberId))
EXPECT_CALL(*channel_proxy_,
EnableReceiveTransportSequenceNumber(kTransportSequenceNumberId))
.Times(1);
EXPECT_CALL(*channel_proxy_,
RegisterReceiverCongestionControlObjects(&packet_router_))
@ -303,7 +304,6 @@ TEST(AudioReceiveStreamTest, ReceiveRtcpPacket) {
EXPECT_TRUE(recv_stream.DeliverRtcp(&rtcp_packet[0], rtcp_packet.size()));
}
TEST(AudioReceiveStreamTest, GetStats) {
ConfigHelper helper;
internal::AudioReceiveStream recv_stream(
@ -345,5 +345,14 @@ TEST(AudioReceiveStreamTest, GetStats) {
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

View File

@ -127,6 +127,10 @@ class AudioReceiveStream {
// 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() {}
};

View File

@ -57,7 +57,7 @@ webrtc::AudioSendStream::Stats FakeAudioSendStream::GetStats() const {
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 @@ void FakeAudioReceiveStream::SetSink(
sink_ = std::move(sink);
}
void FakeAudioReceiveStream::SetGain(float gain) {
gain_ = gain;
}
FakeVideoSendStream::FakeVideoSendStream(
const webrtc::VideoSendStream::Config& config,
const webrtc::VideoEncoderConfig& encoder_config)

View File

@ -75,6 +75,7 @@ class FakeAudioReceiveStream final : public webrtc::AudioReceiveStream {
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 @@ class FakeAudioReceiveStream final : public webrtc::AudioReceiveStream {
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_;
};

View File

@ -129,7 +129,6 @@ class FakeWebRtcVoiceEngine
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 @@ class FakeWebRtcVoiceEngine
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));

View File

@ -1341,6 +1341,11 @@ class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream {
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 @@ bool WebRtcVoiceMediaChannel::SetOutputVolume(uint32_t ssrc, double volume) {
}
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;
}

View File

@ -3130,24 +3130,20 @@ TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
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) {

View File

@ -46,7 +46,8 @@ class MockVoEChannelProxy : public voe::ChannelProxy {
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 @@ class MockVoEChannelProxy : public voe::ChannelProxy {
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

View File

@ -194,9 +194,16 @@ bool ChannelProxy::ReceivedRTCPPacket(const uint8_t* packet, size_t length) {
const rtc::scoped_refptr<AudioDecoderFactory>&
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();

View File

@ -85,6 +85,8 @@ class ChannelProxy {
virtual const rtc::scoped_refptr<AudioDecoderFactory>&
GetAudioDecoderFactory() const;
virtual void SetChannelOutputVolumeScaling(float scaling);
private:
Channel* channel() const;