Refactor encoder-complexity param in VideoCodec w/backward compatibility

Move complexity parameter to the main VideoCodec class to enable
additional video codecs to use the parameter without creating a new
codec-specific structure.

Bug: webrtc:13694
Change-Id: Icb7cf640b178875d799f39ade8b5084e3222bb1c
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/251921
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Michael Horowitz <mhoro@google.com>
Cr-Commit-Position: refs/heads/main@{#36040}
This commit is contained in:
“Michael 2022-02-19 16:48:50 -06:00 committed by WebRTC LUCI CQ
parent 1f6e4308ab
commit 3147e29c4e
7 changed files with 40 additions and 11 deletions

View file

@ -139,4 +139,23 @@ VideoCodecType PayloadStringToCodecType(const std::string& name) {
return kVideoCodecGeneric; return kVideoCodecGeneric;
} }
VideoCodecComplexity VideoCodec::GetVideoEncoderComplexity() const {
if (complexity_.has_value()) {
return complexity_.value();
}
switch (codecType) {
case kVideoCodecVP8:
return VP8().complexity;
case kVideoCodecVP9:
return VP9().complexity;
default:
return VideoCodecComplexity::kComplexityNormal;
}
}
void VideoCodec::SetVideoEncoderComplexity(
VideoCodecComplexity complexity_setting) {
complexity_ = complexity_setting;
}
} // namespace webrtc } // namespace webrtc

View file

@ -109,6 +109,9 @@ class RTC_EXPORT VideoCodec {
scalability_mode_ = std::string(scalability_mode); scalability_mode_ = std::string(scalability_mode);
} }
VideoCodecComplexity GetVideoEncoderComplexity() const;
void SetVideoEncoderComplexity(VideoCodecComplexity complexity_setting);
// Public variables. TODO(hta): Make them private with accessors. // Public variables. TODO(hta): Make them private with accessors.
VideoCodecType codecType; VideoCodecType codecType;
@ -169,6 +172,9 @@ class RTC_EXPORT VideoCodec {
// This will allow removing the VideoCodec* types from this file. // This will allow removing the VideoCodec* types from this file.
VideoCodecUnion codec_specific_; VideoCodecUnion codec_specific_;
std::string scalability_mode_; std::string scalability_mode_;
// 'complexity_' indicates the CPU capability of the client. It's used to
// determine encoder CPU complexity (e.g., cpu_used for VP8, VP9. and AV1).
absl::optional<VideoCodecComplexity> complexity_;
}; };
} // namespace webrtc } // namespace webrtc

View file

