Prepare the AudioSendStream to be hooked up to send-side BWE.
This CL contains three changes as a preparation for adding audio send streams
to the send-side BWE:
1. Audio packets are passed through the pacer with high priority. This
is needed to be able to set transport sequence numbers on the packets.
2. A feedback observer is passed to the audio stream's rtcp receiver so
that the BWE can get notified of any BWE feedback being received on the
audio feedback channel.
3. Support for the transport sequence number header extension is added
to audio send streams.
BUG=webrtc:5263,webrtc:5307
R=mflodman@webrtc.org, solenberg@webrtc.org
Review URL: https://codereview.webrtc.org/1479023002 .
Cr-Commit-Position: refs/heads/master@{#10909}
diff --git a/webrtc/audio/audio_send_stream.cc b/webrtc/audio/audio_send_stream.cc
index 2ff388b..35a6552 100644
--- a/webrtc/audio/audio_send_stream.cc
+++ b/webrtc/audio/audio_send_stream.cc
@@ -17,6 +17,9 @@
#include "webrtc/audio/scoped_voe_interface.h"
#include "webrtc/base/checks.h"
#include "webrtc/base/logging.h"
+#include "webrtc/call/congestion_controller.h"
+#include "webrtc/modules/pacing/paced_sender.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/voice_engine/channel_proxy.h"
#include "webrtc/voice_engine/include/voe_audio_processing.h"
#include "webrtc/voice_engine/include/voe_codec.h"
@@ -55,22 +58,31 @@
namespace internal {
AudioSendStream::AudioSendStream(
const webrtc::AudioSendStream::Config& config,
- const rtc::scoped_refptr<webrtc::AudioState>& audio_state)
+ const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
+ CongestionController* congestion_controller)
: config_(config), audio_state_(audio_state) {
LOG(LS_INFO) << "AudioSendStream: " << config_.ToString();
RTC_DCHECK_NE(config_.voe_channel_id, -1);
RTC_DCHECK(audio_state_.get());
+ RTC_DCHECK(congestion_controller);
VoiceEngineImpl* voe_impl = static_cast<VoiceEngineImpl*>(voice_engine());
channel_proxy_ = voe_impl->GetChannelProxy(config_.voe_channel_id);
+ channel_proxy_->SetCongestionControlObjects(
+ congestion_controller->pacer(),
+ congestion_controller->GetTransportFeedbackObserver(),
+ congestion_controller->packet_router());
channel_proxy_->SetRTCPStatus(true);
channel_proxy_->SetLocalSSRC(config.rtp.ssrc);
channel_proxy_->SetRTCP_CNAME(config.rtp.c_name);
+
for (const auto& extension : config.rtp.extensions) {
if (extension.name == RtpExtension::kAbsSendTime) {
channel_proxy_->SetSendAbsoluteSenderTimeStatus(true, extension.id);
} else if (extension.name == RtpExtension::kAudioLevel) {
channel_proxy_->SetSendAudioLevelIndicationStatus(true, extension.id);
+ } else if (extension.name == RtpExtension::kTransportSequenceNumber) {
+ channel_proxy_->EnableSendTransportSequenceNumber(extension.id);
} else {
RTC_NOTREACHED() << "Registering unsupported RTP extension.";
}
@@ -80,6 +92,7 @@
AudioSendStream::~AudioSendStream() {
RTC_DCHECK(thread_checker_.CalledOnValidThread());
LOG(LS_INFO) << "~AudioSendStream: " << config_.ToString();
+ channel_proxy_->SetCongestionControlObjects(nullptr, nullptr, nullptr);
}
void AudioSendStream::Start() {
diff --git a/webrtc/audio/audio_send_stream.h b/webrtc/audio/audio_send_stream.h
index 88304fd..8b96350 100644
--- a/webrtc/audio/audio_send_stream.h
+++ b/webrtc/audio/audio_send_stream.h
@@ -17,6 +17,7 @@
#include "webrtc/base/scoped_ptr.h"
namespace webrtc {
+class CongestionController;
class VoiceEngine;
namespace voe {
@@ -27,7 +28,8 @@
class AudioSendStream final : public webrtc::AudioSendStream {
public:
AudioSendStream(const webrtc::AudioSendStream::Config& config,
- const rtc::scoped_refptr<webrtc::AudioState>& audio_state);
+ const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
+ CongestionController* congestion_controller);
~AudioSendStream() override;
// webrtc::SendStream implementation.
diff --git a/webrtc/audio/audio_send_stream_unittest.cc b/webrtc/audio/audio_send_stream_unittest.cc
index c3620b2..f907575 100644
--- a/webrtc/audio/audio_send_stream_unittest.cc
+++ b/webrtc/audio/audio_send_stream_unittest.cc
@@ -16,8 +16,12 @@
#include "webrtc/audio/audio_send_stream.h"
#include "webrtc/audio/audio_state.h"
#include "webrtc/audio/conversion.h"
+#include "webrtc/call/congestion_controller.h"
+#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
+#include "webrtc/modules/pacing/paced_sender.h"
#include "webrtc/test/mock_voe_channel_proxy.h"
#include "webrtc/test/mock_voice_engine.h"
+#include "webrtc/video_engine/call_stats.h"
namespace webrtc {
namespace test {
@@ -31,6 +35,7 @@
const char* kCName = "foo_name";
const int kAudioLevelId = 2;
const int kAbsSendTimeId = 3;
+const int kTransportSequenceNumberId = 4;
const int kEchoDelayMedian = 254;
const int kEchoDelayStdDev = -3;
const int kEchoReturnLoss = -65;
@@ -45,7 +50,12 @@
const uint32_t kTelephoneEventDuration = 6789;
struct ConfigHelper {
- ConfigHelper() : stream_config_(nullptr) {
+ ConfigHelper()
+ : stream_config_(nullptr),
+ process_thread_(ProcessThread::Create("AudioTestThread")),
+ congestion_controller_(process_thread_.get(),
+ &call_stats_,
+ &bitrate_observer_) {
using testing::Invoke;
using testing::StrEq;
@@ -68,6 +78,18 @@
SetSendAbsoluteSenderTimeStatus(true, kAbsSendTimeId)).Times(1);
EXPECT_CALL(*channel_proxy_,
SetSendAudioLevelIndicationStatus(true, kAudioLevelId)).Times(1);
+ EXPECT_CALL(*channel_proxy_, EnableSendTransportSequenceNumber(
+ kTransportSequenceNumberId))
+ .Times(1);
+ EXPECT_CALL(*channel_proxy_,
+ SetCongestionControlObjects(
+ congestion_controller_.pacer(),
+ congestion_controller_.GetTransportFeedbackObserver(),
+ congestion_controller_.packet_router()))
+ .Times(1);
+ EXPECT_CALL(*channel_proxy_,
+ SetCongestionControlObjects(nullptr, nullptr, nullptr))
+ .Times(1);
return channel_proxy_;
}));
stream_config_.voe_channel_id = kChannelId;
@@ -77,10 +99,15 @@
RtpExtension(RtpExtension::kAudioLevel, kAudioLevelId));
stream_config_.rtp.extensions.push_back(
RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeId));
+ stream_config_.rtp.extensions.push_back(RtpExtension(
+ RtpExtension::kTransportSequenceNumber, kTransportSequenceNumberId));
}
AudioSendStream::Config& config() { return stream_config_; }
rtc::scoped_refptr<AudioState> audio_state() { return audio_state_; }
+ CongestionController* congestion_controller() {
+ return &congestion_controller_;
+ }
void SetupMockForSendTelephoneEvent() {
EXPECT_TRUE(channel_proxy_);
@@ -126,10 +153,21 @@
}
private:
+ class NullBitrateObserver : public BitrateObserver {
+ public:
+ virtual void OnNetworkChanged(uint32_t bitrate_bps,
+ uint8_t fraction_loss,
+ int64_t rtt_ms) {}
+ };
+
testing::StrictMock<MockVoiceEngine> voice_engine_;
rtc::scoped_refptr<AudioState> audio_state_;
AudioSendStream::Config stream_config_;
testing::StrictMock<MockVoEChannelProxy>* channel_proxy_ = nullptr;
+ CallStats call_stats_;
+ NullBitrateObserver bitrate_observer_;
+ rtc::scoped_ptr<ProcessThread> process_thread_;
+ CongestionController congestion_controller_;
};
} // namespace
@@ -152,12 +190,14 @@
TEST(AudioSendStreamTest, ConstructDestruct) {
ConfigHelper helper;
- internal::AudioSendStream send_stream(helper.config(), helper.audio_state());
+ internal::AudioSendStream send_stream(helper.config(), helper.audio_state(),
+ helper.congestion_controller());
}
TEST(AudioSendStreamTest, SendTelephoneEvent) {
ConfigHelper helper;
- internal::AudioSendStream send_stream(helper.config(), helper.audio_state());
+ internal::AudioSendStream send_stream(helper.config(), helper.audio_state(),
+ helper.congestion_controller());
helper.SetupMockForSendTelephoneEvent();
EXPECT_TRUE(send_stream.SendTelephoneEvent(kTelephoneEventPayloadType,
kTelephoneEventCode, kTelephoneEventDuration));
@@ -165,7 +205,8 @@
TEST(AudioSendStreamTest, GetStats) {
ConfigHelper helper;
- internal::AudioSendStream send_stream(helper.config(), helper.audio_state());
+ internal::AudioSendStream send_stream(helper.config(), helper.audio_state(),
+ helper.congestion_controller());
helper.SetupMockForGetStats();
AudioSendStream::Stats stats = send_stream.GetStats();
EXPECT_EQ(kSsrc, stats.local_ssrc);
@@ -192,7 +233,8 @@
TEST(AudioSendStreamTest, GetStatsTypingNoiseDetected) {
ConfigHelper helper;
- internal::AudioSendStream send_stream(helper.config(), helper.audio_state());
+ internal::AudioSendStream send_stream(helper.config(), helper.audio_state(),
+ helper.congestion_controller());
helper.SetupMockForGetStats();
EXPECT_FALSE(send_stream.GetStats().typing_noise_detected);