Wire up audio packet loss to BWE.
BUG=webtrc:5079
Review-Url: https://codereview.webrtc.org/2658233002
Cr-Commit-Position: refs/heads/master@{#16474}
diff --git a/webrtc/audio/BUILD.gn b/webrtc/audio/BUILD.gn
index 80d5416..acd8dfa 100644
--- a/webrtc/audio/BUILD.gn
+++ b/webrtc/audio/BUILD.gn
@@ -37,6 +37,7 @@
"../common_audio",
"../modules/audio_device",
"../modules/audio_processing",
+ "../modules/bitrate_controller:bitrate_controller",
"../modules/congestion_controller:congestion_controller",
"../modules/pacing:pacing",
"../modules/remote_bitrate_estimator:remote_bitrate_estimator",
diff --git a/webrtc/audio/audio_send_stream.cc b/webrtc/audio/audio_send_stream.cc
index c43d0da..8d4ad32 100644
--- a/webrtc/audio/audio_send_stream.cc
+++ b/webrtc/audio/audio_send_stream.cc
@@ -19,6 +19,7 @@
#include "webrtc/base/event.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/task_queue.h"
+#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
#include "webrtc/modules/congestion_controller/include/congestion_controller.h"
#include "webrtc/modules/pacing/paced_sender.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
@@ -62,9 +63,6 @@
channel_proxy_ = voe_impl->GetChannelProxy(config_.voe_channel_id);
channel_proxy_->SetRtcEventLog(event_log);
channel_proxy_->SetRtcpRttStats(rtcp_rtt_stats);
- channel_proxy_->RegisterSenderCongestionControlObjects(
- congestion_controller->pacer(),
- congestion_controller->GetTransportFeedbackObserver(), packet_router);
channel_proxy_->SetRTCPStatus(true);
channel_proxy_->SetLocalSSRC(config.rtp.ssrc);
channel_proxy_->SetRTCP_CNAME(config.rtp.c_name);
@@ -81,10 +79,16 @@
} else if (extension.uri == RtpExtension::kTransportSequenceNumberUri) {
channel_proxy_->EnableSendTransportSequenceNumber(extension.id);
congestion_controller->EnablePeriodicAlrProbing(true);
+ bandwidth_observer_.reset(congestion_controller->GetBitrateController()
+ ->CreateRtcpBandwidthObserver());
} else {
RTC_NOTREACHED() << "Registering unsupported RTP extension.";
}
}
+ channel_proxy_->RegisterSenderCongestionControlObjects(
+ congestion_controller->pacer(),
+ congestion_controller->GetTransportFeedbackObserver(), packet_router,
+ bandwidth_observer_.get());
if (!SetupSendCodec()) {
LOG(LS_ERROR) << "Failed to set up send codec state.";
}
diff --git a/webrtc/audio/audio_send_stream.h b/webrtc/audio/audio_send_stream.h
index 05ed3aa..5ee49da 100644
--- a/webrtc/audio/audio_send_stream.h
+++ b/webrtc/audio/audio_send_stream.h
@@ -23,6 +23,7 @@
class CongestionController;
class VoiceEngine;
class RtcEventLog;
+class RtcpBandwidthObserver;
class RtcpRttStats;
class PacketRouter;
@@ -77,6 +78,7 @@
BitrateAllocator* const bitrate_allocator_;
CongestionController* const congestion_controller_;
+ std::unique_ptr<RtcpBandwidthObserver> bandwidth_observer_;
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AudioSendStream);
};
diff --git a/webrtc/audio/audio_send_stream_unittest.cc b/webrtc/audio/audio_send_stream_unittest.cc
index 4b7415a..9ae0a87 100644
--- a/webrtc/audio/audio_send_stream_unittest.cc
+++ b/webrtc/audio/audio_send_stream_unittest.cc
@@ -32,6 +32,8 @@
namespace {
using testing::_;
+using testing::Eq;
+using testing::Ne;
using testing::Return;
const int kChannelId = 1;
@@ -62,7 +64,7 @@
};
struct ConfigHelper {
- ConfigHelper()
+ explicit ConfigHelper(bool audio_bwe_enabled)
: simulated_clock_(123456),
stream_config_(nullptr),
congestion_controller_(&simulated_clock_,
@@ -87,7 +89,7 @@
config.audio_mixer = AudioMixerImpl::Create();
audio_state_ = AudioState::Create(config);
- SetupDefaultChannelProxy();
+ SetupDefaultChannelProxy(audio_bwe_enabled);
EXPECT_CALL(voice_engine_, ChannelProxyFactory(kChannelId))
.WillOnce(Invoke([this](int channel_id) {
@@ -102,8 +104,12 @@
stream_config_.rtp.c_name = kCName;
stream_config_.rtp.extensions.push_back(
RtpExtension(RtpExtension::kAudioLevelUri, kAudioLevelId));
- stream_config_.rtp.extensions.push_back(RtpExtension(
- RtpExtension::kTransportSequenceNumberUri, kTransportSequenceNumberId));
+ if (audio_bwe_enabled) {
+ stream_config_.rtp.extensions.push_back(
+ RtpExtension(RtpExtension::kTransportSequenceNumberUri,
+ kTransportSequenceNumberId));
+ stream_config_.send_codec_spec.transport_cc_enabled = true;
+ }
// Use ISAC as default codec so as to prevent unnecessary |voice_engine_|
// calls from the default ctor behavior.
stream_config_.send_codec_spec.codec_inst = kIsacCodec;
@@ -123,7 +129,7 @@
RtcEventLog* event_log() { return &event_log_; }
MockVoiceEngine* voice_engine() { return &voice_engine_; }
- void SetupDefaultChannelProxy() {
+ void SetupDefaultChannelProxy(bool audio_bwe_enabled) {
using testing::StrEq;
channel_proxy_ = new testing::StrictMock<MockVoEChannelProxy>();
EXPECT_CALL(*channel_proxy_, SetRTCPStatus(true)).Times(1);
@@ -133,15 +139,25 @@
EXPECT_CALL(*channel_proxy_,
SetSendAudioLevelIndicationStatus(true, kAudioLevelId))
.Times(1);
- EXPECT_CALL(*channel_proxy_,
- EnableSendTransportSequenceNumber(kTransportSequenceNumberId))
- .Times(1);
- EXPECT_CALL(*channel_proxy_,
- RegisterSenderCongestionControlObjects(
- congestion_controller_.pacer(),
- congestion_controller_.GetTransportFeedbackObserver(),
- packet_router()))
- .Times(1);
+
+ if (audio_bwe_enabled) {
+ EXPECT_CALL(*channel_proxy_,
+ EnableSendTransportSequenceNumber(kTransportSequenceNumberId))
+ .Times(1);
+ EXPECT_CALL(*channel_proxy_,
+ RegisterSenderCongestionControlObjects(
+ congestion_controller_.pacer(),
+ congestion_controller_.GetTransportFeedbackObserver(),
+ packet_router(), Ne(nullptr)))
+ .Times(1);
+ } else {
+ EXPECT_CALL(*channel_proxy_,
+ RegisterSenderCongestionControlObjects(
+ congestion_controller_.pacer(),
+ congestion_controller_.GetTransportFeedbackObserver(),
+ packet_router(), Eq(nullptr)))
+ .Times(1);
+ }
EXPECT_CALL(*channel_proxy_, ResetCongestionControlObjects()).Times(1);
EXPECT_CALL(*channel_proxy_, RegisterExternalTransport(nullptr)).Times(1);
EXPECT_CALL(*channel_proxy_, DeRegisterExternalTransport()).Times(1);
@@ -271,7 +287,7 @@
}
TEST(AudioSendStreamTest, ConstructDestruct) {
- ConfigHelper helper;
+ ConfigHelper helper(false);
internal::AudioSendStream send_stream(
helper.config(), helper.audio_state(), helper.worker_queue(),
helper.packet_router(), helper.congestion_controller(),
@@ -279,7 +295,7 @@
}
TEST(AudioSendStreamTest, SendTelephoneEvent) {
- ConfigHelper helper;
+ ConfigHelper helper(false);
internal::AudioSendStream send_stream(
helper.config(), helper.audio_state(), helper.worker_queue(),
helper.packet_router(), helper.congestion_controller(),
@@ -291,7 +307,7 @@
}
TEST(AudioSendStreamTest, SetMuted) {
- ConfigHelper helper;
+ ConfigHelper helper(false);
internal::AudioSendStream send_stream(
helper.config(), helper.audio_state(), helper.worker_queue(),
helper.packet_router(), helper.congestion_controller(),
@@ -300,8 +316,24 @@
send_stream.SetMuted(true);
}
+TEST(AudioSendStreamTest, AudioBweCorrectObjectsOnChannelProxy) {
+ ConfigHelper helper(true);
+ internal::AudioSendStream send_stream(
+ helper.config(), helper.audio_state(), helper.worker_queue(),
+ helper.packet_router(), helper.congestion_controller(),
+ helper.bitrate_allocator(), helper.event_log(), helper.rtcp_rtt_stats());
+}
+
+TEST(AudioSendStreamTest, NoAudioBweCorrectObjectsOnChannelProxy) {
+ ConfigHelper helper(false);
+ internal::AudioSendStream send_stream(
+ helper.config(), helper.audio_state(), helper.worker_queue(),
+ helper.packet_router(), helper.congestion_controller(),
+ helper.bitrate_allocator(), helper.event_log(), helper.rtcp_rtt_stats());
+}
+
TEST(AudioSendStreamTest, GetStats) {
- ConfigHelper helper;
+ ConfigHelper helper(false);
internal::AudioSendStream send_stream(
helper.config(), helper.audio_state(), helper.worker_queue(),
helper.packet_router(), helper.congestion_controller(),
@@ -332,7 +364,7 @@
}
TEST(AudioSendStreamTest, GetStatsTypingNoiseDetected) {
- ConfigHelper helper;
+ ConfigHelper helper(false);
internal::AudioSendStream send_stream(
helper.config(), helper.audio_state(), helper.worker_queue(),
helper.packet_router(), helper.congestion_controller(),
@@ -351,7 +383,7 @@
}
TEST(AudioSendStreamTest, SendCodecAppliesConfigParams) {
- ConfigHelper helper;
+ ConfigHelper helper(false);
auto stream_config = helper.config();
const CodecInst kOpusCodec = {111, "opus", 48000, 960, 2, 64000};
stream_config.send_codec_spec.codec_inst = kOpusCodec;
@@ -396,7 +428,7 @@
// VAD is applied when codec is mono and the CNG frequency matches the codec
// sample rate.
TEST(AudioSendStreamTest, SendCodecCanApplyVad) {
- ConfigHelper helper;
+ ConfigHelper helper(false);
auto stream_config = helper.config();
const CodecInst kG722Codec = {9, "g722", 8000, 160, 1, 16000};
stream_config.send_codec_spec.codec_inst = kG722Codec;
@@ -411,7 +443,7 @@
}
TEST(AudioSendStreamTest, DoesNotPassHigherBitrateThanMaxBitrate) {
- ConfigHelper helper;
+ ConfigHelper helper(false);
internal::AudioSendStream send_stream(
helper.config(), helper.audio_state(), helper.worker_queue(),
helper.packet_router(), helper.congestion_controller(),
@@ -423,7 +455,7 @@
}
TEST(AudioSendStreamTest, ProbingIntervalOnBitrateUpdated) {
- ConfigHelper helper;
+ ConfigHelper helper(false);
internal::AudioSendStream send_stream(
helper.config(), helper.audio_state(), helper.worker_queue(),
helper.packet_router(), helper.congestion_controller(),
diff --git a/webrtc/test/mock_voe_channel_proxy.h b/webrtc/test/mock_voe_channel_proxy.h
index 39b2e9f..ea51154 100644
--- a/webrtc/test/mock_voe_channel_proxy.h
+++ b/webrtc/test/mock_voe_channel_proxy.h
@@ -29,10 +29,11 @@
MOCK_METHOD2(SetReceiveAudioLevelIndicationStatus, void(bool enable, int id));
MOCK_METHOD1(EnableSendTransportSequenceNumber, void(int id));
MOCK_METHOD1(EnableReceiveTransportSequenceNumber, void(int id));
- MOCK_METHOD3(RegisterSenderCongestionControlObjects,
+ MOCK_METHOD4(RegisterSenderCongestionControlObjects,
void(RtpPacketSender* rtp_packet_sender,
TransportFeedbackObserver* transport_feedback_observer,
- PacketRouter* packet_router));
+ PacketRouter* packet_router,
+ RtcpBandwidthObserver* bandwidth_observer));
MOCK_METHOD1(RegisterReceiverCongestionControlObjects,
void(PacketRouter* packet_router));
MOCK_METHOD0(ResetCongestionControlObjects, void());
diff --git a/webrtc/video/video_quality_test.cc b/webrtc/video/video_quality_test.cc
index 9c73460..42d057d 100644
--- a/webrtc/video/video_quality_test.cc
+++ b/webrtc/video/video_quality_test.cc
@@ -927,6 +927,8 @@
}
void VideoQualityTest::CheckParams() {
+ if (!params_.video.enabled)
+ return;
// Add a default stream in none specified.
if (params_.ss.streams.empty())
params_.ss.streams.push_back(VideoQualityTest::DefaultVideoStream(params_));
diff --git a/webrtc/voice_engine/channel.cc b/webrtc/voice_engine/channel.cc
index 2791f7f..a9cf2b2 100644
--- a/webrtc/voice_engine/channel.cc
+++ b/webrtc/voice_engine/channel.cc
@@ -333,16 +333,32 @@
class VoERtcpObserver : public RtcpBandwidthObserver {
public:
- explicit VoERtcpObserver(Channel* owner) : owner_(owner) {}
+ explicit VoERtcpObserver(Channel* owner)
+ : owner_(owner), bandwidth_observer_(nullptr) {}
virtual ~VoERtcpObserver() {}
+ void SetBandwidthObserver(RtcpBandwidthObserver* bandwidth_observer) {
+ rtc::CritScope lock(&crit_);
+ bandwidth_observer_ = bandwidth_observer;
+ }
+
void OnReceivedEstimatedBitrate(uint32_t bitrate) override {
- // Not used for Voice Engine.
+ rtc::CritScope lock(&crit_);
+ if (bandwidth_observer_) {
+ bandwidth_observer_->OnReceivedEstimatedBitrate(bitrate);
+ }
}
void OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks,
int64_t rtt,
int64_t now_ms) override {
+ {
+ rtc::CritScope lock(&crit_);
+ if (bandwidth_observer_) {
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, rtt,
+ now_ms);
+ }
+ }
// TODO(mflodman): Do we need to aggregate reports here or can we jut send
// what we get? I.e. do we ever get multiple reports bundled into one RTCP
// report for VoiceEngine?
@@ -384,6 +400,8 @@
Channel* owner_;
// Maps remote side ssrc to extended highest sequence number received.
std::map<uint32_t, uint32_t> extended_max_sequence_number_;
+ rtc::CriticalSection crit_;
+ RtcpBandwidthObserver* bandwidth_observer_ GUARDED_BY(crit_);
};
int32_t Channel::SendData(FrameType frameType,
@@ -2424,10 +2442,12 @@
void Channel::RegisterSenderCongestionControlObjects(
RtpPacketSender* rtp_packet_sender,
TransportFeedbackObserver* transport_feedback_observer,
- PacketRouter* packet_router) {
+ PacketRouter* packet_router,
+ RtcpBandwidthObserver* bandwidth_observer) {
RTC_DCHECK(rtp_packet_sender);
RTC_DCHECK(transport_feedback_observer);
RTC_DCHECK(packet_router && !packet_router_);
+ rtcp_observer_->SetBandwidthObserver(bandwidth_observer);
feedback_observer_proxy_->SetTransportFeedbackObserver(
transport_feedback_observer);
seq_num_allocator_proxy_->SetSequenceNumberAllocator(packet_router);
@@ -2447,6 +2467,7 @@
void Channel::ResetCongestionControlObjects() {
RTC_DCHECK(packet_router_);
_rtpRtcpModule->SetStorePacketsStatus(false, 600);
+ rtcp_observer_->SetBandwidthObserver(nullptr);
feedback_observer_proxy_->SetTransportFeedbackObserver(nullptr);
seq_num_allocator_proxy_->SetSequenceNumberAllocator(nullptr);
packet_router_->RemoveRtpModule(_rtpRtcpModule.get());
diff --git a/webrtc/voice_engine/channel.h b/webrtc/voice_engine/channel.h
index 62adc5b..c512c08 100644
--- a/webrtc/voice_engine/channel.h
+++ b/webrtc/voice_engine/channel.h
@@ -304,12 +304,13 @@
void EnableSendTransportSequenceNumber(int id);
void EnableReceiveTransportSequenceNumber(int id);
- void RegisterSenderCongestionControlObjects(
- RtpPacketSender* rtp_packet_sender,
- TransportFeedbackObserver* transport_feedback_observer,
- PacketRouter* packet_router);
- void RegisterReceiverCongestionControlObjects(PacketRouter* packet_router);
- void ResetCongestionControlObjects();
+ void RegisterSenderCongestionControlObjects(
+ RtpPacketSender* rtp_packet_sender,
+ TransportFeedbackObserver* transport_feedback_observer,
+ PacketRouter* packet_router,
+ RtcpBandwidthObserver* bandwidth_observer);
+ void RegisterReceiverCongestionControlObjects(PacketRouter* packet_router);
+ void ResetCongestionControlObjects();
void SetRTCPStatus(bool enable);
int GetRTCPStatus(bool& enabled);
diff --git a/webrtc/voice_engine/channel_proxy.cc b/webrtc/voice_engine/channel_proxy.cc
index e5e3804..a58b2e1 100644
--- a/webrtc/voice_engine/channel_proxy.cc
+++ b/webrtc/voice_engine/channel_proxy.cc
@@ -75,10 +75,12 @@
void ChannelProxy::RegisterSenderCongestionControlObjects(
RtpPacketSender* rtp_packet_sender,
TransportFeedbackObserver* transport_feedback_observer,
- PacketRouter* packet_router) {
+ PacketRouter* packet_router,
+ RtcpBandwidthObserver* bandwidth_observer) {
RTC_DCHECK(thread_checker_.CalledOnValidThread());
channel()->RegisterSenderCongestionControlObjects(
- rtp_packet_sender, transport_feedback_observer, packet_router);
+ rtp_packet_sender, transport_feedback_observer, packet_router,
+ bandwidth_observer);
}
void ChannelProxy::RegisterReceiverCongestionControlObjects(
diff --git a/webrtc/voice_engine/channel_proxy.h b/webrtc/voice_engine/channel_proxy.h
index 20aba6f..966abc4 100644
--- a/webrtc/voice_engine/channel_proxy.h
+++ b/webrtc/voice_engine/channel_proxy.h
@@ -27,6 +27,7 @@
class AudioSinkInterface;
class PacketRouter;
class RtcEventLog;
+class RtcpBandwidthObserver;
class RtcpRttStats;
class RtpPacketSender;
class RtpReceiver;
@@ -62,7 +63,8 @@
virtual void RegisterSenderCongestionControlObjects(
RtpPacketSender* rtp_packet_sender,
TransportFeedbackObserver* transport_feedback_observer,
- PacketRouter* packet_router);
+ PacketRouter* packet_router,
+ RtcpBandwidthObserver* bandwidth_observer);
virtual void RegisterReceiverCongestionControlObjects(
PacketRouter* packet_router);
virtual void ResetCongestionControlObjects();