mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-14 14:20:45 +01:00

Merge approval: https://g-issues.chromium.org/issues/367752722#comment5
(cherry picked from commit e81ba30897
)
Bug: chromium:328598314, chromium:367752722
Change-Id: I132b4c30f132ace2bbef6359edd994c1ad75c9ad
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/362620
Reviewed-by: Johannes Kron <kron@webrtc.org>
Commit-Queue: Sergey Silkin <ssilkin@webrtc.org>
Cr-Original-Commit-Position: refs/heads/main@{#43035}
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/362981
Commit-Queue: Johannes Kron <kron@webrtc.org>
Cr-Commit-Position: refs/branch-heads/6723@{#1}
Cr-Branched-From: 13e377b804f68aa9c20ea5e449666ea5248e3286-refs/heads/main@{#43019}
119 lines
4.3 KiB
C++
119 lines
4.3 KiB
C++
/*
|
|
* Copyright (c) 2024 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/quality_convergence_controller.h"
|
|
|
|
#include <algorithm>
|
|
|
|
#include "rtc_base/checks.h"
|
|
#include "rtc_base/experiments/struct_parameters_parser.h"
|
|
#include "rtc_base/logging.h"
|
|
|
|
namespace webrtc {
|
|
namespace {
|
|
// TODO(https://crbug.com/328598314): Remove default values once HW encoders
|
|
// correctly report the minimum QP value. These thresholds correspond to the
|
|
// default configurations used for the software encoders.
|
|
constexpr int kVp8DefaultStaticQpThreshold = 15;
|
|
constexpr int kVp9DefaultStaticQpThreshold = 32;
|
|
constexpr int kAv1DefaultStaticQpThreshold = 60;
|
|
|
|
struct StaticDetectionConfig {
|
|
// Overrides the static QP threshold if set to a higher value than what is
|
|
// reported by the encoder.
|
|
std::optional<int> static_qp_threshold_override;
|
|
std::unique_ptr<StructParametersParser> Parser();
|
|
};
|
|
|
|
std::unique_ptr<StructParametersParser> StaticDetectionConfig::Parser() {
|
|
// The empty comments ensures that each pair is on a separate line.
|
|
return StructParametersParser::Create("static_qp_threshold",
|
|
&static_qp_threshold_override);
|
|
}
|
|
|
|
int GetDefaultStaticQpThreshold(VideoCodecType codec,
|
|
const FieldTrialsView& trials) {
|
|
StaticDetectionConfig static_config;
|
|
int default_static_qp_threhsold = 0;
|
|
switch (codec) {
|
|
case kVideoCodecVP8:
|
|
default_static_qp_threhsold = kVp8DefaultStaticQpThreshold;
|
|
static_config.Parser()->Parse(trials.Lookup("WebRTC-QCM-Static-VP8"));
|
|
break;
|
|
case kVideoCodecVP9:
|
|
default_static_qp_threhsold = kVp9DefaultStaticQpThreshold;
|
|
static_config.Parser()->Parse(trials.Lookup("WebRTC-QCM-Static-VP9"));
|
|
break;
|
|
case kVideoCodecAV1:
|
|
default_static_qp_threhsold = kAv1DefaultStaticQpThreshold;
|
|
static_config.Parser()->Parse(trials.Lookup("WebRTC-QCM-Static-AV1"));
|
|
break;
|
|
case kVideoCodecGeneric:
|
|
case kVideoCodecH264:
|
|
case kVideoCodecH265:
|
|
// -1 will effectively disable the static QP threshold since QP values are
|
|
// always >= 0.
|
|
return -1;
|
|
}
|
|
|
|
if (static_config.static_qp_threshold_override.has_value()) {
|
|
RTC_LOG(LS_INFO) << "static_qp_threshold_override: "
|
|
<< *static_config.static_qp_threshold_override;
|
|
return *static_config.static_qp_threshold_override;
|
|
}
|
|
|
|
return default_static_qp_threhsold;
|
|
}
|
|
} // namespace
|
|
|
|
void QualityConvergenceController::Initialize(int number_of_layers,
|
|
std::optional<int> encoder_min_qp,
|
|
VideoCodecType codec,
|
|
const FieldTrialsView& trials) {
|
|
RTC_DCHECK(sequence_checker_.IsCurrent());
|
|
RTC_CHECK(number_of_layers > 0);
|
|
number_of_layers_ = number_of_layers;
|
|
convergence_monitors_.clear();
|
|
|
|
int qp_threshold = GetDefaultStaticQpThreshold(codec, trials);
|
|
if (encoder_min_qp.has_value()) {
|
|
qp_threshold = std::max(qp_threshold, *encoder_min_qp);
|
|
}
|
|
|
|
for (int i = 0; i < number_of_layers_; ++i) {
|
|
convergence_monitors_.push_back(
|
|
QualityConvergenceMonitor::Create(qp_threshold, codec, trials));
|
|
}
|
|
initialized_ = true;
|
|
}
|
|
|
|
bool QualityConvergenceController::AddSampleAndCheckTargetQuality(
|
|
int layer_index,
|
|
int qp,
|
|
bool is_refresh_frame) {
|
|
RTC_DCHECK(sequence_checker_.IsCurrent());
|
|
RTC_CHECK(initialized_);
|
|
if (layer_index < 0 || layer_index >= number_of_layers_) {
|
|
return false;
|
|
}
|
|
|
|
// TODO(kron): Remove temporary check that verifies that the initialization is
|
|
// working as expected. See https://crbug.com/359410061.
|
|
RTC_DCHECK(number_of_layers_ ==
|
|
static_cast<int>(convergence_monitors_.size()));
|
|
if (number_of_layers_ != static_cast<int>(convergence_monitors_.size())) {
|
|
return false;
|
|
}
|
|
|
|
convergence_monitors_[layer_index]->AddSample(qp, is_refresh_frame);
|
|
return convergence_monitors_[layer_index]->AtTargetQuality();
|
|
}
|
|
|
|
} // namespace webrtc
|