Implement Injectable Audio Codecs for the Java SDK.

Support Injectable Audio Codecs from the Java SDK.
The PeerConnectionFactory.Builder defaults to
BuiltinAudio(Encoder|Decoder)Factory, but other implementations are
permitted via the Audio(Encoder|Decoder)FactoryFactory interface.

Bug: webrtc:9916
Change-Id: I61ad4a6e57666bc1be79daf5f40b129e0eacad84
Reviewed-on: https://webrtc-review.googlesource.com/c/107711
Commit-Queue: Lennart Kolmodin <kolmodin@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25478}
This commit is contained in:
Lennart Kolmodin
2018-11-01 15:55:26 +01:00
committed by Commit Bot
parent 3e4c77f1c1
commit d4a68bd932
10 changed files with 316 additions and 21 deletions

View File

@ -0,0 +1,21 @@
/*
* Copyright 2018 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::AudioDecoderFactory}.
*/
public interface AudioDecoderFactoryFactory {
/**
* Returns a pointer to a {@code webrtc::AudioDecoderFactory}. The caller takes ownership.
*/
long createNativeAudioDecoderFactory();
}

View File

@ -0,0 +1,21 @@
/*
* Copyright 2018 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::AudioEncoderFactory}.
*/
public interface AudioEncoderFactoryFactory {
/**
* Returns a pointer to a {@code webrtc::AudioEncoderFactory}. The caller takes ownership.
*/
long createNativeAudioEncoderFactory();
}

View File

@ -0,0 +1,23 @@
/*
* Copyright 2018 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;
/**
* Creates a native {@code webrtc::AudioDecoderFactory} with the builtin audio decoders.
*/
public class BuiltinAudioDecoderFactoryFactory implements AudioDecoderFactoryFactory {
@Override
public long createNativeAudioDecoderFactory() {
return nativeCreateBuiltinAudioDecoderFactory();
}
private static native long nativeCreateBuiltinAudioDecoderFactory();
}

View File

@ -0,0 +1,23 @@
/*
* Copyright 2018 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;
/**
* This class creates a native {@code webrtc::AudioEncoderFactory} with the builtin audio encoders.
*/
public class BuiltinAudioEncoderFactoryFactory implements AudioEncoderFactoryFactory {
@Override
public long createNativeAudioEncoderFactory() {
return nativeCreateBuiltinAudioEncoderFactory();
}
private static native long nativeCreateBuiltinAudioEncoderFactory();
}

View File

