1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker 11*d9f75844SAndroid Build Coastguard Worker #ifndef CALL_BITRATE_ALLOCATOR_H_ 12*d9f75844SAndroid Build Coastguard Worker #define CALL_BITRATE_ALLOCATOR_H_ 13*d9f75844SAndroid Build Coastguard Worker 14*d9f75844SAndroid Build Coastguard Worker #include <stdint.h> 15*d9f75844SAndroid Build Coastguard Worker 16*d9f75844SAndroid Build Coastguard Worker #include <map> 17*d9f75844SAndroid Build Coastguard Worker #include <memory> 18*d9f75844SAndroid Build Coastguard Worker #include <string> 19*d9f75844SAndroid Build Coastguard Worker #include <utility> 20*d9f75844SAndroid Build Coastguard Worker #include <vector> 21*d9f75844SAndroid Build Coastguard Worker 22*d9f75844SAndroid Build Coastguard Worker #include "api/call/bitrate_allocation.h" 23*d9f75844SAndroid Build Coastguard Worker #include "api/sequence_checker.h" 24*d9f75844SAndroid Build Coastguard Worker #include "api/transport/network_types.h" 25*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/system/no_unique_address.h" 26*d9f75844SAndroid Build Coastguard Worker 27*d9f75844SAndroid Build Coastguard Worker namespace webrtc { 28*d9f75844SAndroid Build Coastguard Worker 29*d9f75844SAndroid Build Coastguard Worker class Clock; 30*d9f75844SAndroid Build Coastguard Worker 31*d9f75844SAndroid Build Coastguard Worker // Used by all send streams with adaptive bitrate, to get the currently 32*d9f75844SAndroid Build Coastguard Worker // allocated bitrate for the send stream. The current network properties are 33*d9f75844SAndroid Build Coastguard Worker // given at the same time, to let the send stream decide about possible loss 34*d9f75844SAndroid Build Coastguard Worker // protection. 35*d9f75844SAndroid Build Coastguard Worker class BitrateAllocatorObserver { 36*d9f75844SAndroid Build Coastguard Worker public: 37*d9f75844SAndroid Build Coastguard Worker // Returns the amount of protection used by the BitrateAllocatorObserver 38*d9f75844SAndroid Build Coastguard Worker // implementation, as bitrate in bps. 39*d9f75844SAndroid Build Coastguard Worker virtual uint32_t OnBitrateUpdated(BitrateAllocationUpdate update) = 0; 40*d9f75844SAndroid Build Coastguard Worker 41*d9f75844SAndroid Build Coastguard Worker protected: ~BitrateAllocatorObserver()42*d9f75844SAndroid Build Coastguard Worker virtual ~BitrateAllocatorObserver() {} 43*d9f75844SAndroid Build Coastguard Worker }; 44*d9f75844SAndroid Build Coastguard Worker 45*d9f75844SAndroid Build Coastguard Worker // Struct describing parameters for how a media stream should get bitrate 46*d9f75844SAndroid Build Coastguard Worker // allocated to it. 47*d9f75844SAndroid Build Coastguard Worker 48*d9f75844SAndroid Build Coastguard Worker struct MediaStreamAllocationConfig { 49*d9f75844SAndroid Build Coastguard Worker // Minimum bitrate supported by track. 0 equals no min bitrate. 50*d9f75844SAndroid Build Coastguard Worker uint32_t min_bitrate_bps; 51*d9f75844SAndroid Build Coastguard Worker // Maximum bitrate supported by track. 0 equals no max bitrate. 52*d9f75844SAndroid Build Coastguard Worker uint32_t max_bitrate_bps; 53*d9f75844SAndroid Build Coastguard Worker uint32_t pad_up_bitrate_bps; 54*d9f75844SAndroid Build Coastguard Worker int64_t priority_bitrate_bps; 55*d9f75844SAndroid Build Coastguard Worker // True means track may not be paused by allocating 0 bitrate will allocate at 56*d9f75844SAndroid Build Coastguard Worker // least `min_bitrate_bps` for this observer, even if the BWE is too low, 57*d9f75844SAndroid Build Coastguard Worker // false will allocate 0 to the observer if BWE doesn't allow 58*d9f75844SAndroid Build Coastguard Worker // `min_bitrate_bps`. 59*d9f75844SAndroid Build Coastguard Worker bool enforce_min_bitrate; 60*d9f75844SAndroid Build Coastguard Worker // The amount of bitrate allocated to this observer relative to all other 61*d9f75844SAndroid Build Coastguard Worker // observers. If an observer has twice the bitrate_priority of other 62*d9f75844SAndroid Build Coastguard Worker // observers, it should be allocated twice the bitrate above its min. 63*d9f75844SAndroid Build Coastguard Worker double bitrate_priority; 64*d9f75844SAndroid Build Coastguard Worker }; 65*d9f75844SAndroid Build Coastguard Worker 66*d9f75844SAndroid Build Coastguard Worker // Interface used for mocking 67*d9f75844SAndroid Build Coastguard Worker class BitrateAllocatorInterface { 68*d9f75844SAndroid Build Coastguard Worker public: 69*d9f75844SAndroid Build Coastguard Worker virtual void AddObserver(BitrateAllocatorObserver* observer, 70*d9f75844SAndroid Build Coastguard Worker MediaStreamAllocationConfig config) = 0; 71*d9f75844SAndroid Build Coastguard Worker virtual void RemoveObserver(BitrateAllocatorObserver* observer) = 0; 72*d9f75844SAndroid Build Coastguard Worker virtual int GetStartBitrate(BitrateAllocatorObserver* observer) const = 0; 73*d9f75844SAndroid Build Coastguard Worker 74*d9f75844SAndroid Build Coastguard Worker protected: 75*d9f75844SAndroid Build Coastguard Worker virtual ~BitrateAllocatorInterface() = default; 76*d9f75844SAndroid Build Coastguard Worker }; 77*d9f75844SAndroid Build Coastguard Worker 78*d9f75844SAndroid Build Coastguard Worker namespace bitrate_allocator_impl { 79*d9f75844SAndroid Build Coastguard Worker struct AllocatableTrack { AllocatableTrackAllocatableTrack80*d9f75844SAndroid Build Coastguard Worker AllocatableTrack(BitrateAllocatorObserver* observer, 81*d9f75844SAndroid Build Coastguard Worker MediaStreamAllocationConfig allocation_config) 82*d9f75844SAndroid Build Coastguard Worker : observer(observer), 83*d9f75844SAndroid Build Coastguard Worker config(allocation_config), 84*d9f75844SAndroid Build Coastguard Worker allocated_bitrate_bps(-1), 85*d9f75844SAndroid Build Coastguard Worker media_ratio(1.0) {} 86*d9f75844SAndroid Build Coastguard Worker BitrateAllocatorObserver* observer; 87*d9f75844SAndroid Build Coastguard Worker MediaStreamAllocationConfig config; 88*d9f75844SAndroid Build Coastguard Worker int64_t allocated_bitrate_bps; 89*d9f75844SAndroid Build Coastguard Worker double media_ratio; // Part of the total bitrate used for media [0.0, 1.0]. 90*d9f75844SAndroid Build Coastguard Worker 91*d9f75844SAndroid Build Coastguard Worker uint32_t LastAllocatedBitrate() const; 92*d9f75844SAndroid Build Coastguard Worker // The minimum bitrate required by this observer, including 93*d9f75844SAndroid Build Coastguard Worker // enable-hysteresis if the observer is in a paused state. 94*d9f75844SAndroid Build Coastguard Worker uint32_t MinBitrateWithHysteresis() const; 95*d9f75844SAndroid Build Coastguard Worker }; 96*d9f75844SAndroid Build Coastguard Worker } // namespace bitrate_allocator_impl 97*d9f75844SAndroid Build Coastguard Worker 98*d9f75844SAndroid Build Coastguard Worker // Usage: this class will register multiple RtcpBitrateObserver's one at each 99*d9f75844SAndroid Build Coastguard Worker // RTCP module. It will aggregate the results and run one bandwidth estimation 100*d9f75844SAndroid Build Coastguard Worker // and push the result to the encoders via BitrateAllocatorObserver(s). 101*d9f75844SAndroid Build Coastguard Worker class BitrateAllocator : public BitrateAllocatorInterface { 102*d9f75844SAndroid Build Coastguard Worker public: 103*d9f75844SAndroid Build Coastguard Worker // Used to get notified when send stream limits such as the minimum send 104*d9f75844SAndroid Build Coastguard Worker // bitrate and max padding bitrate is changed. 105*d9f75844SAndroid Build Coastguard Worker class LimitObserver { 106*d9f75844SAndroid Build Coastguard Worker public: 107*d9f75844SAndroid Build Coastguard Worker virtual void OnAllocationLimitsChanged(BitrateAllocationLimits limits) = 0; 108*d9f75844SAndroid Build Coastguard Worker 109*d9f75844SAndroid Build Coastguard Worker protected: 110*d9f75844SAndroid Build Coastguard Worker virtual ~LimitObserver() = default; 111*d9f75844SAndroid Build Coastguard Worker }; 112*d9f75844SAndroid Build Coastguard Worker 113*d9f75844SAndroid Build Coastguard Worker explicit BitrateAllocator(LimitObserver* limit_observer); 114*d9f75844SAndroid Build Coastguard Worker ~BitrateAllocator() override; 115*d9f75844SAndroid Build Coastguard Worker 116*d9f75844SAndroid Build Coastguard Worker void UpdateStartRate(uint32_t start_rate_bps); 117*d9f75844SAndroid Build Coastguard Worker 118*d9f75844SAndroid Build Coastguard Worker // Allocate target_bitrate across the registered BitrateAllocatorObservers. 119*d9f75844SAndroid Build Coastguard Worker void OnNetworkEstimateChanged(TargetTransferRate msg); 120*d9f75844SAndroid Build Coastguard Worker 121*d9f75844SAndroid Build Coastguard Worker // Set the configuration used by the bandwidth management. 122*d9f75844SAndroid Build Coastguard Worker // `observer` updates bitrates if already in use. 123*d9f75844SAndroid Build Coastguard Worker // `config` is the configuration to use for allocation. 124*d9f75844SAndroid Build Coastguard Worker // Note that `observer`->OnBitrateUpdated() will be called 125*d9f75844SAndroid Build Coastguard Worker // within the scope of this method with the current rtt, fraction_loss and 126*d9f75844SAndroid Build Coastguard Worker // available bitrate and that the bitrate in OnBitrateUpdated will be zero if 127*d9f75844SAndroid Build Coastguard Worker // the `observer` is currently not allowed to send data. 128*d9f75844SAndroid Build Coastguard Worker void AddObserver(BitrateAllocatorObserver* observer, 129*d9f75844SAndroid Build Coastguard Worker MediaStreamAllocationConfig config) override; 130*d9f75844SAndroid Build Coastguard Worker 131*d9f75844SAndroid Build Coastguard Worker // Removes a previously added observer, but will not trigger a new bitrate 132*d9f75844SAndroid Build Coastguard Worker // allocation. 133*d9f75844SAndroid Build Coastguard Worker void RemoveObserver(BitrateAllocatorObserver* observer) override; 134*d9f75844SAndroid Build Coastguard Worker 135*d9f75844SAndroid Build Coastguard Worker // Returns initial bitrate allocated for `observer`. If `observer` is not in 136*d9f75844SAndroid Build Coastguard Worker // the list of added observers, a best guess is returned. 137*d9f75844SAndroid Build Coastguard Worker int GetStartBitrate(BitrateAllocatorObserver* observer) const override; 138*d9f75844SAndroid Build Coastguard Worker 139*d9f75844SAndroid Build Coastguard Worker private: 140*d9f75844SAndroid Build Coastguard Worker using AllocatableTrack = bitrate_allocator_impl::AllocatableTrack; 141*d9f75844SAndroid Build Coastguard Worker 142*d9f75844SAndroid Build Coastguard Worker // Calculates the minimum requested send bitrate and max padding bitrate and 143*d9f75844SAndroid Build Coastguard Worker // calls LimitObserver::OnAllocationLimitsChanged. 144*d9f75844SAndroid Build Coastguard Worker void UpdateAllocationLimits() RTC_RUN_ON(&sequenced_checker_); 145*d9f75844SAndroid Build Coastguard Worker 146*d9f75844SAndroid Build Coastguard Worker // Allow packets to be transmitted in up to 2 times max video bitrate if the 147*d9f75844SAndroid Build Coastguard Worker // bandwidth estimate allows it. 148*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/8541): May be worth to refactor to keep this logic in 149*d9f75844SAndroid Build Coastguard Worker // video send stream. 150*d9f75844SAndroid Build Coastguard Worker static uint8_t GetTransmissionMaxBitrateMultiplier(); 151*d9f75844SAndroid Build Coastguard Worker 152*d9f75844SAndroid Build Coastguard Worker RTC_NO_UNIQUE_ADDRESS SequenceChecker sequenced_checker_; 153*d9f75844SAndroid Build Coastguard Worker LimitObserver* const limit_observer_ RTC_GUARDED_BY(&sequenced_checker_); 154*d9f75844SAndroid Build Coastguard Worker // Stored in a list to keep track of the insertion order. 155*d9f75844SAndroid Build Coastguard Worker std::vector<AllocatableTrack> allocatable_tracks_ 156*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(&sequenced_checker_); 157*d9f75844SAndroid Build Coastguard Worker uint32_t last_target_bps_ RTC_GUARDED_BY(&sequenced_checker_); 158*d9f75844SAndroid Build Coastguard Worker uint32_t last_stable_target_bps_ RTC_GUARDED_BY(&sequenced_checker_); 159*d9f75844SAndroid Build Coastguard Worker uint32_t last_non_zero_bitrate_bps_ RTC_GUARDED_BY(&sequenced_checker_); 160*d9f75844SAndroid Build Coastguard Worker uint8_t last_fraction_loss_ RTC_GUARDED_BY(&sequenced_checker_); 161*d9f75844SAndroid Build Coastguard Worker int64_t last_rtt_ RTC_GUARDED_BY(&sequenced_checker_); 162*d9f75844SAndroid Build Coastguard Worker int64_t last_bwe_period_ms_ RTC_GUARDED_BY(&sequenced_checker_); 163*d9f75844SAndroid Build Coastguard Worker // Number of mute events based on too low BWE, not network up/down. 164*d9f75844SAndroid Build Coastguard Worker int num_pause_events_ RTC_GUARDED_BY(&sequenced_checker_); 165*d9f75844SAndroid Build Coastguard Worker int64_t last_bwe_log_time_ RTC_GUARDED_BY(&sequenced_checker_); 166*d9f75844SAndroid Build Coastguard Worker BitrateAllocationLimits current_limits_ RTC_GUARDED_BY(&sequenced_checker_); 167*d9f75844SAndroid Build Coastguard Worker }; 168*d9f75844SAndroid Build Coastguard Worker 169*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc 170*d9f75844SAndroid Build Coastguard Worker #endif // CALL_BITRATE_ALLOCATOR_H_ 171