1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright 2020 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 #include "video/adaptation/bitrate_constraint.h" 12*d9f75844SAndroid Build Coastguard Worker 13*d9f75844SAndroid Build Coastguard Worker #include <utility> 14*d9f75844SAndroid Build Coastguard Worker #include <vector> 15*d9f75844SAndroid Build Coastguard Worker 16*d9f75844SAndroid Build Coastguard Worker #include "api/sequence_checker.h" 17*d9f75844SAndroid Build Coastguard Worker #include "call/adaptation/video_stream_adapter.h" 18*d9f75844SAndroid Build Coastguard Worker #include "video/adaptation/video_stream_encoder_resource_manager.h" 19*d9f75844SAndroid Build Coastguard Worker 20*d9f75844SAndroid Build Coastguard Worker namespace webrtc { 21*d9f75844SAndroid Build Coastguard Worker BitrateConstraint()22*d9f75844SAndroid Build Coastguard WorkerBitrateConstraint::BitrateConstraint() 23*d9f75844SAndroid Build Coastguard Worker : encoder_settings_(absl::nullopt), 24*d9f75844SAndroid Build Coastguard Worker encoder_target_bitrate_bps_(absl::nullopt) { 25*d9f75844SAndroid Build Coastguard Worker sequence_checker_.Detach(); 26*d9f75844SAndroid Build Coastguard Worker } 27*d9f75844SAndroid Build Coastguard Worker OnEncoderSettingsUpdated(absl::optional<EncoderSettings> encoder_settings)28*d9f75844SAndroid Build Coastguard Workervoid BitrateConstraint::OnEncoderSettingsUpdated( 29*d9f75844SAndroid Build Coastguard Worker absl::optional<EncoderSettings> encoder_settings) { 30*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 31*d9f75844SAndroid Build Coastguard Worker encoder_settings_ = std::move(encoder_settings); 32*d9f75844SAndroid Build Coastguard Worker } 33*d9f75844SAndroid Build Coastguard Worker OnEncoderTargetBitrateUpdated(absl::optional<uint32_t> encoder_target_bitrate_bps)34*d9f75844SAndroid Build Coastguard Workervoid BitrateConstraint::OnEncoderTargetBitrateUpdated( 35*d9f75844SAndroid Build Coastguard Worker absl::optional<uint32_t> encoder_target_bitrate_bps) { 36*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 37*d9f75844SAndroid Build Coastguard Worker encoder_target_bitrate_bps_ = std::move(encoder_target_bitrate_bps); 38*d9f75844SAndroid Build Coastguard Worker } 39*d9f75844SAndroid Build Coastguard Worker 40*d9f75844SAndroid Build Coastguard Worker // Checks if resolution is allowed to adapt up based on the current bitrate and 41*d9f75844SAndroid Build Coastguard Worker // ResolutionBitrateLimits.min_start_bitrate_bps for the next higher resolution. 42*d9f75844SAndroid Build Coastguard Worker // Bitrate limits usage is restricted to a single active stream/layer (e.g. when 43*d9f75844SAndroid Build Coastguard Worker // quality scaling is enabled). IsAdaptationUpAllowed(const VideoStreamInputState & input_state,const VideoSourceRestrictions & restrictions_before,const VideoSourceRestrictions & restrictions_after) const44*d9f75844SAndroid Build Coastguard Workerbool BitrateConstraint::IsAdaptationUpAllowed( 45*d9f75844SAndroid Build Coastguard Worker const VideoStreamInputState& input_state, 46*d9f75844SAndroid Build Coastguard Worker const VideoSourceRestrictions& restrictions_before, 47*d9f75844SAndroid Build Coastguard Worker const VideoSourceRestrictions& restrictions_after) const { 48*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 49*d9f75844SAndroid Build Coastguard Worker // Make sure bitrate limits are not violated. 50*d9f75844SAndroid Build Coastguard Worker if (DidIncreaseResolution(restrictions_before, restrictions_after)) { 51*d9f75844SAndroid Build Coastguard Worker if (!encoder_settings_.has_value()) { 52*d9f75844SAndroid Build Coastguard Worker return true; 53*d9f75844SAndroid Build Coastguard Worker } 54*d9f75844SAndroid Build Coastguard Worker 55*d9f75844SAndroid Build Coastguard Worker uint32_t bitrate_bps = encoder_target_bitrate_bps_.value_or(0); 56*d9f75844SAndroid Build Coastguard Worker if (bitrate_bps == 0) { 57*d9f75844SAndroid Build Coastguard Worker return true; 58*d9f75844SAndroid Build Coastguard Worker } 59*d9f75844SAndroid Build Coastguard Worker 60*d9f75844SAndroid Build Coastguard Worker if (VideoStreamEncoderResourceManager::IsSimulcastOrMultipleSpatialLayers( 61*d9f75844SAndroid Build Coastguard Worker encoder_settings_->encoder_config())) { 62*d9f75844SAndroid Build Coastguard Worker // Resolution bitrate limits usage is restricted to singlecast. 63*d9f75844SAndroid Build Coastguard Worker return true; 64*d9f75844SAndroid Build Coastguard Worker } 65*d9f75844SAndroid Build Coastguard Worker 66*d9f75844SAndroid Build Coastguard Worker absl::optional<int> current_frame_size_px = 67*d9f75844SAndroid Build Coastguard Worker input_state.single_active_stream_pixels(); 68*d9f75844SAndroid Build Coastguard Worker if (!current_frame_size_px.has_value()) { 69*d9f75844SAndroid Build Coastguard Worker return true; 70*d9f75844SAndroid Build Coastguard Worker } 71*d9f75844SAndroid Build Coastguard Worker 72*d9f75844SAndroid Build Coastguard Worker absl::optional<VideoEncoder::ResolutionBitrateLimits> bitrate_limits = 73*d9f75844SAndroid Build Coastguard Worker encoder_settings_->encoder_info().GetEncoderBitrateLimitsForResolution( 74*d9f75844SAndroid Build Coastguard Worker // Need some sort of expected resulting pixels to be used 75*d9f75844SAndroid Build Coastguard Worker // instead of unrestricted. 76*d9f75844SAndroid Build Coastguard Worker GetHigherResolutionThan(*current_frame_size_px)); 77*d9f75844SAndroid Build Coastguard Worker 78*d9f75844SAndroid Build Coastguard Worker if (bitrate_limits.has_value()) { 79*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_GE(bitrate_limits->frame_size_pixels, *current_frame_size_px); 80*d9f75844SAndroid Build Coastguard Worker return bitrate_bps >= 81*d9f75844SAndroid Build Coastguard Worker static_cast<uint32_t>(bitrate_limits->min_start_bitrate_bps); 82*d9f75844SAndroid Build Coastguard Worker } 83*d9f75844SAndroid Build Coastguard Worker } 84*d9f75844SAndroid Build Coastguard Worker return true; 85*d9f75844SAndroid Build Coastguard Worker } 86*d9f75844SAndroid Build Coastguard Worker 87*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc 88