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:
@ -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;
|
||||
|
@ -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_;
|
||||
|
@ -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);
|
||||
|
@ -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_;
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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) ==
|
||||
|
@ -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
|
||||
|
52
webrtc/call/mock/mock_congestion_controller.h
Normal file
52
webrtc/call/mock/mock_congestion_controller.h
Normal 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_
|
@ -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_
|
@ -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
|
||||
|
@ -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());
|
||||
|
Reference in New Issue
Block a user