Chromium Code Reviews| Index: webrtc/call/call.cc |
| diff --git a/webrtc/call/call.cc b/webrtc/call/call.cc |
| index 0e64269d4e4c70391a00be65da2440778bb14197..7f76cb1e3c8dfb475356eb9f6e4d82f5152d1df6 100644 |
| --- a/webrtc/call/call.cc |
| +++ b/webrtc/call/call.cc |
| @@ -97,7 +97,7 @@ class Call : public webrtc::Call, |
| public BitrateAllocator::LimitObserver { |
| public: |
| Call(const Call::Config& config, |
| - std::unique_ptr<RtpTransportControllerSend> transport_send); |
| + std::unique_ptr<RtpTransportControllerSendInterface> transport_send); |
| virtual ~Call(); |
| // Implements webrtc::Call. |
| @@ -141,6 +141,9 @@ class Call : public webrtc::Call, |
| void SetBitrateConfig( |
| const webrtc::Call::Config::BitrateConfig& bitrate_config) override; |
| + RTCError SetBitrateConfigMask( |
| + const webrtc::Call::Config::BitrateConfigMask& bitrate_config) override; |
| + |
| void SignalChannelNetworkState(MediaType media, NetworkState state) override; |
| void OnTransportOverheadChanged(MediaType media, |
| @@ -187,6 +190,15 @@ class Call : public webrtc::Call, |
| void UpdateHistograms(); |
| void UpdateAggregateNetworkState(); |
| + // Updates the BitrateConfig cached in |config_| by combining |
| + // |base_bitrate_config_| and |bitrate_config_mask_| and updates the |
| + // congestion controller if the combined config changed or if |
| + // |force_update| is true. |
| + RTCError UpdateCurrentBitrateConfig(bool force_update); |
| + |
| + // UpdateCurrentBitrateConfig, but doesn't verify BitrateConfig invariants. |
| + void UpdateCurrentBitrateConfigUnchecked(); |
| + |
| Clock* const clock_; |
| const int num_cpu_cores_; |
| @@ -281,6 +293,14 @@ class Call : public webrtc::Call, |
| // and deleted before any other members. |
| rtc::TaskQueue worker_queue_; |
| + // The config mask set by SetBitrateConfigMask. |
| + // 0 <= min <= start <= max |
| + Config::BitrateConfigMask bitrate_config_mask_; |
| + |
| + // The config set by SetBitrateConfig. |
| + // min >= 0, start != 0, max == -1 || max > 0 |
| + Config::BitrateConfig base_bitrate_config_; |
| + |
| RTC_DISALLOW_COPY_AND_ASSIGN(Call); |
| }; |
| } // namespace internal |
| @@ -304,10 +324,16 @@ Call* Call::Create(const Call::Config& config) { |
| config.event_log))); |
| } |
| +Call* Call::Create( |
| + const Call::Config& config, |
| + std::unique_ptr<RtpTransportControllerSendInterface> transport_send) { |
| + return new internal::Call(config, std::move(transport_send)); |
| +} |
| + |
| namespace internal { |
| Call::Call(const Call::Config& config, |
| - std::unique_ptr<RtpTransportControllerSend> transport_send) |
| + std::unique_ptr<RtpTransportControllerSendInterface> transport_send) |
| : clock_(Clock::GetRealTimeClock()), |
| num_cpu_cores_(CpuInfo::DetectNumberOfCores()), |
| module_process_thread_(ProcessThread::Create("ModuleProcessThread")), |
| @@ -331,7 +357,8 @@ Call::Call(const Call::Config& config, |
| receive_side_cc_(clock_, transport_send->packet_router()), |
| video_send_delay_stats_(new SendDelayStats(clock_)), |
| start_ms_(clock_->TimeInMilliseconds()), |
| - worker_queue_("call_worker_queue") { |
| + worker_queue_("call_worker_queue"), |
| + base_bitrate_config_(config.bitrate_config) { |
| RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread()); |
| RTC_DCHECK(config.event_log != nullptr); |
| RTC_DCHECK_GE(config.bitrate_config.min_bitrate_bps, 0); |
| @@ -342,7 +369,7 @@ Call::Call(const Call::Config& config, |
| config.bitrate_config.start_bitrate_bps); |
| } |
| Trace::CreateTrace(); |
| - transport_send->RegisterNetworkObserver(this); |
| + transport_send->send_side_cc()->RegisterNetworkObserver(this); |
| transport_send_ = std::move(transport_send); |
| transport_send_->send_side_cc()->SignalNetworkState(kNetworkDown); |
| transport_send_->send_side_cc()->SetBweBitrates( |
| @@ -856,29 +883,121 @@ void Call::SetBitrateConfig( |
| const webrtc::Call::Config::BitrateConfig& bitrate_config) { |
| TRACE_EVENT0("webrtc", "Call::SetBitrateConfig"); |
| RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread()); |
| + |
| RTC_DCHECK_GE(bitrate_config.min_bitrate_bps, 0); |
| - if (bitrate_config.max_bitrate_bps != -1) |
| + RTC_DCHECK_NE(bitrate_config.start_bitrate_bps, 0); |
| + if (bitrate_config.max_bitrate_bps != -1) { |
| RTC_DCHECK_GT(bitrate_config.max_bitrate_bps, 0); |
| - if (config_.bitrate_config.min_bitrate_bps == |
| - bitrate_config.min_bitrate_bps && |
| - (bitrate_config.start_bitrate_bps <= 0 || |
| - config_.bitrate_config.start_bitrate_bps == |
| - bitrate_config.start_bitrate_bps) && |
| - config_.bitrate_config.max_bitrate_bps == |
| - bitrate_config.max_bitrate_bps) { |
| + } |
| + |
| + const bool same_min = |
| + base_bitrate_config_.min_bitrate_bps == bitrate_config.min_bitrate_bps; |
| + const bool same_start = base_bitrate_config_.start_bitrate_bps == |
| + bitrate_config.start_bitrate_bps; |
| + const bool same_max = |
| + base_bitrate_config_.max_bitrate_bps == bitrate_config.max_bitrate_bps; |
| + // TODO(zstein): s/same_max/bitrate_config.max_bitrate_bps == -1 || same_max/ |
|
Taylor Brandstetter
2017/05/05 08:04:32
Can you explain this TODO?
Zach Stein
2017/05/09 00:41:26
I thought that setting max == -1 was intended to m
|
| + if (same_min && (bitrate_config.start_bitrate_bps <= 0 || same_start) && |
| + same_max) { |
| // Nothing new to set, early abort to avoid encoder reconfigurations. |
| return; |
| } |
| - config_.bitrate_config.min_bitrate_bps = bitrate_config.min_bitrate_bps; |
| + |
| + base_bitrate_config_.min_bitrate_bps = bitrate_config.min_bitrate_bps; |
| // Start bitrate of -1 means we should keep the old bitrate, which there is |
| // no point in remembering for the future. |
| - if (bitrate_config.start_bitrate_bps > 0) |
| - config_.bitrate_config.start_bitrate_bps = bitrate_config.start_bitrate_bps; |
| - config_.bitrate_config.max_bitrate_bps = bitrate_config.max_bitrate_bps; |
| - RTC_DCHECK_NE(bitrate_config.start_bitrate_bps, 0); |
| + if (bitrate_config.start_bitrate_bps > 0) { |
| + base_bitrate_config_.start_bitrate_bps = bitrate_config.start_bitrate_bps; |
| + } |
| + base_bitrate_config_.max_bitrate_bps = bitrate_config.max_bitrate_bps; |
| + |
| + UpdateCurrentBitrateConfigUnchecked(); |
| +} |
| + |
| +RTCError Call::SetBitrateConfigMask( |
| + const webrtc::Call::Config::BitrateConfigMask& mask) { |
| + TRACE_EVENT0("webrtc", "Call::SetBitrateConfigMask"); |
| + RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread()); |
| + |
| + bitrate_config_mask_ = mask; |
| + |
| + const bool force_update = static_cast<bool>(mask.start_bitrate_bps); |
| + |
| + return UpdateCurrentBitrateConfig(force_update); |
| +} |
| + |
| +Call::Config::BitrateConfig ComputeMasked( |
| + const Call::Config::BitrateConfig& base, |
| + const Call::Config::BitrateConfigMask& mask) { |
| + Call::Config::BitrateConfig masked; |
| + masked.min_bitrate_bps = mask.min_bitrate_bps.value_or(base.min_bitrate_bps); |
| + masked.start_bitrate_bps = |
| + mask.start_bitrate_bps.value_or(base.start_bitrate_bps); |
| + |
| + const rtc::Optional<int>& mask_max = mask.max_bitrate_bps; |
| + const int base_max = base.max_bitrate_bps; |
| + const bool mask_has_max = static_cast<bool>(mask_max); |
| + const bool base_has_max = base_max != -1; |
| + if (mask_has_max && base_has_max) { |
| + masked.max_bitrate_bps = std::min(*mask_max, base_max); |
| + } else if (mask_has_max) { |
| + masked.max_bitrate_bps = *mask_max; |
| + } else if (base_has_max) { |
| + masked.max_bitrate_bps = base_max; |
| + } else { |
| + masked.max_bitrate_bps = -1; |
| + } |
| + |
| + return masked; |
| +} |
| + |
| +void Call::UpdateCurrentBitrateConfigUnchecked() { |
| + Config::BitrateConfig masked = |
| + ComputeMasked(base_bitrate_config_, bitrate_config_mask_); |
| + |
| + // We only get here if SetBitrateConfig changed something. |
| + |
| + config_.bitrate_config = masked; |
| transport_send_->send_side_cc()->SetBweBitrates( |
| - bitrate_config.min_bitrate_bps, bitrate_config.start_bitrate_bps, |
| - bitrate_config.max_bitrate_bps); |
| + masked.min_bitrate_bps, masked.start_bitrate_bps, masked.max_bitrate_bps); |
| +} |
| + |
| +RTCError Call::UpdateCurrentBitrateConfig(bool force_update) { |
| + Config::BitrateConfig masked = |
| + ComputeMasked(base_bitrate_config_, bitrate_config_mask_); |
| + |
| + Config::BitrateConfig& current = config_.bitrate_config; |
| + if (!force_update && masked.min_bitrate_bps == current.min_bitrate_bps && |
| + masked.start_bitrate_bps == current.start_bitrate_bps && |
| + masked.max_bitrate_bps == current.max_bitrate_bps) { |
| + return RTCError::OK(); |
| + } |
| + |
| + RTC_DCHECK_GE(masked.min_bitrate_bps, 0); |
| + if (masked.start_bitrate_bps > 0 && |
| + masked.start_bitrate_bps < masked.min_bitrate_bps) { |
| + LOG_AND_RETURN_ERROR( |
| + RTCErrorType::INVALID_STATE, |
| + "effective start_bitrate_bps < effective min_bitrate_bps"); |
| + } |
| + if (masked.max_bitrate_bps != -1 && masked.start_bitrate_bps > 0 && |
| + masked.max_bitrate_bps < masked.start_bitrate_bps) { |
| + LOG_AND_RETURN_ERROR( |
| + RTCErrorType::INVALID_STATE, |
| + "effective max_bitrate_bps < effective start_bitrate_bps"); |
| + } |
| + if (masked.max_bitrate_bps != -1 && |
| + masked.max_bitrate_bps < masked.min_bitrate_bps) { |
| + LOG_AND_RETURN_ERROR( |
| + RTCErrorType::INVALID_STATE, |
| + "effective max_bitrate_bps < effective min_bitrate_bps"); |
| + } |
| + |
| + current = masked; |
| + transport_send_->send_side_cc()->SetBweBitrates(current.min_bitrate_bps, |
| + current.start_bitrate_bps, |
| + current.max_bitrate_bps); |
| + return RTCError::OK(); |
| } |
| void Call::SignalChannelNetworkState(MediaType media, NetworkState state) { |