aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Holmer <stefan@webrtc.org>2016-01-12 13:55:00 +0100
committerStefan Holmer <stefan@webrtc.org>2016-01-12 12:55:11 +0000
commit3842c5c7f73639527e653f41c65334245d2317a1 (patch)
treeeb9ca7c050f67009b9f5e2be39058810b0f790ad
parent6183de6da0b6a6772b4aafb9a1c49f2dc856b6ea (diff)
downloadwebrtc-3842c5c7f73639527e653f41c65334245d2317a1.tar.gz
Wire-up BWE feedback for audio receive streams.
Also wires up receiving transport sequence numbers. BUG=webrtc:5263 R=mflodman@webrtc.org, pbos@webrtc.org, solenberg@webrtc.org Review URL: https://codereview.webrtc.org/1535963002 . Cr-Commit-Position: refs/heads/master@{#11220}
-rw-r--r--webrtc/audio/audio_receive_stream.cc52
-rw-r--r--webrtc/audio/audio_receive_stream.h5
-rw-r--r--webrtc/audio/audio_receive_stream_unittest.cc155
-rw-r--r--webrtc/audio/audio_send_stream_unittest.cc11
-rw-r--r--webrtc/audio_receive_stream.h6
-rw-r--r--webrtc/call/call.cc3
-rw-r--r--webrtc/call/congestion_controller.h40
-rw-r--r--webrtc/call/mock/mock_congestion_controller.h52
-rw-r--r--webrtc/modules/bitrate_controller/include/mock/mock_bitrate_controller.h30
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_utility.cc11
-rw-r--r--webrtc/voice_engine/channel.cc19
11 files changed, 295 insertions, 89 deletions
diff --git a/webrtc/audio/audio_receive_stream.cc b/webrtc/audio/audio_receive_stream.cc
index dfad79f9d7..64d008326d 100644
--- a/webrtc/audio/audio_receive_stream.cc
+++ b/webrtc/audio/audio_receive_stream.cc
@@ -18,6 +18,7 @@
#include "webrtc/audio/conversion.h"
#include "webrtc/base/checks.h"
#include "webrtc/base/logging.h"
+#include "webrtc/call/congestion_controller.h"
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "webrtc/system_wrappers/include/tick_util.h"
#include "webrtc/voice_engine/channel_proxy.h"
@@ -30,6 +31,21 @@
#include "webrtc/voice_engine/voice_engine_impl.h"
namespace webrtc {
+namespace {
+
+bool UseSendSideBwe(const webrtc::AudioReceiveStream::Config& config) {
+ if (!config.rtp.transport_cc) {
+ return false;
+ }
+ for (const auto& extension : config.rtp.extensions) {
+ if (extension.name == RtpExtension::kTransportSequenceNumber) {
+ return true;
+ }
+ }
+ return false;
+}
+} // namespace
+
std::string AudioReceiveStream::Config::Rtp::ToString() const {
std::stringstream ss;
ss << "{remote_ssrc: " << remote_ssrc;
@@ -65,17 +81,16 @@ std::string AudioReceiveStream::Config::ToString() const {
namespace internal {
AudioReceiveStream::AudioReceiveStream(
- RemoteBitrateEstimator* remote_bitrate_estimator,
+ CongestionController* congestion_controller,
const webrtc::AudioReceiveStream::Config& config,
const rtc::scoped_refptr<webrtc::AudioState>& audio_state)
- : remote_bitrate_estimator_(remote_bitrate_estimator),
- config_(config),
+ : config_(config),
audio_state_(audio_state),
rtp_header_parser_(RtpHeaderParser::Create()) {
LOG(LS_INFO) << "AudioReceiveStream: " << config_.ToString();
RTC_DCHECK_NE(config_.voe_channel_id, -1);
- RTC_DCHECK(remote_bitrate_estimator_);
RTC_DCHECK(audio_state_.get());
+ RTC_DCHECK(congestion_controller);
RTC_DCHECK(rtp_header_parser_);
VoiceEngineImpl* voe_impl = static_cast<VoiceEngineImpl*>(voice_engine());
@@ -93,8 +108,6 @@ AudioReceiveStream::AudioReceiveStream(
kRtpExtensionAbsoluteSendTime, extension.id);
RTC_DCHECK(registered);
} else if (extension.name == RtpExtension::kTransportSequenceNumber) {
- // TODO(holmer): Need to do something here or in DeliverRtp() to actually
- // handle audio packets with this header extension.
bool registered = rtp_header_parser_->RegisterRtpHeaderExtension(
kRtpExtensionTransportSequenceNumber, extension.id);
RTC_DCHECK(registered);
@@ -102,11 +115,28 @@ AudioReceiveStream::AudioReceiveStream(
RTC_NOTREACHED() << "Unsupported RTP extension.";
}
}
+ // Configure bandwidth estimation.
+ channel_proxy_->SetCongestionControlObjects(
+ nullptr, nullptr, congestion_controller->packet_router());
+ if (config.combined_audio_video_bwe) {
+ if (UseSendSideBwe(config)) {
+ remote_bitrate_estimator_ =
+ congestion_controller->GetRemoteBitrateEstimator(true);
+ } else {
+ remote_bitrate_estimator_ =
+ congestion_controller->GetRemoteBitrateEstimator(false);
+ }
+ RTC_DCHECK(remote_bitrate_estimator_);
+ }
}
AudioReceiveStream::~AudioReceiveStream() {
RTC_DCHECK(thread_checker_.CalledOnValidThread());
LOG(LS_INFO) << "~AudioReceiveStream: " << config_.ToString();
+ channel_proxy_->SetCongestionControlObjects(nullptr, nullptr, nullptr);
+ if (remote_bitrate_estimator_) {
+ remote_bitrate_estimator_->RemoveStream(config_.rtp.remote_ssrc);
+ }
}
void AudioReceiveStream::Start() {
@@ -141,10 +171,12 @@ bool AudioReceiveStream::DeliverRtp(const uint8_t* packet,
return false;
}
- // Only forward if the parsed header has absolute sender time. RTP timestamps
- // may have different rates for audio and video and shouldn't be mixed.
- if (config_.combined_audio_video_bwe &&
- header.extension.hasAbsoluteSendTime) {
+ // Only forward if the parsed header has one of the headers necessary for
+ // bandwidth estimation. RTP timestamps has different rates for audio and
+ // video and shouldn't be mixed.
+ if (remote_bitrate_estimator_ &&
+ (header.extension.hasAbsoluteSendTime ||
+ header.extension.hasTransportSequenceNumber)) {
int64_t arrival_time_ms = TickTime::MillisecondTimestamp();
if (packet_time.timestamp >= 0)
arrival_time_ms = (packet_time.timestamp + 500) / 1000;
diff --git a/webrtc/audio/audio_receive_stream.h b/webrtc/audio/audio_receive_stream.h
index 42286af22b..4940c6a64c 100644
--- a/webrtc/audio/audio_receive_stream.h
+++ b/webrtc/audio/audio_receive_stream.h
@@ -17,6 +17,7 @@
#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
namespace webrtc {
+class CongestionController;
class RemoteBitrateEstimator;
namespace voe {
@@ -27,7 +28,7 @@ namespace internal {
class AudioReceiveStream final : public webrtc::AudioReceiveStream {
public:
- AudioReceiveStream(RemoteBitrateEstimator* remote_bitrate_estimator,
+ AudioReceiveStream(CongestionController* congestion_controller,
const webrtc::AudioReceiveStream::Config& config,
const rtc::scoped_refptr<webrtc::AudioState>& audio_state);
~AudioReceiveStream() override;
@@ -52,7 +53,7 @@ class AudioReceiveStream final : public webrtc::AudioReceiveStream {
VoiceEngine* voice_engine() const;
rtc::ThreadChecker thread_checker_;
- RemoteBitrateEstimator* const remote_bitrate_estimator_;
+ RemoteBitrateEstimator* remote_bitrate_estimator_ = nullptr;
const webrtc::AudioReceiveStream::Config config_;
rtc::scoped_refptr<webrtc::AudioState> audio_state_;
rtc::scoped_ptr<RtpHeaderParser> rtp_header_parser_;
diff --git a/webrtc/audio/audio_receive_stream_unittest.cc b/webrtc/audio/audio_receive_stream_unittest.cc
index 01e8a2b76f..eb008b3045 100644
--- a/webrtc/audio/audio_receive_stream_unittest.cc
+++ b/webrtc/audio/audio_receive_stream_unittest.cc
@@ -14,10 +14,16 @@
#include "webrtc/audio/audio_receive_stream.h"
#include "webrtc/audio/conversion.h"
+#include "webrtc/call/mock/mock_congestion_controller.h"
+#include "webrtc/modules/bitrate_controller/include/mock/mock_bitrate_controller.h"
+#include "webrtc/modules/pacing/packet_router.h"
#include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_estimator.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+#include "webrtc/modules/utility/include/mock/mock_process_thread.h"
+#include "webrtc/system_wrappers/include/clock.h"
#include "webrtc/test/mock_voe_channel_proxy.h"
#include "webrtc/test/mock_voice_engine.h"
+#include "webrtc/video/call_stats.h"
namespace webrtc {
namespace test {
@@ -40,9 +46,11 @@ AudioDecodingCallStats MakeAudioDecodeStatsForTest() {
const int kChannelId = 2;
const uint32_t kRemoteSsrc = 1234;
const uint32_t kLocalSsrc = 5678;
-const size_t kAbsoluteSendTimeLength = 4;
+const size_t kOneByteExtensionHeaderLength = 4;
+const size_t kOneByteExtensionLength = 4;
const int kAbsSendTimeId = 2;
const int kAudioLevelId = 3;
+const int kTransportSequenceNumberId = 4;
const int kJitterBufferDelay = -7;
const int kPlayoutBufferDelay = 302;
const unsigned int kSpeechOutputLevel = 99;
@@ -55,7 +63,12 @@ const NetworkStatistics kNetworkStats = {
const AudioDecodingCallStats kAudioDecodeStats = MakeAudioDecodeStatsForTest();
struct ConfigHelper {
- ConfigHelper() {
+ ConfigHelper()
+ : simulated_clock_(123456),
+ call_stats_(&simulated_clock_),
+ congestion_controller_(&process_thread_,
+ &call_stats_,
+ &bitrate_observer_) {
using testing::Invoke;
EXPECT_CALL(voice_engine_,
@@ -77,6 +90,14 @@ struct ConfigHelper {
EXPECT_CALL(*channel_proxy_,
SetReceiveAudioLevelIndicationStatus(true, kAudioLevelId))
.Times(1);
+ EXPECT_CALL(*channel_proxy_, SetCongestionControlObjects(
+ nullptr, nullptr, &packet_router_))
+ .Times(1);
+ EXPECT_CALL(congestion_controller_, packet_router())
+ .WillOnce(Return(&packet_router_));
+ EXPECT_CALL(*channel_proxy_,
+ SetCongestionControlObjects(nullptr, nullptr, nullptr))
+ .Times(1);
return channel_proxy_;
}));
stream_config_.voe_channel_id = kChannelId;
@@ -88,6 +109,9 @@ struct ConfigHelper {
RtpExtension(RtpExtension::kAudioLevel, kAudioLevelId));
}
+ MockCongestionController* congestion_controller() {
+ return &congestion_controller_;
+ }
MockRemoteBitrateEstimator* remote_bitrate_estimator() {
return &remote_bitrate_estimator_;
}
@@ -95,11 +119,19 @@ struct ConfigHelper {
rtc::scoped_refptr<AudioState> audio_state() { return audio_state_; }
MockVoiceEngine& voice_engine() { return voice_engine_; }
+ void SetupMockForBweFeedback(bool send_side_bwe) {
+ EXPECT_CALL(congestion_controller_,
+ GetRemoteBitrateEstimator(send_side_bwe))
+ .WillOnce(Return(&remote_bitrate_estimator_));
+ EXPECT_CALL(remote_bitrate_estimator_,
+ RemoveStream(stream_config_.rtp.remote_ssrc));
+ }
+
void SetupMockForGetStats() {
using testing::DoAll;
using testing::SetArgReferee;
- EXPECT_TRUE(channel_proxy_);
+ ASSERT_TRUE(channel_proxy_);
EXPECT_CALL(*channel_proxy_, GetRTCPStatistics())
.WillOnce(Return(kCallStats));
EXPECT_CALL(*channel_proxy_, GetDelayEstimate())
@@ -116,6 +148,12 @@ struct ConfigHelper {
}
private:
+ SimulatedClock simulated_clock_;
+ CallStats call_stats_;
+ PacketRouter packet_router_;
+ testing::NiceMock<MockBitrateObserver> bitrate_observer_;
+ testing::NiceMock<MockProcessThread> process_thread_;
+ MockCongestionController congestion_controller_;
MockRemoteBitrateEstimator remote_bitrate_estimator_;
testing::StrictMock<MockVoiceEngine> voice_engine_;
rtc::scoped_refptr<AudioState> audio_state_;
@@ -123,39 +161,43 @@ struct ConfigHelper {
testing::StrictMock<MockVoEChannelProxy>* channel_proxy_ = nullptr;
};
-void BuildAbsoluteSendTimeExtension(uint8_t* buffer,
- int id,
- uint32_t abs_send_time) {
- const size_t kRtpOneByteHeaderLength = 4;
+void BuildOneByteExtension(std::vector<uint8_t>::iterator it,
+ int id,
+ uint32_t extension_value,
+ size_t value_length) {
const uint16_t kRtpOneByteHeaderExtensionId = 0xBEDE;
- ByteWriter<uint16_t>::WriteBigEndian(buffer, kRtpOneByteHeaderExtensionId);
-
- const uint32_t kPosLength = 2;
- ByteWriter<uint16_t>::WriteBigEndian(buffer + kPosLength,
- kAbsoluteSendTimeLength / 4);
+ ByteWriter<uint16_t>::WriteBigEndian(&(*it), kRtpOneByteHeaderExtensionId);
+ it += 2;
- const uint8_t kLengthOfData = 3;
- buffer[kRtpOneByteHeaderLength] = (id << 4) + (kLengthOfData - 1);
- ByteWriter<uint32_t, kLengthOfData>::WriteBigEndian(
- buffer + kRtpOneByteHeaderLength + 1, abs_send_time);
+ ByteWriter<uint16_t>::WriteBigEndian(&(*it), kOneByteExtensionLength / 4);
+ it += 2;
+ const size_t kExtensionDataLength = kOneByteExtensionLength - 1;
+ uint32_t shifted_value = extension_value
+ << (8 * (kExtensionDataLength - value_length));
+ *it = (id << 4) + (value_length - 1);
+ ++it;
+ ByteWriter<uint32_t, kExtensionDataLength>::WriteBigEndian(&(*it),
+ shifted_value);
}
-size_t CreateRtpHeaderWithAbsSendTime(uint8_t* header,
- int extension_id,
- uint32_t abs_send_time) {
+std::vector<uint8_t> CreateRtpHeaderWithOneByteExtension(
+ int extension_id,
+ uint32_t extension_value,
+ size_t value_length) {
+ std::vector<uint8_t> header;
+ header.resize(webrtc::kRtpHeaderSize + kOneByteExtensionHeaderLength +
+ kOneByteExtensionLength);
header[0] = 0x80; // Version 2.
header[0] |= 0x10; // Set extension bit.
header[1] = 100; // Payload type.
header[1] |= 0x80; // Marker bit is set.
- ByteWriter<uint16_t>::WriteBigEndian(header + 2, 0x1234); // Sequence number.
- ByteWriter<uint32_t>::WriteBigEndian(header + 4, 0x5678); // Timestamp.
- ByteWriter<uint32_t>::WriteBigEndian(header + 8, 0x4321); // SSRC.
- int32_t rtp_header_length = webrtc::kRtpHeaderSize;
-
- BuildAbsoluteSendTimeExtension(header + rtp_header_length, extension_id,
- abs_send_time);
- rtp_header_length += kAbsoluteSendTimeLength;
- return rtp_header_length;
+ ByteWriter<uint16_t>::WriteBigEndian(&header[2], 0x1234); // Sequence number.
+ ByteWriter<uint32_t>::WriteBigEndian(&header[4], 0x5678); // Timestamp.
+ ByteWriter<uint32_t>::WriteBigEndian(&header[8], 0x4321); // SSRC.
+
+ BuildOneByteExtension(header.begin() + webrtc::kRtpHeaderSize, extension_id,
+ extension_value, value_length);
+ return header;
}
} // namespace
@@ -178,32 +220,73 @@ TEST(AudioReceiveStreamTest, ConfigToString) {
TEST(AudioReceiveStreamTest, ConstructDestruct) {
ConfigHelper helper;
internal::AudioReceiveStream recv_stream(
- helper.remote_bitrate_estimator(), helper.config(), helper.audio_state());
+ helper.congestion_controller(), helper.config(), helper.audio_state());
+}
+
+MATCHER_P(VerifyHeaderExtension, expected_extension, "") {
+ return arg.extension.hasAbsoluteSendTime ==
+ expected_extension.hasAbsoluteSendTime &&
+ arg.extension.absoluteSendTime ==
+ expected_extension.absoluteSendTime &&
+ arg.extension.hasTransportSequenceNumber ==
+ expected_extension.hasTransportSequenceNumber &&
+ arg.extension.transportSequenceNumber ==
+ expected_extension.transportSequenceNumber;
}
TEST(AudioReceiveStreamTest, AudioPacketUpdatesBweWithTimestamp) {
ConfigHelper helper;
helper.config().combined_audio_video_bwe = true;
+ helper.SetupMockForBweFeedback(false);
internal::AudioReceiveStream recv_stream(
- helper.remote_bitrate_estimator(), helper.config(), helper.audio_state());
- uint8_t rtp_packet[30];
+ helper.congestion_controller(), helper.config(), helper.audio_state());
const int kAbsSendTimeValue = 1234;
- CreateRtpHeaderWithAbsSendTime(rtp_packet, kAbsSendTimeId, kAbsSendTimeValue);
+ std::vector<uint8_t> rtp_packet =
+ CreateRtpHeaderWithOneByteExtension(kAbsSendTimeId, kAbsSendTimeValue, 3);
+ PacketTime packet_time(5678000, 0);
+ const size_t kExpectedHeaderLength = 20;
+ RTPHeaderExtension expected_extension;
+ expected_extension.hasAbsoluteSendTime = true;
+ expected_extension.absoluteSendTime = kAbsSendTimeValue;
+ EXPECT_CALL(*helper.remote_bitrate_estimator(),
+ IncomingPacket(packet_time.timestamp / 1000,
+ rtp_packet.size() - kExpectedHeaderLength,
+ VerifyHeaderExtension(expected_extension), false))
+ .Times(1);
+ EXPECT_TRUE(
+ recv_stream.DeliverRtp(&rtp_packet[0], rtp_packet.size(), packet_time));
+}
+
+TEST(AudioReceiveStreamTest, AudioPacketUpdatesBweFeedback) {
+ ConfigHelper helper;
+ helper.config().combined_audio_video_bwe = true;
+ helper.config().rtp.transport_cc = true;
+ helper.config().rtp.extensions.push_back(RtpExtension(
+ RtpExtension::kTransportSequenceNumber, kTransportSequenceNumberId));
+ helper.SetupMockForBweFeedback(true);
+ internal::AudioReceiveStream recv_stream(
+ helper.congestion_controller(), helper.config(), helper.audio_state());
+ const int kTransportSequenceNumberValue = 1234;
+ std::vector<uint8_t> rtp_packet = CreateRtpHeaderWithOneByteExtension(
+ kTransportSequenceNumberId, kTransportSequenceNumberValue, 2);
PacketTime packet_time(5678000, 0);
const size_t kExpectedHeaderLength = 20;
+ RTPHeaderExtension expected_extension;
+ expected_extension.hasTransportSequenceNumber = true;
+ expected_extension.transportSequenceNumber = kTransportSequenceNumberValue;
EXPECT_CALL(*helper.remote_bitrate_estimator(),
IncomingPacket(packet_time.timestamp / 1000,
- sizeof(rtp_packet) - kExpectedHeaderLength,
- testing::_, false))
+ rtp_packet.size() - kExpectedHeaderLength,
+ VerifyHeaderExtension(expected_extension), false))
.Times(1);
EXPECT_TRUE(
- recv_stream.DeliverRtp(rtp_packet, sizeof(rtp_packet), packet_time));
+ recv_stream.DeliverRtp(&rtp_packet[0], rtp_packet.size(), packet_time));
}
TEST(AudioReceiveStreamTest, GetStats) {
ConfigHelper helper;
internal::AudioReceiveStream recv_stream(
- helper.remote_bitrate_estimator(), helper.config(), helper.audio_state());
+ helper.congestion_controller(), helper.config(), helper.audio_state());
helper.SetupMockForGetStats();
AudioReceiveStream::Stats stats = recv_stream.GetStats();
EXPECT_EQ(kRemoteSsrc, stats.remote_ssrc);
diff --git a/webrtc/audio/audio_send_stream_unittest.cc b/webrtc/audio/audio_send_stream_unittest.cc
index 08ff9a6de9..466c1571ac 100644
--- a/webrtc/audio/audio_send_stream_unittest.cc
+++ b/webrtc/audio/audio_send_stream_unittest.cc
@@ -17,7 +17,7 @@
#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/bitrate_controller/include/mock/mock_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"
@@ -154,19 +154,12 @@ struct ConfigHelper {
}
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_;
+ testing::NiceMock<MockBitrateObserver> bitrate_observer_;
rtc::scoped_ptr<ProcessThread> process_thread_;
CongestionController congestion_controller_;
};
diff --git a/webrtc/audio_receive_stream.h b/webrtc/audio_receive_stream.h
index daf45985d3..8cab094f4b 100644
--- a/webrtc/audio_receive_stream.h
+++ b/webrtc/audio_receive_stream.h
@@ -73,6 +73,12 @@ class AudioReceiveStream : public ReceiveStream {
// Sender SSRC used for sending RTCP (such as receiver reports).
uint32_t local_ssrc = 0;
+ // Enable feedback for send side bandwidth estimation.
+ // See
+ // https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions
+ // for details.
+ bool transport_cc = false;
+
// RTP header extensions used for the received stream.
std::vector<RtpExtension> extensions;
} rtp;
diff --git a/webrtc/call/call.cc b/webrtc/call/call.cc
index f8611398c3..5c46a48f14 100644
--- a/webrtc/call/call.cc
+++ b/webrtc/call/call.cc
@@ -336,8 +336,7 @@ webrtc::AudioReceiveStream* Call::CreateAudioReceiveStream(
TRACE_EVENT0("webrtc", "Call::CreateAudioReceiveStream");
RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
AudioReceiveStream* receive_stream = new AudioReceiveStream(
- congestion_controller_->GetRemoteBitrateEstimator(false), config,
- config_.audio_state);
+ congestion_controller_.get(), config, config_.audio_state);
{
WriteLockScoped write_lock(*receive_crit_);
RTC_DCHECK(audio_receive_ssrcs_.find(config.rtp.remote_ssrc) ==
diff --git a/webrtc/call/congestion_controller.h b/webrtc/call/congestion_controller.h
index 98d8e433fd..b77c46faa3 100644
--- a/webrtc/call/congestion_controller.h
+++ b/webrtc/call/congestion_controller.h
@@ -40,28 +40,32 @@ class CongestionController {
public:
CongestionController(ProcessThread* process_thread, CallStats* call_stats,
BitrateObserver* bitrate_observer);
- ~CongestionController();
- void AddEncoder(ViEEncoder* encoder);
- void RemoveEncoder(ViEEncoder* encoder);
- void SetBweBitrates(int min_bitrate_bps,
- int start_bitrate_bps,
- int max_bitrate_bps);
+ virtual ~CongestionController();
+ virtual void AddEncoder(ViEEncoder* encoder);
+ virtual void RemoveEncoder(ViEEncoder* encoder);
+ virtual void SetBweBitrates(int min_bitrate_bps,
+ int start_bitrate_bps,
+ int max_bitrate_bps);
- void SetChannelRembStatus(bool sender, bool receiver, RtpRtcp* rtp_module);
+ virtual void SetChannelRembStatus(bool sender,
+ bool receiver,
+ RtpRtcp* rtp_module);
- void SignalNetworkState(NetworkState state);
+ virtual void SignalNetworkState(NetworkState state);
- BitrateController* GetBitrateController() const;
- RemoteBitrateEstimator* GetRemoteBitrateEstimator(bool send_side_bwe) const;
- int64_t GetPacerQueuingDelayMs() const;
- PacedSender* pacer() const { return pacer_.get(); }
- PacketRouter* packet_router() const { return packet_router_.get(); }
- TransportFeedbackObserver* GetTransportFeedbackObserver();
+ virtual BitrateController* GetBitrateController() const;
+ virtual RemoteBitrateEstimator* GetRemoteBitrateEstimator(
+ bool send_side_bwe) const;
+ virtual int64_t GetPacerQueuingDelayMs() const;
+ virtual PacedSender* pacer() const { return pacer_.get(); }
+ virtual PacketRouter* packet_router() const { return packet_router_.get(); }
+ virtual TransportFeedbackObserver* GetTransportFeedbackObserver();
- void UpdatePacerBitrate(int bitrate_kbps, int max_bitrate_kbps,
- int min_bitrate_kbps);
+ virtual void UpdatePacerBitrate(int bitrate_kbps,
+ int max_bitrate_kbps,
+ int min_bitrate_kbps);
- void OnSentPacket(const rtc::SentPacket& sent_packet);
+ virtual void OnSentPacket(const rtc::SentPacket& sent_packet);
private:
rtc::scoped_ptr<VieRemb> remb_;
@@ -82,6 +86,8 @@ class CongestionController {
rtc::scoped_ptr<BitrateController> bitrate_controller_;
rtc::scoped_ptr<TransportFeedbackAdapter> transport_feedback_adapter_;
int min_bitrate_bps_;
+
+ RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(CongestionController);
};
} // namespace webrtc
diff --git a/webrtc/call/mock/mock_congestion_controller.h b/webrtc/call/mock/mock_congestion_controller.h
new file mode 100644
index 0000000000..54014da339
--- /dev/null
+++ b/webrtc/call/mock/mock_congestion_controller.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_CALL_MOCK_MOCK_CONGESTION_CONTROLLER_H_
+#define WEBRTC_CALL_MOCK_MOCK_CONGESTION_CONTROLLER_H_
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "webrtc/call/congestion_controller.h"
+
+namespace webrtc {
+namespace test {
+
+class MockCongestionController : public CongestionController {
+ public:
+ MockCongestionController(ProcessThread* process_thread,
+ CallStats* call_stats,
+ BitrateObserver* bitrate_observer)
+ : CongestionController(process_thread, call_stats, bitrate_observer) {}
+ MOCK_METHOD1(AddEncoder, void(ViEEncoder* encoder));
+ MOCK_METHOD1(RemoveEncoder, void(ViEEncoder* encoder));
+ MOCK_METHOD3(SetBweBitrates,
+ void(int min_bitrate_bps,
+ int start_bitrate_bps,
+ int max_bitrate_bps));
+ MOCK_METHOD3(SetChannelRembStatus,
+ void(bool sender, bool receiver, RtpRtcp* rtp_module));
+ MOCK_METHOD1(SignalNetworkState, void(NetworkState state));
+ MOCK_CONST_METHOD0(GetBitrateController, BitrateController*());
+ MOCK_CONST_METHOD1(GetRemoteBitrateEstimator,
+ RemoteBitrateEstimator*(bool send_side_bwe));
+ MOCK_CONST_METHOD0(GetPacerQueuingDelayMs, int64_t());
+ MOCK_CONST_METHOD0(pacer, PacedSender*());
+ MOCK_CONST_METHOD0(packet_router, PacketRouter*());
+ MOCK_METHOD0(GetTransportFeedbackObserver, TransportFeedbackObserver*());
+ MOCK_METHOD3(UpdatePacerBitrate,
+ void(int bitrate_kbps,
+ int max_bitrate_kbps,
+ int min_bitrate_kbps));
+ MOCK_METHOD1(OnSentPacket, void(const rtc::SentPacket& sent_packet));
+
+ RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(MockCongestionController);
+};
+} // namespace test
+} // namespace webrtc
+#endif // WEBRTC_CALL_MOCK_MOCK_CONGESTION_CONTROLLER_H_
diff --git a/webrtc/modules/bitrate_controller/include/mock/mock_bitrate_controller.h b/webrtc/modules/bitrate_controller/include/mock/mock_bitrate_controller.h
new file mode 100644
index 0000000000..7a7d2e406b
--- /dev/null
+++ b/webrtc/modules/bitrate_controller/include/mock/mock_bitrate_controller.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_MODULES_BITRATE_CONTROLLER_INCLUDE_MOCK_MOCK_BITRATE_CONTROLLER_H_
+#define WEBRTC_MODULES_BITRATE_CONTROLLER_INCLUDE_MOCK_MOCK_BITRATE_CONTROLLER_H_
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
+
+namespace webrtc {
+namespace test {
+
+class MockBitrateObserver : public BitrateObserver {
+ public:
+ MOCK_METHOD3(OnNetworkChanged,
+ void(uint32_t bitrate_bps,
+ uint8_t fraction_loss,
+ int64_t rtt_ms));
+};
+} // namespace test
+} // namespace webrtc
+
+#endif // WEBRTC_MODULES_BITRATE_CONTROLLER_INCLUDE_MOCK_MOCK_BITRATE_CONTROLLER_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_utility.cc b/webrtc/modules/rtp_rtcp/source/rtp_utility.cc
index 43433b94d9..0f0ad835b1 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_utility.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_utility.cc
@@ -314,8 +314,8 @@ void RtpHeaderParser::ParseOneByteExtensionHeader(
// Note that 'len' is the header extension element length, which is the
// number of bytes - 1.
- const uint8_t id = (*ptr & 0xf0) >> 4;
- const uint8_t len = (*ptr & 0x0f);
+ const int id = (*ptr & 0xf0) >> 4;
+ const int len = (*ptr & 0x0f);
ptr++;
if (id == 15) {
@@ -327,8 +327,7 @@ void RtpHeaderParser::ParseOneByteExtensionHeader(
RTPExtensionType type;
if (ptrExtensionMap->GetType(id, &type) != 0) {
// If we encounter an unknown extension, just skip over it.
- LOG(LS_WARNING) << "Failed to find extension id: "
- << static_cast<int>(id);
+ LOG(LS_WARNING) << "Failed to find extension id: " << id;
} else {
switch (type) {
case kRtpExtensionTransmissionTimeOffset: {
@@ -397,8 +396,8 @@ void RtpHeaderParser::ParseOneByteExtensionHeader(
}
case kRtpExtensionTransportSequenceNumber: {
if (len != 1) {
- LOG(LS_WARNING)
- << "Incorrect peer connection sequence number len: " << len;
+ LOG(LS_WARNING) << "Incorrect transport sequence number len: "
+ << len;
return;
}
// 0 1 2
diff --git a/webrtc/voice_engine/channel.cc b/webrtc/voice_engine/channel.cc
index 48111dbb67..64b40a864b 100644
--- a/webrtc/voice_engine/channel.cc
+++ b/webrtc/voice_engine/channel.cc
@@ -2927,14 +2927,19 @@ void Channel::SetCongestionControlObjects(
RtpPacketSender* rtp_packet_sender,
TransportFeedbackObserver* transport_feedback_observer,
PacketRouter* packet_router) {
- RTC_DCHECK(feedback_observer_proxy_.get());
- RTC_DCHECK(seq_num_allocator_proxy_.get());
- RTC_DCHECK(rtp_packet_sender_proxy_.get());
RTC_DCHECK(packet_router != nullptr || packet_router_ != nullptr);
- feedback_observer_proxy_->SetTransportFeedbackObserver(
- transport_feedback_observer);
- seq_num_allocator_proxy_->SetSequenceNumberAllocator(packet_router);
- rtp_packet_sender_proxy_->SetPacketSender(rtp_packet_sender);
+ if (transport_feedback_observer) {
+ RTC_DCHECK(feedback_observer_proxy_.get());
+ feedback_observer_proxy_->SetTransportFeedbackObserver(
+ transport_feedback_observer);
+ }
+ if (rtp_packet_sender) {
+ RTC_DCHECK(rtp_packet_sender_proxy_.get());
+ rtp_packet_sender_proxy_->SetPacketSender(rtp_packet_sender);
+ }
+ if (seq_num_allocator_proxy_.get()) {
+ seq_num_allocator_proxy_->SetSequenceNumberAllocator(packet_router);
+ }
_rtpRtcpModule->SetStorePacketsStatus(rtp_packet_sender != nullptr, 600);
if (packet_router != nullptr) {
packet_router->AddRtpModule(_rtpRtcpModule.get());