@ -181,13 +181,17 @@ public class PeerConnectionFactory {
}
public static class Builder {
private @Nullable Options options;
private @Nullable AudioDeviceModule audioDeviceModule = new LegacyAudioDeviceModule();
private @Nullable VideoEncoderFactory encoderFactory;
private @Nullable VideoDecoderFactory decoderFactory;
private @Nullable AudioProcessingFactory audioProcessingFactory;
private @Nullable FecControllerFactoryFactoryInterface fecControllerFactoryFactory;
private @Nullable MediaTransportFactoryFactory mediaTransportFactoryFactory;
@Nullable private Options options;
@Nullable private AudioDeviceModule audioDeviceModule = new LegacyAudioDeviceModule();
private AudioEncoderFactoryFactory audioEncoderFactoryFactory =
new BuiltinAudioEncoderFactoryFactory();
private AudioDecoderFactoryFactory audioDecoderFactoryFactory =
new BuiltinAudioDecoderFactoryFactory();
@Nullable private VideoEncoderFactory videoEncoderFactory;
@Nullable private VideoDecoderFactory videoDecoderFactory;
@Nullable private AudioProcessingFactory audioProcessingFactory;
@Nullable private FecControllerFactoryFactoryInterface fecControllerFactoryFactory;
@Nullable private MediaTransportFactoryFactory mediaTransportFactoryFactory;
private Builder() {}
@ -201,13 +205,33 @@ public class PeerConnectionFactory {
return this;
}
public Builder setVideoEncoderFactory(VideoEncoderFactory encoderFactory) {
this.encoderFactory = encoderFactory;
public Builder setAudioEncoderFactoryFactory(
AudioEncoderFactoryFactory audioEncoderFactoryFactory) {
if (audioEncoderFactoryFactory == null) {
throw new IllegalArgumentException(
"PeerConnectionFactory.Builder does not accept a null AudioEncoderFactoryFactory.");
}
this.audioEncoderFactoryFactory = audioEncoderFactoryFactory;
return this;
}
public Builder setVideoDecoderFactory(VideoDecoderFactory decoderFactory) {
this.decoderFactory = decoderFactory;
public Builder setAudioDecoderFactoryFactory(
AudioDecoderFactoryFactory audioDecoderFactoryFactory) {
if (audioDecoderFactoryFactory == null) {
throw new IllegalArgumentException(
"PeerConnectionFactory.Builder does not accept a null AudioDecoderFactoryFactory.");
}
this.audioDecoderFactoryFactory = audioDecoderFactoryFactory;
return this;
}
public Builder setVideoEncoderFactory(VideoEncoderFactory videoEncoderFactory) {
this.videoEncoderFactory = videoEncoderFactory;
return this;
}
public Builder setVideoDecoderFactory(VideoDecoderFactory videoDecoderFactory) {
this.videoDecoderFactory = videoDecoderFactory;
return this;
}
@ -234,7 +258,8 @@ public class PeerConnectionFactory {
}
public PeerConnectionFactory createPeerConnectionFactory() {
return new PeerConnectionFactory(options, audioDeviceModule, encoderFactory, decoderFactory,
return new PeerConnectionFactory(options, audioDeviceModule, audioEncoderFactoryFactory,
audioDecoderFactoryFactory, videoEncoderFactory, videoDecoderFactory,
audioProcessingFactory, fecControllerFactoryFactory, mediaTransportFactoryFactory);
}
}
@ -314,14 +339,19 @@ public class PeerConnectionFactory {
}
private PeerConnectionFactory(Options options, @Nullable AudioDeviceModule audioDeviceModule,
@Nullable VideoEncoderFactory encoderFactory, @Nullable VideoDecoderFactory decoderFactory,
AudioEncoderFactoryFactory audioEncoderFactoryFactory,
AudioDecoderFactoryFactory audioDecoderFactoryFactory,
@Nullable VideoEncoderFactory videoEncoderFactory,
@Nullable VideoDecoderFactory videoDecoderFactory,
@Nullable AudioProcessingFactory audioProcessingFactory,
@Nullable FecControllerFactoryFactoryInterface fecControllerFactoryFactory,
@Nullable MediaTransportFactoryFactory mediaTransportFactoryFactory) {
checkInitializeHasBeenCalled();
nativeFactory = nativeCreatePeerConnectionFactory(ContextUtils.getApplicationContext(), options,
audioDeviceModule == null ? 0 : audioDeviceModule.getNativeAudioDeviceModulePointer(),
encoderFactory, decoderFactory,
audioEncoderFactoryFactory.createNativeAudioEncoderFactory(),
audioDecoderFactoryFactory.createNativeAudioDecoderFactory(), videoEncoderFactory,
videoDecoderFactory,
audioProcessingFactory == null ? 0 : audioProcessingFactory.createNative(),
fecControllerFactoryFactory == null ? 0 : fecControllerFactoryFactory.createNative(),
mediaTransportFactoryFactory == null
@ -527,10 +557,12 @@ public class PeerConnectionFactory {
private static native void nativeShutdownInternalTracer();
private static native boolean nativeStartInternalTracingCapture(String tracingFilename);
private static native void nativeStopInternalTracingCapture();
private static native long nativeCreatePeerConnectionFactory(Context context, Options options,
long nativeAudioDeviceModule, VideoEncoderFactory encoderFactory,
VideoDecoderFactory decoderFactory, long nativeAudioProcessor,
long nativeFecControllerFactory, long mediaTransportFactory);
long nativeAudioDeviceModule, long audioEncoderFactory, long audioDecoderFactory,
VideoEncoderFactory encoderFactory, VideoDecoderFactory decoderFactory,
long nativeAudioProcessor, long nativeFecControllerFactory, long mediaTransportFactory);
private static native long nativeCreatePeerConnection(long factory,
PeerConnection.RTCConfiguration rtcConfig, MediaConstraints constraints, long nativeObserver,
SSLCertificateVerifier sslCertificateVerifier);