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}
This commit is contained in:
Stefan Holmer
2016-01-12 13:55:00 +01:00
parent 6183de6da0
commit 3842c5c7f7
11 changed files with 294 additions and 88 deletions

View File

@ -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;

View File

@ -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_;

View File

@ -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);
ByteWriter<uint16_t>::WriteBigEndian(&(*it), kRtpOneByteHeaderExtensionId);
it += 2;
const uint32_t kPosLength = 2;
ByteWriter<uint16_t>::WriteBigEndian(buffer + kPosLength,
kAbsoluteSendTimeLength / 4);
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;
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.
BuildAbsoluteSendTimeExtension(header + rtp_header_length, extension_id,
abs_send_time);
rtp_header_length += kAbsoluteSendTimeLength;
return rtp_header_length;
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,
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, 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,
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, 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);

View File

@ -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_;
};

View File

@ -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;

View File

@ -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) ==

View File

@ -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

View File

@ -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_

View File

@ -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_

View File

@ -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

View File

@ -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());