There are now multiple ways to configure VP9 L1Tx: - Legacy API: configure legacy SVC and disable encodings, this gets interpreted as disabling spatial layers (non-standard API hack). - Standard API: configure scalability_mode. This can be done either with a single encoding or multiple encodings. As long as only one encoding is active we get a single L1Tx ssrc, same as legacy API. Due to a bug, the ApplySpatialLayerBitrateLimits() logic which tweaks bitrates was only applied in the legacy API code path, not the standard API code path, despite both code paths configuring L1Tx. The issue is that IsSimulcastOrMultipleSpatialLayers() was checking if `number_of_streams == 1`. This is true in legacy code path but not standard code path. The fix is to look at `numberOfSimulcastStreams == 1` instead, which is set to the correct value regardless of code path used. This CL adds comments documenting the difference between `number_of_streams` and `numberOfSimulcastStreams` to reduce the risk of more mistakes like this in the future. Bug: chromium:1455039, b:279161263 Change-Id: I69789b68cc5d45ef1b3becd310687c8dec8e7c87 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/308722 Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Cr-Commit-Position: refs/heads/main@{#40287}
89 lines
3.1 KiB
C++
89 lines
3.1 KiB
C++
/*
|
|
* 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 <utility>
|
|
#include <vector>
|
|
|
|
#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<EncoderSettings> encoder_settings) {
|
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
|
encoder_settings_ = std::move(encoder_settings);
|
|
}
|
|
|
|
void BitrateConstraint::OnEncoderTargetBitrateUpdated(
|
|
absl::optional<uint32_t> 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(),
|
|
encoder_settings_->video_codec())) {
|
|
// Resolution bitrate limits usage is restricted to singlecast.
|
|
return true;
|
|
}
|
|
|
|
absl::optional<int> current_frame_size_px =
|
|
input_state.single_active_stream_pixels();
|
|
if (!current_frame_size_px.has_value()) {
|
|
return true;
|
|
}
|
|
|
|
absl::optional<VideoEncoder::ResolutionBitrateLimits> 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<uint32_t>(bitrate_limits->min_start_bitrate_bps);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
} // namespace webrtc
|