From 266021dfa28f0c51cfd005a5666e493340034926 Mon Sep 17 00:00:00 2001 From: Florent Castelli Date: Tue, 7 Jan 2020 17:43:52 +0100 Subject: [PATCH] Add support for DegradationPreference in Android SDK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This wires the current degradation preference in the SDK, it will later be nullable in a follow up change once the native API supports it. Bug: webrtc:11164 Change-Id: I8324e6e0af996dfddfa07e3aff4ba242d9533388 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/161321 Commit-Queue: Florent Castelli Reviewed-by: Sami Kalliomäki Cr-Commit-Position: refs/heads/master@{#30170} --- sdk/android/BUILD.gn | 3 +- sdk/android/api/org/webrtc/RtpParameters.java | 36 +++++++-- .../src/org/webrtc/RtpSenderTest.java | 79 +++++++++++++++++++ ...eiverTest.java => RtpTransceiverTest.java} | 2 +- sdk/android/src/jni/pc/rtp_parameters.cc | 31 ++++++++ 5 files changed, 144 insertions(+), 7 deletions(-) create mode 100644 sdk/android/instrumentationtests/src/org/webrtc/RtpSenderTest.java rename sdk/android/instrumentationtests/src/org/webrtc/{RtpTranceiverTest.java => RtpTransceiverTest.java} (98%) diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn index 89fb602937..8b61ecfe43 100644 --- a/sdk/android/BUILD.gn +++ b/sdk/android/BUILD.gn @@ -1393,7 +1393,8 @@ if (is_android) { "instrumentationtests/src/org/webrtc/PeerConnectionTest.java", "instrumentationtests/src/org/webrtc/RendererCommonTest.java", "instrumentationtests/src/org/webrtc/RtcCertificatePemTest.java", - "instrumentationtests/src/org/webrtc/RtpTranceiverTest.java", + "instrumentationtests/src/org/webrtc/RtpSenderTest.java", + "instrumentationtests/src/org/webrtc/RtpTransceiverTest.java", "instrumentationtests/src/org/webrtc/SurfaceTextureHelperTest.java", "instrumentationtests/src/org/webrtc/SurfaceViewRendererOnMeasureTest.java", "instrumentationtests/src/org/webrtc/TestConstants.java", diff --git a/sdk/android/api/org/webrtc/RtpParameters.java b/sdk/android/api/org/webrtc/RtpParameters.java index 183facaeda..4293ce77d2 100644 --- a/sdk/android/api/org/webrtc/RtpParameters.java +++ b/sdk/android/api/org/webrtc/RtpParameters.java @@ -27,6 +27,22 @@ import org.webrtc.MediaStreamTrack; * default value". */ public class RtpParameters { + public enum DegradationPreference { + /** Does not degrade resolution or framerate. */ + DISABLED, + /** Degrade resolution in order to maintain framerate. */ + MAINTAIN_FRAMERATE, + /** Degrade framerate in order to maintain resolution. */ + MAINTAIN_RESOLUTION, + /** Degrade a balance of framerate and resolution. */ + BALANCED; + + @CalledByNative("DegradationPreference") + static DegradationPreference fromNativeIndex(int nativeIndex) { + return values()[nativeIndex]; + } + } + public static class Encoding { // If non-null, this represents the RID that identifies this encoding layer. // RIDs are used to identify layers in simulcast. @@ -230,20 +246,25 @@ public class RtpParameters { public final String transactionId; + /** + * When bandwidth is constrained and the RtpSender needs to choose between degrading resolution or + * degrading framerate, degradationPreference indicates which is preferred. + */ + @Nullable public DegradationPreference degradationPreference; + private final Rtcp rtcp; private final List headerExtensions; public final List encodings; - // Codec parameters can't currently be changed between getParameters and - // setParameters. Though in the future it will be possible to reorder them or - // remove them. + public final List codecs; @CalledByNative - RtpParameters(String transactionId, Rtcp rtcp, List headerExtensions, - List encodings, List codecs) { + RtpParameters(String transactionId, DegradationPreference degradationPreference, Rtcp rtcp, + List headerExtensions, List encodings, List codecs) { this.transactionId = transactionId; + this.degradationPreference = degradationPreference; this.rtcp = rtcp; this.headerExtensions = headerExtensions; this.encodings = encodings; @@ -255,6 +276,11 @@ public class RtpParameters { return transactionId; } + @CalledByNative + DegradationPreference getDegradationPreference() { + return degradationPreference; + } + @CalledByNative public Rtcp getRtcp() { return rtcp; diff --git a/sdk/android/instrumentationtests/src/org/webrtc/RtpSenderTest.java b/sdk/android/instrumentationtests/src/org/webrtc/RtpSenderTest.java new file mode 100644 index 0000000000..14d76d0c4c --- /dev/null +++ b/sdk/android/instrumentationtests/src/org/webrtc/RtpSenderTest.java @@ -0,0 +1,79 @@ +/* + * 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. + */ + +package org.webrtc; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.SmallTest; +import java.util.Arrays; +import org.chromium.base.test.BaseJUnit4ClassRunner; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.webrtc.RtpParameters.DegradationPreference; + +/** Unit-tests for {@link RtpSender}. */ +@RunWith(BaseJUnit4ClassRunner.class) +public class RtpSenderTest { + private PeerConnectionFactory factory; + private PeerConnection pc; + + @Before + public void setUp() { + PeerConnectionFactory.initialize(PeerConnectionFactory.InitializationOptions + .builder(InstrumentationRegistry.getTargetContext()) + .setNativeLibraryName(TestConstants.NATIVE_LIBRARY) + .createInitializationOptions()); + + factory = PeerConnectionFactory.builder().createPeerConnectionFactory(); + + PeerConnection.RTCConfiguration config = new PeerConnection.RTCConfiguration(Arrays.asList()); + // RtpTranceiver is part of new unified plan semantics. + config.sdpSemantics = PeerConnection.SdpSemantics.UNIFIED_PLAN; + pc = factory.createPeerConnection(config, mock(PeerConnection.Observer.class)); + } + + /** Test checking the enum values for DegradationPreference stay consistent */ + @Test + @SmallTest + public void testSetDegradationPreference() throws Exception { + RtpTransceiver transceiver = pc.addTransceiver(MediaStreamTrack.MediaType.MEDIA_TYPE_VIDEO); + RtpSender sender = transceiver.getSender(); + + RtpParameters parameters = sender.getParameters(); + assertNotNull(parameters); + assertEquals(DegradationPreference.BALANCED, parameters.degradationPreference); + + parameters.degradationPreference = DegradationPreference.MAINTAIN_FRAMERATE; + assertTrue(sender.setParameters(parameters)); + parameters = sender.getParameters(); + assertEquals(DegradationPreference.MAINTAIN_FRAMERATE, parameters.degradationPreference); + + parameters.degradationPreference = DegradationPreference.MAINTAIN_RESOLUTION; + assertTrue(sender.setParameters(parameters)); + parameters = sender.getParameters(); + assertEquals(DegradationPreference.MAINTAIN_RESOLUTION, parameters.degradationPreference); + + parameters.degradationPreference = DegradationPreference.BALANCED; + assertTrue(sender.setParameters(parameters)); + parameters = sender.getParameters(); + assertEquals(DegradationPreference.BALANCED, parameters.degradationPreference); + + parameters.degradationPreference = DegradationPreference.DISABLED; + assertTrue(sender.setParameters(parameters)); + parameters = sender.getParameters(); + assertEquals(DegradationPreference.DISABLED, parameters.degradationPreference); + } +} diff --git a/sdk/android/instrumentationtests/src/org/webrtc/RtpTranceiverTest.java b/sdk/android/instrumentationtests/src/org/webrtc/RtpTransceiverTest.java similarity index 98% rename from sdk/android/instrumentationtests/src/org/webrtc/RtpTranceiverTest.java rename to sdk/android/instrumentationtests/src/org/webrtc/RtpTransceiverTest.java index 3b03df73b3..fd13d11b22 100644 --- a/sdk/android/instrumentationtests/src/org/webrtc/RtpTranceiverTest.java +++ b/sdk/android/instrumentationtests/src/org/webrtc/RtpTransceiverTest.java @@ -28,7 +28,7 @@ import org.webrtc.RtpTransceiver.RtpTransceiverInit; /** Unit-tests for {@link RtpTransceiver}. */ @RunWith(BaseJUnit4ClassRunner.class) -public class RtpTranceiverTest { +public class RtpTransceiverTest { private PeerConnectionFactory factory; private PeerConnection pc; diff --git a/sdk/android/src/jni/pc/rtp_parameters.cc b/sdk/android/src/jni/pc/rtp_parameters.cc index c6dc870180..4bed3f8127 100644 --- a/sdk/android/src/jni/pc/rtp_parameters.cc +++ b/sdk/android/src/jni/pc/rtp_parameters.cc @@ -20,6 +20,28 @@ namespace jni { namespace { +webrtc::DegradationPreference JavaToNativeDegradationPreference( + JNIEnv* jni, + const JavaRef& j_degradation_preference) { + std::string enum_name = GetJavaEnumName(jni, j_degradation_preference); + + if (enum_name == "DISABLED") + return webrtc::DegradationPreference::DISABLED; + + if (enum_name == "MAINTAIN_FRAMERATE") + return webrtc::DegradationPreference::MAINTAIN_FRAMERATE; + + if (enum_name == "MAINTAIN_RESOLUTION") + return webrtc::DegradationPreference::MAINTAIN_RESOLUTION; + + if (enum_name == "BALANCED") + return webrtc::DegradationPreference::BALANCED; + + RTC_CHECK(false) << "Unexpected DegradationPreference enum_name " + << enum_name; + return webrtc::DegradationPreference::DISABLED; +} + ScopedJavaLocalRef NativeToJavaRtpEncodingParameter( JNIEnv* env, const RtpEncodingParameters& encoding) { @@ -103,6 +125,13 @@ RtpParameters JavaToNativeRtpParameters(JNIEnv* jni, Java_RtpParameters_getTransactionId(jni, j_parameters); parameters.transaction_id = JavaToNativeString(jni, j_transaction_id); + ScopedJavaLocalRef j_degradation_preference = + Java_RtpParameters_getDegradationPreference(jni, j_parameters); + if (!IsNull(jni, j_degradation_preference)) { + parameters.degradation_preference = + JavaToNativeDegradationPreference(jni, j_degradation_preference); + } + ScopedJavaLocalRef j_rtcp = Java_RtpParameters_getRtcp(jni, j_parameters); ScopedJavaLocalRef j_rtcp_cname = Java_Rtcp_getCname(jni, j_rtcp); @@ -158,6 +187,8 @@ ScopedJavaLocalRef NativeToJavaRtpParameters( const RtpParameters& parameters) { return Java_RtpParameters_Constructor( env, NativeToJavaString(env, parameters.transaction_id), + Java_DegradationPreference_fromNativeIndex( + env, static_cast(parameters.degradation_preference)), NativeToJavaRtpRtcpParameters(env, parameters.rtcp), NativeToJavaList(env, parameters.header_extensions, &NativeToJavaRtpHeaderExtensionParameter),