@ -791,8 +791,8 @@ webrtc::VideoCodec SimulcastEncoderAdapter::MakeStreamCodec(
// kComplexityHigher, which maps to cpu_used = -4. // kComplexityHigher, which maps to cpu_used = -4.
int pixels_per_frame = codec_params.width * codec_params.height; int pixels_per_frame = codec_params.width * codec_params.height;
if (pixels_per_frame < 352 * 288) { if (pixels_per_frame < 352 * 288) {
codec_params.VP8()->complexity = codec_params.SetVideoEncoderComplexity(
webrtc::VideoCodecComplexity::kComplexityHigher; webrtc::VideoCodecComplexity::kComplexityHigher);
} }
// Turn off denoising for all streams but the highest resolution. // Turn off denoising for all streams but the highest resolution.
codec_params.VP8()->denoisingOn = false; codec_params.VP8()->denoisingOn = false;

View file

@ -502,7 +502,8 @@ class TestSimulcastEncoderAdapterFake : public ::testing::Test,
EXPECT_EQ(ref.maxBitrate, target.maxBitrate); EXPECT_EQ(ref.maxBitrate, target.maxBitrate);
EXPECT_EQ(ref.minBitrate, target.minBitrate); EXPECT_EQ(ref.minBitrate, target.minBitrate);
EXPECT_EQ(ref.maxFramerate, target.maxFramerate); EXPECT_EQ(ref.maxFramerate, target.maxFramerate);
EXPECT_EQ(ref.VP8().complexity, target.VP8().complexity); EXPECT_EQ(ref.GetVideoEncoderComplexity(),
target.GetVideoEncoderComplexity());
EXPECT_EQ(ref.VP8().numberOfTemporalLayers, EXPECT_EQ(ref.VP8().numberOfTemporalLayers,
target.VP8().numberOfTemporalLayers); target.VP8().numberOfTemporalLayers);
EXPECT_EQ(ref.VP8().denoisingOn, target.VP8().denoisingOn); EXPECT_EQ(ref.VP8().denoisingOn, target.VP8().denoisingOn);
@ -538,8 +539,8 @@ class TestSimulcastEncoderAdapterFake : public ::testing::Test,
// stream 0, the lowest resolution stream. // stream 0, the lowest resolution stream.
InitRefCodec(0, &ref_codec); InitRefCodec(0, &ref_codec);
ref_codec.qpMax = 45; ref_codec.qpMax = 45;
ref_codec.VP8()->complexity = ref_codec.SetVideoEncoderComplexity(
webrtc::VideoCodecComplexity::kComplexityHigher; webrtc::VideoCodecComplexity::kComplexityHigher);
ref_codec.VP8()->denoisingOn = false; ref_codec.VP8()->denoisingOn = false;
ref_codec.startBitrate = 100; // Should equal to the target bitrate. ref_codec.startBitrate = 100; // Should equal to the target bitrate.
VerifyCodec(ref_codec, 0); VerifyCodec(ref_codec, 0);
@ -1134,7 +1135,8 @@ TEST_F(TestSimulcastEncoderAdapterFake, DoesNotAlterMaxQpForScreenshare) {
VideoCodec ref_codec; VideoCodec ref_codec;
InitRefCodec(0, &ref_codec); InitRefCodec(0, &ref_codec);
ref_codec.qpMax = kHighMaxQp; ref_codec.qpMax = kHighMaxQp;
ref_codec.VP8()->complexity = webrtc::VideoCodecComplexity::kComplexityHigher; ref_codec.SetVideoEncoderComplexity(
webrtc::VideoCodecComplexity::kComplexityHigher);
ref_codec.VP8()->denoisingOn = false; ref_codec.VP8()->denoisingOn = false;
ref_codec.startBitrate = 100; // Should equal to the target bitrate. ref_codec.startBitrate = 100; // Should equal to the target bitrate.
VerifyCodec(ref_codec, 0); VerifyCodec(ref_codec, 0);
@ -1167,7 +1169,8 @@ TEST_F(TestSimulcastEncoderAdapterFake,
VideoCodec ref_codec; VideoCodec ref_codec;
InitRefCodec(2, &ref_codec, true /* reverse_layer_order */); InitRefCodec(2, &ref_codec, true /* reverse_layer_order */);
ref_codec.qpMax = kHighMaxQp; ref_codec.qpMax = kHighMaxQp;
ref_codec.VP8()->complexity = webrtc::VideoCodecComplexity::kComplexityHigher; ref_codec.SetVideoEncoderComplexity(
webrtc::VideoCodecComplexity::kComplexityHigher);
ref_codec.VP8()->denoisingOn = false; ref_codec.VP8()->denoisingOn = false;
ref_codec.startBitrate = 100; // Should equal to the target bitrate. ref_codec.startBitrate = 100; // Should equal to the target bitrate.
VerifyCodec(ref_codec, 2); VerifyCodec(ref_codec, 2);

View file

@ -104,7 +104,6 @@ std::string CodecSpecificToString(const VideoCodec& codec) {
rtc::SimpleStringBuilder ss(buf); rtc::SimpleStringBuilder ss(buf);
switch (codec.codecType) { switch (codec.codecType) {
case kVideoCodecVP8: case kVideoCodecVP8:
ss << "complexity: " << static_cast<int>(codec.VP8().complexity);
ss << "\nnum_temporal_layers: " ss << "\nnum_temporal_layers: "
<< static_cast<int>(codec.VP8().numberOfTemporalLayers); << static_cast<int>(codec.VP8().numberOfTemporalLayers);
ss << "\ndenoising: " << codec.VP8().denoisingOn; ss << "\ndenoising: " << codec.VP8().denoisingOn;
@ -113,7 +112,6 @@ std::string CodecSpecificToString(const VideoCodec& codec) {
ss << "\nkey_frame_interval: " << codec.VP8().keyFrameInterval; ss << "\nkey_frame_interval: " << codec.VP8().keyFrameInterval;
break; break;
case kVideoCodecVP9: case kVideoCodecVP9:
ss << "complexity: " << static_cast<int>(codec.VP9().complexity);
ss << "\nnum_temporal_layers: " ss << "\nnum_temporal_layers: "
<< static_cast<int>(codec.VP9().numberOfTemporalLayers); << static_cast<int>(codec.VP9().numberOfTemporalLayers);
ss << "\nnum_spatial_layers: " ss << "\nnum_spatial_layers: "
@ -302,6 +300,8 @@ std::string VideoCodecTestFixtureImpl::Config::ToString() const {
ss << "\nnum_simulcast_streams: " ss << "\nnum_simulcast_streams: "
<< static_cast<int>(codec_settings.numberOfSimulcastStreams); << static_cast<int>(codec_settings.numberOfSimulcastStreams);
ss << "\n\n--> codec_settings." << codec_type; ss << "\n\n--> codec_settings." << codec_type;
ss << "complexity: "
<< static_cast<int>(codec_settings.GetVideoEncoderComplexity());
ss << "\n" << CodecSpecificToString(codec_settings); ss << "\n" << CodecSpecificToString(codec_settings);
if (codec_settings.numberOfSimulcastStreams > 1) { if (codec_settings.numberOfSimulcastStreams > 1) {
for (int i = 0; i < codec_settings.numberOfSimulcastStreams; ++i) { for (int i = 0; i < codec_settings.numberOfSimulcastStreams; ++i) {

View file

@ -591,7 +591,7 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst,
} }
// Allow the user to set the complexity for the base stream. // Allow the user to set the complexity for the base stream.
switch (inst->VP8().complexity) { switch (inst->GetVideoEncoderComplexity()) {
case VideoCodecComplexity::kComplexityHigh: case VideoCodecComplexity::kComplexityHigh:
cpu_speed_[0] = -5; cpu_speed_[0] = -5;
break; break;

View file

@ -76,7 +76,8 @@ class TestVp8Impl : public VideoCodecUnitTest {
webrtc::test::CodecSettings(kVideoCodecVP8, codec_settings); webrtc::test::CodecSettings(kVideoCodecVP8, codec_settings);
codec_settings->width = kWidth; codec_settings->width = kWidth;
codec_settings->height = kHeight; codec_settings->height = kHeight;
codec_settings->VP8()->complexity = VideoCodecComplexity::kComplexityNormal; codec_settings->SetVideoEncoderComplexity(
VideoCodecComplexity::kComplexityNormal);
} }
void EncodeAndWaitForFrame(const VideoFrame& input_frame, void EncodeAndWaitForFrame(const VideoFrame& input_frame,