Implement new specification for degradation preference
The degradation preference is now based on the content hint of the track
if it's unspecified.
Bug: webrtc:11164
Change-Id: Iaa0dbf1c1bf68a46fc5131e534d423c30c5439c7
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/161233
Commit-Queue: Florent Castelli <orphis@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Åsa Persson <asapersson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30691}
diff --git a/api/rtp_parameters.h b/api/rtp_parameters.h
index 358a582..a22f764 100644
--- a/api/rtp_parameters.h
+++ b/api/rtp_parameters.h
@@ -609,8 +609,7 @@
// When bandwidth is constrained and the RtpSender needs to choose between
// degrading resolution or degrading framerate, degradationPreference
// indicates which is preferred. Only for video tracks.
- DegradationPreference degradation_preference =
- DegradationPreference::BALANCED;
+ absl::optional<DegradationPreference> degradation_preference;
bool operator==(const RtpParameters& o) const {
return mid == o.mid && codecs == o.codecs &&
diff --git a/media/BUILD.gn b/media/BUILD.gn
index f68f991..8c2d8c0 100644
--- a/media/BUILD.gn
+++ b/media/BUILD.gn
@@ -280,6 +280,7 @@
"..:webrtc_common",
"../api:call_api",
"../api:libjingle_peerconnection_api",
+ "../api:media_stream_interface",
"../api:rtp_parameters",
"../api:scoped_refptr",
"../api:transport_api",
diff --git a/media/base/media_channel.cc b/media/base/media_channel.cc
index 3417924..2e9bfc3 100644
--- a/media/base/media_channel.cc
+++ b/media/base/media_channel.cc
@@ -12,7 +12,8 @@
namespace cricket {
-VideoOptions::VideoOptions() = default;
+VideoOptions::VideoOptions()
+ : content_hint(webrtc::VideoTrackInterface::ContentHint::kNone) {}
VideoOptions::~VideoOptions() = default;
MediaChannel::MediaChannel(const MediaConfig& config)
diff --git a/media/base/media_channel.h b/media/base/media_channel.h
index 8ee4a23..a62c618 100644
--- a/media/base/media_channel.h
+++ b/media/base/media_channel.h
@@ -23,6 +23,7 @@
#include "api/crypto/frame_decryptor_interface.h"
#include "api/crypto/frame_encryptor_interface.h"
#include "api/frame_transformer_interface.h"
+#include "api/media_stream_interface.h"
#include "api/rtc_error.h"
#include "api/rtp_parameters.h"
#include "api/transport/media/media_transport_config.h"
@@ -144,6 +145,7 @@
// things, e.g., screencast of a text document and screencast of a
// youtube video have different needs.
absl::optional<bool> is_screencast;
+ webrtc::VideoTrackInterface::ContentHint content_hint;
private:
template <typename T>
diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc
index b2f8429..48aea63 100644
--- a/media/engine/webrtc_video_engine.cc
+++ b/media/engine/webrtc_video_engine.cc
@@ -19,6 +19,7 @@
#include "absl/algorithm/container.h"
#include "absl/strings/match.h"
+#include "api/media_stream_interface.h"
#include "api/transport/datagram_transport_interface.h"
#include "api/units/data_rate.h"
#include "api/video/video_codec_constants.h"
@@ -1948,25 +1949,37 @@
// result in blurry and unreadable text.
// |this| acts like a VideoSource to make sure SinkWants are handled on the
// correct thread.
- webrtc::DegradationPreference degradation_preference;
- if (rtp_parameters_.degradation_preference !=
- webrtc::DegradationPreference::BALANCED) {
- // If the degradationPreference is different from the default value, assume
- // it is what we want, regardless of trials or other internal settings.
- degradation_preference = rtp_parameters_.degradation_preference;
- } else if (!enable_cpu_overuse_detection_) {
- degradation_preference = webrtc::DegradationPreference::DISABLED;
- } else if (parameters_.options.is_screencast.value_or(false)) {
- degradation_preference = webrtc::DegradationPreference::MAINTAIN_RESOLUTION;
- } else if (webrtc::field_trial::IsEnabled(
- "WebRTC-Video-BalancedDegradation")) {
- degradation_preference = webrtc::DegradationPreference::BALANCED;
- } else {
- // TODO(orphis): The default should be BALANCED as the standard mandates.
- // Right now, there is no way to set it to BALANCED as it would change
- // the behavior for any project expecting MAINTAIN_FRAMERATE by default.
- degradation_preference = webrtc::DegradationPreference::MAINTAIN_FRAMERATE;
+ if (!enable_cpu_overuse_detection_) {
+ return webrtc::DegradationPreference::DISABLED;
}
+
+ webrtc::DegradationPreference degradation_preference;
+ if (rtp_parameters_.degradation_preference.has_value()) {
+ degradation_preference = *rtp_parameters_.degradation_preference;
+ } else {
+ if (parameters_.options.content_hint ==
+ webrtc::VideoTrackInterface::ContentHint::kFluid) {
+ degradation_preference =
+ webrtc::DegradationPreference::MAINTAIN_FRAMERATE;
+ } else if (parameters_.options.is_screencast.value_or(false) ||
+ parameters_.options.content_hint ==
+ webrtc::VideoTrackInterface::ContentHint::kDetailed ||
+ parameters_.options.content_hint ==
+ webrtc::VideoTrackInterface::ContentHint::kText) {
+ degradation_preference =
+ webrtc::DegradationPreference::MAINTAIN_RESOLUTION;
+ } else if (webrtc::field_trial::IsEnabled(
+ "WebRTC-Video-BalancedDegradation")) {
+ // Standard wants balanced by default, but it needs to be tuned first.
+ degradation_preference = webrtc::DegradationPreference::BALANCED;
+ } else {
+ // Keep MAINTAIN_FRAMERATE by default until BALANCED has been tuned for
+ // all codecs and launched.
+ degradation_preference =
+ webrtc::DegradationPreference::MAINTAIN_FRAMERATE;
+ }
+ }
+
return degradation_preference;
}
diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc
index d294d31..d33a2c3 100644
--- a/media/engine/webrtc_video_engine_unittest.cc
+++ b/media/engine/webrtc_video_engine_unittest.cc
@@ -7318,8 +7318,7 @@
webrtc::RtpParameters rtp_parameters =
channel_->GetRtpSendParameters(last_ssrc_);
- EXPECT_EQ(rtp_parameters.degradation_preference,
- webrtc::DegradationPreference::BALANCED);
+ EXPECT_FALSE(rtp_parameters.degradation_preference.has_value());
rtp_parameters.degradation_preference =
webrtc::DegradationPreference::MAINTAIN_FRAMERATE;
diff --git a/pc/rtp_sender.cc b/pc/rtp_sender.cc
index 5a955e3..c56f4a9 100644
--- a/pc/rtp_sender.cc
+++ b/pc/rtp_sender.cc
@@ -606,6 +606,7 @@
options.is_screencast = source->is_screencast();
options.video_noise_reduction = source->needs_denoising();
}
+ options.content_hint = cached_track_content_hint_;
switch (cached_track_content_hint_) {
case VideoTrackInterface::ContentHint::kNone:
break;
diff --git a/sdk/android/instrumentationtests/src/org/webrtc/RtpSenderTest.java b/sdk/android/instrumentationtests/src/org/webrtc/RtpSenderTest.java
index 14d76d0..af9c62b 100644
--- a/sdk/android/instrumentationtests/src/org/webrtc/RtpSenderTest.java
+++ b/sdk/android/instrumentationtests/src/org/webrtc/RtpSenderTest.java
@@ -12,6 +12,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
@@ -54,7 +55,7 @@
RtpParameters parameters = sender.getParameters();
assertNotNull(parameters);
- assertEquals(DegradationPreference.BALANCED, parameters.degradationPreference);
+ assertNull(parameters.degradationPreference);
parameters.degradationPreference = DegradationPreference.MAINTAIN_FRAMERATE;
assertTrue(sender.setParameters(parameters));
diff --git a/sdk/android/src/jni/pc/rtp_parameters.cc b/sdk/android/src/jni/pc/rtp_parameters.cc
index 4bed3f8..5b394ab 100644
--- a/sdk/android/src/jni/pc/rtp_parameters.cc
+++ b/sdk/android/src/jni/pc/rtp_parameters.cc
@@ -187,8 +187,10 @@
const RtpParameters& parameters) {
return Java_RtpParameters_Constructor(
env, NativeToJavaString(env, parameters.transaction_id),
- Java_DegradationPreference_fromNativeIndex(
- env, static_cast<int>(parameters.degradation_preference)),
+ parameters.degradation_preference.has_value()
+ ? Java_DegradationPreference_fromNativeIndex(
+ env, static_cast<int>(*parameters.degradation_preference))
+ : nullptr,
NativeToJavaRtpRtcpParameters(env, parameters.rtcp),
NativeToJavaList(env, parameters.header_extensions,
&NativeToJavaRtpHeaderExtensionParameter),
diff --git a/sdk/objc/api/peerconnection/RTCRtpParameters.mm b/sdk/objc/api/peerconnection/RTCRtpParameters.mm
index d70f7da..cbb4576 100644
--- a/sdk/objc/api/peerconnection/RTCRtpParameters.mm
+++ b/sdk/objc/api/peerconnection/RTCRtpParameters.mm
@@ -56,9 +56,9 @@
}
_codecs = codecs;
- _degradationPreference = @([RTCRtpParameters
+ _degradationPreference = [RTCRtpParameters
degradationPreferenceFromNativeDegradationPreference:nativeParameters
- .degradation_preference]);
+ .degradation_preference];
}
return self;
}
@@ -98,17 +98,21 @@
}
}
-+ (RTCDegradationPreference)degradationPreferenceFromNativeDegradationPreference:
- (webrtc::DegradationPreference)nativeDegradationPreference {
- switch (nativeDegradationPreference) {
++ (NSNumber *)degradationPreferenceFromNativeDegradationPreference:
+ (absl::optional<webrtc::DegradationPreference>)nativeDegradationPreference {
+ if (!nativeDegradationPreference.has_value()) {
+ return nil;
+ }
+
+ switch (*nativeDegradationPreference) {
case webrtc::DegradationPreference::DISABLED:
- return RTCDegradationPreferenceDisabled;
+ return @(RTCDegradationPreferenceDisabled);
case webrtc::DegradationPreference::MAINTAIN_FRAMERATE:
- return RTCDegradationPreferenceMaintainFramerate;
+ return @(RTCDegradationPreferenceMaintainFramerate);
case webrtc::DegradationPreference::MAINTAIN_RESOLUTION:
- return RTCDegradationPreferenceMaintainResolution;
+ return @(RTCDegradationPreferenceMaintainResolution);
case webrtc::DegradationPreference::BALANCED:
- return RTCDegradationPreferenceBalanced;
+ return @(RTCDegradationPreferenceBalanced);
}
}