/* * Copyright 2020 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 "video/adaptation/bitrate_constraint.h" #include #include #include "api/sequence_checker.h" #include "call/adaptation/video_stream_adapter.h" #include "video/adaptation/video_stream_encoder_resource_manager.h" namespace webrtc { BitrateConstraint::BitrateConstraint() : encoder_settings_(absl::nullopt), encoder_target_bitrate_bps_(absl::nullopt) { sequence_checker_.Detach(); } void BitrateConstraint::OnEncoderSettingsUpdated( absl::optional encoder_settings) { RTC_DCHECK_RUN_ON(&sequence_checker_); encoder_settings_ = std::move(encoder_settings); } void BitrateConstraint::OnEncoderTargetBitrateUpdated( absl::optional encoder_target_bitrate_bps) { RTC_DCHECK_RUN_ON(&sequence_checker_); encoder_target_bitrate_bps_ = std::move(encoder_target_bitrate_bps); } // Checks if resolution is allowed to adapt up based on the current bitrate and // ResolutionBitrateLimits.min_start_bitrate_bps for the next higher resolution. // Bitrate limits usage is restricted to a single active stream/layer (e.g. when // quality scaling is enabled). bool BitrateConstraint::IsAdaptationUpAllowed( const VideoStreamInputState& input_state, const VideoSourceRestrictions& restrictions_before, const VideoSourceRestrictions& restrictions_after) const { RTC_DCHECK_RUN_ON(&sequence_checker_); // Make sure bitrate limits are not violated. if (DidIncreaseResolution(restrictions_before, restrictions_after)) { if (!encoder_settings_.has_value()) { return true; } uint32_t bitrate_bps = encoder_target_bitrate_bps_.value_or(0); if (bitrate_bps == 0) { return true; } if (VideoStreamEncoderResourceManager::IsSimulcastOrMultipleSpatialLayers( encoder_settings_->encoder_config())) { // Resolution bitrate limits usage is restricted to singlecast. return true; } absl::optional current_frame_size_px = input_state.single_active_stream_pixels(); if (!current_frame_size_px.has_value()) { return true; } absl::optional bitrate_limits = encoder_settings_->encoder_info().GetEncoderBitrateLimitsForResolution( // Need some sort of expected resulting pixels to be used // instead of unrestricted. GetHigherResolutionThan(*current_frame_size_px)); if (bitrate_limits.has_value()) { RTC_DCHECK_GE(bitrate_limits->frame_size_pixels, *current_frame_size_px); return bitrate_bps >= static_cast(bitrate_limits->min_start_bitrate_bps); } } return true; } } // namespace webrtc