SimulcastEncoderAdapter: Add field trial for EncoderInfo settings.

Allowed settings:
- requested_resolution_alignment
- apply_alignment_to_all_simulcast_layers


Bug: none
Change-Id: Ic4c733fd1134b9d097a2d19963eef1b676058f49
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/201626
Commit-Queue: Åsa Persson <asapersson@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Sergey Silkin <ssilkin@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33010}
This commit is contained in:
Åsa Persson 2021-01-15 15:03:31 +01:00 committed by Commit Bot
parent fd9500e3b5
commit 2397b6e75d
4 changed files with 92 additions and 1 deletions

View File

@ -193,6 +193,7 @@ rtc_library("rtc_simulcast_encoder_adapter") {
"../modules/video_coding:video_coding_utility",
"../rtc_base:checks",
"../rtc_base:rtc_base_approved",
"../rtc_base/experiments:field_trial_parser",
"../rtc_base/experiments:rate_control_settings",
"../rtc_base/synchronization:sequence_checker",
"../rtc_base/system:no_unique_address",

View File

@ -228,6 +228,11 @@ SimulcastEncoderAdapter::SimulcastEncoderAdapter(
"WebRTC-Video-PreferTemporalSupportOnBaseLayer")) {
RTC_DCHECK(primary_factory);
ParseFieldTrial({&requested_resolution_alignment_override_,
&apply_alignment_to_all_simulcast_layers_override_},
field_trial::FindFullName(
"WebRTC-SimulcastEncoderAdapter-GetEncoderInfoOverride"));
// The adapter is typically created on the worker thread, but operated on
// the encoder task queue.
encoder_queue_.Detach();
@ -425,6 +430,27 @@ int SimulcastEncoderAdapter::Encode(
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
}
if (requested_resolution_alignment_override_) {
const int alignment = *requested_resolution_alignment_override_;
if (input_image.width() % alignment != 0 ||
input_image.height() % alignment != 0) {
RTC_LOG(LS_WARNING) << "Frame " << input_image.width() << "x"
<< input_image.height() << " not divisible by "
<< alignment;
return WEBRTC_VIDEO_CODEC_ERROR;
}
if (apply_alignment_to_all_simulcast_layers_override_.Get()) {
for (const auto& layer : encoder_contexts_) {
if (layer.width() % alignment != 0 || layer.height() % alignment != 0) {
RTC_LOG(LS_WARNING)
<< "Codec " << layer.width() << "x" << layer.height()
<< " not divisible by " << alignment;
return WEBRTC_VIDEO_CODEC_ERROR;
}
}
}
}
// All active streams should generate a key frame if
// a key frame is requested by any stream.
bool send_key_frame = false;
@ -713,10 +739,23 @@ void SimulcastEncoderAdapter::DestroyStoredEncoders() {
}
}
void SimulcastEncoderAdapter::OverrideFromFieldTrial(
VideoEncoder::EncoderInfo* info) const {
if (requested_resolution_alignment_override_) {
info->requested_resolution_alignment =
*requested_resolution_alignment_override_;
info->apply_alignment_to_all_simulcast_layers =
apply_alignment_to_all_simulcast_layers_override_.Get();
}
}
VideoEncoder::EncoderInfo SimulcastEncoderAdapter::GetEncoderInfo() const {
if (encoder_contexts_.size() == 1) {
// Not using simulcast adapting functionality, just pass through.
return encoder_contexts_.front().encoder().GetEncoderInfo();
VideoEncoder::EncoderInfo info =
encoder_contexts_.front().encoder().GetEncoderInfo();
OverrideFromFieldTrial(&info);
return info;
}
VideoEncoder::EncoderInfo encoder_info;
@ -726,6 +765,7 @@ VideoEncoder::EncoderInfo SimulcastEncoderAdapter::GetEncoderInfo() const {
encoder_info.supports_native_handle = true;
encoder_info.scaling_settings.thresholds = absl::nullopt;
if (encoder_contexts_.empty()) {
OverrideFromFieldTrial(&encoder_info);
return encoder_info;
}
@ -784,6 +824,8 @@ VideoEncoder::EncoderInfo SimulcastEncoderAdapter::GetEncoderInfo() const {
}
encoder_info.implementation_name += ")";
OverrideFromFieldTrial(&encoder_info);
return encoder_info;
}

View File

@ -26,6 +26,7 @@
#include "modules/video_coding/include/video_codec_interface.h"
#include "modules/video_coding/utility/framerate_controller.h"
#include "rtc_base/atomic_ops.h"
#include "rtc_base/experiments/field_trial_parser.h"
#include "rtc_base/synchronization/sequence_checker.h"
#include "rtc_base/system/no_unique_address.h"
#include "rtc_base/system/rtc_export.h"
@ -138,6 +139,8 @@ class RTC_EXPORT SimulcastEncoderAdapter : public VideoEncoder {
void OnDroppedFrame(size_t stream_idx);
void OverrideFromFieldTrial(VideoEncoder::EncoderInfo* info) const;
volatile int inited_; // Accessed atomically.
VideoEncoderFactory* const primary_encoder_factory_;
VideoEncoderFactory* const fallback_encoder_factory_;
@ -158,6 +161,14 @@ class RTC_EXPORT SimulcastEncoderAdapter : public VideoEncoder {
const absl::optional<unsigned int> experimental_boosted_screenshare_qp_;
const bool boost_base_layer_quality_;
const bool prefer_temporal_support_on_base_layer_;
// Overrides from field trial.
// EncoderInfo::requested_resolution_alignment.
FieldTrialOptional<int> requested_resolution_alignment_override_{
"requested_resolution_alignment"};
// EncoderInfo::apply_alignment_to_all_simulcast_layers.
FieldTrialFlag apply_alignment_to_all_simulcast_layers_override_{
"apply_alignment_to_all_simulcast_layers"};
};
} // namespace webrtc

View File

@ -28,6 +28,7 @@
#include "modules/video_coding/include/video_codec_interface.h"
#include "modules/video_coding/utility/simulcast_test_fixture_impl.h"
#include "rtc_base/checks.h"
#include "test/field_trial.h"
#include "test/gmock.h"
#include "test/gtest.h"
@ -1291,6 +1292,42 @@ TEST_F(TestSimulcastEncoderAdapterFake,
adapter_->GetEncoderInfo().apply_alignment_to_all_simulcast_layers);
}
TEST_F(TestSimulcastEncoderAdapterFake, AlignmentFromFieldTrial) {
test::ScopedFieldTrials field_trials(
"WebRTC-SimulcastEncoderAdapter-GetEncoderInfoOverride/"
"requested_resolution_alignment:8,"
"apply_alignment_to_all_simulcast_layers/");
SetUp();
SimulcastTestFixtureImpl::DefaultSettings(
&codec_, static_cast<const int*>(kTestTemporalLayerProfile),
kVideoCodecVP8);
codec_.numberOfSimulcastStreams = 3;
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
ASSERT_EQ(3u, helper_->factory()->encoders().size());
EXPECT_EQ(8, adapter_->GetEncoderInfo().requested_resolution_alignment);
EXPECT_TRUE(
adapter_->GetEncoderInfo().apply_alignment_to_all_simulcast_layers);
}
TEST_F(TestSimulcastEncoderAdapterFake,
AlignmentFromFieldTrialForSingleStream) {
test::ScopedFieldTrials field_trials(
"WebRTC-SimulcastEncoderAdapter-GetEncoderInfoOverride/"
"requested_resolution_alignment:9/");
SetUp();
SimulcastTestFixtureImpl::DefaultSettings(
&codec_, static_cast<const int*>(kTestTemporalLayerProfile),
kVideoCodecVP8);
codec_.numberOfSimulcastStreams = 1;
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
ASSERT_EQ(1u, helper_->factory()->encoders().size());
EXPECT_EQ(9, adapter_->GetEncoderInfo().requested_resolution_alignment);
EXPECT_FALSE(
adapter_->GetEncoderInfo().apply_alignment_to_all_simulcast_layers);
}
TEST_F(TestSimulcastEncoderAdapterFake, ReportsInternalSource) {
SimulcastTestFixtureImpl::DefaultSettings(
&codec_, static_cast<const int*>(kTestTemporalLayerProfile),