diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn index 1e49597f1f..8d2e1837fc 100644 --- a/sdk/android/BUILD.gn +++ b/sdk/android/BUILD.gn @@ -285,6 +285,7 @@ if (is_android) { "api/org/webrtc/MediaStreamTrack.java", "api/org/webrtc/NativeLibraryLoader.java", "api/org/webrtc/NativePeerConnectionFactory.java", + "api/org/webrtc/NetEqFactoryFactory.java", "api/org/webrtc/NetworkMonitor.java", # TODO(sakal): Break dependencies and move to base_java. "api/org/webrtc/NetworkMonitorAutoDetect.java", # TODO(sakal): Break dependencies and move to base_java. "api/org/webrtc/PeerConnection.java", diff --git a/sdk/android/api/org/webrtc/NetEqFactoryFactory.java b/sdk/android/api/org/webrtc/NetEqFactoryFactory.java new file mode 100644 index 0000000000..8464324cbc --- /dev/null +++ b/sdk/android/api/org/webrtc/NetEqFactoryFactory.java @@ -0,0 +1,21 @@ +/* + * Copyright 2019 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; + +/** + * Implementations of this interface can create a native {@code webrtc::NetEqFactory}. + */ +public interface NetEqFactoryFactory { + /** + * Returns a pointer to a {@code webrtc::NetEqFactory}. The caller takes ownership. + */ + long createNativeNetEqFactory(); +} diff --git a/sdk/android/api/org/webrtc/PeerConnectionFactory.java b/sdk/android/api/org/webrtc/PeerConnectionFactory.java index d48ef55263..a2acfdd95e 100644 --- a/sdk/android/api/org/webrtc/PeerConnectionFactory.java +++ b/sdk/android/api/org/webrtc/PeerConnectionFactory.java @@ -167,6 +167,7 @@ public class PeerConnectionFactory { @Nullable private AudioDeviceModule audioDeviceModule; private AudioEncoderFactoryFactory audioEncoderFactoryFactory = new BuiltinAudioEncoderFactoryFactory(); + @Nullable private AudioDecoderFactoryFactory audioDecoderFactoryFactory = new BuiltinAudioDecoderFactoryFactory(); @Nullable private VideoEncoderFactory videoEncoderFactory; @@ -176,6 +177,7 @@ public class PeerConnectionFactory { @Nullable private NetworkControllerFactoryFactory networkControllerFactoryFactory; @Nullable private NetworkStatePredictorFactoryFactory networkStatePredictorFactoryFactory; @Nullable private MediaTransportFactoryFactory mediaTransportFactoryFactory; + @Nullable private NetEqFactoryFactory neteqFactoryFactory; private Builder() {} @@ -199,6 +201,7 @@ public class PeerConnectionFactory { return this; } + @Deprecated public Builder setAudioDecoderFactoryFactory( AudioDecoderFactoryFactory audioDecoderFactoryFactory) { if (audioDecoderFactoryFactory == null) { @@ -253,17 +256,36 @@ public class PeerConnectionFactory { return this; } + /** + * Sets a NetEqFactoryFactory for the PeerConnectionFactory. When using a + * custom NetEqFactoryFactory, the AudioDecoderFactoryFactory will be set + * to null. The AudioDecoderFactoryFactory should be wrapped in the + * NetEqFactoryFactory. + */ + public Builder setNetEqFactoryFactory(NetEqFactoryFactory neteqFactoryFactory) { + this.audioDecoderFactoryFactory = null; + this.neteqFactoryFactory = neteqFactoryFactory; + return this; + } + public PeerConnectionFactory createPeerConnectionFactory() { checkInitializeHasBeenCalled(); if (audioDeviceModule == null) { audioDeviceModule = JavaAudioDeviceModule.builder(ContextUtils.getApplicationContext()) .createAudioDeviceModule(); } + if (neteqFactoryFactory == null && audioDecoderFactoryFactory == null) { + throw new IllegalStateException( + "Setting both audioDecoderFactoryFactory and neteqFactoryFactory " + + "to null is not allowed."); + } return nativeCreatePeerConnectionFactory(ContextUtils.getApplicationContext(), options, audioDeviceModule.getNativeAudioDeviceModulePointer(), audioEncoderFactoryFactory.createNativeAudioEncoderFactory(), - audioDecoderFactoryFactory.createNativeAudioDecoderFactory(), videoEncoderFactory, - videoDecoderFactory, + audioDecoderFactoryFactory == null + ? 0 + : audioDecoderFactoryFactory.createNativeAudioDecoderFactory(), + videoEncoderFactory, videoDecoderFactory, audioProcessingFactory == null ? 0 : audioProcessingFactory.createNative(), fecControllerFactoryFactory == null ? 0 : fecControllerFactoryFactory.createNative(), networkControllerFactoryFactory == null @@ -274,7 +296,8 @@ public class PeerConnectionFactory { : networkStatePredictorFactoryFactory.createNativeNetworkStatePredictorFactory(), mediaTransportFactoryFactory == null ? 0 - : mediaTransportFactoryFactory.createNativeMediaTransportFactory()); + : mediaTransportFactoryFactory.createNativeMediaTransportFactory(), + neteqFactoryFactory == null ? 0 : neteqFactoryFactory.createNativeNetEqFactory()); } } @@ -596,7 +619,7 @@ public class PeerConnectionFactory { long audioDecoderFactory, VideoEncoderFactory encoderFactory, VideoDecoderFactory decoderFactory, long nativeAudioProcessor, long nativeFecControllerFactory, long nativeNetworkControllerFactory, - long nativeNetworkStatePredictorFactory, long mediaTransportFactory); + long nativeNetworkStatePredictorFactory, long mediaTransportFactory, long neteqFactory); private static native long nativeCreatePeerConnection(long factory, PeerConnection.RTCConfiguration rtcConfig, MediaConstraints constraints, long nativeObserver, diff --git a/sdk/android/src/jni/pc/peer_connection_factory.cc b/sdk/android/src/jni/pc/peer_connection_factory.cc index 4ae6fafe0a..2a7569b882 100644 --- a/sdk/android/src/jni/pc/peer_connection_factory.cc +++ b/sdk/android/src/jni/pc/peer_connection_factory.cc @@ -247,7 +247,7 @@ static void JNI_PeerConnectionFactory_ShutdownInternalTracer(JNIEnv* jni) { // Following parameters are optional: // |audio_device_module|, |jencoder_factory|, |jdecoder_factory|, // |audio_processor|, |media_transport_factory|, |fec_controller_factory|, -// |network_state_predictor_factory|. +// |network_state_predictor_factory|, |neteq_factory|. ScopedJavaLocalRef CreatePeerConnectionFactoryForJava( JNIEnv* jni, const JavaParamRef& jcontext, @@ -263,7 +263,8 @@ ScopedJavaLocalRef CreatePeerConnectionFactoryForJava( network_controller_factory, std::unique_ptr network_state_predictor_factory, - std::unique_ptr media_transport_factory) { + std::unique_ptr media_transport_factory, + std::unique_ptr neteq_factory) { // talk/ assumes pretty widely that the current Thread is ThreadManager'd, but // ThreadManager only WrapCurrentThread()s the thread where it is first // created. Since the semantics around when auto-wrapping happens in @@ -310,6 +311,7 @@ ScopedJavaLocalRef CreatePeerConnectionFactoryForJava( dependencies.network_state_predictor_factory = std::move(network_state_predictor_factory); dependencies.media_transport_factory = std::move(media_transport_factory); + dependencies.neteq_factory = std::move(neteq_factory); cricket::MediaEngineDependencies media_dependencies; media_dependencies.task_queue_factory = dependencies.task_queue_factory.get(); @@ -353,7 +355,8 @@ JNI_PeerConnectionFactory_CreatePeerConnectionFactory( jlong native_fec_controller_factory, jlong native_network_controller_factory, jlong native_network_state_predictor_factory, - jlong native_media_transport_factory) { + jlong native_media_transport_factory, + jlong native_neteq_factory) { rtc::scoped_refptr audio_processor = reinterpret_cast(native_audio_processor); return CreatePeerConnectionFactoryForJava( @@ -370,7 +373,8 @@ JNI_PeerConnectionFactory_CreatePeerConnectionFactory( TakeOwnershipOfUniquePtr( native_network_state_predictor_factory), TakeOwnershipOfUniquePtr( - native_media_transport_factory)); + native_media_transport_factory), + TakeOwnershipOfUniquePtr(native_neteq_factory)); } static void JNI_PeerConnectionFactory_FreeFactory(JNIEnv*,