mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 05:40:42 +01:00
Revert "Remove the injectable bitrate allocation strategy API."
This reverts commit 80cb3f6db6
.
Reason for revert: Performance regression on downstream project.
Original change's description:
> Remove the injectable bitrate allocation strategy API.
>
> This removes PeerConnectionInterface::SetBitrateAllocationStrategy()
> plus a ton of now-dead code.
>
> Bug: webrtc:10556
> Change-Id: Icfae3bdd011588552934d9db4df16000847db7c3
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/133169
> Reviewed-by: Henrik Andreassson <henrika@webrtc.org>
> Reviewed-by: Niels Moller <nisse@webrtc.org>
> Reviewed-by: Sebastian Jansson <srte@webrtc.org>
> Commit-Queue: Jonas Olsson <jonasolsson@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#28523}
TBR=henrika@webrtc.org,kwiberg@webrtc.org,nisse@webrtc.org,srte@webrtc.org,alexnarest@webrtc.org,jonasolsson@webrtc.org
# Not skipping CQ checks because original CL landed > 1 day ago.
Bug: webrtc:10556
Change-Id: Ife905d661e7b1a227662395c729a9336c62fd2d7
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/145338
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28560}
This commit is contained in:
parent
2c850afe8d
commit
e95b57cdfc
34 changed files with 847 additions and 81 deletions
1
api/DEPS
1
api/DEPS
|
@ -120,6 +120,7 @@ specific_include_rules = {
|
||||||
"+media/base/media_config.h",
|
"+media/base/media_config.h",
|
||||||
"+media/base/media_engine.h",
|
"+media/base/media_engine.h",
|
||||||
"+p2p/base/port_allocator.h",
|
"+p2p/base/port_allocator.h",
|
||||||
|
"+rtc_base/bitrate_allocation_strategy.h",
|
||||||
"+rtc_base/network.h",
|
"+rtc_base/network.h",
|
||||||
"+rtc_base/rtc_certificate.h",
|
"+rtc_base/rtc_certificate.h",
|
||||||
"+rtc_base/rtc_certificate_generator.h",
|
"+rtc_base/rtc_certificate_generator.h",
|
||||||
|
|
|
@ -105,6 +105,8 @@
|
||||||
// PortAllocator in the PeerConnection api.
|
// PortAllocator in the PeerConnection api.
|
||||||
#include "media/base/media_engine.h" // nogncheck
|
#include "media/base/media_engine.h" // nogncheck
|
||||||
#include "p2p/base/port_allocator.h" // nogncheck
|
#include "p2p/base/port_allocator.h" // nogncheck
|
||||||
|
// TODO(nisse): The interface for bitrate allocation strategy belongs in api/.
|
||||||
|
#include "rtc_base/bitrate_allocation_strategy.h"
|
||||||
#include "rtc_base/network.h"
|
#include "rtc_base/network.h"
|
||||||
#include "rtc_base/rtc_certificate.h"
|
#include "rtc_base/rtc_certificate.h"
|
||||||
#include "rtc_base/rtc_certificate_generator.h"
|
#include "rtc_base/rtc_certificate_generator.h"
|
||||||
|
@ -1034,6 +1036,14 @@ class RTC_EXPORT PeerConnectionInterface : public rtc::RefCountInterface {
|
||||||
// of the methods.
|
// of the methods.
|
||||||
virtual RTCError SetBitrate(const BitrateParameters& bitrate_parameters);
|
virtual RTCError SetBitrate(const BitrateParameters& bitrate_parameters);
|
||||||
|
|
||||||
|
// Sets current strategy. If not set default WebRTC allocator will be used.
|
||||||
|
// May be changed during an active session. The strategy
|
||||||
|
// ownership is passed with std::unique_ptr
|
||||||
|
// TODO(alexnarest): Make this pure virtual when tests will be updated
|
||||||
|
virtual void SetBitrateAllocationStrategy(
|
||||||
|
std::unique_ptr<rtc::BitrateAllocationStrategy>
|
||||||
|
bitrate_allocation_strategy) {}
|
||||||
|
|
||||||
// Enable/disable playout of received audio streams. Enabled by default. Note
|
// Enable/disable playout of received audio streams. Enabled by default. Note
|
||||||
// that even if playout is enabled, streams will only be played out if the
|
// that even if playout is enabled, streams will only be played out if the
|
||||||
// appropriate SDP is also applied. Setting |playout| to false will stop
|
// appropriate SDP is also applied. Setting |playout| to false will stop
|
||||||
|
|
|
@ -117,6 +117,9 @@ PROXY_METHOD1(bool,
|
||||||
PROXY_METHOD1(bool, AddIceCandidate, const IceCandidateInterface*)
|
PROXY_METHOD1(bool, AddIceCandidate, const IceCandidateInterface*)
|
||||||
PROXY_METHOD1(bool, RemoveIceCandidates, const std::vector<cricket::Candidate>&)
|
PROXY_METHOD1(bool, RemoveIceCandidates, const std::vector<cricket::Candidate>&)
|
||||||
PROXY_METHOD1(RTCError, SetBitrate, const BitrateSettings&)
|
PROXY_METHOD1(RTCError, SetBitrate, const BitrateSettings&)
|
||||||
|
PROXY_METHOD1(void,
|
||||||
|
SetBitrateAllocationStrategy,
|
||||||
|
std::unique_ptr<rtc::BitrateAllocationStrategy>)
|
||||||
PROXY_METHOD1(void, SetAudioPlayout, bool)
|
PROXY_METHOD1(void, SetAudioPlayout, bool)
|
||||||
PROXY_METHOD1(void, SetAudioRecording, bool)
|
PROXY_METHOD1(void, SetAudioRecording, bool)
|
||||||
PROXY_METHOD1(rtc::scoped_refptr<DtlsTransportInterface>,
|
PROXY_METHOD1(rtc::scoped_refptr<DtlsTransportInterface>,
|
||||||
|
|
|
@ -117,6 +117,8 @@ class MockPeerConnectionInterface
|
||||||
bool(const std::vector<cricket::Candidate>&));
|
bool(const std::vector<cricket::Candidate>&));
|
||||||
MOCK_METHOD1(SetBitrate, RTCError(const BitrateSettings&));
|
MOCK_METHOD1(SetBitrate, RTCError(const BitrateSettings&));
|
||||||
MOCK_METHOD1(SetBitrate, RTCError(const BitrateParameters&));
|
MOCK_METHOD1(SetBitrate, RTCError(const BitrateParameters&));
|
||||||
|
MOCK_METHOD1(SetBitrateAllocationStrategy,
|
||||||
|
void(std::unique_ptr<rtc::BitrateAllocationStrategy>));
|
||||||
MOCK_METHOD1(SetAudioPlayout, void(bool));
|
MOCK_METHOD1(SetAudioPlayout, void(bool));
|
||||||
MOCK_METHOD1(SetAudioRecording, void(bool));
|
MOCK_METHOD1(SetAudioRecording, void(bool));
|
||||||
MOCK_METHOD0(signaling_state, SignalingState());
|
MOCK_METHOD0(signaling_state, SignalingState());
|
||||||
|
|
|
@ -827,6 +827,7 @@ void AudioSendStream::ConfigureBitrateObserver() {
|
||||||
MediaStreamAllocationConfig{
|
MediaStreamAllocationConfig{
|
||||||
constraints.min.bps<uint32_t>(), constraints.max.bps<uint32_t>(), 0,
|
constraints.min.bps<uint32_t>(), constraints.max.bps<uint32_t>(), 0,
|
||||||
allocation_settings_.DefaultPriorityBitrate().bps(), true,
|
allocation_settings_.DefaultPriorityBitrate().bps(), true,
|
||||||
|
config_.track_id,
|
||||||
allocation_settings_.BitratePriority().value_or(
|
allocation_settings_.BitratePriority().value_or(
|
||||||
config_.bitrate_priority)});
|
config_.bitrate_priority)});
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,8 +64,11 @@ BitrateAllocator::BitrateAllocator(Clock* clock, LimitObserver* limit_observer)
|
||||||
total_requested_padding_bitrate_(0),
|
total_requested_padding_bitrate_(0),
|
||||||
total_requested_min_bitrate_(0),
|
total_requested_min_bitrate_(0),
|
||||||
total_requested_max_bitrate_(0),
|
total_requested_max_bitrate_(0),
|
||||||
|
bitrate_allocation_strategy_(nullptr),
|
||||||
transmission_max_bitrate_multiplier_(
|
transmission_max_bitrate_multiplier_(
|
||||||
GetTransmissionMaxBitrateMultiplier()) {
|
GetTransmissionMaxBitrateMultiplier()),
|
||||||
|
ignore_injected_strategy_(
|
||||||
|
field_trial::IsEnabled("WebRTC-IgnoreInjectedAllocationStrategy")) {
|
||||||
sequenced_checker_.Detach();
|
sequenced_checker_.Detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,10 +175,10 @@ void BitrateAllocator::AddObserver(BitrateAllocatorObserver* observer,
|
||||||
it->enforce_min_bitrate = config.enforce_min_bitrate;
|
it->enforce_min_bitrate = config.enforce_min_bitrate;
|
||||||
it->bitrate_priority = config.bitrate_priority;
|
it->bitrate_priority = config.bitrate_priority;
|
||||||
} else {
|
} else {
|
||||||
bitrate_observer_configs_.push_back(
|
bitrate_observer_configs_.push_back(ObserverConfig(
|
||||||
ObserverConfig(observer, config.min_bitrate_bps, config.max_bitrate_bps,
|
observer, config.min_bitrate_bps, config.max_bitrate_bps,
|
||||||
config.pad_up_bitrate_bps, config.priority_bitrate_bps,
|
config.pad_up_bitrate_bps, config.priority_bitrate_bps,
|
||||||
config.enforce_min_bitrate, config.bitrate_priority));
|
config.enforce_min_bitrate, config.track_id, config.bitrate_priority));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last_target_bps_ > 0) {
|
if (last_target_bps_ > 0) {
|
||||||
|
@ -280,6 +283,13 @@ int BitrateAllocator::GetStartBitrate(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BitrateAllocator::SetBitrateAllocationStrategy(
|
||||||
|
std::unique_ptr<rtc::BitrateAllocationStrategy>
|
||||||
|
bitrate_allocation_strategy) {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequenced_checker_);
|
||||||
|
bitrate_allocation_strategy_ = std::move(bitrate_allocation_strategy);
|
||||||
|
}
|
||||||
|
|
||||||
BitrateAllocator::ObserverConfigs::const_iterator
|
BitrateAllocator::ObserverConfigs::const_iterator
|
||||||
BitrateAllocator::FindObserverConfig(
|
BitrateAllocator::FindObserverConfig(
|
||||||
const BitrateAllocatorObserver* observer) const {
|
const BitrateAllocatorObserver* observer) const {
|
||||||
|
@ -306,6 +316,25 @@ BitrateAllocator::ObserverAllocation BitrateAllocator::AllocateBitrates(
|
||||||
if (bitrate_observer_configs_.empty())
|
if (bitrate_observer_configs_.empty())
|
||||||
return ObserverAllocation();
|
return ObserverAllocation();
|
||||||
|
|
||||||
|
if (!ignore_injected_strategy_ && bitrate_allocation_strategy_ != nullptr) {
|
||||||
|
// Note: This intentionally causes slicing, we only copy the fields in
|
||||||
|
// ObserverConfig that are inherited from TrackConfig.
|
||||||
|
std::vector<rtc::BitrateAllocationStrategy::TrackConfig> track_configs(
|
||||||
|
bitrate_observer_configs_.begin(), bitrate_observer_configs_.end());
|
||||||
|
|
||||||
|
std::vector<uint32_t> track_allocations =
|
||||||
|
bitrate_allocation_strategy_->AllocateBitrates(
|
||||||
|
bitrate, std::move(track_configs));
|
||||||
|
// The strategy should return allocation for all tracks.
|
||||||
|
RTC_CHECK(track_allocations.size() == bitrate_observer_configs_.size());
|
||||||
|
ObserverAllocation allocation;
|
||||||
|
auto track_allocations_it = track_allocations.begin();
|
||||||
|
for (const auto& observer_config : bitrate_observer_configs_) {
|
||||||
|
allocation[observer_config.observer] = *track_allocations_it++;
|
||||||
|
}
|
||||||
|
return allocation;
|
||||||
|
}
|
||||||
|
|
||||||
if (bitrate == 0)
|
if (bitrate == 0)
|
||||||
return ZeroRateAllocation();
|
return ZeroRateAllocation();
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "api/call/bitrate_allocation.h"
|
#include "api/call/bitrate_allocation.h"
|
||||||
|
#include "rtc_base/bitrate_allocation_strategy.h"
|
||||||
#include "rtc_base/synchronization/sequence_checker.h"
|
#include "rtc_base/synchronization/sequence_checker.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
@ -56,6 +57,7 @@ struct MediaStreamAllocationConfig {
|
||||||
uint32_t pad_up_bitrate_bps;
|
uint32_t pad_up_bitrate_bps;
|
||||||
int64_t priority_bitrate_bps;
|
int64_t priority_bitrate_bps;
|
||||||
bool enforce_min_bitrate;
|
bool enforce_min_bitrate;
|
||||||
|
std::string track_id;
|
||||||
double bitrate_priority;
|
double bitrate_priority;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -114,24 +116,33 @@ class BitrateAllocator : public BitrateAllocatorInterface {
|
||||||
// the list of added observers, a best guess is returned.
|
// the list of added observers, a best guess is returned.
|
||||||
int GetStartBitrate(BitrateAllocatorObserver* observer) const override;
|
int GetStartBitrate(BitrateAllocatorObserver* observer) const override;
|
||||||
|
|
||||||
|
// Sets external allocation strategy. If strategy is not set default WebRTC
|
||||||
|
// allocation mechanism will be used. The strategy may be changed during call.
|
||||||
|
// Setting NULL value will restore default WEBRTC allocation strategy.
|
||||||
|
void SetBitrateAllocationStrategy(
|
||||||
|
std::unique_ptr<rtc::BitrateAllocationStrategy>
|
||||||
|
bitrate_allocation_strategy);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ObserverConfig {
|
struct ObserverConfig : rtc::BitrateAllocationStrategy::TrackConfig {
|
||||||
ObserverConfig(BitrateAllocatorObserver* observer,
|
ObserverConfig(BitrateAllocatorObserver* observer,
|
||||||
uint32_t min_bitrate_bps,
|
uint32_t min_bitrate_bps,
|
||||||
uint32_t max_bitrate_bps,
|
uint32_t max_bitrate_bps,
|
||||||
uint32_t pad_up_bitrate_bps,
|
uint32_t pad_up_bitrate_bps,
|
||||||
int64_t priority_bitrate_bps,
|
int64_t priority_bitrate_bps,
|
||||||
bool enforce_min_bitrate,
|
bool enforce_min_bitrate,
|
||||||
|
std::string track_id,
|
||||||
double bitrate_priority)
|
double bitrate_priority)
|
||||||
: observer(observer),
|
: TrackConfig(min_bitrate_bps,
|
||||||
|
max_bitrate_bps,
|
||||||
|
enforce_min_bitrate,
|
||||||
|
track_id),
|
||||||
|
observer(observer),
|
||||||
pad_up_bitrate_bps(pad_up_bitrate_bps),
|
pad_up_bitrate_bps(pad_up_bitrate_bps),
|
||||||
priority_bitrate_bps(priority_bitrate_bps),
|
priority_bitrate_bps(priority_bitrate_bps),
|
||||||
allocated_bitrate_bps(-1),
|
allocated_bitrate_bps(-1),
|
||||||
media_ratio(1.0),
|
media_ratio(1.0),
|
||||||
bitrate_priority(bitrate_priority),
|
bitrate_priority(bitrate_priority) {}
|
||||||
min_bitrate_bps(min_bitrate_bps),
|
|
||||||
max_bitrate_bps(max_bitrate_bps),
|
|
||||||
enforce_min_bitrate(enforce_min_bitrate) {}
|
|
||||||
|
|
||||||
BitrateAllocatorObserver* observer;
|
BitrateAllocatorObserver* observer;
|
||||||
uint32_t pad_up_bitrate_bps;
|
uint32_t pad_up_bitrate_bps;
|
||||||
|
@ -143,15 +154,6 @@ class BitrateAllocator : public BitrateAllocatorInterface {
|
||||||
// observers, it should be allocated twice the bitrate above its min.
|
// observers, it should be allocated twice the bitrate above its min.
|
||||||
double bitrate_priority;
|
double bitrate_priority;
|
||||||
|
|
||||||
// Minimum bitrate supported by track.
|
|
||||||
uint32_t min_bitrate_bps;
|
|
||||||
|
|
||||||
// Maximum bitrate supported by track.
|
|
||||||
uint32_t max_bitrate_bps;
|
|
||||||
|
|
||||||
// True means track may not be paused by allocating 0 bitrate.
|
|
||||||
bool enforce_min_bitrate;
|
|
||||||
|
|
||||||
uint32_t LastAllocatedBitrate() const;
|
uint32_t LastAllocatedBitrate() const;
|
||||||
// The minimum bitrate required by this observer, including
|
// The minimum bitrate required by this observer, including
|
||||||
// enable-hysteresis if the observer is in a paused state.
|
// enable-hysteresis if the observer is in a paused state.
|
||||||
|
@ -220,7 +222,8 @@ class BitrateAllocator : public BitrateAllocatorInterface {
|
||||||
// Allow packets to be transmitted in up to 2 times max video bitrate if the
|
// Allow packets to be transmitted in up to 2 times max video bitrate if the
|
||||||
// bandwidth estimate allows it.
|
// bandwidth estimate allows it.
|
||||||
// TODO(bugs.webrtc.org/8541): May be worth to refactor to keep this logic in
|
// TODO(bugs.webrtc.org/8541): May be worth to refactor to keep this logic in
|
||||||
// video send stream.
|
// video send stream. Similar logic is implemented in
|
||||||
|
// AudioPriorityBitrateAllocationStrategy.
|
||||||
static uint8_t GetTransmissionMaxBitrateMultiplier();
|
static uint8_t GetTransmissionMaxBitrateMultiplier();
|
||||||
|
|
||||||
SequenceChecker sequenced_checker_;
|
SequenceChecker sequenced_checker_;
|
||||||
|
@ -240,7 +243,10 @@ class BitrateAllocator : public BitrateAllocatorInterface {
|
||||||
uint32_t total_requested_padding_bitrate_ RTC_GUARDED_BY(&sequenced_checker_);
|
uint32_t total_requested_padding_bitrate_ RTC_GUARDED_BY(&sequenced_checker_);
|
||||||
uint32_t total_requested_min_bitrate_ RTC_GUARDED_BY(&sequenced_checker_);
|
uint32_t total_requested_min_bitrate_ RTC_GUARDED_BY(&sequenced_checker_);
|
||||||
uint32_t total_requested_max_bitrate_ RTC_GUARDED_BY(&sequenced_checker_);
|
uint32_t total_requested_max_bitrate_ RTC_GUARDED_BY(&sequenced_checker_);
|
||||||
|
std::unique_ptr<rtc::BitrateAllocationStrategy> bitrate_allocation_strategy_
|
||||||
|
RTC_GUARDED_BY(&sequenced_checker_);
|
||||||
const uint8_t transmission_max_bitrate_multiplier_;
|
const uint8_t transmission_max_bitrate_multiplier_;
|
||||||
|
const bool ignore_injected_strategy_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
|
@ -97,11 +97,12 @@ class BitrateAllocatorTest : public ::testing::Test {
|
||||||
uint32_t max_bitrate_bps,
|
uint32_t max_bitrate_bps,
|
||||||
uint32_t pad_up_bitrate_bps,
|
uint32_t pad_up_bitrate_bps,
|
||||||
bool enforce_min_bitrate,
|
bool enforce_min_bitrate,
|
||||||
|
std::string track_id,
|
||||||
double bitrate_priority) {
|
double bitrate_priority) {
|
||||||
allocator_->AddObserver(
|
allocator_->AddObserver(
|
||||||
observer,
|
observer, {min_bitrate_bps, max_bitrate_bps, pad_up_bitrate_bps,
|
||||||
{min_bitrate_bps, max_bitrate_bps, pad_up_bitrate_bps,
|
/* priority_bitrate */ 0, enforce_min_bitrate, track_id,
|
||||||
/* priority_bitrate */ 0, enforce_min_bitrate, bitrate_priority});
|
bitrate_priority});
|
||||||
}
|
}
|
||||||
MediaStreamAllocationConfig DefaultConfig() const {
|
MediaStreamAllocationConfig DefaultConfig() const {
|
||||||
MediaStreamAllocationConfig default_config;
|
MediaStreamAllocationConfig default_config;
|
||||||
|
@ -110,6 +111,7 @@ class BitrateAllocatorTest : public ::testing::Test {
|
||||||
default_config.pad_up_bitrate_bps = 0;
|
default_config.pad_up_bitrate_bps = 0;
|
||||||
default_config.priority_bitrate_bps = 0;
|
default_config.priority_bitrate_bps = 0;
|
||||||
default_config.enforce_min_bitrate = true;
|
default_config.enforce_min_bitrate = true;
|
||||||
|
default_config.track_id = "";
|
||||||
default_config.bitrate_priority = kDefaultBitratePriority;
|
default_config.bitrate_priority = kDefaultBitratePriority;
|
||||||
return default_config;
|
return default_config;
|
||||||
}
|
}
|
||||||
|
@ -163,7 +165,7 @@ TEST_F(BitrateAllocatorTest, UpdatingBitrateObserver) {
|
||||||
OnAllocationLimitsChanged(kMinSendBitrateBps, kPadUpToBitrateBps,
|
OnAllocationLimitsChanged(kMinSendBitrateBps, kPadUpToBitrateBps,
|
||||||
kMaxBitrateBps));
|
kMaxBitrateBps));
|
||||||
AddObserver(&bitrate_observer, kMinSendBitrateBps, kMaxBitrateBps,
|
AddObserver(&bitrate_observer, kMinSendBitrateBps, kMaxBitrateBps,
|
||||||
kPadUpToBitrateBps, true, kDefaultBitratePriority);
|
kPadUpToBitrateBps, true, "", kDefaultBitratePriority);
|
||||||
EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer));
|
EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer));
|
||||||
allocator_->OnNetworkChanged(200000, 0, 0, kDefaultProbingIntervalMs);
|
allocator_->OnNetworkChanged(200000, 0, 0, kDefaultProbingIntervalMs);
|
||||||
EXPECT_EQ(200000, allocator_->GetStartBitrate(&bitrate_observer));
|
EXPECT_EQ(200000, allocator_->GetStartBitrate(&bitrate_observer));
|
||||||
|
@ -176,14 +178,14 @@ TEST_F(BitrateAllocatorTest, UpdatingBitrateObserver) {
|
||||||
// Expect |max_padding_bitrate_bps| to change to 0 if the observer is updated.
|
// Expect |max_padding_bitrate_bps| to change to 0 if the observer is updated.
|
||||||
EXPECT_CALL(limit_observer_,
|
EXPECT_CALL(limit_observer_,
|
||||||
OnAllocationLimitsChanged(kMinSendBitrateBps, 0, _));
|
OnAllocationLimitsChanged(kMinSendBitrateBps, 0, _));
|
||||||
AddObserver(&bitrate_observer, kMinSendBitrateBps, 4000000, 0, true,
|
AddObserver(&bitrate_observer, kMinSendBitrateBps, 4000000, 0, true, "",
|
||||||
kDefaultBitratePriority);
|
kDefaultBitratePriority);
|
||||||
EXPECT_CALL(limit_observer_,
|
EXPECT_CALL(limit_observer_,
|
||||||
OnAllocationLimitsChanged(kMinSendBitrateBps, 0, _));
|
OnAllocationLimitsChanged(kMinSendBitrateBps, 0, _));
|
||||||
EXPECT_EQ(4000000, allocator_->GetStartBitrate(&bitrate_observer));
|
EXPECT_EQ(4000000, allocator_->GetStartBitrate(&bitrate_observer));
|
||||||
|
|
||||||
AddObserver(&bitrate_observer, kMinSendBitrateBps, kMaxBitrateBps, 0, true,
|
AddObserver(&bitrate_observer, kMinSendBitrateBps, kMaxBitrateBps, 0, true,
|
||||||
kDefaultBitratePriority);
|
"", kDefaultBitratePriority);
|
||||||
EXPECT_EQ(3000000, allocator_->GetStartBitrate(&bitrate_observer));
|
EXPECT_EQ(3000000, allocator_->GetStartBitrate(&bitrate_observer));
|
||||||
EXPECT_EQ(3000000u, bitrate_observer.last_bitrate_bps_);
|
EXPECT_EQ(3000000u, bitrate_observer.last_bitrate_bps_);
|
||||||
allocator_->OnNetworkChanged(kMaxBitrateBps, 0, 0, kDefaultProbingIntervalMs);
|
allocator_->OnNetworkChanged(kMaxBitrateBps, 0, 0, kDefaultProbingIntervalMs);
|
||||||
|
@ -202,14 +204,14 @@ TEST_F(BitrateAllocatorTest, TwoBitrateObserversOneRtcpObserver) {
|
||||||
limit_observer_,
|
limit_observer_,
|
||||||
OnAllocationLimitsChanged(kObs1StartBitrateBps, 0, kObs1MaxBitrateBps));
|
OnAllocationLimitsChanged(kObs1StartBitrateBps, 0, kObs1MaxBitrateBps));
|
||||||
AddObserver(&bitrate_observer_1, kObs1StartBitrateBps, kObs1MaxBitrateBps, 0,
|
AddObserver(&bitrate_observer_1, kObs1StartBitrateBps, kObs1MaxBitrateBps, 0,
|
||||||
true, kDefaultBitratePriority);
|
true, "", kDefaultBitratePriority);
|
||||||
EXPECT_EQ(static_cast<int>(kObs1MaxBitrateBps),
|
EXPECT_EQ(static_cast<int>(kObs1MaxBitrateBps),
|
||||||
allocator_->GetStartBitrate(&bitrate_observer_1));
|
allocator_->GetStartBitrate(&bitrate_observer_1));
|
||||||
EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(
|
EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(
|
||||||
kObs1StartBitrateBps + kObs2StartBitrateBps,
|
kObs1StartBitrateBps + kObs2StartBitrateBps,
|
||||||
0, kObs1MaxBitrateBps + kObs2MaxBitrateBps));
|
0, kObs1MaxBitrateBps + kObs2MaxBitrateBps));
|
||||||
AddObserver(&bitrate_observer_2, kObs2StartBitrateBps, kObs2MaxBitrateBps, 0,
|
AddObserver(&bitrate_observer_2, kObs2StartBitrateBps, kObs2MaxBitrateBps, 0,
|
||||||
true, kDefaultBitratePriority);
|
true, "", kDefaultBitratePriority);
|
||||||
EXPECT_EQ(static_cast<int>(kObs2StartBitrateBps),
|
EXPECT_EQ(static_cast<int>(kObs2StartBitrateBps),
|
||||||
allocator_->GetStartBitrate(&bitrate_observer_2));
|
allocator_->GetStartBitrate(&bitrate_observer_2));
|
||||||
|
|
||||||
|
@ -258,7 +260,7 @@ TEST_F(BitrateAllocatorTest, RemoveObserverTriggersLimitObserver) {
|
||||||
OnAllocationLimitsChanged(kMinSendBitrateBps, kPadUpToBitrateBps,
|
OnAllocationLimitsChanged(kMinSendBitrateBps, kPadUpToBitrateBps,
|
||||||
kMaxBitrateBps));
|
kMaxBitrateBps));
|
||||||
AddObserver(&bitrate_observer, kMinSendBitrateBps, kMaxBitrateBps,
|
AddObserver(&bitrate_observer, kMinSendBitrateBps, kMaxBitrateBps,
|
||||||
kPadUpToBitrateBps, true, kDefaultBitratePriority);
|
kPadUpToBitrateBps, true, "", kDefaultBitratePriority);
|
||||||
EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(0, 0, _));
|
EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(0, 0, _));
|
||||||
allocator_->RemoveObserver(&bitrate_observer);
|
allocator_->RemoveObserver(&bitrate_observer);
|
||||||
}
|
}
|
||||||
|
@ -280,7 +282,7 @@ class BitrateAllocatorTestNoEnforceMin : public ::testing::Test {
|
||||||
double bitrate_priority) {
|
double bitrate_priority) {
|
||||||
allocator_->AddObserver(
|
allocator_->AddObserver(
|
||||||
observer, {min_bitrate_bps, max_bitrate_bps, pad_up_bitrate_bps, 0,
|
observer, {min_bitrate_bps, max_bitrate_bps, pad_up_bitrate_bps, 0,
|
||||||
enforce_min_bitrate, bitrate_priority});
|
enforce_min_bitrate, track_id, bitrate_priority});
|
||||||
}
|
}
|
||||||
NiceMock<MockLimitObserver> limit_observer_;
|
NiceMock<MockLimitObserver> limit_observer_;
|
||||||
std::unique_ptr<BitrateAllocatorForTest> allocator_;
|
std::unique_ptr<BitrateAllocatorForTest> allocator_;
|
||||||
|
@ -532,16 +534,16 @@ TEST_F(BitrateAllocatorTest, ThreeBitrateObserversLowBweEnforceMin) {
|
||||||
TestBitrateObserver bitrate_observer_2;
|
TestBitrateObserver bitrate_observer_2;
|
||||||
TestBitrateObserver bitrate_observer_3;
|
TestBitrateObserver bitrate_observer_3;
|
||||||
|
|
||||||
AddObserver(&bitrate_observer_1, 100000, 400000, 0, true,
|
AddObserver(&bitrate_observer_1, 100000, 400000, 0, true, "",
|
||||||
kDefaultBitratePriority);
|
kDefaultBitratePriority);
|
||||||
EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_1));
|
EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_1));
|
||||||
|
|
||||||
AddObserver(&bitrate_observer_2, 200000, 400000, 0, true,
|
AddObserver(&bitrate_observer_2, 200000, 400000, 0, true, "",
|
||||||
kDefaultBitratePriority);
|
kDefaultBitratePriority);
|
||||||
EXPECT_EQ(200000, allocator_->GetStartBitrate(&bitrate_observer_2));
|
EXPECT_EQ(200000, allocator_->GetStartBitrate(&bitrate_observer_2));
|
||||||
EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_);
|
EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_);
|
||||||
|
|
||||||
AddObserver(&bitrate_observer_3, 300000, 400000, 0, true,
|
AddObserver(&bitrate_observer_3, 300000, 400000, 0, true, "",
|
||||||
kDefaultBitratePriority);
|
kDefaultBitratePriority);
|
||||||
EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_3));
|
EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_3));
|
||||||
EXPECT_EQ(100000, static_cast<int>(bitrate_observer_1.last_bitrate_bps_));
|
EXPECT_EQ(100000, static_cast<int>(bitrate_observer_1.last_bitrate_bps_));
|
||||||
|
@ -563,7 +565,7 @@ TEST_F(BitrateAllocatorTest, AddObserverWhileNetworkDown) {
|
||||||
TestBitrateObserver bitrate_observer_1;
|
TestBitrateObserver bitrate_observer_1;
|
||||||
EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(50000, 0, _));
|
EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(50000, 0, _));
|
||||||
|
|
||||||
AddObserver(&bitrate_observer_1, 50000, 400000, 0, true,
|
AddObserver(&bitrate_observer_1, 50000, 400000, 0, true, "",
|
||||||
kDefaultBitratePriority);
|
kDefaultBitratePriority);
|
||||||
EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_1));
|
EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_1));
|
||||||
|
|
||||||
|
@ -575,7 +577,7 @@ TEST_F(BitrateAllocatorTest, AddObserverWhileNetworkDown) {
|
||||||
TestBitrateObserver bitrate_observer_2;
|
TestBitrateObserver bitrate_observer_2;
|
||||||
// Adding an observer while the network is down should not affect the limits.
|
// Adding an observer while the network is down should not affect the limits.
|
||||||
EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(50000 + 50000, 0, _));
|
EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(50000 + 50000, 0, _));
|
||||||
AddObserver(&bitrate_observer_2, 50000, 400000, 0, true,
|
AddObserver(&bitrate_observer_2, 50000, 400000, 0, true, "",
|
||||||
kDefaultBitratePriority);
|
kDefaultBitratePriority);
|
||||||
|
|
||||||
// Expect the start_bitrate to be set as if the network was still up but that
|
// Expect the start_bitrate to be set as if the network was still up but that
|
||||||
|
@ -592,12 +594,12 @@ TEST_F(BitrateAllocatorTest, AddObserverWhileNetworkDown) {
|
||||||
|
|
||||||
TEST_F(BitrateAllocatorTest, MixedEnforecedConfigs) {
|
TEST_F(BitrateAllocatorTest, MixedEnforecedConfigs) {
|
||||||
TestBitrateObserver enforced_observer;
|
TestBitrateObserver enforced_observer;
|
||||||
AddObserver(&enforced_observer, 6000, 30000, 0, true,
|
AddObserver(&enforced_observer, 6000, 30000, 0, true, "",
|
||||||
kDefaultBitratePriority);
|
kDefaultBitratePriority);
|
||||||
EXPECT_EQ(60000, allocator_->GetStartBitrate(&enforced_observer));
|
EXPECT_EQ(60000, allocator_->GetStartBitrate(&enforced_observer));
|
||||||
|
|
||||||
TestBitrateObserver not_enforced_observer;
|
TestBitrateObserver not_enforced_observer;
|
||||||
AddObserver(¬_enforced_observer, 30000, 2500000, 0, false,
|
AddObserver(¬_enforced_observer, 30000, 2500000, 0, false, "",
|
||||||
kDefaultBitratePriority);
|
kDefaultBitratePriority);
|
||||||
EXPECT_EQ(270000, allocator_->GetStartBitrate(¬_enforced_observer));
|
EXPECT_EQ(270000, allocator_->GetStartBitrate(¬_enforced_observer));
|
||||||
EXPECT_EQ(30000u, enforced_observer.last_bitrate_bps_);
|
EXPECT_EQ(30000u, enforced_observer.last_bitrate_bps_);
|
||||||
|
@ -636,7 +638,7 @@ TEST_F(BitrateAllocatorTest, MixedEnforecedConfigs) {
|
||||||
|
|
||||||
TEST_F(BitrateAllocatorTest, AvoidToggleAbsolute) {
|
TEST_F(BitrateAllocatorTest, AvoidToggleAbsolute) {
|
||||||
TestBitrateObserver observer;
|
TestBitrateObserver observer;
|
||||||
AddObserver(&observer, 30000, 300000, 0, false, kDefaultBitratePriority);
|
AddObserver(&observer, 30000, 300000, 0, false, "", kDefaultBitratePriority);
|
||||||
EXPECT_EQ(300000, allocator_->GetStartBitrate(&observer));
|
EXPECT_EQ(300000, allocator_->GetStartBitrate(&observer));
|
||||||
|
|
||||||
allocator_->OnNetworkChanged(30000, 0, 50, kDefaultProbingIntervalMs);
|
allocator_->OnNetworkChanged(30000, 0, 50, kDefaultProbingIntervalMs);
|
||||||
|
@ -662,7 +664,7 @@ TEST_F(BitrateAllocatorTest, AvoidToggleAbsolute) {
|
||||||
|
|
||||||
TEST_F(BitrateAllocatorTest, AvoidTogglePercent) {
|
TEST_F(BitrateAllocatorTest, AvoidTogglePercent) {
|
||||||
TestBitrateObserver observer;
|
TestBitrateObserver observer;
|
||||||
AddObserver(&observer, 300000, 600000, 0, false, kDefaultBitratePriority);
|
AddObserver(&observer, 300000, 600000, 0, false, "", kDefaultBitratePriority);
|
||||||
EXPECT_EQ(300000, allocator_->GetStartBitrate(&observer));
|
EXPECT_EQ(300000, allocator_->GetStartBitrate(&observer));
|
||||||
|
|
||||||
allocator_->OnNetworkChanged(300000, 0, 50, kDefaultProbingIntervalMs);
|
allocator_->OnNetworkChanged(300000, 0, 50, kDefaultProbingIntervalMs);
|
||||||
|
@ -688,7 +690,7 @@ TEST_F(BitrateAllocatorTest, AvoidTogglePercent) {
|
||||||
|
|
||||||
TEST_F(BitrateAllocatorTest, PassProbingInterval) {
|
TEST_F(BitrateAllocatorTest, PassProbingInterval) {
|
||||||
TestBitrateObserver observer;
|
TestBitrateObserver observer;
|
||||||
AddObserver(&observer, 300000, 600000, 0, false, kDefaultBitratePriority);
|
AddObserver(&observer, 300000, 600000, 0, false, "", kDefaultBitratePriority);
|
||||||
EXPECT_EQ(300000, allocator_->GetStartBitrate(&observer));
|
EXPECT_EQ(300000, allocator_->GetStartBitrate(&observer));
|
||||||
|
|
||||||
allocator_->OnNetworkChanged(300000, 0, 50, 5000);
|
allocator_->OnNetworkChanged(300000, 0, 50, 5000);
|
||||||
|
@ -703,7 +705,8 @@ TEST_F(BitrateAllocatorTest, PriorityRateOneObserverBasic) {
|
||||||
const uint32_t kMaxSendBitrateBps = 60;
|
const uint32_t kMaxSendBitrateBps = 60;
|
||||||
const uint32_t kNetworkBandwidthBps = 30;
|
const uint32_t kNetworkBandwidthBps = 30;
|
||||||
|
|
||||||
AddObserver(&observer, kMinSendBitrateBps, kMaxSendBitrateBps, 0, true, 2.0);
|
AddObserver(&observer, kMinSendBitrateBps, kMaxSendBitrateBps, 0, true, "",
|
||||||
|
2.0);
|
||||||
allocator_->OnNetworkChanged(kNetworkBandwidthBps, 0, 0,
|
allocator_->OnNetworkChanged(kNetworkBandwidthBps, 0, 0,
|
||||||
kDefaultProbingIntervalMs);
|
kDefaultProbingIntervalMs);
|
||||||
|
|
||||||
|
@ -721,9 +724,9 @@ TEST_F(BitrateAllocatorTest, PriorityRateTwoObserversBasic) {
|
||||||
const uint32_t kMaxSendBitrateBps = 60;
|
const uint32_t kMaxSendBitrateBps = 60;
|
||||||
const uint32_t kNetworkBandwidthBps = 60;
|
const uint32_t kNetworkBandwidthBps = 60;
|
||||||
AddObserver(&observer_low_1, kMinSendBitrateBps, kMaxSendBitrateBps, 0, false,
|
AddObserver(&observer_low_1, kMinSendBitrateBps, kMaxSendBitrateBps, 0, false,
|
||||||
2.0);
|
"low1", 2.0);
|
||||||
AddObserver(&observer_low_2, kMinSendBitrateBps, kMaxSendBitrateBps, 0, false,
|
AddObserver(&observer_low_2, kMinSendBitrateBps, kMaxSendBitrateBps, 0, false,
|
||||||
2.0);
|
"low2", 2.0);
|
||||||
allocator_->OnNetworkChanged(kNetworkBandwidthBps, 0, 0,
|
allocator_->OnNetworkChanged(kNetworkBandwidthBps, 0, 0,
|
||||||
kDefaultProbingIntervalMs);
|
kDefaultProbingIntervalMs);
|
||||||
|
|
||||||
|
@ -743,9 +746,9 @@ TEST_F(BitrateAllocatorTest, PriorityRateTwoObserversBasicMinEnforced) {
|
||||||
const uint32_t kMaxSendBitrateBps = 60;
|
const uint32_t kMaxSendBitrateBps = 60;
|
||||||
const uint32_t kNetworkBandwidthBps = 60;
|
const uint32_t kNetworkBandwidthBps = 60;
|
||||||
AddObserver(&observer_low_1, kMinSendBitrateBps, kMaxSendBitrateBps, 0, true,
|
AddObserver(&observer_low_1, kMinSendBitrateBps, kMaxSendBitrateBps, 0, true,
|
||||||
2.0);
|
"low1", 2.0);
|
||||||
AddObserver(&observer_low_2, kMinSendBitrateBps, kMaxSendBitrateBps, 0, true,
|
AddObserver(&observer_low_2, kMinSendBitrateBps, kMaxSendBitrateBps, 0, true,
|
||||||
2.0);
|
"low2", 2.0);
|
||||||
allocator_->OnNetworkChanged(kNetworkBandwidthBps, 0, 0,
|
allocator_->OnNetworkChanged(kNetworkBandwidthBps, 0, 0,
|
||||||
kDefaultProbingIntervalMs);
|
kDefaultProbingIntervalMs);
|
||||||
|
|
||||||
|
@ -765,9 +768,9 @@ TEST_F(BitrateAllocatorTest, PriorityRateTwoObserversBothAllocatedMax) {
|
||||||
const uint32_t kMaxSendBitrateBps = 60;
|
const uint32_t kMaxSendBitrateBps = 60;
|
||||||
const uint32_t kNetworkBandwidthBps = kMaxSendBitrateBps * 2;
|
const uint32_t kNetworkBandwidthBps = kMaxSendBitrateBps * 2;
|
||||||
AddObserver(&observer_low, kMinSendBitrateBps, kMaxSendBitrateBps, 0, true,
|
AddObserver(&observer_low, kMinSendBitrateBps, kMaxSendBitrateBps, 0, true,
|
||||||
2.0);
|
"low", 2.0);
|
||||||
AddObserver(&observer_mid, kMinSendBitrateBps, kMaxSendBitrateBps, 0, true,
|
AddObserver(&observer_mid, kMinSendBitrateBps, kMaxSendBitrateBps, 0, true,
|
||||||
4.0);
|
"mid", 4.0);
|
||||||
allocator_->OnNetworkChanged(kNetworkBandwidthBps, 0, 0,
|
allocator_->OnNetworkChanged(kNetworkBandwidthBps, 0, 0,
|
||||||
kDefaultProbingIntervalMs);
|
kDefaultProbingIntervalMs);
|
||||||
|
|
||||||
|
@ -784,8 +787,8 @@ TEST_F(BitrateAllocatorTest, PriorityRateTwoObserversBothAllocatedMax) {
|
||||||
TEST_F(BitrateAllocatorTest, PriorityRateTwoObserversOneAllocatedToMax) {
|
TEST_F(BitrateAllocatorTest, PriorityRateTwoObserversOneAllocatedToMax) {
|
||||||
TestBitrateObserver observer_low;
|
TestBitrateObserver observer_low;
|
||||||
TestBitrateObserver observer_mid;
|
TestBitrateObserver observer_mid;
|
||||||
AddObserver(&observer_low, 10, 50, 0, false, 2.0);
|
AddObserver(&observer_low, 10, 50, 0, false, "low", 2.0);
|
||||||
AddObserver(&observer_mid, 10, 50, 0, false, 4.0);
|
AddObserver(&observer_mid, 10, 50, 0, false, "mid", 4.0);
|
||||||
allocator_->OnNetworkChanged(90, 0, 0, kDefaultProbingIntervalMs);
|
allocator_->OnNetworkChanged(90, 0, 0, kDefaultProbingIntervalMs);
|
||||||
|
|
||||||
EXPECT_EQ(40u, observer_low.last_bitrate_bps_);
|
EXPECT_EQ(40u, observer_low.last_bitrate_bps_);
|
||||||
|
@ -810,9 +813,12 @@ TEST_F(BitrateAllocatorTest,
|
||||||
const double kHighBitratePriority = 8.0;
|
const double kHighBitratePriority = 8.0;
|
||||||
const double kTotalBitratePriority =
|
const double kTotalBitratePriority =
|
||||||
kLowBitratePriority + kMidBitratePriority + kHighBitratePriority;
|
kLowBitratePriority + kMidBitratePriority + kHighBitratePriority;
|
||||||
AddObserver(&observer_low, 0, kMaxBitrate, 0, false, kLowBitratePriority);
|
AddObserver(&observer_low, 0, kMaxBitrate, 0, false, "low",
|
||||||
AddObserver(&observer_mid, 0, kMaxBitrate, 0, false, kMidBitratePriority);
|
kLowBitratePriority);
|
||||||
AddObserver(&observer_high, 0, kMaxBitrate, 0, false, kHighBitratePriority);
|
AddObserver(&observer_mid, 0, kMaxBitrate, 0, false, "mid",
|
||||||
|
kMidBitratePriority);
|
||||||
|
AddObserver(&observer_high, 0, kMaxBitrate, 0, false, "high",
|
||||||
|
kHighBitratePriority);
|
||||||
allocator_->OnNetworkChanged(kNetworkBandwidthBps, 0, 0,
|
allocator_->OnNetworkChanged(kNetworkBandwidthBps, 0, 0,
|
||||||
kDefaultProbingIntervalMs);
|
kDefaultProbingIntervalMs);
|
||||||
|
|
||||||
|
@ -853,11 +859,11 @@ TEST_F(BitrateAllocatorTest, PriorityRateThreeObserversHighAllocatedToMax) {
|
||||||
const uint32_t kRemainingBitrate =
|
const uint32_t kRemainingBitrate =
|
||||||
kAvailableBitrate - kMaxBitrate - (2 * kMinBitrate);
|
kAvailableBitrate - kMaxBitrate - (2 * kMinBitrate);
|
||||||
|
|
||||||
AddObserver(&observer_low, kMinBitrate, kMaxBitrate, 0, false,
|
AddObserver(&observer_low, kMinBitrate, kMaxBitrate, 0, false, "low",
|
||||||
kLowBitratePriority);
|
kLowBitratePriority);
|
||||||
AddObserver(&observer_mid, kMinBitrate, kMaxBitrate, 0, false,
|
AddObserver(&observer_mid, kMinBitrate, kMaxBitrate, 0, false, "mid",
|
||||||
kMidBitratePriority);
|
kMidBitratePriority);
|
||||||
AddObserver(&observer_high, kMinBitrate, kMaxBitrate, 0, false,
|
AddObserver(&observer_high, kMinBitrate, kMaxBitrate, 0, false, "high",
|
||||||
kHighBitratePriority);
|
kHighBitratePriority);
|
||||||
allocator_->OnNetworkChanged(kAvailableBitrate, 0, 0,
|
allocator_->OnNetworkChanged(kAvailableBitrate, 0, 0,
|
||||||
kDefaultProbingIntervalMs);
|
kDefaultProbingIntervalMs);
|
||||||
|
@ -897,11 +903,11 @@ TEST_F(BitrateAllocatorTest, PriorityRateThreeObserversLowAllocatedToMax) {
|
||||||
// available bitrate, so 70 bps would be sufficient network bandwidth.
|
// available bitrate, so 70 bps would be sufficient network bandwidth.
|
||||||
const uint32_t kRemainingBitrate = kAvailableBitrate - kLowMaxBitrate;
|
const uint32_t kRemainingBitrate = kAvailableBitrate - kLowMaxBitrate;
|
||||||
|
|
||||||
AddObserver(&observer_low, kMinBitrate, kLowMaxBitrate, 0, false,
|
AddObserver(&observer_low, kMinBitrate, kLowMaxBitrate, 0, false, "low",
|
||||||
kLowBitratePriority);
|
kLowBitratePriority);
|
||||||
AddObserver(&observer_mid, kMinBitrate, kMaxBitrate, 0, false,
|
AddObserver(&observer_mid, kMinBitrate, kMaxBitrate, 0, false, "mid",
|
||||||
kMidBitratePriority);
|
kMidBitratePriority);
|
||||||
AddObserver(&observer_high, kMinBitrate, kMaxBitrate, 0, false,
|
AddObserver(&observer_high, kMinBitrate, kMaxBitrate, 0, false, "high",
|
||||||
kHighBitratePriority);
|
kHighBitratePriority);
|
||||||
allocator_->OnNetworkChanged(kAvailableBitrate, 0, 0,
|
allocator_->OnNetworkChanged(kAvailableBitrate, 0, 0,
|
||||||
kDefaultProbingIntervalMs);
|
kDefaultProbingIntervalMs);
|
||||||
|
@ -931,12 +937,12 @@ TEST_F(BitrateAllocatorTest, PriorityRateThreeObserversTwoAllocatedToMax) {
|
||||||
TestBitrateObserver observer_low;
|
TestBitrateObserver observer_low;
|
||||||
TestBitrateObserver observer_mid;
|
TestBitrateObserver observer_mid;
|
||||||
TestBitrateObserver observer_high;
|
TestBitrateObserver observer_high;
|
||||||
AddObserver(&observer_low, 10, 40, 0, false, 2.0);
|
AddObserver(&observer_low, 10, 40, 0, false, "low", 2.0);
|
||||||
// Scaled allocation above the min allocation is the same for these two,
|
// Scaled allocation above the min allocation is the same for these two,
|
||||||
// meaning they will get allocated their max at the same time.
|
// meaning they will get allocated their max at the same time.
|
||||||
// Scaled (target allocation) = (max - min) / bitrate priority
|
// Scaled (target allocation) = (max - min) / bitrate priority
|
||||||
AddObserver(&observer_mid, 10, 30, 0, false, 4.0);
|
AddObserver(&observer_mid, 10, 30, 0, false, "mid", 4.0);
|
||||||
AddObserver(&observer_high, 10, 50, 0, false, 8.0);
|
AddObserver(&observer_high, 10, 50, 0, false, "high", 8.0);
|
||||||
allocator_->OnNetworkChanged(110, 0, 0, kDefaultProbingIntervalMs);
|
allocator_->OnNetworkChanged(110, 0, 0, kDefaultProbingIntervalMs);
|
||||||
|
|
||||||
EXPECT_EQ(30u, observer_low.last_bitrate_bps_);
|
EXPECT_EQ(30u, observer_low.last_bitrate_bps_);
|
||||||
|
|
22
call/call.cc
22
call/call.cc
|
@ -215,6 +215,10 @@ class Call final : public webrtc::Call,
|
||||||
// Implements RecoveredPacketReceiver.
|
// Implements RecoveredPacketReceiver.
|
||||||
void OnRecoveredPacket(const uint8_t* packet, size_t length) override;
|
void OnRecoveredPacket(const uint8_t* packet, size_t length) override;
|
||||||
|
|
||||||
|
void SetBitrateAllocationStrategy(
|
||||||
|
std::unique_ptr<rtc::BitrateAllocationStrategy>
|
||||||
|
bitrate_allocation_strategy) override;
|
||||||
|
|
||||||
void SignalChannelNetworkState(MediaType media, NetworkState state) override;
|
void SignalChannelNetworkState(MediaType media, NetworkState state) override;
|
||||||
|
|
||||||
void OnAudioTransportOverheadChanged(
|
void OnAudioTransportOverheadChanged(
|
||||||
|
@ -1076,6 +1080,24 @@ Call::Stats Call::GetStats() const {
|
||||||
return stats;
|
return stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Call::SetBitrateAllocationStrategy(
|
||||||
|
std::unique_ptr<rtc::BitrateAllocationStrategy>
|
||||||
|
bitrate_allocation_strategy) {
|
||||||
|
// TODO(srte): This function should be moved to RtpTransportControllerSend
|
||||||
|
// when BitrateAllocator is moved there.
|
||||||
|
struct Functor {
|
||||||
|
void operator()() {
|
||||||
|
bitrate_allocator_->SetBitrateAllocationStrategy(
|
||||||
|
std::move(bitrate_allocation_strategy_));
|
||||||
|
}
|
||||||
|
BitrateAllocator* bitrate_allocator_;
|
||||||
|
std::unique_ptr<rtc::BitrateAllocationStrategy>
|
||||||
|
bitrate_allocation_strategy_;
|
||||||
|
};
|
||||||
|
transport_send_ptr_->GetWorkerQueue()->PostTask(Functor{
|
||||||
|
bitrate_allocator_.get(), std::move(bitrate_allocation_strategy)});
|
||||||
|
}
|
||||||
|
|
||||||
void Call::SignalChannelNetworkState(MediaType media, NetworkState state) {
|
void Call::SignalChannelNetworkState(MediaType media, NetworkState state) {
|
||||||
RTC_DCHECK_RUN_ON(&configuration_sequence_checker_);
|
RTC_DCHECK_RUN_ON(&configuration_sequence_checker_);
|
||||||
switch (media) {
|
switch (media) {
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "call/video_receive_stream.h"
|
#include "call/video_receive_stream.h"
|
||||||
#include "call/video_send_stream.h"
|
#include "call/video_send_stream.h"
|
||||||
#include "modules/utility/include/process_thread.h"
|
#include "modules/utility/include/process_thread.h"
|
||||||
|
#include "rtc_base/bitrate_allocation_strategy.h"
|
||||||
#include "rtc_base/copy_on_write_buffer.h"
|
#include "rtc_base/copy_on_write_buffer.h"
|
||||||
#include "rtc_base/network/sent_packet.h"
|
#include "rtc_base/network/sent_packet.h"
|
||||||
#include "rtc_base/network_route.h"
|
#include "rtc_base/network_route.h"
|
||||||
|
@ -106,6 +107,10 @@ class Call {
|
||||||
// pacing delay, etc.
|
// pacing delay, etc.
|
||||||
virtual Stats GetStats() const = 0;
|
virtual Stats GetStats() const = 0;
|
||||||
|
|
||||||
|
virtual void SetBitrateAllocationStrategy(
|
||||||
|
std::unique_ptr<rtc::BitrateAllocationStrategy>
|
||||||
|
bitrate_allocation_strategy) = 0;
|
||||||
|
|
||||||
// TODO(skvlad): When the unbundled case with multiple streams for the same
|
// TODO(skvlad): When the unbundled case with multiple streams for the same
|
||||||
// media type going over different networks is supported, track the state
|
// media type going over different networks is supported, track the state
|
||||||
// for each stream separately. Right now it's global per media type.
|
// for each stream separately. Right now it's global per media type.
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "modules/audio_device/include/test_audio_device.h"
|
#include "modules/audio_device/include/test_audio_device.h"
|
||||||
#include "modules/audio_mixer/audio_mixer_impl.h"
|
#include "modules/audio_mixer/audio_mixer_impl.h"
|
||||||
#include "modules/rtp_rtcp/include/rtp_header_parser.h"
|
#include "modules/rtp_rtcp/include/rtp_header_parser.h"
|
||||||
|
#include "rtc_base/bitrate_allocation_strategy.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
#include "rtc_base/thread_annotations.h"
|
#include "rtc_base/thread_annotations.h"
|
||||||
#include "system_wrappers/include/metrics.h"
|
#include "system_wrappers/include/metrics.h"
|
||||||
|
@ -80,7 +81,8 @@ class CallPerfTest : public test::CallTest {
|
||||||
int threshold_ms,
|
int threshold_ms,
|
||||||
int start_time_ms,
|
int start_time_ms,
|
||||||
int run_time_ms);
|
int run_time_ms);
|
||||||
void TestMinAudioVideoBitrate(int test_bitrate_from,
|
void TestMinAudioVideoBitrate(bool use_bitrate_allocation_strategy,
|
||||||
|
int test_bitrate_from,
|
||||||
int test_bitrate_to,
|
int test_bitrate_to,
|
||||||
int test_bitrate_step,
|
int test_bitrate_step,
|
||||||
int min_bwe,
|
int min_bwe,
|
||||||
|
@ -840,17 +842,22 @@ TEST_F(CallPerfTest, MAYBE_KeepsHighBitrateWhenReconfiguringSender) {
|
||||||
// considered supported if Rtt does not go above 400ms with the network
|
// considered supported if Rtt does not go above 400ms with the network
|
||||||
// contrained to the test bitrate.
|
// contrained to the test bitrate.
|
||||||
//
|
//
|
||||||
|
// |use_bitrate_allocation_strategy| use AudioPriorityBitrateAllocationStrategy
|
||||||
// |test_bitrate_from test_bitrate_to| bitrate constraint range
|
// |test_bitrate_from test_bitrate_to| bitrate constraint range
|
||||||
// |test_bitrate_step| bitrate constraint update step during the test
|
// |test_bitrate_step| bitrate constraint update step during the test
|
||||||
// |min_bwe max_bwe| BWE range
|
// |min_bwe max_bwe| BWE range
|
||||||
// |start_bwe| initial BWE
|
// |start_bwe| initial BWE
|
||||||
void CallPerfTest::TestMinAudioVideoBitrate(int test_bitrate_from,
|
void CallPerfTest::TestMinAudioVideoBitrate(
|
||||||
int test_bitrate_to,
|
bool use_bitrate_allocation_strategy,
|
||||||
int test_bitrate_step,
|
int test_bitrate_from,
|
||||||
int min_bwe,
|
int test_bitrate_to,
|
||||||
int start_bwe,
|
int test_bitrate_step,
|
||||||
int max_bwe) {
|
int min_bwe,
|
||||||
|
int start_bwe,
|
||||||
|
int max_bwe) {
|
||||||
static const std::string kAudioTrackId = "audio_track_0";
|
static const std::string kAudioTrackId = "audio_track_0";
|
||||||
|
static constexpr uint32_t kSufficientAudioBitrateBps = 16000;
|
||||||
|
static constexpr int kOpusMinBitrateBps = 6000;
|
||||||
static constexpr int kOpusBitrateFbBps = 32000;
|
static constexpr int kOpusBitrateFbBps = 32000;
|
||||||
static constexpr int kBitrateStabilizationMs = 10000;
|
static constexpr int kBitrateStabilizationMs = 10000;
|
||||||
static constexpr int kBitrateMeasurements = 10;
|
static constexpr int kBitrateMeasurements = 10;
|
||||||
|
@ -860,13 +867,18 @@ void CallPerfTest::TestMinAudioVideoBitrate(int test_bitrate_from,
|
||||||
|
|
||||||
class MinVideoAndAudioBitrateTester : public test::EndToEndTest {
|
class MinVideoAndAudioBitrateTester : public test::EndToEndTest {
|
||||||
public:
|
public:
|
||||||
MinVideoAndAudioBitrateTester(int test_bitrate_from,
|
MinVideoAndAudioBitrateTester(bool use_bitrate_allocation_strategy,
|
||||||
|
int test_bitrate_from,
|
||||||
int test_bitrate_to,
|
int test_bitrate_to,
|
||||||
int test_bitrate_step,
|
int test_bitrate_step,
|
||||||
int min_bwe,
|
int min_bwe,
|
||||||
int start_bwe,
|
int start_bwe,
|
||||||
int max_bwe)
|
int max_bwe)
|
||||||
: EndToEndTest(),
|
: EndToEndTest(),
|
||||||
|
allocation_strategy_(new rtc::AudioPriorityBitrateAllocationStrategy(
|
||||||
|
kAudioTrackId,
|
||||||
|
kSufficientAudioBitrateBps)),
|
||||||
|
use_bitrate_allocation_strategy_(use_bitrate_allocation_strategy),
|
||||||
test_bitrate_from_(test_bitrate_from),
|
test_bitrate_from_(test_bitrate_from),
|
||||||
test_bitrate_to_(test_bitrate_to),
|
test_bitrate_to_(test_bitrate_to),
|
||||||
test_bitrate_step_(test_bitrate_step),
|
test_bitrate_step_(test_bitrate_step),
|
||||||
|
@ -941,8 +953,11 @@ void CallPerfTest::TestMinAudioVideoBitrate(int test_bitrate_from,
|
||||||
}
|
}
|
||||||
EXPECT_GT(last_passed_test_bitrate, -1)
|
EXPECT_GT(last_passed_test_bitrate, -1)
|
||||||
<< "Minimum supported bitrate out of the test scope";
|
<< "Minimum supported bitrate out of the test scope";
|
||||||
webrtc::test::PrintResult("min_test_bitrate_", "", "min_bitrate",
|
webrtc::test::PrintResult(
|
||||||
last_passed_test_bitrate, "kbps", false);
|
"min_test_bitrate_",
|
||||||
|
use_bitrate_allocation_strategy_ ? "with_allocation_strategy"
|
||||||
|
: "no_allocation_strategy",
|
||||||
|
"min_bitrate", last_passed_test_bitrate, "kbps", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
|
void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
|
||||||
|
@ -953,6 +968,10 @@ void CallPerfTest::TestMinAudioVideoBitrate(int test_bitrate_from,
|
||||||
bitrate_config.max_bitrate_bps = max_bwe_;
|
bitrate_config.max_bitrate_bps = max_bwe_;
|
||||||
sender_call->GetTransportControllerSend()->SetSdpBitrateParameters(
|
sender_call->GetTransportControllerSend()->SetSdpBitrateParameters(
|
||||||
bitrate_config);
|
bitrate_config);
|
||||||
|
if (use_bitrate_allocation_strategy_) {
|
||||||
|
sender_call->SetBitrateAllocationStrategy(
|
||||||
|
std::move(allocation_strategy_));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t GetNumVideoStreams() const override { return 1; }
|
size_t GetNumVideoStreams() const override { return 1; }
|
||||||
|
@ -962,11 +981,19 @@ void CallPerfTest::TestMinAudioVideoBitrate(int test_bitrate_from,
|
||||||
void ModifyAudioConfigs(
|
void ModifyAudioConfigs(
|
||||||
AudioSendStream::Config* send_config,
|
AudioSendStream::Config* send_config,
|
||||||
std::vector<AudioReceiveStream::Config>* receive_configs) override {
|
std::vector<AudioReceiveStream::Config>* receive_configs) override {
|
||||||
send_config->send_codec_spec->target_bitrate_bps =
|
if (use_bitrate_allocation_strategy_) {
|
||||||
absl::optional<int>(kOpusBitrateFbBps);
|
send_config->track_id = kAudioTrackId;
|
||||||
|
send_config->min_bitrate_bps = kOpusMinBitrateBps;
|
||||||
|
send_config->max_bitrate_bps = kOpusBitrateFbBps;
|
||||||
|
} else {
|
||||||
|
send_config->send_codec_spec->target_bitrate_bps =
|
||||||
|
absl::optional<int>(kOpusBitrateFbBps);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::unique_ptr<rtc::BitrateAllocationStrategy> allocation_strategy_;
|
||||||
|
const bool use_bitrate_allocation_strategy_;
|
||||||
const int test_bitrate_from_;
|
const int test_bitrate_from_;
|
||||||
const int test_bitrate_to_;
|
const int test_bitrate_to_;
|
||||||
const int test_bitrate_step_;
|
const int test_bitrate_step_;
|
||||||
|
@ -976,8 +1003,8 @@ void CallPerfTest::TestMinAudioVideoBitrate(int test_bitrate_from,
|
||||||
SimulatedNetwork* send_simulated_network_;
|
SimulatedNetwork* send_simulated_network_;
|
||||||
SimulatedNetwork* receive_simulated_network_;
|
SimulatedNetwork* receive_simulated_network_;
|
||||||
Call* sender_call_;
|
Call* sender_call_;
|
||||||
} test(test_bitrate_from, test_bitrate_to, test_bitrate_step, min_bwe,
|
} test(use_bitrate_allocation_strategy, test_bitrate_from, test_bitrate_to,
|
||||||
start_bwe, max_bwe);
|
test_bitrate_step, min_bwe, start_bwe, max_bwe);
|
||||||
|
|
||||||
RunBaseTest(&test);
|
RunBaseTest(&test);
|
||||||
}
|
}
|
||||||
|
@ -989,7 +1016,10 @@ void CallPerfTest::TestMinAudioVideoBitrate(int test_bitrate_from,
|
||||||
#define MAYBE_MinVideoAndAudioBitrate MinVideoAndAudioBitrate
|
#define MAYBE_MinVideoAndAudioBitrate MinVideoAndAudioBitrate
|
||||||
#endif
|
#endif
|
||||||
TEST_F(CallPerfTest, MAYBE_MinVideoAndAudioBitrate) {
|
TEST_F(CallPerfTest, MAYBE_MinVideoAndAudioBitrate) {
|
||||||
TestMinAudioVideoBitrate(110, 40, -10, 10000, 70000, 200000);
|
TestMinAudioVideoBitrate(false, 110, 40, -10, 10000, 70000, 200000);
|
||||||
|
}
|
||||||
|
TEST_F(CallPerfTest, MinVideoAndAudioBitrateWStrategy) {
|
||||||
|
TestMinAudioVideoBitrate(true, 110, 40, -10, 10000, 70000, 200000);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
|
@ -196,6 +196,12 @@ Call::Stats DegradedCall::GetStats() const {
|
||||||
return call_->GetStats();
|
return call_->GetStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DegradedCall::SetBitrateAllocationStrategy(
|
||||||
|
std::unique_ptr<rtc::BitrateAllocationStrategy>
|
||||||
|
bitrate_allocation_strategy) {
|
||||||
|
call_->SetBitrateAllocationStrategy(std::move(bitrate_allocation_strategy));
|
||||||
|
}
|
||||||
|
|
||||||
void DegradedCall::SignalChannelNetworkState(MediaType media,
|
void DegradedCall::SignalChannelNetworkState(MediaType media,
|
||||||
NetworkState state) {
|
NetworkState state) {
|
||||||
call_->SignalChannelNetworkState(media, state);
|
call_->SignalChannelNetworkState(media, state);
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "call/video_send_stream.h"
|
#include "call/video_send_stream.h"
|
||||||
#include "modules/include/module.h"
|
#include "modules/include/module.h"
|
||||||
#include "modules/utility/include/process_thread.h"
|
#include "modules/utility/include/process_thread.h"
|
||||||
|
#include "rtc_base/bitrate_allocation_strategy.h"
|
||||||
#include "rtc_base/copy_on_write_buffer.h"
|
#include "rtc_base/copy_on_write_buffer.h"
|
||||||
#include "rtc_base/network/sent_packet.h"
|
#include "rtc_base/network/sent_packet.h"
|
||||||
#include "system_wrappers/include/clock.h"
|
#include "system_wrappers/include/clock.h"
|
||||||
|
@ -106,6 +107,10 @@ class DegradedCall : public Call, private Transport, private PacketReceiver {
|
||||||
|
|
||||||
Stats GetStats() const override;
|
Stats GetStats() const override;
|
||||||
|
|
||||||
|
void SetBitrateAllocationStrategy(
|
||||||
|
std::unique_ptr<rtc::BitrateAllocationStrategy>
|
||||||
|
bitrate_allocation_strategy) override;
|
||||||
|
|
||||||
void SignalChannelNetworkState(MediaType media, NetworkState state) override;
|
void SignalChannelNetworkState(MediaType media, NetworkState state) override;
|
||||||
void OnAudioTransportOverheadChanged(
|
void OnAudioTransportOverheadChanged(
|
||||||
int transport_overhead_per_packet) override;
|
int transport_overhead_per_packet) override;
|
||||||
|
|
|
@ -156,6 +156,9 @@ class VideoSendStream {
|
||||||
// Enables periodic bandwidth probing in application-limited region.
|
// Enables periodic bandwidth probing in application-limited region.
|
||||||
bool periodic_alr_bandwidth_probing = false;
|
bool periodic_alr_bandwidth_probing = false;
|
||||||
|
|
||||||
|
// Track ID as specified during track creation.
|
||||||
|
std::string track_id;
|
||||||
|
|
||||||
// An optional custom frame encryptor that allows the entire frame to be
|
// An optional custom frame encryptor that allows the entire frame to be
|
||||||
// encrypted in whatever way the caller chooses. This is not required by
|
// encrypted in whatever way the caller chooses. This is not required by
|
||||||
// default.
|
// default.
|
||||||
|
|
|
@ -618,6 +618,12 @@ webrtc::Call::Stats FakeCall::GetStats() const {
|
||||||
return stats_;
|
return stats_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FakeCall::SetBitrateAllocationStrategy(
|
||||||
|
std::unique_ptr<rtc::BitrateAllocationStrategy>
|
||||||
|
bitrate_allocation_strategy) {
|
||||||
|
// TODO(alexnarest): not implemented
|
||||||
|
}
|
||||||
|
|
||||||
void FakeCall::SignalChannelNetworkState(webrtc::MediaType media,
|
void FakeCall::SignalChannelNetworkState(webrtc::MediaType media,
|
||||||
webrtc::NetworkState state) {
|
webrtc::NetworkState state) {
|
||||||
switch (media) {
|
switch (media) {
|
||||||
|
|
|
@ -347,6 +347,10 @@ class FakeCall final : public webrtc::Call, public webrtc::PacketReceiver {
|
||||||
|
|
||||||
webrtc::Call::Stats GetStats() const override;
|
webrtc::Call::Stats GetStats() const override;
|
||||||
|
|
||||||
|
void SetBitrateAllocationStrategy(
|
||||||
|
std::unique_ptr<rtc::BitrateAllocationStrategy>
|
||||||
|
bitrate_allocation_strategy) override;
|
||||||
|
|
||||||
void SignalChannelNetworkState(webrtc::MediaType media,
|
void SignalChannelNetworkState(webrtc::MediaType media,
|
||||||
webrtc::NetworkState state) override;
|
webrtc::NetworkState state) override;
|
||||||
void OnAudioTransportOverheadChanged(
|
void OnAudioTransportOverheadChanged(
|
||||||
|
|
|
@ -1839,6 +1839,7 @@ WebRtcVideoChannel::WebRtcVideoSendStream::WebRtcVideoSendStream(
|
||||||
}
|
}
|
||||||
|
|
||||||
parameters_.config.rtp.c_name = sp.cname;
|
parameters_.config.rtp.c_name = sp.cname;
|
||||||
|
parameters_.config.track_id = sp.id;
|
||||||
if (rtp_extensions) {
|
if (rtp_extensions) {
|
||||||
parameters_.config.rtp.extensions = *rtp_extensions;
|
parameters_.config.rtp.extensions = *rtp_extensions;
|
||||||
rtp_parameters_.header_extensions = *rtp_extensions;
|
rtp_parameters_.header_extensions = *rtp_extensions;
|
||||||
|
|
|
@ -235,7 +235,6 @@ rtc_static_library("peerconnection") {
|
||||||
"../rtc_base:checks",
|
"../rtc_base:checks",
|
||||||
"../rtc_base:rtc_base_approved",
|
"../rtc_base:rtc_base_approved",
|
||||||
"../rtc_base:safe_minmax",
|
"../rtc_base:safe_minmax",
|
||||||
"../rtc_base/experiments:field_trial_parser",
|
|
||||||
"../rtc_base/system:file_wrapper",
|
"../rtc_base/system:file_wrapper",
|
||||||
"../rtc_base/system:rtc_export",
|
"../rtc_base/system:rtc_export",
|
||||||
"../rtc_base/third_party/base64",
|
"../rtc_base/third_party/base64",
|
||||||
|
|
|
@ -3724,6 +3724,29 @@ RTCError PeerConnection::SetBitrate(const BitrateSettings& bitrate) {
|
||||||
return RTCError::OK();
|
return RTCError::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PeerConnection::SetBitrateAllocationStrategy(
|
||||||
|
std::unique_ptr<rtc::BitrateAllocationStrategy>
|
||||||
|
bitrate_allocation_strategy) {
|
||||||
|
if (!worker_thread()->IsCurrent()) {
|
||||||
|
// TODO(kwiberg): Use a lambda instead when C++14 makes it possible to
|
||||||
|
// move-capture values in lambdas.
|
||||||
|
struct Task {
|
||||||
|
PeerConnection* const pc;
|
||||||
|
std::unique_ptr<rtc::BitrateAllocationStrategy> strategy;
|
||||||
|
void operator()() {
|
||||||
|
RTC_DCHECK_RUN_ON(pc->worker_thread());
|
||||||
|
pc->call_->SetBitrateAllocationStrategy(std::move(strategy));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
worker_thread()->Invoke<void>(
|
||||||
|
RTC_FROM_HERE, Task{this, std::move(bitrate_allocation_strategy)});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RTC_DCHECK_RUN_ON(worker_thread());
|
||||||
|
RTC_DCHECK(call_.get());
|
||||||
|
call_->SetBitrateAllocationStrategy(std::move(bitrate_allocation_strategy));
|
||||||
|
}
|
||||||
|
|
||||||
void PeerConnection::SetAudioPlayout(bool playout) {
|
void PeerConnection::SetAudioPlayout(bool playout) {
|
||||||
if (!worker_thread()->IsCurrent()) {
|
if (!worker_thread()->IsCurrent()) {
|
||||||
worker_thread()->Invoke<void>(
|
worker_thread()->Invoke<void>(
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
#include "pc/stats_collector.h"
|
#include "pc/stats_collector.h"
|
||||||
#include "pc/stream_collection.h"
|
#include "pc/stream_collection.h"
|
||||||
#include "pc/webrtc_session_description_factory.h"
|
#include "pc/webrtc_session_description_factory.h"
|
||||||
#include "rtc_base/experiments/field_trial_parser.h"
|
|
||||||
#include "rtc_base/race_checker.h"
|
#include "rtc_base/race_checker.h"
|
||||||
#include "rtc_base/unique_id_generator.h"
|
#include "rtc_base/unique_id_generator.h"
|
||||||
|
|
||||||
|
@ -196,6 +195,10 @@ class PeerConnection : public PeerConnectionInternal,
|
||||||
|
|
||||||
RTCError SetBitrate(const BitrateSettings& bitrate) override;
|
RTCError SetBitrate(const BitrateSettings& bitrate) override;
|
||||||
|
|
||||||
|
void SetBitrateAllocationStrategy(
|
||||||
|
std::unique_ptr<rtc::BitrateAllocationStrategy>
|
||||||
|
bitrate_allocation_strategy) override;
|
||||||
|
|
||||||
void SetAudioPlayout(bool playout) override;
|
void SetAudioPlayout(bool playout) override;
|
||||||
void SetAudioRecording(bool recording) override;
|
void SetAudioRecording(bool recording) override;
|
||||||
|
|
||||||
|
|
|
@ -186,6 +186,10 @@ class FakePeerConnectionBase : public PeerConnectionInternal {
|
||||||
return RTCError(RTCErrorType::UNSUPPORTED_OPERATION, "Not implemented");
|
return RTCError(RTCErrorType::UNSUPPORTED_OPERATION, "Not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetBitrateAllocationStrategy(
|
||||||
|
std::unique_ptr<rtc::BitrateAllocationStrategy>
|
||||||
|
bitrate_allocation_strategy) override {}
|
||||||
|
|
||||||
void SetAudioPlayout(bool playout) override {}
|
void SetAudioPlayout(bool playout) override {}
|
||||||
|
|
||||||
void SetAudioRecording(bool recording) override {}
|
void SetAudioRecording(bool recording) override {}
|
||||||
|
|
|
@ -75,10 +75,13 @@ rtc_source_set("rtc_base_approved") {
|
||||||
":checks",
|
":checks",
|
||||||
":rtc_task_queue",
|
":rtc_task_queue",
|
||||||
":safe_compare",
|
":safe_compare",
|
||||||
|
":safe_minmax",
|
||||||
":type_traits",
|
":type_traits",
|
||||||
"../api:array_view",
|
"../api:array_view",
|
||||||
"../api:function_view",
|
"../api:function_view",
|
||||||
"../api:scoped_refptr",
|
"../api:scoped_refptr",
|
||||||
|
"../system_wrappers:field_trial",
|
||||||
|
"experiments:field_trial_parser",
|
||||||
"system:arch",
|
"system:arch",
|
||||||
"system:unused",
|
"system:unused",
|
||||||
"third_party/base64",
|
"third_party/base64",
|
||||||
|
@ -91,6 +94,8 @@ rtc_source_set("rtc_base_approved") {
|
||||||
"bind.h",
|
"bind.h",
|
||||||
"bit_buffer.cc",
|
"bit_buffer.cc",
|
||||||
"bit_buffer.h",
|
"bit_buffer.h",
|
||||||
|
"bitrate_allocation_strategy.cc",
|
||||||
|
"bitrate_allocation_strategy.h",
|
||||||
"buffer.h",
|
"buffer.h",
|
||||||
"buffer_queue.cc",
|
"buffer_queue.cc",
|
||||||
"buffer_queue.h",
|
"buffer_queue.h",
|
||||||
|
@ -1155,6 +1160,7 @@ if (rtc_include_tests) {
|
||||||
"base64_unittest.cc",
|
"base64_unittest.cc",
|
||||||
"bind_unittest.cc",
|
"bind_unittest.cc",
|
||||||
"bit_buffer_unittest.cc",
|
"bit_buffer_unittest.cc",
|
||||||
|
"bitrate_allocation_strategy_unittest.cc",
|
||||||
"buffer_queue_unittest.cc",
|
"buffer_queue_unittest.cc",
|
||||||
"buffer_unittest.cc",
|
"buffer_unittest.cc",
|
||||||
"byte_buffer_unittest.cc",
|
"byte_buffer_unittest.cc",
|
||||||
|
|
169
rtc_base/bitrate_allocation_strategy.cc
Normal file
169
rtc_base/bitrate_allocation_strategy.cc
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rtc_base/bitrate_allocation_strategy.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <map>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "rtc_base/numerics/safe_minmax.h"
|
||||||
|
#include "system_wrappers/include/field_trial.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
AudioPriorityConfig::AudioPriorityConfig()
|
||||||
|
: min_rate("min"), max_rate("max"), target_rate("target") {
|
||||||
|
std::string trial_string;
|
||||||
|
// TODO(bugs.webrtc.org/9889): Remove this when Chromium build has been fixed.
|
||||||
|
#if !defined(WEBRTC_CHROMIUM_BUILD)
|
||||||
|
trial_string = field_trial::FindFullName("WebRTC-Bwe-AudioPriority");
|
||||||
|
#endif
|
||||||
|
ParseFieldTrial({&min_rate, &max_rate, &target_rate}, trial_string);
|
||||||
|
}
|
||||||
|
AudioPriorityConfig::AudioPriorityConfig(const AudioPriorityConfig&) = default;
|
||||||
|
AudioPriorityConfig::~AudioPriorityConfig() = default;
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
namespace rtc {
|
||||||
|
|
||||||
|
// The purpose of this is to allow video streams to use extra bandwidth for FEC.
|
||||||
|
// TODO(bugs.webrtc.org/8541): May be worth to refactor to keep this logic in
|
||||||
|
// video send stream. Similar logic is implemented in BitrateAllocator.
|
||||||
|
|
||||||
|
const int kTransmissionMaxBitrateMultiplier = 2;
|
||||||
|
|
||||||
|
std::vector<uint32_t> BitrateAllocationStrategy::SetAllBitratesToMinimum(
|
||||||
|
const std::vector<BitrateAllocationStrategy::TrackConfig>& track_configs) {
|
||||||
|
std::vector<uint32_t> track_allocations;
|
||||||
|
track_allocations.reserve(track_configs.size());
|
||||||
|
for (const auto& track_config : track_configs) {
|
||||||
|
track_allocations.push_back(track_config.min_bitrate_bps);
|
||||||
|
}
|
||||||
|
return track_allocations;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint32_t> BitrateAllocationStrategy::DistributeBitratesEvenly(
|
||||||
|
const std::vector<BitrateAllocationStrategy::TrackConfig>& track_configs,
|
||||||
|
uint32_t available_bitrate) {
|
||||||
|
std::vector<uint32_t> track_allocations =
|
||||||
|
SetAllBitratesToMinimum(track_configs);
|
||||||
|
uint32_t sum_min_bitrates = 0;
|
||||||
|
uint32_t sum_max_bitrates = 0;
|
||||||
|
for (const auto& track_config : track_configs) {
|
||||||
|
sum_min_bitrates += track_config.min_bitrate_bps;
|
||||||
|
sum_max_bitrates += track_config.max_bitrate_bps;
|
||||||
|
}
|
||||||
|
if (sum_min_bitrates >= available_bitrate) {
|
||||||
|
return track_allocations;
|
||||||
|
} else if (available_bitrate >= sum_max_bitrates) {
|
||||||
|
auto track_allocations_it = track_allocations.begin();
|
||||||
|
for (const auto& track_config : track_configs) {
|
||||||
|
*track_allocations_it++ = track_config.max_bitrate_bps;
|
||||||
|
}
|
||||||
|
return track_allocations;
|
||||||
|
} else {
|
||||||
|
// If sum_min_bitrates < available_bitrate < sum_max_bitrates allocate
|
||||||
|
// bitrates evenly up to max_bitrate_bps starting from the track with the
|
||||||
|
// lowest max_bitrate_bps. Remainder of available bitrate split evenly among
|
||||||
|
// remaining tracks.
|
||||||
|
std::multimap<uint32_t, size_t> max_bitrate_sorted_configs;
|
||||||
|
for (const auto& track_config : track_configs) {
|
||||||
|
max_bitrate_sorted_configs.insert(
|
||||||
|
std::make_pair(track_config.max_bitrate_bps,
|
||||||
|
&track_config - &track_configs.front()));
|
||||||
|
}
|
||||||
|
uint32_t total_available_increase = available_bitrate - sum_min_bitrates;
|
||||||
|
int processed_configs = 0;
|
||||||
|
for (const auto& track_config_pair : max_bitrate_sorted_configs) {
|
||||||
|
uint32_t available_increase =
|
||||||
|
total_available_increase /
|
||||||
|
(static_cast<uint32_t>(track_configs.size() - processed_configs));
|
||||||
|
uint32_t consumed_increase =
|
||||||
|
std::min(track_configs[track_config_pair.second].max_bitrate_bps -
|
||||||
|
track_configs[track_config_pair.second].min_bitrate_bps,
|
||||||
|
available_increase);
|
||||||
|
track_allocations[track_config_pair.second] += consumed_increase;
|
||||||
|
total_available_increase -= consumed_increase;
|
||||||
|
++processed_configs;
|
||||||
|
}
|
||||||
|
return track_allocations;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AudioPriorityBitrateAllocationStrategy::AudioPriorityBitrateAllocationStrategy(
|
||||||
|
std::string audio_track_id,
|
||||||
|
uint32_t sufficient_audio_bitrate)
|
||||||
|
: audio_track_id_(audio_track_id),
|
||||||
|
sufficient_audio_bitrate_(sufficient_audio_bitrate) {
|
||||||
|
if (config_.target_rate) {
|
||||||
|
sufficient_audio_bitrate_ = config_.target_rate->bps();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint32_t> AudioPriorityBitrateAllocationStrategy::AllocateBitrates(
|
||||||
|
uint32_t available_bitrate,
|
||||||
|
std::vector<BitrateAllocationStrategy::TrackConfig> track_configs) {
|
||||||
|
TrackConfig* audio_track_config = nullptr;
|
||||||
|
size_t audio_config_index = 0;
|
||||||
|
uint32_t sum_min_bitrates = 0;
|
||||||
|
uint32_t sum_max_bitrates = 0;
|
||||||
|
|
||||||
|
for (auto& track_config : track_configs) {
|
||||||
|
if (track_config.track_id == audio_track_id_) {
|
||||||
|
audio_config_index = &track_config - &track_configs[0];
|
||||||
|
audio_track_config = &track_config;
|
||||||
|
if (config_.min_rate)
|
||||||
|
audio_track_config->min_bitrate_bps = config_.min_rate->bps();
|
||||||
|
if (config_.max_rate)
|
||||||
|
audio_track_config->max_bitrate_bps = config_.max_rate->bps();
|
||||||
|
}
|
||||||
|
sum_min_bitrates += track_config.min_bitrate_bps;
|
||||||
|
sum_max_bitrates += track_config.max_bitrate_bps;
|
||||||
|
}
|
||||||
|
if (sum_max_bitrates < available_bitrate) {
|
||||||
|
// Allow non audio streams to go above max upto
|
||||||
|
// kTransmissionMaxBitrateMultiplier * max_bitrate_bps
|
||||||
|
for (auto& track_config : track_configs) {
|
||||||
|
if (&track_config != audio_track_config)
|
||||||
|
track_config.max_bitrate_bps *= kTransmissionMaxBitrateMultiplier;
|
||||||
|
}
|
||||||
|
return DistributeBitratesEvenly(track_configs, available_bitrate);
|
||||||
|
}
|
||||||
|
if (!audio_track_config) {
|
||||||
|
return DistributeBitratesEvenly(track_configs, available_bitrate);
|
||||||
|
}
|
||||||
|
auto safe_sufficient_audio_bitrate = rtc::SafeClamp(
|
||||||
|
sufficient_audio_bitrate_, audio_track_config->min_bitrate_bps,
|
||||||
|
audio_track_config->max_bitrate_bps);
|
||||||
|
if (available_bitrate <= sum_min_bitrates) {
|
||||||
|
return SetAllBitratesToMinimum(track_configs);
|
||||||
|
} else {
|
||||||
|
if (available_bitrate <= sum_min_bitrates + safe_sufficient_audio_bitrate -
|
||||||
|
audio_track_config->min_bitrate_bps) {
|
||||||
|
std::vector<uint32_t> track_allocations =
|
||||||
|
SetAllBitratesToMinimum(track_configs);
|
||||||
|
track_allocations[audio_config_index] +=
|
||||||
|
available_bitrate - sum_min_bitrates;
|
||||||
|
return track_allocations;
|
||||||
|
} else {
|
||||||
|
// Setting audio track minimum to safe_sufficient_audio_bitrate will
|
||||||
|
// allow using DistributeBitratesEvenly to allocate at least sufficient
|
||||||
|
// bitrate for audio and the rest evenly.
|
||||||
|
audio_track_config->min_bitrate_bps = safe_sufficient_audio_bitrate;
|
||||||
|
std::vector<uint32_t> track_allocations =
|
||||||
|
DistributeBitratesEvenly(track_configs, available_bitrate);
|
||||||
|
return track_allocations;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace rtc
|
121
rtc_base/bitrate_allocation_strategy.h
Normal file
121
rtc_base/bitrate_allocation_strategy.h
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 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 RTC_BASE_BITRATE_ALLOCATION_STRATEGY_H_
|
||||||
|
#define RTC_BASE_BITRATE_ALLOCATION_STRATEGY_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "api/array_view.h"
|
||||||
|
#include "rtc_base/experiments/field_trial_parser.h"
|
||||||
|
#include "rtc_base/experiments/field_trial_units.h"
|
||||||
|
|
||||||
|
namespace rtc {
|
||||||
|
|
||||||
|
// Pluggable strategy allows configuration of bitrate allocation per media
|
||||||
|
// track.
|
||||||
|
//
|
||||||
|
// The strategy should provide allocation for every track passed with
|
||||||
|
// track_configs in AllocateBitrates. The allocations are constrained by
|
||||||
|
// max_bitrate_bps, min_bitrate_bps defining the track supported range and
|
||||||
|
// enforce_min_bitrate indicating if the track my be paused by allocating 0
|
||||||
|
// bitrate.
|
||||||
|
class BitrateAllocationStrategy {
|
||||||
|
public:
|
||||||
|
struct TrackConfig {
|
||||||
|
TrackConfig(uint32_t min_bitrate_bps,
|
||||||
|
uint32_t max_bitrate_bps,
|
||||||
|
bool enforce_min_bitrate,
|
||||||
|
std::string track_id)
|
||||||
|
: min_bitrate_bps(min_bitrate_bps),
|
||||||
|
max_bitrate_bps(max_bitrate_bps),
|
||||||
|
enforce_min_bitrate(enforce_min_bitrate),
|
||||||
|
track_id(track_id) {}
|
||||||
|
TrackConfig(const TrackConfig& track_config) = default;
|
||||||
|
virtual ~TrackConfig() = default;
|
||||||
|
TrackConfig() {}
|
||||||
|
|
||||||
|
// Minimum bitrate supported by track.
|
||||||
|
uint32_t min_bitrate_bps;
|
||||||
|
|
||||||
|
// Maximum bitrate supported by track.
|
||||||
|
uint32_t max_bitrate_bps;
|
||||||
|
|
||||||
|
// True means track may not be paused by allocating 0 bitrate.
|
||||||
|
bool enforce_min_bitrate;
|
||||||
|
|
||||||
|
// MediaStreamTrack ID as defined by application. May be empty.
|
||||||
|
std::string track_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
// These are only used by AudioPriorityBitrateAllocationStrategy. They are
|
||||||
|
// exposed here to they can be unit tested.
|
||||||
|
static std::vector<uint32_t> SetAllBitratesToMinimum(
|
||||||
|
const std::vector<BitrateAllocationStrategy::TrackConfig>& track_configs);
|
||||||
|
static std::vector<uint32_t> DistributeBitratesEvenly(
|
||||||
|
const std::vector<BitrateAllocationStrategy::TrackConfig>& track_configs,
|
||||||
|
uint32_t available_bitrate);
|
||||||
|
|
||||||
|
// Strategy is expected to allocate all available_bitrate up to the sum of
|
||||||
|
// max_bitrate_bps of all tracks. If available_bitrate is less than the sum of
|
||||||
|
// min_bitrate_bps of all tracks, tracks having enforce_min_bitrate set to
|
||||||
|
// false may get 0 allocation and are suppoused to pause, tracks with
|
||||||
|
// enforce_min_bitrate set to true are expecting to get min_bitrate_bps.
|
||||||
|
//
|
||||||
|
// If the strategy will allocate more than available_bitrate it may cause
|
||||||
|
// overuse of the currently available network capacity and may cause increase
|
||||||
|
// in RTT and packet loss. Allocating less than available bitrate may cause
|
||||||
|
// available_bitrate decrease.
|
||||||
|
virtual std::vector<uint32_t> AllocateBitrates(
|
||||||
|
uint32_t available_bitrate,
|
||||||
|
std::vector<BitrateAllocationStrategy::TrackConfig> track_configs) = 0;
|
||||||
|
|
||||||
|
virtual ~BitrateAllocationStrategy() = default;
|
||||||
|
};
|
||||||
|
} // namespace rtc
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
struct AudioPriorityConfig {
|
||||||
|
FieldTrialOptional<DataRate> min_rate;
|
||||||
|
FieldTrialOptional<DataRate> max_rate;
|
||||||
|
FieldTrialOptional<DataRate> target_rate;
|
||||||
|
AudioPriorityConfig();
|
||||||
|
AudioPriorityConfig(const AudioPriorityConfig&);
|
||||||
|
AudioPriorityConfig& operator=(const AudioPriorityConfig&) = default;
|
||||||
|
~AudioPriorityConfig();
|
||||||
|
};
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
namespace rtc {
|
||||||
|
// Simple allocation strategy giving priority to audio until
|
||||||
|
// sufficient_audio_bitrate is reached. Bitrate is distributed evenly between
|
||||||
|
// the tracks after sufficient_audio_bitrate is reached. This implementation
|
||||||
|
// does not pause tracks even if enforce_min_bitrate is false.
|
||||||
|
class AudioPriorityBitrateAllocationStrategy
|
||||||
|
: public BitrateAllocationStrategy {
|
||||||
|
public:
|
||||||
|
AudioPriorityBitrateAllocationStrategy(std::string audio_track_id,
|
||||||
|
uint32_t sufficient_audio_bitrate);
|
||||||
|
std::vector<uint32_t> AllocateBitrates(
|
||||||
|
uint32_t available_bitrate,
|
||||||
|
std::vector<BitrateAllocationStrategy::TrackConfig> track_configs)
|
||||||
|
override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
webrtc::AudioPriorityConfig config_;
|
||||||
|
std::string audio_track_id_;
|
||||||
|
uint32_t sufficient_audio_bitrate_;
|
||||||
|
};
|
||||||
|
} // namespace rtc
|
||||||
|
|
||||||
|
#endif // RTC_BASE_BITRATE_ALLOCATION_STRATEGY_H_
|
237
rtc_base/bitrate_allocation_strategy_unittest.cc
Normal file
237
rtc_base/bitrate_allocation_strategy_unittest.cc
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rtc_base/bitrate_allocation_strategy.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "test/gtest.h"
|
||||||
|
|
||||||
|
namespace rtc {
|
||||||
|
|
||||||
|
std::vector<const rtc::BitrateAllocationStrategy::TrackConfig*>
|
||||||
|
MakeTrackConfigPtrsVector(
|
||||||
|
const std::vector<BitrateAllocationStrategy::TrackConfig>& track_configs) {
|
||||||
|
std::vector<const rtc::BitrateAllocationStrategy::TrackConfig*>
|
||||||
|
track_config_ptrs(track_configs.size());
|
||||||
|
int i = 0;
|
||||||
|
for (const auto& c : track_configs) {
|
||||||
|
track_config_ptrs[i++] = &c;
|
||||||
|
}
|
||||||
|
return track_config_ptrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(BitrateAllocationStrategyTest, SetAllBitratesToMinimum) {
|
||||||
|
const std::string audio_track_id = "audio_track";
|
||||||
|
constexpr uint32_t min_audio_bitrate = 6000;
|
||||||
|
constexpr uint32_t max_audio_bitrate = 64000;
|
||||||
|
const std::string video_track_id = "video_track";
|
||||||
|
constexpr uint32_t min_video_bitrate = 30000;
|
||||||
|
constexpr uint32_t max_video_bitrate = 300000;
|
||||||
|
constexpr uint32_t min_other_bitrate = 3000;
|
||||||
|
constexpr uint32_t max_other_bitrate = 30000;
|
||||||
|
|
||||||
|
std::vector<BitrateAllocationStrategy::TrackConfig> track_configs = {
|
||||||
|
BitrateAllocationStrategy::TrackConfig(
|
||||||
|
min_audio_bitrate, max_audio_bitrate, false, audio_track_id),
|
||||||
|
BitrateAllocationStrategy::TrackConfig(
|
||||||
|
min_video_bitrate, max_video_bitrate, false, video_track_id),
|
||||||
|
BitrateAllocationStrategy::TrackConfig(min_other_bitrate,
|
||||||
|
max_other_bitrate, false, "")};
|
||||||
|
|
||||||
|
std::vector<uint32_t> allocations =
|
||||||
|
BitrateAllocationStrategy::SetAllBitratesToMinimum(track_configs);
|
||||||
|
EXPECT_EQ(min_audio_bitrate, allocations[0]);
|
||||||
|
EXPECT_EQ(min_video_bitrate, allocations[1]);
|
||||||
|
EXPECT_EQ(min_other_bitrate, allocations[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(BitrateAllocationStrategyTest, DistributeBitratesEvenly) {
|
||||||
|
const std::string audio_track_id = "audio_track";
|
||||||
|
constexpr uint32_t min_audio_bitrate = 16000;
|
||||||
|
constexpr uint32_t max_audio_bitrate = 64000;
|
||||||
|
const std::string video_track_id = "video_track";
|
||||||
|
constexpr uint32_t min_video_bitrate = 30000;
|
||||||
|
constexpr uint32_t max_video_bitrate = 300000;
|
||||||
|
constexpr uint32_t min_other_bitrate = 3000;
|
||||||
|
constexpr uint32_t max_other_bitrate = 30000;
|
||||||
|
constexpr uint32_t available_bitrate = 52000;
|
||||||
|
constexpr uint32_t even_bitrate_increase =
|
||||||
|
(available_bitrate - min_audio_bitrate - min_video_bitrate -
|
||||||
|
min_other_bitrate) /
|
||||||
|
3;
|
||||||
|
|
||||||
|
std::vector<BitrateAllocationStrategy::TrackConfig> track_configs = {
|
||||||
|
BitrateAllocationStrategy::TrackConfig(
|
||||||
|
min_audio_bitrate, max_audio_bitrate, false, audio_track_id),
|
||||||
|
BitrateAllocationStrategy::TrackConfig(
|
||||||
|
min_video_bitrate, max_video_bitrate, false, video_track_id),
|
||||||
|
BitrateAllocationStrategy::TrackConfig(min_other_bitrate,
|
||||||
|
max_other_bitrate, false, "")};
|
||||||
|
|
||||||
|
std::vector<uint32_t> allocations =
|
||||||
|
BitrateAllocationStrategy::DistributeBitratesEvenly(track_configs,
|
||||||
|
available_bitrate);
|
||||||
|
EXPECT_EQ(min_audio_bitrate + even_bitrate_increase, allocations[0]);
|
||||||
|
EXPECT_EQ(min_video_bitrate + even_bitrate_increase, allocations[1]);
|
||||||
|
EXPECT_EQ(min_other_bitrate + even_bitrate_increase, allocations[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint32_t> RunAudioPriorityAllocation(
|
||||||
|
uint32_t sufficient_audio_bitrate,
|
||||||
|
std::string audio_track_id,
|
||||||
|
uint32_t min_audio_bitrate,
|
||||||
|
uint32_t max_audio_bitrate,
|
||||||
|
std::string video_track_id,
|
||||||
|
uint32_t min_video_bitrate,
|
||||||
|
uint32_t max_video_bitrate,
|
||||||
|
uint32_t min_other_bitrate,
|
||||||
|
uint32_t max_other_bitrate,
|
||||||
|
uint32_t available_bitrate) {
|
||||||
|
AudioPriorityBitrateAllocationStrategy allocation_strategy(
|
||||||
|
audio_track_id, sufficient_audio_bitrate);
|
||||||
|
std::vector<BitrateAllocationStrategy::TrackConfig> track_configs = {
|
||||||
|
BitrateAllocationStrategy::TrackConfig(
|
||||||
|
min_audio_bitrate, max_audio_bitrate, false, audio_track_id),
|
||||||
|
BitrateAllocationStrategy::TrackConfig(
|
||||||
|
min_video_bitrate, max_video_bitrate, false, video_track_id),
|
||||||
|
BitrateAllocationStrategy::TrackConfig(min_other_bitrate,
|
||||||
|
max_other_bitrate, false, "")};
|
||||||
|
|
||||||
|
return allocation_strategy.AllocateBitrates(available_bitrate, track_configs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that when the available bitrate is less than the sum of the minimum
|
||||||
|
// bitrates, the minimum bitrate is allocated for each track.
|
||||||
|
TEST(AudioPriorityBitrateAllocationStrategyTest, MinAllocateBitrate) {
|
||||||
|
constexpr uint32_t sufficient_audio_bitrate = 16000;
|
||||||
|
const std::string audio_track_id = "audio_track";
|
||||||
|
constexpr uint32_t min_audio_bitrate = 6000;
|
||||||
|
constexpr uint32_t max_audio_bitrate = 64000;
|
||||||
|
const std::string video_track_id = "video_track";
|
||||||
|
constexpr uint32_t min_video_bitrate = 30000;
|
||||||
|
constexpr uint32_t max_video_bitrate = 300000;
|
||||||
|
constexpr uint32_t min_other_bitrate = 3000;
|
||||||
|
constexpr uint32_t max_other_bitrate = 30000;
|
||||||
|
constexpr uint32_t available_bitrate = 10000;
|
||||||
|
|
||||||
|
std::vector<uint32_t> allocations = RunAudioPriorityAllocation(
|
||||||
|
sufficient_audio_bitrate, audio_track_id, min_audio_bitrate,
|
||||||
|
max_audio_bitrate, video_track_id, min_video_bitrate, max_video_bitrate,
|
||||||
|
min_other_bitrate, max_other_bitrate, available_bitrate);
|
||||||
|
EXPECT_EQ(min_audio_bitrate, allocations[0]);
|
||||||
|
EXPECT_EQ(min_video_bitrate, allocations[1]);
|
||||||
|
EXPECT_EQ(min_other_bitrate, allocations[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that when the available bitrate is more than the sum of the max
|
||||||
|
// bitrates, the max bitrate is allocated for each track.
|
||||||
|
TEST(AudioPriorityBitrateAllocationStrategyTest, MaxAllocateBitrate) {
|
||||||
|
constexpr uint32_t sufficient_audio_bitrate = 16000;
|
||||||
|
const std::string audio_track_id = "audio_track";
|
||||||
|
constexpr uint32_t min_audio_bitrate = 6000;
|
||||||
|
constexpr uint32_t max_audio_bitrate = 64000;
|
||||||
|
const std::string video_track_id = "video_track";
|
||||||
|
constexpr uint32_t min_video_bitrate = 30000;
|
||||||
|
constexpr uint32_t max_video_bitrate = 300000;
|
||||||
|
constexpr uint32_t min_other_bitrate = 3000;
|
||||||
|
constexpr uint32_t max_other_bitrate = 30000;
|
||||||
|
constexpr uint32_t available_bitrate = 400000;
|
||||||
|
|
||||||
|
std::vector<uint32_t> allocations = RunAudioPriorityAllocation(
|
||||||
|
sufficient_audio_bitrate, audio_track_id, min_audio_bitrate,
|
||||||
|
max_audio_bitrate, video_track_id, min_video_bitrate, max_video_bitrate,
|
||||||
|
min_other_bitrate, max_other_bitrate, available_bitrate);
|
||||||
|
|
||||||
|
// TODO(bugs.webrtc.org/8541): Until the bug is fixed not audio streams will
|
||||||
|
// get up to kTransmissionMaxBitrateMultiplier*max_bitrate
|
||||||
|
constexpr uint32_t video_bitrate =
|
||||||
|
(available_bitrate - max_audio_bitrate - max_other_bitrate * 2);
|
||||||
|
EXPECT_EQ(max_audio_bitrate, allocations[0]);
|
||||||
|
EXPECT_EQ(video_bitrate, allocations[1]);
|
||||||
|
EXPECT_EQ(max_other_bitrate * 2, allocations[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that audio track will get up to sufficient bitrate before video and
|
||||||
|
// other bitrate will be allocated.
|
||||||
|
TEST(AudioPriorityBitrateAllocationStrategyTest, AudioPriorityAllocateBitrate) {
|
||||||
|
constexpr uint32_t sufficient_audio_bitrate = 16000;
|
||||||
|
const std::string audio_track_id = "audio_track";
|
||||||
|
constexpr uint32_t min_audio_bitrate = 6000;
|
||||||
|
constexpr uint32_t max_audio_bitrate = 64000;
|
||||||
|
const std::string video_track_id = "video_track";
|
||||||
|
constexpr uint32_t min_video_bitrate = 30000;
|
||||||
|
constexpr uint32_t max_video_bitrate = 300000;
|
||||||
|
constexpr uint32_t min_other_bitrate = 3000;
|
||||||
|
constexpr uint32_t max_other_bitrate = 30000;
|
||||||
|
constexpr uint32_t available_bitrate = 49000;
|
||||||
|
|
||||||
|
std::vector<uint32_t> allocations = RunAudioPriorityAllocation(
|
||||||
|
sufficient_audio_bitrate, audio_track_id, min_audio_bitrate,
|
||||||
|
max_audio_bitrate, video_track_id, min_video_bitrate, max_video_bitrate,
|
||||||
|
min_other_bitrate, max_other_bitrate, available_bitrate);
|
||||||
|
EXPECT_EQ(sufficient_audio_bitrate, allocations[0]);
|
||||||
|
EXPECT_EQ(min_video_bitrate, allocations[1]);
|
||||||
|
EXPECT_EQ(min_other_bitrate, allocations[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that bitrate will be allocated evenly after sufficient audio bitrate is
|
||||||
|
// allocated.
|
||||||
|
TEST(AudioPriorityBitrateAllocationStrategyTest, EvenAllocateBitrate) {
|
||||||
|
constexpr uint32_t sufficient_audio_bitrate = 16000;
|
||||||
|
const std::string audio_track_id = "audio_track";
|
||||||
|
constexpr uint32_t min_audio_bitrate = 6000;
|
||||||
|
constexpr uint32_t max_audio_bitrate = 64000;
|
||||||
|
const std::string video_track_id = "video_track";
|
||||||
|
constexpr uint32_t min_video_bitrate = 30000;
|
||||||
|
constexpr uint32_t max_video_bitrate = 300000;
|
||||||
|
constexpr uint32_t min_other_bitrate = 3000;
|
||||||
|
constexpr uint32_t max_other_bitrate = 30000;
|
||||||
|
constexpr uint32_t available_bitrate = 52000;
|
||||||
|
constexpr uint32_t even_bitrate_increase =
|
||||||
|
(available_bitrate - sufficient_audio_bitrate - min_video_bitrate -
|
||||||
|
min_other_bitrate) /
|
||||||
|
3;
|
||||||
|
|
||||||
|
std::vector<uint32_t> allocations = RunAudioPriorityAllocation(
|
||||||
|
sufficient_audio_bitrate, audio_track_id, min_audio_bitrate,
|
||||||
|
max_audio_bitrate, video_track_id, min_video_bitrate, max_video_bitrate,
|
||||||
|
min_other_bitrate, max_other_bitrate, available_bitrate);
|
||||||
|
EXPECT_EQ(sufficient_audio_bitrate + even_bitrate_increase, allocations[0]);
|
||||||
|
EXPECT_EQ(min_video_bitrate + even_bitrate_increase, allocations[1]);
|
||||||
|
EXPECT_EQ(min_other_bitrate + even_bitrate_increase, allocations[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that bitrate will be allocated to video after audio and other max
|
||||||
|
// allocation.
|
||||||
|
TEST(AudioPriorityBitrateAllocationStrategyTest, VideoAllocateBitrate) {
|
||||||
|
constexpr uint32_t sufficient_audio_bitrate = 16000;
|
||||||
|
const std::string audio_track_id = "audio_track";
|
||||||
|
constexpr uint32_t min_audio_bitrate = 6000;
|
||||||
|
constexpr uint32_t max_audio_bitrate = 64000;
|
||||||
|
const std::string video_track_id = "video_track";
|
||||||
|
constexpr uint32_t min_video_bitrate = 30000;
|
||||||
|
constexpr uint32_t max_video_bitrate = 300000;
|
||||||
|
constexpr uint32_t min_other_bitrate = 3000;
|
||||||
|
constexpr uint32_t max_other_bitrate = 30000;
|
||||||
|
constexpr uint32_t available_bitrate = 200000;
|
||||||
|
constexpr uint32_t video_bitrate =
|
||||||
|
available_bitrate - max_audio_bitrate - max_other_bitrate;
|
||||||
|
|
||||||
|
std::vector<uint32_t> allocations = RunAudioPriorityAllocation(
|
||||||
|
sufficient_audio_bitrate, audio_track_id, min_audio_bitrate,
|
||||||
|
max_audio_bitrate, video_track_id, min_video_bitrate, max_video_bitrate,
|
||||||
|
min_other_bitrate, max_other_bitrate, available_bitrate);
|
||||||
|
EXPECT_EQ(max_audio_bitrate, allocations[0]);
|
||||||
|
EXPECT_EQ(video_bitrate, allocations[1]);
|
||||||
|
EXPECT_EQ(max_other_bitrate, allocations[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace rtc
|
|
@ -840,6 +840,7 @@ if (is_ios || is_mac) {
|
||||||
"objc/api/peerconnection/RTCMetricsSampleInfo.h",
|
"objc/api/peerconnection/RTCMetricsSampleInfo.h",
|
||||||
"objc/api/peerconnection/RTCMetricsSampleInfo.mm",
|
"objc/api/peerconnection/RTCMetricsSampleInfo.mm",
|
||||||
"objc/api/peerconnection/RTCPeerConnection+DataChannel.mm",
|
"objc/api/peerconnection/RTCPeerConnection+DataChannel.mm",
|
||||||
|
"objc/api/peerconnection/RTCPeerConnection+Native.h",
|
||||||
"objc/api/peerconnection/RTCPeerConnection+Private.h",
|
"objc/api/peerconnection/RTCPeerConnection+Private.h",
|
||||||
"objc/api/peerconnection/RTCPeerConnection+Stats.mm",
|
"objc/api/peerconnection/RTCPeerConnection+Stats.mm",
|
||||||
"objc/api/peerconnection/RTCPeerConnection.h",
|
"objc/api/peerconnection/RTCPeerConnection.h",
|
||||||
|
@ -955,6 +956,7 @@ if (is_ios || is_mac) {
|
||||||
"objc/Framework/Classes/Common/NSString+StdString.h",
|
"objc/Framework/Classes/Common/NSString+StdString.h",
|
||||||
"objc/Framework/Classes/Common/scoped_cftyperef.h",
|
"objc/Framework/Classes/Common/scoped_cftyperef.h",
|
||||||
"objc/Framework/Classes/PeerConnection/RTCConfiguration+Native.h",
|
"objc/Framework/Classes/PeerConnection/RTCConfiguration+Native.h",
|
||||||
|
"objc/Framework/Classes/PeerConnection/RTCPeerConnection+Native.h",
|
||||||
"objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory+Native.h",
|
"objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory+Native.h",
|
||||||
"objc/Framework/Classes/PeerConnection/RTCVideoCodec+Private.h",
|
"objc/Framework/Classes/PeerConnection/RTCVideoCodec+Private.h",
|
||||||
"objc/Framework/Classes/Video/RTCDefaultShader.h",
|
"objc/Framework/Classes/Video/RTCDefaultShader.h",
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "api/peerconnection/RTCPeerConnection+Native.h"
|
34
sdk/objc/api/peerconnection/RTCPeerConnection+Native.h
Normal file
34
sdk/objc/api/peerconnection/RTCPeerConnection+Native.h
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "RTCPeerConnection.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace rtc {
|
||||||
|
class BitrateAllocationStrategy;
|
||||||
|
} // namespace rtc
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class extension exposes methods that work directly with injectable C++ components.
|
||||||
|
*/
|
||||||
|
@interface RTCPeerConnection ()
|
||||||
|
|
||||||
|
/** Sets current strategy. If not set default WebRTC allocator will be used. May be changed during
|
||||||
|
* an active session.
|
||||||
|
*/
|
||||||
|
- (void)setBitrateAllocationStrategy:
|
||||||
|
(std::unique_ptr<rtc::BitrateAllocationStrategy>)bitrateAllocationStrategy;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
|
@ -17,6 +17,7 @@
|
||||||
#import "RTCMediaConstraints+Private.h"
|
#import "RTCMediaConstraints+Private.h"
|
||||||
#import "RTCMediaStream+Private.h"
|
#import "RTCMediaStream+Private.h"
|
||||||
#import "RTCMediaStreamTrack+Private.h"
|
#import "RTCMediaStreamTrack+Private.h"
|
||||||
|
#import "RTCPeerConnection+Native.h"
|
||||||
#import "RTCPeerConnectionFactory+Private.h"
|
#import "RTCPeerConnectionFactory+Private.h"
|
||||||
#import "RTCRtpReceiver+Private.h"
|
#import "RTCRtpReceiver+Private.h"
|
||||||
#import "RTCRtpSender+Private.h"
|
#import "RTCRtpSender+Private.h"
|
||||||
|
@ -521,6 +522,11 @@ void PeerConnectionDelegateAdapter::OnRemoveTrack(
|
||||||
return _peerConnection->SetBitrate(params).ok();
|
return _peerConnection->SetBitrate(params).ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setBitrateAllocationStrategy:
|
||||||
|
(std::unique_ptr<rtc::BitrateAllocationStrategy>)bitrateAllocationStrategy {
|
||||||
|
_peerConnection->SetBitrateAllocationStrategy(std::move(bitrateAllocationStrategy));
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath
|
- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath
|
||||||
maxSizeInBytes:(int64_t)maxSizeInBytes {
|
maxSizeInBytes:(int64_t)maxSizeInBytes {
|
||||||
RTC_DCHECK(filePath.length);
|
RTC_DCHECK(filePath.length);
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "test/scenario/audio_stream.h"
|
#include "test/scenario/audio_stream.h"
|
||||||
|
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
|
#include "rtc_base/bitrate_allocation_strategy.h"
|
||||||
#include "test/call_test.h"
|
#include "test/call_test.h"
|
||||||
|
|
||||||
#if WEBRTC_ENABLE_PROTOBUF
|
#if WEBRTC_ENABLE_PROTOBUF
|
||||||
|
@ -129,6 +130,10 @@ SendAudioStream::SendAudioStream(
|
||||||
|
|
||||||
if (config.encoder.priority_rate) {
|
if (config.encoder.priority_rate) {
|
||||||
send_config.track_id = sender->GetNextPriorityId();
|
send_config.track_id = sender->GetNextPriorityId();
|
||||||
|
sender_->call_->SetBitrateAllocationStrategy(
|
||||||
|
absl::make_unique<rtc::AudioPriorityBitrateAllocationStrategy>(
|
||||||
|
send_config.track_id,
|
||||||
|
config.encoder.priority_rate->bps<uint32_t>()));
|
||||||
}
|
}
|
||||||
sender_->SendTask([&] {
|
sender_->SendTask([&] {
|
||||||
send_stream_ = sender_->call_->CreateAudioSendStream(send_config);
|
send_stream_ = sender_->call_->CreateAudioSendStream(send_config);
|
||||||
|
|
|
@ -100,7 +100,6 @@ rtc_static_library("video") {
|
||||||
"../rtc_base:stringutils",
|
"../rtc_base:stringutils",
|
||||||
"../rtc_base:weak_ptr",
|
"../rtc_base:weak_ptr",
|
||||||
"../rtc_base/experiments:alr_experiment",
|
"../rtc_base/experiments:alr_experiment",
|
||||||
"../rtc_base/experiments:field_trial_parser",
|
|
||||||
"../rtc_base/experiments:keyframe_interval_settings_experiment",
|
"../rtc_base/experiments:keyframe_interval_settings_experiment",
|
||||||
"../rtc_base/experiments:quality_scaling_experiment",
|
"../rtc_base/experiments:quality_scaling_experiment",
|
||||||
"../rtc_base/experiments:rate_control_settings",
|
"../rtc_base/experiments:rate_control_settings",
|
||||||
|
|
|
@ -511,6 +511,7 @@ MediaStreamAllocationConfig VideoSendStreamImpl::GetAllocationConfig() const {
|
||||||
static_cast<uint32_t>(disable_padding_ ? 0 : max_padding_bitrate_),
|
static_cast<uint32_t>(disable_padding_ ? 0 : max_padding_bitrate_),
|
||||||
/* priority_bitrate */ 0,
|
/* priority_bitrate */ 0,
|
||||||
!config_->suspend_below_min_bitrate,
|
!config_->suspend_below_min_bitrate,
|
||||||
|
config_->track_id,
|
||||||
encoder_bitrate_priority_};
|
encoder_bitrate_priority_};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@
|
||||||
#include "modules/utility/include/process_thread.h"
|
#include "modules/utility/include/process_thread.h"
|
||||||
#include "modules/video_coding/include/video_codec_interface.h"
|
#include "modules/video_coding/include/video_codec_interface.h"
|
||||||
#include "rtc_base/critical_section.h"
|
#include "rtc_base/critical_section.h"
|
||||||
#include "rtc_base/experiments/field_trial_parser.h"
|
|
||||||
#include "rtc_base/task_queue.h"
|
#include "rtc_base/task_queue.h"
|
||||||
#include "rtc_base/task_utils/repeating_task.h"
|
#include "rtc_base/task_utils/repeating_task.h"
|
||||||
#include "rtc_base/thread_annotations.h"
|
#include "rtc_base/thread_annotations.h"
|
||||||
|
|
|
@ -154,6 +154,7 @@ class VideoSendStreamImplTest : public ::testing::Test {
|
||||||
|
|
||||||
TEST_F(VideoSendStreamImplTest, RegistersAsBitrateObserverOnStart) {
|
TEST_F(VideoSendStreamImplTest, RegistersAsBitrateObserverOnStart) {
|
||||||
test_queue_.SendTask([this] {
|
test_queue_.SendTask([this] {
|
||||||
|
config_.track_id = "test";
|
||||||
const bool kSuspend = false;
|
const bool kSuspend = false;
|
||||||
config_.suspend_below_min_bitrate = kSuspend;
|
config_.suspend_below_min_bitrate = kSuspend;
|
||||||
auto vss_impl = CreateVideoSendStreamImpl(
|
auto vss_impl = CreateVideoSendStreamImpl(
|
||||||
|
@ -166,6 +167,7 @@ TEST_F(VideoSendStreamImplTest, RegistersAsBitrateObserverOnStart) {
|
||||||
EXPECT_EQ(config.max_bitrate_bps, kDefaultInitialBitrateBps);
|
EXPECT_EQ(config.max_bitrate_bps, kDefaultInitialBitrateBps);
|
||||||
EXPECT_EQ(config.pad_up_bitrate_bps, 0u);
|
EXPECT_EQ(config.pad_up_bitrate_bps, 0u);
|
||||||
EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
|
EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
|
||||||
|
EXPECT_EQ(config.track_id, "test");
|
||||||
EXPECT_EQ(config.bitrate_priority, kDefaultBitratePriority);
|
EXPECT_EQ(config.bitrate_priority, kDefaultBitratePriority);
|
||||||
}));
|
}));
|
||||||
vss_impl->Start();
|
vss_impl->Start();
|
||||||
|
@ -176,6 +178,7 @@ TEST_F(VideoSendStreamImplTest, RegistersAsBitrateObserverOnStart) {
|
||||||
|
|
||||||
TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) {
|
TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) {
|
||||||
test_queue_.SendTask([this] {
|
test_queue_.SendTask([this] {
|
||||||
|
config_.track_id = "test";
|
||||||
const bool kSuspend = false;
|
const bool kSuspend = false;
|
||||||
config_.suspend_below_min_bitrate = kSuspend;
|
config_.suspend_below_min_bitrate = kSuspend;
|
||||||
config_.rtp.extensions.emplace_back(
|
config_.rtp.extensions.emplace_back(
|
||||||
|
@ -238,6 +241,7 @@ TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) {
|
||||||
|
|
||||||
TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChangeWithAlr) {
|
TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChangeWithAlr) {
|
||||||
test_queue_.SendTask([this] {
|
test_queue_.SendTask([this] {
|
||||||
|
config_.track_id = "test";
|
||||||
const bool kSuspend = false;
|
const bool kSuspend = false;
|
||||||
config_.suspend_below_min_bitrate = kSuspend;
|
config_.suspend_below_min_bitrate = kSuspend;
|
||||||
config_.rtp.extensions.emplace_back(
|
config_.rtp.extensions.emplace_back(
|
||||||
|
@ -626,6 +630,7 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
|
||||||
|
|
||||||
TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) {
|
TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) {
|
||||||
test_queue_.SendTask([this] {
|
test_queue_.SendTask([this] {
|
||||||
|
config_.track_id = "test";
|
||||||
const bool kSuspend = false;
|
const bool kSuspend = false;
|
||||||
config_.suspend_below_min_bitrate = kSuspend;
|
config_.suspend_below_min_bitrate = kSuspend;
|
||||||
config_.rtp.extensions.emplace_back(
|
config_.rtp.extensions.emplace_back(
|
||||||
|
@ -753,6 +758,8 @@ TEST_F(VideoSendStreamImplTest, DisablesPaddingOnPausedEncoder) {
|
||||||
EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _))
|
EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _))
|
||||||
.WillRepeatedly(Return(
|
.WillRepeatedly(Return(
|
||||||
EncodedImageCallback::Result(EncodedImageCallback::Result::OK)));
|
EncodedImageCallback::Result(EncodedImageCallback::Result::OK)));
|
||||||
|
|
||||||
|
config_.track_id = "test";
|
||||||
const bool kSuspend = false;
|
const bool kSuspend = false;
|
||||||
config_.suspend_below_min_bitrate = kSuspend;
|
config_.suspend_below_min_bitrate = kSuspend;
|
||||||
config_.rtp.extensions.emplace_back(
|
config_.rtp.extensions.emplace_back(
|
||||||
|
|
Loading…
Reference in a new issue