Android: Use scoped java refs
We currently use raw jobject in our code mixed with sporadic ScopedLocalRefFrame. This CL moves every jobject into a scoped object, either local, global, or a parameter. Also, this CL uses the JNI generation script to generate declaration stubs for the Java->C++ functions so that it no longer becomes possible to mistype them without getting compilation errors. TBR=brandt@webrtc.org Bug: webrtc:8278,webrtc:6969 Change-Id: Ic7bac74a89c11180177d65041086d7db1cdfb516 Reviewed-on: https://webrtc-review.googlesource.com/34655 Commit-Queue: Magnus Jedvert <magjed@webrtc.org> Reviewed-by: Sami Kalliomäki <sakal@webrtc.org> Cr-Commit-Position: refs/heads/master@{#21387}
This commit is contained in:
parent
ec22e3f503
commit
84d8ae5df7
@ -65,23 +65,6 @@ class AttachThreadScoped {
|
||||
JNIEnv* env_;
|
||||
};
|
||||
|
||||
// Scoped holder for global Java refs.
|
||||
template<class T> // T is jclass, jobject, jintArray, etc.
|
||||
class ScopedGlobalRef {
|
||||
public:
|
||||
ScopedGlobalRef(JNIEnv* jni, T obj)
|
||||
: jni_(jni), obj_(static_cast<T>(NewGlobalRef(jni, obj))) {}
|
||||
~ScopedGlobalRef() {
|
||||
DeleteGlobalRef(jni_, obj_);
|
||||
}
|
||||
T operator*() const {
|
||||
return obj_;
|
||||
}
|
||||
private:
|
||||
JNIEnv* jni_;
|
||||
T obj_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_UTILITY_INCLUDE_HELPERS_ANDROID_H_
|
||||
|
||||
@ -290,15 +290,15 @@ void VideoProcessorIntegrationTest::CreateEncoderAndDecoder() {
|
||||
if (config_.hw_encoder) {
|
||||
#if defined(WEBRTC_ANDROID)
|
||||
JNIEnv* env = jni::AttachCurrentThreadIfNeeded();
|
||||
jni::ScopedLocalRefFrame local_ref_frame(env);
|
||||
jclass factory_class =
|
||||
webrtc::jni::GetClass(env, "org/webrtc/HardwareVideoEncoderFactory");
|
||||
jni::ScopedJavaLocalRef<jclass> factory_class =
|
||||
jni::GetClass(env, "org/webrtc/HardwareVideoEncoderFactory");
|
||||
jmethodID factory_constructor = env->GetMethodID(
|
||||
factory_class, "<init>", "(Lorg/webrtc/EglBase$Context;ZZ)V");
|
||||
jobject factory_object = env->NewObject(
|
||||
factory_class, factory_constructor, nullptr /* shared_context */,
|
||||
false /* enable_intel_vp8_encoder */,
|
||||
true /* enable_h264_high_profile */);
|
||||
factory_class.obj(), "<init>", "(Lorg/webrtc/EglBase$Context;ZZ)V");
|
||||
jni::ScopedJavaLocalRef<jobject> factory_object(
|
||||
env, env->NewObject(factory_class.obj(), factory_constructor,
|
||||
nullptr /* shared_context */,
|
||||
false /* enable_intel_vp8_encoder */,
|
||||
true /* enable_h264_high_profile */));
|
||||
encoder_factory = rtc::MakeUnique<webrtc::jni::VideoEncoderFactoryWrapper>(
|
||||
env, factory_object);
|
||||
#elif defined(WEBRTC_IOS)
|
||||
@ -316,13 +316,13 @@ void VideoProcessorIntegrationTest::CreateEncoderAndDecoder() {
|
||||
if (config_.hw_decoder) {
|
||||
#if defined(WEBRTC_ANDROID)
|
||||
JNIEnv* env = jni::AttachCurrentThreadIfNeeded();
|
||||
jni::ScopedLocalRefFrame local_ref_frame(env);
|
||||
jclass factory_class =
|
||||
webrtc::jni::GetClass(env, "org/webrtc/HardwareVideoDecoderFactory");
|
||||
jni::ScopedJavaLocalRef<jclass> factory_class =
|
||||
jni::GetClass(env, "org/webrtc/HardwareVideoDecoderFactory");
|
||||
jmethodID factory_constructor = env->GetMethodID(
|
||||
factory_class, "<init>", "(Lorg/webrtc/EglBase$Context;)V");
|
||||
jobject factory_object = env->NewObject(factory_class, factory_constructor,
|
||||
nullptr /* shared_context */);
|
||||
factory_class.obj(), "<init>", "(Lorg/webrtc/EglBase$Context;)V");
|
||||
jni::ScopedJavaLocalRef<jobject> factory_object(
|
||||
env, env->NewObject(factory_class.obj(), factory_constructor,
|
||||
nullptr /* shared_context */));
|
||||
decoder_factory = rtc::MakeUnique<webrtc::jni::VideoDecoderFactoryWrapper>(
|
||||
env, factory_object);
|
||||
#elif defined(WEBRTC_IOS)
|
||||
|
||||
@ -35,6 +35,8 @@ config("libjingle_peerconnection_jni_warnings_config") {
|
||||
|
||||
generate_jni("generated_base_jni") {
|
||||
sources = [
|
||||
"src/java/org/webrtc/Histogram.java",
|
||||
"src/java/org/webrtc/JniCommon.java",
|
||||
"src/java/org/webrtc/JniHelper.java",
|
||||
"src/java/org/webrtc/WebRtcClassLoader.java",
|
||||
]
|
||||
@ -74,6 +76,7 @@ rtc_source_set("base_jni") {
|
||||
"src/jni/pc/audio.h",
|
||||
"src/jni/pc/media.h",
|
||||
"src/jni/pc/video.h",
|
||||
"src/jni/scoped_java_ref.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
@ -96,6 +99,14 @@ rtc_source_set("base_jni") {
|
||||
}
|
||||
}
|
||||
|
||||
generate_jni("generated_audio_jni") {
|
||||
sources = [
|
||||
"api/org/webrtc/DefaultAudioProcessingFactory.java",
|
||||
]
|
||||
jni_package = ""
|
||||
jni_generator_include = "//sdk/android/src/jni/jni_generator_helper.h"
|
||||
}
|
||||
|
||||
rtc_static_library("audio_jni") {
|
||||
sources = [
|
||||
"src/jni/pc/audio.cc",
|
||||
@ -104,6 +115,7 @@ rtc_static_library("audio_jni") {
|
||||
|
||||
deps = [
|
||||
":base_jni",
|
||||
":generated_audio_jni",
|
||||
"../../api/audio_codecs:builtin_audio_decoder_factory",
|
||||
"../../api/audio_codecs:builtin_audio_encoder_factory",
|
||||
"../../modules/audio_processing:audio_processing",
|
||||
@ -125,6 +137,7 @@ rtc_static_library("null_audio_jni") {
|
||||
generate_jni("generated_video_jni") {
|
||||
sources = [
|
||||
"api/org/webrtc/EncodedImage.java",
|
||||
"api/org/webrtc/HardwareVideoEncoderFactory.java",
|
||||
"api/org/webrtc/MediaCodecVideoDecoder.java",
|
||||
"api/org/webrtc/MediaCodecVideoEncoder.java",
|
||||
"api/org/webrtc/SurfaceTextureHelper.java",
|
||||
@ -132,12 +145,25 @@ generate_jni("generated_video_jni") {
|
||||
"api/org/webrtc/VideoCodecStatus.java",
|
||||
"api/org/webrtc/VideoDecoder.java",
|
||||
"api/org/webrtc/VideoDecoderFactory.java",
|
||||
"api/org/webrtc/VideoDecoderFallback.java",
|
||||
"api/org/webrtc/VideoEncoder.java",
|
||||
"api/org/webrtc/VideoEncoderFactory.java",
|
||||
"api/org/webrtc/VideoEncoderFallback.java",
|
||||
"api/org/webrtc/VideoFileRenderer.java",
|
||||
"api/org/webrtc/VideoFrame.java",
|
||||
"api/org/webrtc/VideoRenderer.java",
|
||||
"api/org/webrtc/VideoSink.java",
|
||||
"api/org/webrtc/VideoSource.java",
|
||||
"api/org/webrtc/VideoTrack.java",
|
||||
"api/org/webrtc/YuvHelper.java",
|
||||
"src/java/org/webrtc/AndroidVideoTrackSourceObserver.java",
|
||||
"src/java/org/webrtc/EglBase14.java",
|
||||
"src/java/org/webrtc/NV12Buffer.java",
|
||||
"src/java/org/webrtc/NV21Buffer.java",
|
||||
"src/java/org/webrtc/VP8Decoder.java",
|
||||
"src/java/org/webrtc/VP8Encoder.java",
|
||||
"src/java/org/webrtc/VP9Decoder.java",
|
||||
"src/java/org/webrtc/VP9Encoder.java",
|
||||
"src/java/org/webrtc/VideoDecoderWrapper.java",
|
||||
"src/java/org/webrtc/VideoEncoderWrapper.java",
|
||||
"src/java/org/webrtc/WrappedNativeI420Buffer.java",
|
||||
@ -297,7 +323,10 @@ rtc_static_library("null_media_jni") {
|
||||
|
||||
generate_jni("generated_peerconnection_jni") {
|
||||
sources = [
|
||||
"api/org/webrtc/AudioTrack.java",
|
||||
"api/org/webrtc/CallSessionFileRotatingLogSink.java",
|
||||
"api/org/webrtc/DataChannel.java",
|
||||
"api/org/webrtc/DtmfSender.java",
|
||||
"api/org/webrtc/IceCandidate.java",
|
||||
"api/org/webrtc/MediaConstraints.java",
|
||||
"api/org/webrtc/MediaSource.java",
|
||||
@ -637,6 +666,7 @@ rtc_android_library("libjingle_peerconnection_java") {
|
||||
"src/java/org/webrtc/BitrateAdjuster.java",
|
||||
"src/java/org/webrtc/CalledByNative.java",
|
||||
"src/java/org/webrtc/CalledByNativeUnchecked.java",
|
||||
"src/java/org/webrtc/JNINamespace.java",
|
||||
"src/java/org/webrtc/Camera1Session.java",
|
||||
"src/java/org/webrtc/Camera2Session.java",
|
||||
"src/java/org/webrtc/CameraCapturer.java",
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
package org.webrtc;
|
||||
|
||||
/** Java wrapper for a C++ AudioTrackInterface */
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class AudioTrack extends MediaStreamTrack {
|
||||
public AudioTrack(long nativeTrack) {
|
||||
super(nativeTrack);
|
||||
@ -23,5 +24,5 @@ public class AudioTrack extends MediaStreamTrack {
|
||||
nativeSetVolume(super.nativeTrack, volume);
|
||||
}
|
||||
|
||||
private static native void nativeSetVolume(long nativeTrack, double volume);
|
||||
private static native void nativeSetVolume(long track, double volume);
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
|
||||
package org.webrtc;
|
||||
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class CallSessionFileRotatingLogSink {
|
||||
private long nativeSink;
|
||||
|
||||
@ -30,6 +31,6 @@ public class CallSessionFileRotatingLogSink {
|
||||
}
|
||||
|
||||
private static native long nativeAddSink(String dirPath, int maxFileSize, int severity);
|
||||
private static native void nativeDeleteSink(long nativeSink);
|
||||
private static native void nativeDeleteSink(long sink);
|
||||
private static native byte[] nativeGetLogData(String dirPath);
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ package org.webrtc;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/** Java wrapper for a C++ DataChannelInterface. */
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class DataChannel {
|
||||
/** Java wrapper for WebIDL RTCDataChannel. */
|
||||
public static class Init {
|
||||
@ -113,33 +114,41 @@ public class DataChannel {
|
||||
/** Register |observer|, replacing any previously-registered observer. */
|
||||
public void registerObserver(Observer observer) {
|
||||
if (nativeObserver != 0) {
|
||||
unregisterObserverNative(nativeObserver);
|
||||
nativeUnregisterObserver(nativeObserver);
|
||||
}
|
||||
nativeObserver = registerObserverNative(observer);
|
||||
nativeObserver = nativeRegisterObserver(observer);
|
||||
}
|
||||
private native long registerObserverNative(Observer observer);
|
||||
|
||||
/** Unregister the (only) observer. */
|
||||
public void unregisterObserver() {
|
||||
unregisterObserverNative(nativeObserver);
|
||||
nativeUnregisterObserver(nativeObserver);
|
||||
}
|
||||
private native void unregisterObserverNative(long nativeObserver);
|
||||
|
||||
public native String label();
|
||||
public String label() {
|
||||
return nativeLabel();
|
||||
}
|
||||
|
||||
public native int id();
|
||||
public int id() {
|
||||
return nativeId();
|
||||
}
|
||||
|
||||
public native State state();
|
||||
public State state() {
|
||||
return nativeState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of bytes of application data (UTF-8 text and binary data)
|
||||
* that have been queued using SendBuffer but have not yet been transmitted
|
||||
* to the network.
|
||||
*/
|
||||
public native long bufferedAmount();
|
||||
public long bufferedAmount() {
|
||||
return nativeBufferedAmount();
|
||||
}
|
||||
|
||||
/** Close the channel. */
|
||||
public native void close();
|
||||
public void close() {
|
||||
nativeClose();
|
||||
}
|
||||
|
||||
/** Send |data| to the remote peer; return success. */
|
||||
public boolean send(Buffer buffer) {
|
||||
@ -147,9 +156,8 @@ public class DataChannel {
|
||||
// ByteBuffer is direct and/or is backed by an array.
|
||||
byte[] data = new byte[buffer.data.remaining()];
|
||||
buffer.data.get(data);
|
||||
return sendNative(data, buffer.binary);
|
||||
return nativeSend(data, buffer.binary);
|
||||
}
|
||||
private native boolean sendNative(byte[] data, boolean binary);
|
||||
|
||||
/** Dispose of native resources attached to this channel. */
|
||||
public void dispose() {
|
||||
@ -160,4 +168,13 @@ public class DataChannel {
|
||||
long getNativeDataChannel() {
|
||||
return nativeDataChannel;
|
||||
}
|
||||
|
||||
private native long nativeRegisterObserver(Observer observer);
|
||||
private native void nativeUnregisterObserver(long observer);
|
||||
private native String nativeLabel();
|
||||
private native int nativeId();
|
||||
private native State nativeState();
|
||||
private native long nativeBufferedAmount();
|
||||
private native void nativeClose();
|
||||
private native boolean nativeSend(byte[] data, boolean binary);
|
||||
};
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
package org.webrtc;
|
||||
|
||||
/** Factory for instantiating the default webrtc::AudioProcessing implementation. */
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class DefaultAudioProcessingFactory implements AudioProcessingFactory {
|
||||
public DefaultAudioProcessingFactory() {
|
||||
this(null /* postProcessingFactory */);
|
||||
@ -43,5 +44,5 @@ public class DefaultAudioProcessingFactory implements AudioProcessingFactory {
|
||||
|
||||
private PostProcessingFactory postProcessingFactory;
|
||||
|
||||
private static native long nativeCreateAudioProcessing(long nativePostProcessor);
|
||||
private static native long nativeCreateAudioProcessing(long postProcessor);
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
package org.webrtc;
|
||||
|
||||
/** Java wrapper for a C++ DtmfSenderInterface. */
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class DtmfSender {
|
||||
final long nativeDtmfSender;
|
||||
|
||||
@ -74,10 +75,10 @@ public class DtmfSender {
|
||||
JniCommon.nativeReleaseRef(nativeDtmfSender);
|
||||
}
|
||||
|
||||
private static native boolean nativeCanInsertDtmf(long nativeDtmfSender);
|
||||
private static native boolean nativeCanInsertDtmf(long dtmfSender);
|
||||
private static native boolean nativeInsertDtmf(
|
||||
long nativeDtmfSender, String tones, int duration, int interToneGap);
|
||||
private static native String nativeTones(long nativeDtmfSender);
|
||||
private static native int nativeDuration(long nativeDtmfSender);
|
||||
private static native int nativeInterToneGap(long nativeDtmfSender);
|
||||
long dtmfSender, String tones, int duration, int interToneGap);
|
||||
private static native String nativeTones(long dtmfSender);
|
||||
private static native int nativeDuration(long dtmfSender);
|
||||
private static native int nativeInterToneGap(long dtmfSender);
|
||||
};
|
||||
|
||||
@ -25,6 +25,7 @@ import java.util.Map;
|
||||
|
||||
/** Factory for android hardware video encoders. */
|
||||
@SuppressWarnings("deprecation") // API 16 requires the use of deprecated methods.
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class HardwareVideoEncoderFactory implements VideoEncoderFactory {
|
||||
private static final String TAG = "HardwareVideoEncoderFactory";
|
||||
|
||||
@ -94,9 +95,10 @@ public class HardwareVideoEncoderFactory implements VideoEncoderFactory {
|
||||
MediaCodecUtils.ENCODER_COLOR_FORMATS, info.getCapabilitiesForType(mime));
|
||||
|
||||
if (type == VideoCodecType.H264) {
|
||||
boolean isHighProfile = isSameH264Profile(input.params, getCodecProperties(type, true))
|
||||
boolean isHighProfile = nativeIsSameH264Profile(input.params, getCodecProperties(type, true))
|
||||
&& isH264HighProfileSupported(info);
|
||||
boolean isBaselineProfile = isSameH264Profile(input.params, getCodecProperties(type, false));
|
||||
boolean isBaselineProfile =
|
||||
nativeIsSameH264Profile(input.params, getCodecProperties(type, false));
|
||||
|
||||
if (!isHighProfile && !isBaselineProfile) {
|
||||
return null;
|
||||
@ -281,6 +283,6 @@ public class HardwareVideoEncoderFactory implements VideoEncoderFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private static native boolean isSameH264Profile(
|
||||
private static native boolean nativeIsSameH264Profile(
|
||||
Map<String, String> params1, Map<String, String> params2);
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@ import org.webrtc.VideoFrame;
|
||||
// This class is an implementation detail of the Java PeerConnection API.
|
||||
@TargetApi(19)
|
||||
@SuppressWarnings("deprecation")
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class MediaCodecVideoEncoder {
|
||||
// This class is constructed, operated, and destroyed by its C++ incarnation,
|
||||
// so the class and its methods have non-public visibility. The API this
|
||||
@ -658,7 +659,7 @@ public class MediaCodecVideoEncoder {
|
||||
if (dataV.capacity() < strideV * chromaHeight) {
|
||||
throw new RuntimeException("V-plane buffer size too small.");
|
||||
}
|
||||
fillInputBufferNative(
|
||||
nativeFillInputBuffer(
|
||||
nativeEncoder, bufferIndex, dataY, strideY, dataU, strideU, dataV, strideV);
|
||||
i420Buffer.release();
|
||||
// I420 consists of one full-resolution and two half-resolution planes.
|
||||
@ -993,6 +994,6 @@ public class MediaCodecVideoEncoder {
|
||||
}
|
||||
|
||||
/** Fills an inputBuffer with the given index with data from the byte buffers. */
|
||||
private static native void fillInputBufferNative(long nativeEncoder, int inputBuffer,
|
||||
ByteBuffer dataY, int strideY, ByteBuffer dataU, int strideU, ByteBuffer dataV, int strideV);
|
||||
private static native void nativeFillInputBuffer(long encoder, int inputBuffer, ByteBuffer dataY,
|
||||
int strideY, ByteBuffer dataU, int strideU, ByteBuffer dataV, int strideV);
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
package org.webrtc;
|
||||
|
||||
/** Java wrapper for a C++ MediaSourceInterface. */
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class MediaSource {
|
||||
/** Tracks MediaSourceInterface.SourceState */
|
||||
public enum State {
|
||||
@ -32,12 +33,12 @@ public class MediaSource {
|
||||
}
|
||||
|
||||
public State state() {
|
||||
return getNativeState(nativeSource);
|
||||
return nativeGetState(nativeSource);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
JniCommon.nativeReleaseRef(nativeSource);
|
||||
}
|
||||
|
||||
private static native State getNativeState(long pointer);
|
||||
private static native State nativeGetState(long pointer);
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@ import java.util.List;
|
||||
import java.util.Iterator;
|
||||
|
||||
/** Java wrapper for a C++ MediaStreamInterface. */
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class MediaStream {
|
||||
private static final String TAG = "MediaStream";
|
||||
|
||||
@ -30,7 +31,7 @@ public class MediaStream {
|
||||
}
|
||||
|
||||
public boolean addTrack(AudioTrack track) {
|
||||
if (addAudioTrackToNativeStream(nativeStream, track.nativeTrack)) {
|
||||
if (nativeAddAudioTrackToNativeStream(nativeStream, track.nativeTrack)) {
|
||||
audioTracks.add(track);
|
||||
return true;
|
||||
}
|
||||
@ -38,7 +39,7 @@ public class MediaStream {
|
||||
}
|
||||
|
||||
public boolean addTrack(VideoTrack track) {
|
||||
if (addVideoTrackToNativeStream(nativeStream, track.nativeTrack)) {
|
||||
if (nativeAddVideoTrackToNativeStream(nativeStream, track.nativeTrack)) {
|
||||
videoTracks.add(track);
|
||||
return true;
|
||||
}
|
||||
@ -49,7 +50,7 @@ public class MediaStream {
|
||||
// is called. If video track need to be preserved after MediaStream is destroyed it
|
||||
// should be added to MediaStream using addPreservedTrack() call.
|
||||
public boolean addPreservedTrack(VideoTrack track) {
|
||||
if (addVideoTrackToNativeStream(nativeStream, track.nativeTrack)) {
|
||||
if (nativeAddVideoTrackToNativeStream(nativeStream, track.nativeTrack)) {
|
||||
preservedVideoTracks.add(track);
|
||||
return true;
|
||||
}
|
||||
@ -58,13 +59,13 @@ public class MediaStream {
|
||||
|
||||
public boolean removeTrack(AudioTrack track) {
|
||||
audioTracks.remove(track);
|
||||
return removeNativeAudioTrack(nativeStream, track.nativeTrack);
|
||||
return nativeRemoveAudioTrack(nativeStream, track.nativeTrack);
|
||||
}
|
||||
|
||||
public boolean removeTrack(VideoTrack track) {
|
||||
videoTracks.remove(track);
|
||||
preservedVideoTracks.remove(track);
|
||||
return removeNativeVideoTrack(nativeStream, track.nativeTrack);
|
||||
return nativeRemoveVideoTrack(nativeStream, track.nativeTrack);
|
||||
}
|
||||
|
||||
@CalledByNative
|
||||
@ -88,7 +89,7 @@ public class MediaStream {
|
||||
}
|
||||
|
||||
public String label() {
|
||||
return getNativeLabel(nativeStream);
|
||||
return nativeGetLabel(nativeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -130,15 +131,11 @@ public class MediaStream {
|
||||
Logging.e(TAG, "Couldn't not find track");
|
||||
}
|
||||
|
||||
private static native boolean addAudioTrackToNativeStream(
|
||||
long nativeStream, long nativeAudioTrack);
|
||||
|
||||
private static native boolean addVideoTrackToNativeStream(
|
||||
long nativeStream, long nativeVideoTrack);
|
||||
|
||||
private static native boolean removeNativeAudioTrack(long nativeStream, long nativeAudioTrack);
|
||||
|
||||
private static native boolean removeNativeVideoTrack(long nativeStream, long nativeVideoTrack);
|
||||
|
||||
private static native String getNativeLabel(long nativeStream);
|
||||
private static native boolean nativeAddAudioTrackToNativeStream(
|
||||
long stream, long nativeAudioTrack);
|
||||
private static native boolean nativeAddVideoTrackToNativeStream(
|
||||
long stream, long nativeVideoTrack);
|
||||
private static native boolean nativeRemoveAudioTrack(long stream, long nativeAudioTrack);
|
||||
private static native boolean nativeRemoveVideoTrack(long stream, long nativeVideoTrack);
|
||||
private static native String nativeGetLabel(long stream);
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
package org.webrtc;
|
||||
|
||||
/** Java wrapper for a C++ MediaStreamTrackInterface. */
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class MediaStreamTrack {
|
||||
/** Tracks MediaStreamTrackInterface.TrackState */
|
||||
public enum State {
|
||||
@ -57,36 +58,32 @@ public class MediaStreamTrack {
|
||||
}
|
||||
|
||||
public String id() {
|
||||
return getNativeId(nativeTrack);
|
||||
return nativeGetId(nativeTrack);
|
||||
}
|
||||
|
||||
public String kind() {
|
||||
return getNativeKind(nativeTrack);
|
||||
return nativeGetKind(nativeTrack);
|
||||
}
|
||||
|
||||
public boolean enabled() {
|
||||
return getNativeEnabled(nativeTrack);
|
||||
return nativeGetEnabled(nativeTrack);
|
||||
}
|
||||
|
||||
public boolean setEnabled(boolean enable) {
|
||||
return setNativeEnabled(nativeTrack, enable);
|
||||
return nativeSetEnabled(nativeTrack, enable);
|
||||
}
|
||||
|
||||
public State state() {
|
||||
return getNativeState(nativeTrack);
|
||||
return nativeGetState(nativeTrack);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
JniCommon.nativeReleaseRef(nativeTrack);
|
||||
}
|
||||
|
||||
private static native String getNativeId(long nativeTrack);
|
||||
|
||||
private static native String getNativeKind(long nativeTrack);
|
||||
|
||||
private static native boolean getNativeEnabled(long nativeTrack);
|
||||
|
||||
private static native boolean setNativeEnabled(long nativeTrack, boolean enabled);
|
||||
|
||||
private static native State getNativeState(long nativeTrack);
|
||||
private static native String nativeGetId(long track);
|
||||
private static native String nativeGetKind(long track);
|
||||
private static native boolean nativeGetEnabled(long track);
|
||||
private static native boolean nativeSetEnabled(long track, boolean enabled);
|
||||
private static native State nativeGetState(long track);
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ import java.util.Map;
|
||||
// Most histograms are not updated frequently (e.g. most video metrics are an
|
||||
// average over the call and recorded when a stream is removed).
|
||||
// The metrics can for example be retrieved when a peer connection is closed.
|
||||
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class Metrics {
|
||||
private static final String TAG = "Metrics";
|
||||
|
||||
@ -69,14 +69,14 @@ public class Metrics {
|
||||
// Enables gathering of metrics (which can be fetched with getAndReset()).
|
||||
// Must be called before PeerConnectionFactory is created.
|
||||
public static void enable() {
|
||||
enableNative();
|
||||
nativeEnable();
|
||||
}
|
||||
|
||||
// Gets and clears native histograms.
|
||||
public static Metrics getAndReset() {
|
||||
return getAndResetNative();
|
||||
return nativeGetAndReset();
|
||||
}
|
||||
|
||||
private static native void enableNative();
|
||||
private static native Metrics getAndResetNative();
|
||||
private static native void nativeEnable();
|
||||
private static native Metrics nativeGetAndReset();
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ import java.util.List;
|
||||
* JS APIs: http://dev.w3.org/2011/webrtc/editor/webrtc.html and
|
||||
* http://www.w3.org/TR/mediacapture-streams/
|
||||
*/
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class PeerConnection {
|
||||
/** Tracks PeerConnectionInterface::IceGatheringState */
|
||||
public enum IceGatheringState {
|
||||
@ -565,46 +566,64 @@ public class PeerConnection {
|
||||
}
|
||||
|
||||
// JsepInterface.
|
||||
public native SessionDescription getLocalDescription();
|
||||
public SessionDescription getLocalDescription() {
|
||||
return nativeGetLocalDescription();
|
||||
}
|
||||
|
||||
public native SessionDescription getRemoteDescription();
|
||||
public SessionDescription getRemoteDescription() {
|
||||
return nativeGetRemoteDescription();
|
||||
}
|
||||
|
||||
public native DataChannel createDataChannel(String label, DataChannel.Init init);
|
||||
public DataChannel createDataChannel(String label, DataChannel.Init init) {
|
||||
return nativeCreateDataChannel(label, init);
|
||||
}
|
||||
|
||||
public native void createOffer(SdpObserver observer, MediaConstraints constraints);
|
||||
public void createOffer(SdpObserver observer, MediaConstraints constraints) {
|
||||
nativeCreateOffer(observer, constraints);
|
||||
}
|
||||
|
||||
public native void createAnswer(SdpObserver observer, MediaConstraints constraints);
|
||||
public void createAnswer(SdpObserver observer, MediaConstraints constraints) {
|
||||
nativeCreateAnswer(observer, constraints);
|
||||
}
|
||||
|
||||
public native void setLocalDescription(SdpObserver observer, SessionDescription sdp);
|
||||
public void setLocalDescription(SdpObserver observer, SessionDescription sdp) {
|
||||
nativeSetLocalDescription(observer, sdp);
|
||||
}
|
||||
|
||||
public native void setRemoteDescription(SdpObserver observer, SessionDescription sdp);
|
||||
public void setRemoteDescription(SdpObserver observer, SessionDescription sdp) {
|
||||
nativeSetRemoteDescription(observer, sdp);
|
||||
}
|
||||
|
||||
// True if remote audio should be played out. Defaults to true.
|
||||
// Note that even if playout is enabled, streams will only be played out if
|
||||
// the appropriate SDP is also applied. The main purpose of this API is to
|
||||
// be able to control the exact time when audio playout starts.
|
||||
public native void setAudioPlayout(boolean playout);
|
||||
public void setAudioPlayout(boolean playout) {
|
||||
nativeSetAudioPlayout(playout);
|
||||
}
|
||||
|
||||
// True if local audio shall be recorded. Defaults to true.
|
||||
// Note that even if recording is enabled, streams will only be recorded if
|
||||
// the appropriate SDP is also applied. The main purpose of this API is to
|
||||
// be able to control the exact time when audio recording starts.
|
||||
public native void setAudioRecording(boolean recording);
|
||||
public void setAudioRecording(boolean recording) {
|
||||
nativeSetAudioRecording(recording);
|
||||
}
|
||||
|
||||
public boolean setConfiguration(RTCConfiguration config) {
|
||||
return setNativeConfiguration(config, nativeObserver);
|
||||
return nativeSetConfiguration(config, nativeObserver);
|
||||
}
|
||||
|
||||
public boolean addIceCandidate(IceCandidate candidate) {
|
||||
return addNativeIceCandidate(candidate.sdpMid, candidate.sdpMLineIndex, candidate.sdp);
|
||||
return nativeAddIceCandidate(candidate.sdpMid, candidate.sdpMLineIndex, candidate.sdp);
|
||||
}
|
||||
|
||||
public boolean removeIceCandidates(final IceCandidate[] candidates) {
|
||||
return removeNativeIceCandidates(candidates);
|
||||
return nativeRemoveIceCandidates(candidates);
|
||||
}
|
||||
|
||||
public boolean addStream(MediaStream stream) {
|
||||
boolean ret = addNativeLocalStream(stream.nativeStream);
|
||||
boolean ret = nativeAddLocalStream(stream.nativeStream);
|
||||
if (!ret) {
|
||||
return false;
|
||||
}
|
||||
@ -613,7 +632,7 @@ public class PeerConnection {
|
||||
}
|
||||
|
||||
public void removeStream(MediaStream stream) {
|
||||
removeNativeLocalStream(stream.nativeStream);
|
||||
nativeRemoveLocalStream(stream.nativeStream);
|
||||
localStreams.remove(stream);
|
||||
}
|
||||
|
||||
@ -655,7 +674,7 @@ public class PeerConnection {
|
||||
* @return A new RtpSender object if successful, or null otherwise.
|
||||
*/
|
||||
public RtpSender createSender(String kind, String stream_id) {
|
||||
RtpSender new_sender = createNativeSender(kind, stream_id);
|
||||
RtpSender new_sender = nativeCreateSender(kind, stream_id);
|
||||
if (new_sender != null) {
|
||||
senders.add(new_sender);
|
||||
}
|
||||
@ -668,7 +687,7 @@ public class PeerConnection {
|
||||
for (RtpSender sender : senders) {
|
||||
sender.dispose();
|
||||
}
|
||||
senders = getNativeSenders();
|
||||
senders = nativeGetSenders();
|
||||
return Collections.unmodifiableList(senders);
|
||||
}
|
||||
|
||||
@ -676,25 +695,27 @@ public class PeerConnection {
|
||||
for (RtpReceiver receiver : receivers) {
|
||||
receiver.dispose();
|
||||
}
|
||||
receivers = getNativeReceivers();
|
||||
receivers = nativeGetReceivers();
|
||||
return Collections.unmodifiableList(receivers);
|
||||
}
|
||||
|
||||
// Older, non-standard implementation of getStats.
|
||||
@Deprecated
|
||||
public boolean getStats(StatsObserver observer, MediaStreamTrack track) {
|
||||
return oldGetNativeStats(observer, (track == null) ? 0 : track.nativeTrack);
|
||||
return nativeOldGetStats(observer, (track == null) ? 0 : track.nativeTrack);
|
||||
}
|
||||
|
||||
// Gets stats using the new stats collection API, see webrtc/api/stats/. These
|
||||
// will replace old stats collection API when the new API has matured enough.
|
||||
public void getStats(RTCStatsCollectorCallback callback) {
|
||||
newGetNativeStats(callback);
|
||||
nativeNewGetStats(callback);
|
||||
}
|
||||
|
||||
// Limits the bandwidth allocated for all RTP streams sent by this
|
||||
// PeerConnection. Pass null to leave a value unchanged.
|
||||
public native boolean setBitrate(Integer min, Integer current, Integer max);
|
||||
public boolean setBitrate(Integer min, Integer current, Integer max) {
|
||||
return nativeSetBitrate(min, current, max);
|
||||
}
|
||||
|
||||
// Starts recording an RTC event log. Ownership of the file is transfered to
|
||||
// the native code. If an RTC event log is already being recorded, it will be
|
||||
@ -702,24 +723,32 @@ public class PeerConnection {
|
||||
// continue until the stopRtcEventLog function is called. The max_size_bytes
|
||||
// argument is ignored, it is added for future use.
|
||||
public boolean startRtcEventLog(int file_descriptor, int max_size_bytes) {
|
||||
return startNativeRtcEventLog(file_descriptor, max_size_bytes);
|
||||
return nativeStartRtcEventLog(file_descriptor, max_size_bytes);
|
||||
}
|
||||
|
||||
// Stops recording an RTC event log. If no RTC event log is currently being
|
||||
// recorded, this call will have no effect.
|
||||
public void stopRtcEventLog() {
|
||||
stopNativeRtcEventLog();
|
||||
nativeStopRtcEventLog();
|
||||
}
|
||||
|
||||
// TODO(fischman): add support for DTMF-related methods once that API
|
||||
// stabilizes.
|
||||
public native SignalingState signalingState();
|
||||
public SignalingState signalingState() {
|
||||
return nativeSignalingState();
|
||||
}
|
||||
|
||||
public native IceConnectionState iceConnectionState();
|
||||
public IceConnectionState iceConnectionState() {
|
||||
return nativeIceConnectionState();
|
||||
}
|
||||
|
||||
public native IceGatheringState iceGatheringState();
|
||||
public IceGatheringState iceGatheringState() {
|
||||
return nativeIceGatheringState();
|
||||
}
|
||||
|
||||
public native void close();
|
||||
public void close() {
|
||||
nativeClose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Free native resources associated with this PeerConnection instance.
|
||||
@ -740,7 +769,7 @@ public class PeerConnection {
|
||||
public void dispose() {
|
||||
close();
|
||||
for (MediaStream stream : localStreams) {
|
||||
removeNativeLocalStream(stream.nativeStream);
|
||||
nativeRemoveLocalStream(stream.nativeStream);
|
||||
stream.dispose();
|
||||
}
|
||||
localStreams.clear();
|
||||
@ -754,7 +783,7 @@ public class PeerConnection {
|
||||
receivers.clear();
|
||||
JniCommon.nativeReleaseRef(nativePeerConnection);
|
||||
if (nativeObserver != 0) {
|
||||
freeNativePeerConnectionObserver(nativeObserver);
|
||||
nativeFreePeerConnectionObserver(nativeObserver);
|
||||
}
|
||||
}
|
||||
|
||||
@ -763,31 +792,41 @@ public class PeerConnection {
|
||||
return nativePeerConnection;
|
||||
}
|
||||
|
||||
public static native long createNativePeerConnectionObserver(Observer observer);
|
||||
public static native void freeNativePeerConnectionObserver(long nativeObserver);
|
||||
public static long createNativePeerConnectionObserver(Observer observer) {
|
||||
return nativeCreatePeerConnectionObserver(observer);
|
||||
}
|
||||
|
||||
private native boolean setNativeConfiguration(RTCConfiguration config, long nativeObserver);
|
||||
public static void freeNativePeerConnectionObserver(long observer) {
|
||||
nativeFreePeerConnectionObserver(observer);
|
||||
}
|
||||
|
||||
private native boolean addNativeIceCandidate(
|
||||
private native SessionDescription nativeGetLocalDescription();
|
||||
private native SessionDescription nativeGetRemoteDescription();
|
||||
private native DataChannel nativeCreateDataChannel(String label, DataChannel.Init init);
|
||||
private native void nativeCreateOffer(SdpObserver observer, MediaConstraints constraints);
|
||||
private native void nativeCreateAnswer(SdpObserver observer, MediaConstraints constraints);
|
||||
private native void nativeSetLocalDescription(SdpObserver observer, SessionDescription sdp);
|
||||
private native void nativeSetRemoteDescription(SdpObserver observer, SessionDescription sdp);
|
||||
private native void nativeSetAudioPlayout(boolean playout);
|
||||
private native void nativeSetAudioRecording(boolean recording);
|
||||
private native boolean nativeSetBitrate(Integer min, Integer current, Integer max);
|
||||
private native SignalingState nativeSignalingState();
|
||||
private native IceConnectionState nativeIceConnectionState();
|
||||
private native IceGatheringState nativeIceGatheringState();
|
||||
private native void nativeClose();
|
||||
private static native long nativeCreatePeerConnectionObserver(Observer observer);
|
||||
private static native void nativeFreePeerConnectionObserver(long observer);
|
||||
private native boolean nativeSetConfiguration(RTCConfiguration config, long nativeObserver);
|
||||
private native boolean nativeAddIceCandidate(
|
||||
String sdpMid, int sdpMLineIndex, String iceCandidateSdp);
|
||||
|
||||
private native boolean removeNativeIceCandidates(final IceCandidate[] candidates);
|
||||
|
||||
private native boolean addNativeLocalStream(long nativeStream);
|
||||
|
||||
private native void removeNativeLocalStream(long nativeStream);
|
||||
|
||||
private native boolean oldGetNativeStats(StatsObserver observer, long nativeTrack);
|
||||
|
||||
private native void newGetNativeStats(RTCStatsCollectorCallback callback);
|
||||
|
||||
private native RtpSender createNativeSender(String kind, String stream_id);
|
||||
|
||||
private native List<RtpSender> getNativeSenders();
|
||||
|
||||
private native List<RtpReceiver> getNativeReceivers();
|
||||
|
||||
private native boolean startNativeRtcEventLog(int file_descriptor, int max_size_bytes);
|
||||
|
||||
private native void stopNativeRtcEventLog();
|
||||
private native boolean nativeRemoveIceCandidates(final IceCandidate[] candidates);
|
||||
private native boolean nativeAddLocalStream(long stream);
|
||||
private native void nativeRemoveLocalStream(long stream);
|
||||
private native boolean nativeOldGetStats(StatsObserver observer, long nativeTrack);
|
||||
private native void nativeNewGetStats(RTCStatsCollectorCallback callback);
|
||||
private native RtpSender nativeCreateSender(String kind, String stream_id);
|
||||
private native List<RtpSender> nativeGetSenders();
|
||||
private native List<RtpReceiver> nativeGetReceivers();
|
||||
private native boolean nativeStartRtcEventLog(int file_descriptor, int max_size_bytes);
|
||||
private native void nativeStopRtcEventLog();
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ import java.util.List;
|
||||
* Java wrapper for a C++ PeerConnectionFactoryInterface. Main entry point to
|
||||
* the PeerConnection API for clients.
|
||||
*/
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class PeerConnectionFactory {
|
||||
public static final String TRIAL_ENABLED = "Enabled";
|
||||
public static final String VIDEO_FRAME_EMIT_TRIAL = "VideoFrameEmit";
|
||||
@ -129,7 +130,7 @@ public class PeerConnectionFactory {
|
||||
public static void initialize(InitializationOptions options) {
|
||||
ContextUtils.initialize(options.applicationContext);
|
||||
NativeLibrary.initialize(options.nativeLibraryLoader);
|
||||
initializeNativeAndroidGlobals(options.applicationContext, options.enableVideoHwAcceleration);
|
||||
nativeInitializeAndroidGlobals(options.applicationContext, options.enableVideoHwAcceleration);
|
||||
initializeFieldTrials(options.fieldTrials);
|
||||
if (options.enableInternalTracer && !internalTracerInitialized) {
|
||||
initializeInternalTracer();
|
||||
@ -144,25 +145,24 @@ public class PeerConnectionFactory {
|
||||
}
|
||||
}
|
||||
|
||||
// Must be called at least once before creating a PeerConnectionFactory
|
||||
// (for example, at application startup time).
|
||||
private static native void initializeNativeAndroidGlobals(
|
||||
Context context, boolean videoHwAcceleration);
|
||||
|
||||
private static void initializeInternalTracer() {
|
||||
internalTracerInitialized = true;
|
||||
initializeNativeInternalTracer();
|
||||
nativeInitializeInternalTracer();
|
||||
}
|
||||
|
||||
public static void shutdownInternalTracer() {
|
||||
internalTracerInitialized = false;
|
||||
shutdownNativeInternalTracer();
|
||||
nativeShutdownInternalTracer();
|
||||
}
|
||||
|
||||
// Field trial initialization. Must be called before PeerConnectionFactory
|
||||
// is created.
|
||||
// Deprecated, use PeerConnectionFactory.initialize instead.
|
||||
@Deprecated public static native void initializeFieldTrials(String fieldTrialsInitString);
|
||||
@Deprecated
|
||||
public static void initializeFieldTrials(String fieldTrialsInitString) {
|
||||
nativeInitializeFieldTrials(fieldTrialsInitString);
|
||||
}
|
||||
|
||||
// Wrapper of webrtc::field_trial::FindFullName. Develop the feature with default behaviour off.
|
||||
// Example usage:
|
||||
// if (PeerConnectionFactory.fieldTrialsFindFullName("WebRTCExperiment").equals("Enabled")) {
|
||||
@ -171,19 +171,16 @@ public class PeerConnectionFactory {
|
||||
// method2();
|
||||
// }
|
||||
public static String fieldTrialsFindFullName(String name) {
|
||||
return NativeLibrary.isLoaded() ? findNativeFieldTrialsFullName(name) : "";
|
||||
return NativeLibrary.isLoaded() ? nativeFindFieldTrialsFullName(name) : "";
|
||||
}
|
||||
private static native String findNativeFieldTrialsFullName(String name);
|
||||
// Internal tracing initialization. Must be called before PeerConnectionFactory is created to
|
||||
// prevent racing with tracing code.
|
||||
// Deprecated, use PeerConnectionFactory.initialize instead.
|
||||
private static native void initializeNativeInternalTracer();
|
||||
// Internal tracing shutdown, called to prevent resource leaks. Must be called after
|
||||
// PeerConnectionFactory is gone to prevent races with code performing tracing.
|
||||
private static native void shutdownNativeInternalTracer();
|
||||
// Start/stop internal capturing of internal tracing.
|
||||
public static native boolean startInternalTracingCapture(String tracing_filename);
|
||||
public static native void stopInternalTracingCapture();
|
||||
public static boolean startInternalTracingCapture(String tracingFilename) {
|
||||
return nativeStartInternalTracingCapture(tracingFilename);
|
||||
}
|
||||
|
||||
public static void stopInternalTracingCapture() {
|
||||
nativeStopInternalTracingCapture();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public PeerConnectionFactory() {
|
||||
@ -199,7 +196,7 @@ public class PeerConnectionFactory {
|
||||
public PeerConnectionFactory(
|
||||
Options options, VideoEncoderFactory encoderFactory, VideoDecoderFactory decoderFactory) {
|
||||
checkInitializeHasBeenCalled();
|
||||
nativeFactory = createNativePeerConnectionFactory(options, encoderFactory, decoderFactory);
|
||||
nativeFactory = nativeCreatePeerConnectionFactory(options, encoderFactory, decoderFactory);
|
||||
if (nativeFactory == 0) {
|
||||
throw new RuntimeException("Failed to initialize PeerConnectionFactory!");
|
||||
}
|
||||
@ -212,7 +209,7 @@ public class PeerConnectionFactory {
|
||||
throw new NullPointerException(
|
||||
"PeerConnectionFactory constructor does not accept a null AudioProcessingFactory.");
|
||||
}
|
||||
nativeFactory = createNativePeerConnectionFactoryWithAudioProcessing(
|
||||
nativeFactory = nativeCreatePeerConnectionFactoryWithAudioProcessing(
|
||||
options, encoderFactory, decoderFactory, audioProcessingFactory.createNative());
|
||||
if (nativeFactory == 0) {
|
||||
throw new RuntimeException("Failed to initialize PeerConnectionFactory!");
|
||||
@ -231,7 +228,7 @@ public class PeerConnectionFactory {
|
||||
return null;
|
||||
}
|
||||
long nativePeerConnection =
|
||||
createNativePeerConnection(nativeFactory, rtcConfig, constraints, nativeObserver);
|
||||
nativeCreatePeerConnection(nativeFactory, rtcConfig, constraints, nativeObserver);
|
||||
if (nativePeerConnection == 0) {
|
||||
return null;
|
||||
}
|
||||
@ -261,7 +258,7 @@ public class PeerConnectionFactory {
|
||||
}
|
||||
|
||||
public MediaStream createLocalMediaStream(String label) {
|
||||
return new MediaStream(createNativeLocalMediaStream(nativeFactory, label));
|
||||
return new MediaStream(nativeCreateLocalMediaStream(nativeFactory, label));
|
||||
}
|
||||
|
||||
public VideoSource createVideoSource(VideoCapturer capturer) {
|
||||
@ -270,7 +267,7 @@ public class PeerConnectionFactory {
|
||||
final SurfaceTextureHelper surfaceTextureHelper =
|
||||
SurfaceTextureHelper.create(VIDEO_CAPTURER_THREAD_NAME, eglContext);
|
||||
long nativeAndroidVideoTrackSource =
|
||||
createNativeVideoSource(nativeFactory, surfaceTextureHelper, capturer.isScreencast());
|
||||
nativeCreateVideoSource(nativeFactory, surfaceTextureHelper, capturer.isScreencast());
|
||||
VideoCapturer.CapturerObserver capturerObserver =
|
||||
new AndroidVideoTrackSourceObserver(nativeAndroidVideoTrackSource);
|
||||
capturer.initialize(
|
||||
@ -279,33 +276,33 @@ public class PeerConnectionFactory {
|
||||
}
|
||||
|
||||
public VideoTrack createVideoTrack(String id, VideoSource source) {
|
||||
return new VideoTrack(createNativeVideoTrack(nativeFactory, id, source.nativeSource));
|
||||
return new VideoTrack(nativeCreateVideoTrack(nativeFactory, id, source.nativeSource));
|
||||
}
|
||||
|
||||
public AudioSource createAudioSource(MediaConstraints constraints) {
|
||||
return new AudioSource(createNativeAudioSource(nativeFactory, constraints));
|
||||
return new AudioSource(nativeCreateAudioSource(nativeFactory, constraints));
|
||||
}
|
||||
|
||||
public AudioTrack createAudioTrack(String id, AudioSource source) {
|
||||
return new AudioTrack(createNativeAudioTrack(nativeFactory, id, source.nativeSource));
|
||||
return new AudioTrack(nativeCreateAudioTrack(nativeFactory, id, source.nativeSource));
|
||||
}
|
||||
|
||||
// Starts recording an AEC dump. Ownership of the file is transfered to the
|
||||
// native code. If an AEC dump is already in progress, it will be stopped and
|
||||
// a new one will start using the provided file.
|
||||
public boolean startAecDump(int file_descriptor, int filesize_limit_bytes) {
|
||||
return startNativeAecDump(nativeFactory, file_descriptor, filesize_limit_bytes);
|
||||
return nativeStartAecDump(nativeFactory, file_descriptor, filesize_limit_bytes);
|
||||
}
|
||||
|
||||
// Stops recording an AEC dump. If no AEC dump is currently being recorded,
|
||||
// this call will have no effect.
|
||||
public void stopAecDump() {
|
||||
stopNativeAecDump(nativeFactory);
|
||||
nativeStopAecDump(nativeFactory);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setOptions(Options options) {
|
||||
setNativeOptions(nativeFactory, options);
|
||||
nativeSetOptions(nativeFactory, options);
|
||||
}
|
||||
|
||||
/** Set the EGL context used by HW Video encoding and decoding.
|
||||
@ -326,12 +323,12 @@ public class PeerConnectionFactory {
|
||||
}
|
||||
localEglbase = EglBase.create(localEglContext);
|
||||
remoteEglbase = EglBase.create(remoteEglContext);
|
||||
setNativeVideoHwAccelerationOptions(
|
||||
nativeSetVideoHwAccelerationOptions(
|
||||
nativeFactory, localEglbase.getEglBaseContext(), remoteEglbase.getEglBaseContext());
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
freeNativeFactory(nativeFactory);
|
||||
nativeFreeFactory(nativeFactory);
|
||||
networkThread = null;
|
||||
workerThread = null;
|
||||
signalingThread = null;
|
||||
@ -342,7 +339,7 @@ public class PeerConnectionFactory {
|
||||
}
|
||||
|
||||
public void threadsCallbacks() {
|
||||
invokeNativeThreadsCallbacks(nativeFactory);
|
||||
nativeInvokeThreadsCallbacks(nativeFactory);
|
||||
}
|
||||
|
||||
private static void printStackTrace(Thread thread, String threadName) {
|
||||
@ -381,46 +378,41 @@ public class PeerConnectionFactory {
|
||||
Logging.d(TAG, "onSignalingThreadReady");
|
||||
}
|
||||
|
||||
private static native long createNativePeerConnectionFactory(
|
||||
// Must be called at least once before creating a PeerConnectionFactory
|
||||
// (for example, at application startup time).
|
||||
private static native void nativeInitializeAndroidGlobals(
|
||||
Context context, boolean videoHwAcceleration);
|
||||
private static native void nativeInitializeFieldTrials(String fieldTrialsInitString);
|
||||
private static native String nativeFindFieldTrialsFullName(String name);
|
||||
// Internal tracing initialization. Must be called before PeerConnectionFactory is created to
|
||||
// prevent racing with tracing code.
|
||||
// Deprecated, use PeerConnectionFactory.initialize instead.
|
||||
private static native void nativeInitializeInternalTracer();
|
||||
// Internal tracing shutdown, called to prevent resource leaks. Must be called after
|
||||
// PeerConnectionFactory is gone to prevent races with code performing tracing.
|
||||
private static native void nativeShutdownInternalTracer();
|
||||
private static native boolean nativeStartInternalTracingCapture(String tracingFilename);
|
||||
private static native void nativeStopInternalTracingCapture();
|
||||
private static native long nativeCreatePeerConnectionFactory(
|
||||
Options options, VideoEncoderFactory encoderFactory, VideoDecoderFactory decoderFactory);
|
||||
|
||||
private static native long createNativePeerConnectionFactoryWithAudioProcessing(Options options,
|
||||
private static native long nativeCreatePeerConnectionFactoryWithAudioProcessing(Options options,
|
||||
VideoEncoderFactory encoderFactory, VideoDecoderFactory decoderFactory,
|
||||
long nativeAudioProcessor);
|
||||
|
||||
private static native long createNativePeerConnection(long nativeFactory,
|
||||
private static native long nativeCreatePeerConnection(long factory,
|
||||
PeerConnection.RTCConfiguration rtcConfig, MediaConstraints constraints, long nativeObserver);
|
||||
|
||||
private static native long createNativeLocalMediaStream(long nativeFactory, String label);
|
||||
|
||||
private static native long createNativeVideoSource(
|
||||
long nativeFactory, SurfaceTextureHelper surfaceTextureHelper, boolean is_screencast);
|
||||
|
||||
private static native long createNativeVideoTrack(
|
||||
long nativeFactory, String id, long nativeVideoSource);
|
||||
|
||||
private static native long createNativeAudioSource(
|
||||
long nativeFactory, MediaConstraints constraints);
|
||||
|
||||
private static native long createNativeAudioTrack(
|
||||
long nativeFactory, String id, long nativeSource);
|
||||
|
||||
private static native boolean startNativeAecDump(
|
||||
long nativeFactory, int file_descriptor, int filesize_limit_bytes);
|
||||
|
||||
private static native void stopNativeAecDump(long nativeFactory);
|
||||
|
||||
@Deprecated
|
||||
public void nativeSetOptions(long nativeFactory, Options options) {
|
||||
setNativeOptions(nativeFactory, options);
|
||||
}
|
||||
|
||||
private native void setNativeOptions(long nativeFactory, Options options);
|
||||
|
||||
private static native void setNativeVideoHwAccelerationOptions(
|
||||
long nativeFactory, Object localEGLContext, Object remoteEGLContext);
|
||||
|
||||
private static native void invokeNativeThreadsCallbacks(long nativeFactory);
|
||||
|
||||
private static native void freeNativeFactory(long nativeFactory);
|
||||
private static native long nativeCreateLocalMediaStream(long factory, String label);
|
||||
private static native long nativeCreateVideoSource(
|
||||
long factory, SurfaceTextureHelper surfaceTextureHelper, boolean is_screencast);
|
||||
private static native long nativeCreateVideoTrack(
|
||||
long factory, String id, long nativeVideoSource);
|
||||
private static native long nativeCreateAudioSource(long factory, MediaConstraints constraints);
|
||||
private static native long nativeCreateAudioTrack(long factory, String id, long nativeSource);
|
||||
private static native boolean nativeStartAecDump(
|
||||
long factory, int file_descriptor, int filesize_limit_bytes);
|
||||
private static native void nativeStopAecDump(long factory);
|
||||
@Deprecated public native void nativeSetOptions(long factory, Options options);
|
||||
private static native void nativeSetVideoHwAccelerationOptions(
|
||||
long factory, Object localEGLContext, Object remoteEGLContext);
|
||||
private static native void nativeInvokeThreadsCallbacks(long factory);
|
||||
private static native void nativeFreeFactory(long factory);
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ package org.webrtc;
|
||||
import org.webrtc.MediaStreamTrack;
|
||||
|
||||
/** Java wrapper for a C++ RtpReceiverInterface. */
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class RtpReceiver {
|
||||
/** Java wrapper for a C++ RtpReceiverObserverInterface*/
|
||||
public static interface Observer {
|
||||
@ -29,7 +30,7 @@ public class RtpReceiver {
|
||||
@CalledByNative
|
||||
public RtpReceiver(long nativeRtpReceiver) {
|
||||
this.nativeRtpReceiver = nativeRtpReceiver;
|
||||
long track = getNativeTrack(nativeRtpReceiver);
|
||||
long track = nativeGetTrack(nativeRtpReceiver);
|
||||
// We can assume that an RtpReceiver always has an associated track.
|
||||
cachedTrack = new MediaStreamTrack(track);
|
||||
}
|
||||
@ -39,22 +40,22 @@ public class RtpReceiver {
|
||||
}
|
||||
|
||||
public boolean setParameters(RtpParameters parameters) {
|
||||
return parameters == null ? false : setNativeParameters(nativeRtpReceiver, parameters);
|
||||
return parameters == null ? false : nativeSetParameters(nativeRtpReceiver, parameters);
|
||||
}
|
||||
|
||||
public RtpParameters getParameters() {
|
||||
return getNativeParameters(nativeRtpReceiver);
|
||||
return nativeGetParameters(nativeRtpReceiver);
|
||||
}
|
||||
|
||||
public String id() {
|
||||
return getNativeId(nativeRtpReceiver);
|
||||
return nativeGetId(nativeRtpReceiver);
|
||||
}
|
||||
|
||||
@CalledByNative
|
||||
public void dispose() {
|
||||
cachedTrack.dispose();
|
||||
if (nativeObserver != 0) {
|
||||
unsetNativeObserver(nativeRtpReceiver, nativeObserver);
|
||||
nativeUnsetObserver(nativeRtpReceiver, nativeObserver);
|
||||
nativeObserver = 0;
|
||||
}
|
||||
JniCommon.nativeReleaseRef(nativeRtpReceiver);
|
||||
@ -63,23 +64,17 @@ public class RtpReceiver {
|
||||
public void SetObserver(Observer observer) {
|
||||
// Unset the existing one before setting a new one.
|
||||
if (nativeObserver != 0) {
|
||||
unsetNativeObserver(nativeRtpReceiver, nativeObserver);
|
||||
nativeUnsetObserver(nativeRtpReceiver, nativeObserver);
|
||||
}
|
||||
nativeObserver = setNativeObserver(nativeRtpReceiver, observer);
|
||||
nativeObserver = nativeSetObserver(nativeRtpReceiver, observer);
|
||||
}
|
||||
|
||||
// This should increment the reference count of the track.
|
||||
// Will be released in dispose().
|
||||
private static native long getNativeTrack(long nativeRtpReceiver);
|
||||
|
||||
private static native boolean setNativeParameters(
|
||||
long nativeRtpReceiver, RtpParameters parameters);
|
||||
|
||||
private static native RtpParameters getNativeParameters(long nativeRtpReceiver);
|
||||
|
||||
private static native String getNativeId(long nativeRtpReceiver);
|
||||
|
||||
private static native long setNativeObserver(long nativeRtpReceiver, Observer observer);
|
||||
|
||||
private static native void unsetNativeObserver(long nativeRtpReceiver, long nativeObserver);
|
||||
private static native long nativeGetTrack(long rtpReceiver);
|
||||
private static native boolean nativeSetParameters(long rtpReceiver, RtpParameters parameters);
|
||||
private static native RtpParameters nativeGetParameters(long rtpReceiver);
|
||||
private static native String nativeGetId(long rtpReceiver);
|
||||
private static native long nativeSetObserver(long rtpReceiver, Observer observer);
|
||||
private static native void nativeUnsetObserver(long rtpReceiver, long nativeObserver);
|
||||
};
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
package org.webrtc;
|
||||
|
||||
/** Java wrapper for a C++ RtpSenderInterface. */
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class RtpSender {
|
||||
final long nativeRtpSender;
|
||||
|
||||
@ -22,11 +23,11 @@ public class RtpSender {
|
||||
@CalledByNative
|
||||
public RtpSender(long nativeRtpSender) {
|
||||
this.nativeRtpSender = nativeRtpSender;
|
||||
long track = getNativeTrack(nativeRtpSender);
|
||||
long track = nativeGetTrack(nativeRtpSender);
|
||||
// It may be possible for an RtpSender to be created without a track.
|
||||
cachedTrack = (track != 0) ? new MediaStreamTrack(track) : null;
|
||||
|
||||
long nativeDtmfSender = getNativeDtmfSender(nativeRtpSender);
|
||||
long nativeDtmfSender = nativeGetDtmfSender(nativeRtpSender);
|
||||
dtmfSender = (nativeDtmfSender != 0) ? new DtmfSender(nativeDtmfSender) : null;
|
||||
}
|
||||
|
||||
@ -45,7 +46,7 @@ public class RtpSender {
|
||||
* @return true on success and false on failure.
|
||||
*/
|
||||
public boolean setTrack(MediaStreamTrack track, boolean takeOwnership) {
|
||||
if (!setNativeTrack(nativeRtpSender, (track == null) ? 0 : track.nativeTrack)) {
|
||||
if (!nativeSetTrack(nativeRtpSender, (track == null) ? 0 : track.nativeTrack)) {
|
||||
return false;
|
||||
}
|
||||
if (cachedTrack != null && ownsTrack) {
|
||||
@ -61,15 +62,15 @@ public class RtpSender {
|
||||
}
|
||||
|
||||
public boolean setParameters(RtpParameters parameters) {
|
||||
return setNativeParameters(nativeRtpSender, parameters);
|
||||
return nativeSetParameters(nativeRtpSender, parameters);
|
||||
}
|
||||
|
||||
public RtpParameters getParameters() {
|
||||
return getNativeParameters(nativeRtpSender);
|
||||
return nativeGetParameters(nativeRtpSender);
|
||||
}
|
||||
|
||||
public String id() {
|
||||
return getNativeId(nativeRtpSender);
|
||||
return nativeGetId(nativeRtpSender);
|
||||
}
|
||||
|
||||
public DtmfSender dtmf() {
|
||||
@ -86,19 +87,19 @@ public class RtpSender {
|
||||
JniCommon.nativeReleaseRef(nativeRtpSender);
|
||||
}
|
||||
|
||||
private static native boolean setNativeTrack(long nativeRtpSender, long nativeTrack);
|
||||
private static native boolean nativeSetTrack(long rtpSender, long nativeTrack);
|
||||
|
||||
// This should increment the reference count of the track.
|
||||
// Will be released in dispose() or setTrack().
|
||||
private static native long getNativeTrack(long nativeRtpSender);
|
||||
private static native long nativeGetTrack(long rtpSender);
|
||||
|
||||
// This should increment the reference count of the DTMF sender.
|
||||
// Will be released in dispose().
|
||||
private static native long getNativeDtmfSender(long nativeRtpSender);
|
||||
private static native long nativeGetDtmfSender(long rtpSender);
|
||||
|
||||
private static native boolean setNativeParameters(long nativeRtpSender, RtpParameters parameters);
|
||||
private static native boolean nativeSetParameters(long rtpSender, RtpParameters parameters);
|
||||
|
||||
private static native RtpParameters getNativeParameters(long nativeRtpSender);
|
||||
private static native RtpParameters nativeGetParameters(long rtpSender);
|
||||
|
||||
private static native String getNativeId(long nativeRtpSender);
|
||||
private static native String nativeGetId(long rtpSender);
|
||||
};
|
||||
|
||||
@ -16,7 +16,7 @@ public class SoftwareVideoDecoderFactory implements VideoDecoderFactory {
|
||||
if (codecType.equalsIgnoreCase("VP8")) {
|
||||
return new VP8Decoder();
|
||||
}
|
||||
if (codecType.equalsIgnoreCase("VP9") && VP9Decoder.isSupported()) {
|
||||
if (codecType.equalsIgnoreCase("VP9") && VP9Decoder.nativeIsSupported()) {
|
||||
return new VP9Decoder();
|
||||
}
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@ public class SoftwareVideoEncoderFactory implements VideoEncoderFactory {
|
||||
if (info.name.equalsIgnoreCase("VP8")) {
|
||||
return new VP8Encoder();
|
||||
}
|
||||
if (info.name.equalsIgnoreCase("VP9") && VP9Encoder.isSupported()) {
|
||||
if (info.name.equalsIgnoreCase("VP9") && VP9Encoder.nativeIsSupported()) {
|
||||
return new VP9Encoder();
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ public class SoftwareVideoEncoderFactory implements VideoEncoderFactory {
|
||||
List<VideoCodecInfo> codecs = new ArrayList<VideoCodecInfo>();
|
||||
|
||||
codecs.add(new VideoCodecInfo("VP8", new HashMap<>()));
|
||||
if (VP9Encoder.isSupported()) {
|
||||
if (VP9Encoder.nativeIsSupported()) {
|
||||
codecs.add(new VideoCodecInfo("VP9", new HashMap<>()));
|
||||
}
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
package org.webrtc;
|
||||
|
||||
/** Java wrapper for a C++ TurnCustomizer. */
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class TurnCustomizer {
|
||||
final long nativeTurnCustomizer;
|
||||
|
||||
@ -19,10 +20,10 @@ public class TurnCustomizer {
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
freeNativeTurnCustomizer(nativeTurnCustomizer);
|
||||
nativeFreeTurnCustomizer(nativeTurnCustomizer);
|
||||
}
|
||||
|
||||
private static native void freeNativeTurnCustomizer(long nativeTurnCustomizer);
|
||||
private static native void nativeFreeTurnCustomizer(long turnCustomizer);
|
||||
|
||||
@CalledByNative
|
||||
long getNativeTurnCustomizer() {
|
||||
|
||||
@ -13,6 +13,7 @@ package org.webrtc;
|
||||
/**
|
||||
* A combined video decoder that falls back on a secondary decoder if the primary decoder fails.
|
||||
*/
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class VideoDecoderFallback extends WrappedNativeVideoDecoder {
|
||||
private final VideoDecoder fallback;
|
||||
private final VideoDecoder primary;
|
||||
@ -24,8 +25,8 @@ public class VideoDecoderFallback extends WrappedNativeVideoDecoder {
|
||||
|
||||
@Override
|
||||
long createNativeDecoder() {
|
||||
return createNativeDecoder(fallback, primary);
|
||||
return nativeCreateDecoder(fallback, primary);
|
||||
}
|
||||
|
||||
private static native long createNativeDecoder(VideoDecoder fallback, VideoDecoder primary);
|
||||
private static native long nativeCreateDecoder(VideoDecoder fallback, VideoDecoder primary);
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ package org.webrtc;
|
||||
/**
|
||||
* A combined video encoder that falls back on a secondary encoder if the primary encoder fails.
|
||||
*/
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class VideoEncoderFallback extends WrappedNativeVideoEncoder {
|
||||
private final VideoEncoder fallback;
|
||||
private final VideoEncoder primary;
|
||||
@ -24,7 +25,7 @@ public class VideoEncoderFallback extends WrappedNativeVideoEncoder {
|
||||
|
||||
@Override
|
||||
long createNativeEncoder() {
|
||||
return createNativeEncoder(fallback, primary);
|
||||
return nativeCreateEncoder(fallback, primary);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -32,5 +33,5 @@ public class VideoEncoderFallback extends WrappedNativeVideoEncoder {
|
||||
return isWrappedSoftwareEncoder(primary);
|
||||
}
|
||||
|
||||
private static native long createNativeEncoder(VideoEncoder fallback, VideoEncoder primary);
|
||||
private static native long nativeCreateEncoder(VideoEncoder fallback, VideoEncoder primary);
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@ import java.util.concurrent.CountDownLatch;
|
||||
/**
|
||||
* Can be used to save the video frames to file.
|
||||
*/
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class VideoFileRenderer implements VideoRenderer.Callbacks {
|
||||
private static final String TAG = "VideoFileRenderer";
|
||||
|
||||
@ -94,7 +95,7 @@ public class VideoFileRenderer implements VideoRenderer.Callbacks {
|
||||
final float[] texMatrix = RendererCommon.multiplyMatrices(rotatedSamplingMatrix, layoutMatrix);
|
||||
|
||||
try {
|
||||
ByteBuffer buffer = JniCommon.allocateNativeByteBuffer(outputFrameSize);
|
||||
ByteBuffer buffer = JniCommon.nativeAllocateByteBuffer(outputFrameSize);
|
||||
if (!frame.yuvFrame) {
|
||||
yuvConverter.convert(outputFrameBuffer, outputFileWidth, outputFileHeight, outputFileWidth,
|
||||
frame.textureId, texMatrix);
|
||||
@ -153,7 +154,7 @@ public class VideoFileRenderer implements VideoRenderer.Callbacks {
|
||||
|
||||
videoOutFile.write(data);
|
||||
|
||||
JniCommon.freeNativeByteBuffer(buffer);
|
||||
JniCommon.nativeFreeByteBuffer(buffer);
|
||||
}
|
||||
videoOutFile.close();
|
||||
Logging.d(TAG, "Video written to disk as " + outputFileName + ". Number frames are "
|
||||
|
||||
@ -25,6 +25,7 @@ import java.nio.ByteBuffer;
|
||||
* format and serves as a fallback for video sinks that can only handle I420, e.g. the internal
|
||||
* WebRTC software encoders.
|
||||
*/
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class VideoFrame {
|
||||
public interface Buffer {
|
||||
/**
|
||||
@ -199,7 +200,7 @@ public class VideoFrame {
|
||||
}
|
||||
|
||||
JavaI420Buffer newBuffer = JavaI420Buffer.allocate(scaleWidth, scaleHeight);
|
||||
cropAndScaleI420Native(buffer.getDataY(), buffer.getStrideY(), buffer.getDataU(),
|
||||
nativeCropAndScaleI420(buffer.getDataY(), buffer.getStrideY(), buffer.getDataU(),
|
||||
buffer.getStrideU(), buffer.getDataV(), buffer.getStrideV(), cropX, cropY, cropWidth,
|
||||
cropHeight, newBuffer.getDataY(), newBuffer.getStrideY(), newBuffer.getDataU(),
|
||||
newBuffer.getStrideU(), newBuffer.getDataV(), newBuffer.getStrideV(), scaleWidth,
|
||||
@ -207,7 +208,7 @@ public class VideoFrame {
|
||||
return newBuffer;
|
||||
}
|
||||
|
||||
private static native void cropAndScaleI420Native(ByteBuffer srcY, int srcStrideY,
|
||||
private static native void nativeCropAndScaleI420(ByteBuffer srcY, int srcStrideY,
|
||||
ByteBuffer srcU, int srcStrideU, ByteBuffer srcV, int srcStrideV, int cropX, int cropY,
|
||||
int cropWidth, int cropHeight, ByteBuffer dstY, int dstStrideY, ByteBuffer dstU,
|
||||
int dstStrideU, ByteBuffer dstV, int dstStrideV, int scaleWidth, int scaleHeight);
|
||||
|
||||
@ -95,7 +95,7 @@ public class VideoFrameDrawer {
|
||||
// Input is packed already.
|
||||
packedByteBuffer = planes[i];
|
||||
} else {
|
||||
VideoRenderer.copyPlaneNative(
|
||||
VideoRenderer.nativeCopyPlane(
|
||||
planes[i], planeWidths[i], planeHeights[i], strides[i], copyBuffer, planeWidths[i]);
|
||||
packedByteBuffer = copyBuffer;
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ import org.webrtc.VideoFrame;
|
||||
* class also provides a createGui() method for creating a GUI-rendering window
|
||||
* on various platforms.
|
||||
*/
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class VideoRenderer {
|
||||
/**
|
||||
* Java version of webrtc::VideoFrame. Frames are only constructed from native code and test
|
||||
@ -194,7 +195,7 @@ public class VideoRenderer {
|
||||
}
|
||||
|
||||
// Helper native function to do a video frame plane copying.
|
||||
static native void copyPlaneNative(
|
||||
static native void nativeCopyPlane(
|
||||
ByteBuffer src, int width, int height, int srcStride, ByteBuffer dst, int dstStride);
|
||||
|
||||
/** The real meat of VideoSinkInterface. */
|
||||
@ -213,7 +214,7 @@ public class VideoRenderer {
|
||||
frame.yuvPlanes = null;
|
||||
frame.textureId = 0;
|
||||
if (frame.nativeFramePointer != 0) {
|
||||
releaseNativeFrame(frame.nativeFramePointer);
|
||||
nativeReleaseFrame(frame.nativeFramePointer);
|
||||
frame.nativeFramePointer = 0;
|
||||
}
|
||||
}
|
||||
@ -221,7 +222,7 @@ public class VideoRenderer {
|
||||
long nativeVideoRenderer;
|
||||
|
||||
public VideoRenderer(Callbacks callbacks) {
|
||||
nativeVideoRenderer = createNativeVideoRenderer(callbacks);
|
||||
nativeVideoRenderer = nativeCreateVideoRenderer(callbacks);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
@ -230,11 +231,11 @@ public class VideoRenderer {
|
||||
return;
|
||||
}
|
||||
|
||||
freeWrappedVideoRenderer(nativeVideoRenderer);
|
||||
nativeFreeWrappedVideoRenderer(nativeVideoRenderer);
|
||||
nativeVideoRenderer = 0;
|
||||
}
|
||||
|
||||
private static native long createNativeVideoRenderer(Callbacks callbacks);
|
||||
private static native void freeWrappedVideoRenderer(long nativeVideoRenderer);
|
||||
private static native void releaseNativeFrame(long nativeFramePointer);
|
||||
private static native long nativeCreateVideoRenderer(Callbacks callbacks);
|
||||
private static native void nativeFreeWrappedVideoRenderer(long videoRenderer);
|
||||
private static native void nativeReleaseFrame(long framePointer);
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ package org.webrtc;
|
||||
/**
|
||||
* Java wrapper of native AndroidVideoTrackSource.
|
||||
*/
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class VideoSource extends MediaSource {
|
||||
public VideoSource(long nativeSource) {
|
||||
super(nativeSource);
|
||||
@ -28,6 +29,5 @@ public class VideoSource extends MediaSource {
|
||||
nativeAdaptOutputFormat(nativeSource, width, height, fps);
|
||||
}
|
||||
|
||||
private static native void nativeAdaptOutputFormat(
|
||||
long nativeSource, int width, int height, int fps);
|
||||
private static native void nativeAdaptOutputFormat(long source, int width, int height, int fps);
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** Java version of VideoTrackInterface. */
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class VideoTrack extends MediaStreamTrack {
|
||||
private final List<VideoRenderer> renderers = new ArrayList<>();
|
||||
private final IdentityHashMap<VideoSink, Long> sinks = new IdentityHashMap<VideoSink, Long>();
|
||||
@ -78,9 +79,8 @@ public class VideoTrack extends MediaStreamTrack {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
private static native void nativeAddSink(long nativeTrack, long nativeSink);
|
||||
private static native void nativeRemoveSink(long nativeTrack, long nativeSink);
|
||||
|
||||
private static native void nativeAddSink(long track, long nativeSink);
|
||||
private static native void nativeRemoveSink(long track, long nativeSink);
|
||||
private static native long nativeWrapSink(VideoSink sink);
|
||||
private static native void nativeFreeSink(long nativeSink);
|
||||
private static native void nativeFreeSink(long sink);
|
||||
}
|
||||
|
||||
@ -141,7 +141,7 @@ public class YuvConverter {
|
||||
// extra row, but now other code does not have to deal with v stride * v height exceeding the
|
||||
// buffer's capacity.
|
||||
final int size = stride * (height + uvHeight + 1);
|
||||
ByteBuffer buffer = JniCommon.allocateNativeByteBuffer(size);
|
||||
ByteBuffer buffer = JniCommon.nativeAllocateByteBuffer(size);
|
||||
convert(buffer, width, height, stride, textureBuffer.getTextureId(),
|
||||
RendererCommon.convertMatrixFromAndroidGraphicsMatrix(textureBuffer.getTransformMatrix()),
|
||||
textureBuffer.getType());
|
||||
@ -165,7 +165,7 @@ public class YuvConverter {
|
||||
|
||||
// SurfaceTextureHelper uses the same stride for Y, U, and V data.
|
||||
return JavaI420Buffer.wrap(width, height, dataY, stride, dataU, stride, dataV, stride,
|
||||
() -> { JniCommon.freeNativeByteBuffer(buffer); });
|
||||
() -> { JniCommon.nativeFreeByteBuffer(buffer); });
|
||||
}
|
||||
|
||||
/** Deprecated, use convert(TextureBuffer). */
|
||||
|
||||
@ -13,6 +13,7 @@ package org.webrtc;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/** Wraps libyuv methods to Java. All passed byte buffers must be direct byte buffers. */
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class YuvHelper {
|
||||
/** Helper method for copying I420 to tightly packed destination buffer. */
|
||||
public static void I420Copy(ByteBuffer srcY, int srcStrideY, ByteBuffer srcU, int srcStrideU,
|
||||
@ -37,8 +38,8 @@ public class YuvHelper {
|
||||
dst.position(startV);
|
||||
final ByteBuffer dstV = dst.slice();
|
||||
|
||||
I420Copy(srcY, srcStrideY, srcU, srcStrideU, srcV, srcStrideV, dstY, width, dstU, chromaWidth,
|
||||
dstV, chromaWidth, width, height);
|
||||
nativeI420Copy(srcY, srcStrideY, srcU, srcStrideU, srcV, srcStrideV, dstY, width, dstU,
|
||||
chromaWidth, dstV, chromaWidth, width, height);
|
||||
}
|
||||
|
||||
/** Helper method for copying I420 to tightly packed NV12 destination buffer. */
|
||||
@ -61,14 +62,28 @@ public class YuvHelper {
|
||||
dst.position(startUV);
|
||||
final ByteBuffer dstUV = dst.slice();
|
||||
|
||||
I420ToNV12(srcY, srcStrideY, srcU, srcStrideU, srcV, srcStrideV, dstY, width, dstUV,
|
||||
nativeI420ToNV12(srcY, srcStrideY, srcU, srcStrideU, srcV, srcStrideV, dstY, width, dstUV,
|
||||
chromaWidth * 2, width, height);
|
||||
}
|
||||
|
||||
public static native void I420Copy(ByteBuffer srcY, int srcStrideY, ByteBuffer srcU,
|
||||
public static void I420Copy(ByteBuffer srcY, int srcStrideY, ByteBuffer srcU, int srcStrideU,
|
||||
ByteBuffer srcV, int srcStrideV, ByteBuffer dstY, int dstStrideY, ByteBuffer dstU,
|
||||
int dstStrideU, ByteBuffer dstV, int dstStrideV, int width, int height) {
|
||||
nativeI420Copy(srcY, srcStrideY, srcU, srcStrideU, srcV, srcStrideV, dstY, dstStrideY, dstU,
|
||||
dstStrideU, dstV, dstStrideV, width, height);
|
||||
}
|
||||
|
||||
public static void I420ToNV12(ByteBuffer srcY, int srcStrideY, ByteBuffer srcU, int srcStrideU,
|
||||
ByteBuffer srcV, int srcStrideV, ByteBuffer dstY, int dstStrideY, ByteBuffer dstUV,
|
||||
int dstStrideUV, int width, int height) {
|
||||
nativeI420ToNV12(srcY, srcStrideY, srcU, srcStrideU, srcV, srcStrideV, dstY, dstStrideY, dstUV,
|
||||
dstStrideUV, width, height);
|
||||
}
|
||||
|
||||
private static native void nativeI420Copy(ByteBuffer srcY, int srcStrideY, ByteBuffer srcU,
|
||||
int srcStrideU, ByteBuffer srcV, int srcStrideV, ByteBuffer dstY, int dstStrideY,
|
||||
ByteBuffer dstU, int dstStrideU, ByteBuffer dstV, int dstStrideV, int width, int height);
|
||||
public static native void I420ToNV12(ByteBuffer srcY, int srcStrideY, ByteBuffer srcU,
|
||||
private static native void nativeI420ToNV12(ByteBuffer srcY, int srcStrideY, ByteBuffer srcU,
|
||||
int srcStrideU, ByteBuffer srcV, int srcStrideV, ByteBuffer dstY, int dstStrideY,
|
||||
ByteBuffer dstUV, int dstStrideUV, int width, int height);
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
package org.webrtc;
|
||||
|
||||
/** An implementation of CapturerObserver that forwards all calls from Java to the C layer. */
|
||||
@JNINamespace("webrtc::jni")
|
||||
class AndroidVideoTrackSourceObserver implements VideoCapturer.CapturerObserver {
|
||||
// Pointer to VideoTrackSourceProxy proxying AndroidVideoTrackSource.
|
||||
private final long nativeSource;
|
||||
@ -49,12 +50,12 @@ class AndroidVideoTrackSourceObserver implements VideoCapturer.CapturerObserver
|
||||
frame.getRotation(), frame.getTimestampNs(), frame.getBuffer());
|
||||
}
|
||||
|
||||
private native void nativeCapturerStarted(long nativeSource, boolean success);
|
||||
private native void nativeCapturerStopped(long nativeSource);
|
||||
private native void nativeOnByteBufferFrameCaptured(long nativeSource, byte[] data, int length,
|
||||
int width, int height, int rotation, long timeStamp);
|
||||
private native void nativeOnTextureFrameCaptured(long nativeSource, int width, int height,
|
||||
private static native void nativeCapturerStarted(long source, boolean success);
|
||||
private static native void nativeCapturerStopped(long source);
|
||||
private static native void nativeOnByteBufferFrameCaptured(
|
||||
long source, byte[] data, int length, int width, int height, int rotation, long timeStamp);
|
||||
private static native void nativeOnTextureFrameCaptured(long source, int width, int height,
|
||||
int oesTextureId, float[] transformMatrix, int rotation, long timestamp);
|
||||
private native void nativeOnFrameCaptured(long nativeSource, int width, int height, int rotation,
|
||||
long timestampNs, VideoFrame.Buffer frame);
|
||||
private static native void nativeOnFrameCaptured(
|
||||
long source, int width, int height, int rotation, long timestampNs, VideoFrame.Buffer frame);
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ package org.webrtc;
|
||||
* Histogram.createCounts("WebRTC.Video.SomeMetric", 1, 10000, 50);
|
||||
* someMetricHistogram.addSample(someVariable);
|
||||
*/
|
||||
@JNINamespace("webrtc::jni")
|
||||
class Histogram {
|
||||
private final long handle;
|
||||
|
||||
|
||||
26
sdk/android/src/java/org/webrtc/JNINamespace.java
Normal file
26
sdk/android/src/java/org/webrtc/JNINamespace.java
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2017 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 java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @JNINamespace is used by the JNI generator to create the necessary JNI
|
||||
* bindings and expose this method to native code using the specified namespace.
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface JNINamespace {
|
||||
public String value();
|
||||
}
|
||||
@ -13,11 +13,12 @@ package org.webrtc;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/** Class with static JNI helper functions that are used in many places. */
|
||||
@JNINamespace("webrtc::jni")
|
||||
class JniCommon {
|
||||
/** Functions to increment/decrement an rtc::RefCountInterface pointer. */
|
||||
static native void nativeAddRef(long nativeRefCountedPointer);
|
||||
static native void nativeReleaseRef(long nativeRefCountedPointer);
|
||||
static native void nativeAddRef(long refCountedPointer);
|
||||
static native void nativeReleaseRef(long refCountedPointer);
|
||||
|
||||
public static native ByteBuffer allocateNativeByteBuffer(int size);
|
||||
public static native void freeNativeByteBuffer(ByteBuffer buffer);
|
||||
public static native ByteBuffer nativeAllocateByteBuffer(int size);
|
||||
public static native void nativeFreeByteBuffer(ByteBuffer buffer);
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ package org.webrtc;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class NV12Buffer implements VideoFrame.Buffer {
|
||||
private final int width;
|
||||
private final int height;
|
||||
|
||||
@ -12,6 +12,7 @@ package org.webrtc;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
@JNINamespace("webrtc::jni")
|
||||
public class NV21Buffer implements VideoFrame.Buffer {
|
||||
private final byte[] data;
|
||||
private final int width;
|
||||
|
||||
@ -10,6 +10,12 @@
|
||||
|
||||
package org.webrtc;
|
||||
|
||||
@JNINamespace("webrtc::jni")
|
||||
class VP8Decoder extends WrappedNativeVideoDecoder {
|
||||
@Override native long createNativeDecoder();
|
||||
@Override
|
||||
long createNativeDecoder() {
|
||||
return nativeCreateDecoder();
|
||||
}
|
||||
|
||||
static native long nativeCreateDecoder();
|
||||
}
|
||||
|
||||
@ -10,8 +10,14 @@
|
||||
|
||||
package org.webrtc;
|
||||
|
||||
@JNINamespace("webrtc::jni")
|
||||
class VP8Encoder extends WrappedNativeVideoEncoder {
|
||||
@Override native long createNativeEncoder();
|
||||
@Override
|
||||
long createNativeEncoder() {
|
||||
return nativeCreateEncoder();
|
||||
}
|
||||
|
||||
static native long nativeCreateEncoder();
|
||||
|
||||
@Override
|
||||
boolean isSoftwareEncoder() {
|
||||
|
||||
@ -10,8 +10,14 @@
|
||||
|
||||
package org.webrtc;
|
||||
|
||||
@JNINamespace("webrtc::jni")
|
||||
class VP9Decoder extends WrappedNativeVideoDecoder {
|
||||
@Override native long createNativeDecoder();
|
||||
@Override
|
||||
long createNativeDecoder() {
|
||||
return nativeCreateDecoder();
|
||||
}
|
||||
|
||||
static native boolean isSupported();
|
||||
static native long nativeCreateDecoder();
|
||||
|
||||
static native boolean nativeIsSupported();
|
||||
}
|
||||
|
||||
@ -10,13 +10,19 @@
|
||||
|
||||
package org.webrtc;
|
||||
|
||||
@JNINamespace("webrtc::jni")
|
||||
class VP9Encoder extends WrappedNativeVideoEncoder {
|
||||
@Override native long createNativeEncoder();
|
||||
@Override
|
||||
long createNativeEncoder() {
|
||||
return nativeCreateEncoder();
|
||||
}
|
||||
|
||||
static native long nativeCreateEncoder();
|
||||
|
||||
@Override
|
||||
boolean isSoftwareEncoder() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static native boolean isSupported();
|
||||
static native boolean nativeIsSupported();
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include "sdk/android/generated_base_jni/jni/Histogram_jni.h"
|
||||
#include "sdk/android/src/jni/jni_helpers.h"
|
||||
#include "system_wrappers/include/metrics.h"
|
||||
|
||||
@ -18,35 +19,30 @@
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jlong,
|
||||
Histogram_nativeCreateCounts,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jstring j_name,
|
||||
jint min,
|
||||
jint max,
|
||||
jint buckets) {
|
||||
static jlong JNI_Histogram_CreateCounts(JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
const JavaParamRef<jstring>& j_name,
|
||||
jint min,
|
||||
jint max,
|
||||
jint buckets) {
|
||||
std::string name = JavaToStdString(jni, j_name);
|
||||
return jlongFromPointer(
|
||||
metrics::HistogramFactoryGetCounts(name, min, max, buckets));
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jlong,
|
||||
Histogram_nativeCreateEnumeration,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jstring j_name,
|
||||
jint max) {
|
||||
static jlong JNI_Histogram_CreateEnumeration(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
const JavaParamRef<jstring>& j_name,
|
||||
jint max) {
|
||||
std::string name = JavaToStdString(jni, j_name);
|
||||
return jlongFromPointer(metrics::HistogramFactoryGetEnumeration(name, max));
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
Histogram_nativeAddSample,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong histogram,
|
||||
jint sample) {
|
||||
static void JNI_Histogram_AddSample(JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong histogram,
|
||||
jint sample) {
|
||||
if (histogram) {
|
||||
HistogramAdd(reinterpret_cast<metrics::Histogram*>(histogram), sample);
|
||||
}
|
||||
|
||||
@ -130,10 +130,10 @@ class MediaCodecVideoDecoder : public VideoDecoder, public rtc::MessageHandler {
|
||||
// returns.
|
||||
std::unique_ptr<Thread>
|
||||
codec_thread_; // Thread on which to operate MediaCodec.
|
||||
ScopedGlobalRef<jobject> j_media_codec_video_decoder_;
|
||||
ScopedJavaGlobalRef<jobject> j_media_codec_video_decoder_;
|
||||
|
||||
// Global references; must be deleted in Release().
|
||||
std::vector<ScopedGlobalRef<jobject>> input_buffers_;
|
||||
std::vector<ScopedJavaGlobalRef<jobject>> input_buffers_;
|
||||
};
|
||||
|
||||
MediaCodecVideoDecoder::MediaCodecVideoDecoder(JNIEnv* jni,
|
||||
@ -225,7 +225,8 @@ int32_t MediaCodecVideoDecoder::InitDecodeOnCodecThread() {
|
||||
|
||||
if (use_surface_) {
|
||||
surface_texture_helper_ = SurfaceTextureHelper::create(
|
||||
jni, "Decoder SurfaceTextureHelper", render_egl_context_);
|
||||
jni, "Decoder SurfaceTextureHelper",
|
||||
JavaParamRef<jobject>(render_egl_context_));
|
||||
if (!surface_texture_helper_) {
|
||||
ALOGE << "Couldn't create SurfaceTextureHelper - fallback to SW codec";
|
||||
sw_fallback_required_ = true;
|
||||
@ -233,13 +234,15 @@ int32_t MediaCodecVideoDecoder::InitDecodeOnCodecThread() {
|
||||
}
|
||||
}
|
||||
|
||||
jobject j_video_codec_enum =
|
||||
ScopedJavaLocalRef<jobject> j_video_codec_enum =
|
||||
Java_VideoCodecType_fromNativeIndex(jni, codecType_);
|
||||
jobject j_surface_texture_helper =
|
||||
use_surface_
|
||||
? surface_texture_helper_->GetJavaSurfaceTextureHelper().obj()
|
||||
: nullptr;
|
||||
bool success = Java_MediaCodecVideoDecoder_initDecode(
|
||||
jni, *j_media_codec_video_decoder_, j_video_codec_enum, codec_.width,
|
||||
codec_.height,
|
||||
use_surface_ ? surface_texture_helper_->GetJavaSurfaceTextureHelper()
|
||||
: nullptr);
|
||||
jni, j_media_codec_video_decoder_, j_video_codec_enum, codec_.width,
|
||||
codec_.height, JavaParamRef<jobject>(j_surface_texture_helper));
|
||||
|
||||
if (CheckException(jni) || !success) {
|
||||
ALOGE << "Codec initialization error - fallback to SW codec.";
|
||||
@ -263,11 +266,13 @@ int32_t MediaCodecVideoDecoder::InitDecodeOnCodecThread() {
|
||||
}
|
||||
ALOGD << "Maximum amount of pending frames: " << max_pending_frames_;
|
||||
|
||||
jobjectArray input_buffers = Java_MediaCodecVideoDecoder_getInputBuffers(
|
||||
jni, *j_media_codec_video_decoder_);
|
||||
input_buffers_ = JavaToNativeVector<ScopedGlobalRef<jobject>>(
|
||||
jni, input_buffers,
|
||||
[](JNIEnv* env, jobject o) { return ScopedGlobalRef<jobject>(env, o); });
|
||||
ScopedJavaLocalRef<jobjectArray> input_buffers =
|
||||
Java_MediaCodecVideoDecoder_getInputBuffers(jni,
|
||||
j_media_codec_video_decoder_);
|
||||
input_buffers_ = JavaToNativeVector<ScopedJavaGlobalRef<jobject>>(
|
||||
jni, input_buffers, [](JNIEnv* env, const JavaRef<jobject>& o) {
|
||||
return ScopedJavaGlobalRef<jobject>(env, o);
|
||||
});
|
||||
|
||||
codec_thread_->PostDelayed(RTC_FROM_HERE, kMediaCodecPollMs, this);
|
||||
|
||||
@ -287,7 +292,7 @@ int32_t MediaCodecVideoDecoder::ResetDecodeOnCodecThread() {
|
||||
rtc::MessageQueueManager::Clear(this);
|
||||
ResetVariables();
|
||||
|
||||
Java_MediaCodecVideoDecoder_reset(jni, *j_media_codec_video_decoder_,
|
||||
Java_MediaCodecVideoDecoder_reset(jni, j_media_codec_video_decoder_,
|
||||
codec_.width, codec_.height);
|
||||
|
||||
if (CheckException(jni)) {
|
||||
@ -318,7 +323,7 @@ int32_t MediaCodecVideoDecoder::ReleaseOnCodecThread() {
|
||||
frames_received_ << ". Frames decoded: " << frames_decoded_;
|
||||
ScopedLocalRefFrame local_ref_frame(jni);
|
||||
input_buffers_.clear();
|
||||
Java_MediaCodecVideoDecoder_release(jni, *j_media_codec_video_decoder_);
|
||||
Java_MediaCodecVideoDecoder_release(jni, j_media_codec_video_decoder_);
|
||||
surface_texture_helper_ = nullptr;
|
||||
inited_ = false;
|
||||
rtc::MessageQueueManager::Clear(this);
|
||||
@ -470,7 +475,7 @@ int32_t MediaCodecVideoDecoder::DecodeOnCodecThread(
|
||||
|
||||
// Get input buffer.
|
||||
int j_input_buffer_index = Java_MediaCodecVideoDecoder_dequeueInputBuffer(
|
||||
jni, *j_media_codec_video_decoder_);
|
||||
jni, j_media_codec_video_decoder_);
|
||||
if (CheckException(jni) || j_input_buffer_index < 0) {
|
||||
ALOGE << "dequeueInputBuffer error: " << j_input_buffer_index <<
|
||||
". Retry DeliverPendingOutputs.";
|
||||
@ -483,7 +488,7 @@ int32_t MediaCodecVideoDecoder::DecodeOnCodecThread(
|
||||
}
|
||||
// Try dequeue input buffer one last time.
|
||||
j_input_buffer_index = Java_MediaCodecVideoDecoder_dequeueInputBuffer(
|
||||
jni, *j_media_codec_video_decoder_);
|
||||
jni, j_media_codec_video_decoder_);
|
||||
if (CheckException(jni) || j_input_buffer_index < 0) {
|
||||
ALOGE << "dequeueInputBuffer critical error: " << j_input_buffer_index;
|
||||
return ProcessHWErrorOnCodecThread();
|
||||
@ -491,7 +496,7 @@ int32_t MediaCodecVideoDecoder::DecodeOnCodecThread(
|
||||
}
|
||||
|
||||
// Copy encoded data to Java ByteBuffer.
|
||||
jobject j_input_buffer = *input_buffers_[j_input_buffer_index];
|
||||
jobject j_input_buffer = input_buffers_[j_input_buffer_index].obj();
|
||||
uint8_t* buffer =
|
||||
reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(j_input_buffer));
|
||||
RTC_CHECK(buffer) << "Indirect buffer??";
|
||||
@ -534,7 +539,7 @@ int32_t MediaCodecVideoDecoder::DecodeOnCodecThread(
|
||||
|
||||
// Feed input to decoder.
|
||||
bool success = Java_MediaCodecVideoDecoder_queueInputBuffer(
|
||||
jni, *j_media_codec_video_decoder_, j_input_buffer_index,
|
||||
jni, j_media_codec_video_decoder_, j_input_buffer_index,
|
||||
inputImage._length, presentation_timestamp_us,
|
||||
static_cast<int64_t>(inputImage._timeStamp), inputImage.ntp_time_ms_);
|
||||
if (CheckException(jni) || !success) {
|
||||
@ -559,10 +564,10 @@ bool MediaCodecVideoDecoder::DeliverPendingOutputs(
|
||||
return true;
|
||||
}
|
||||
// Get decoder output.
|
||||
jobject j_decoder_output_buffer =
|
||||
ScopedJavaLocalRef<jobject> j_decoder_output_buffer =
|
||||
(use_surface_ ? &Java_MediaCodecVideoDecoder_dequeueTextureBuffer
|
||||
: &Java_MediaCodecVideoDecoder_dequeueOutputBuffer)(
|
||||
jni, *j_media_codec_video_decoder_, dequeue_timeout_ms);
|
||||
jni, j_media_codec_video_decoder_, dequeue_timeout_ms);
|
||||
if (CheckException(jni)) {
|
||||
ALOGE << "dequeueOutputBuffer() error";
|
||||
return false;
|
||||
@ -574,11 +579,11 @@ bool MediaCodecVideoDecoder::DeliverPendingOutputs(
|
||||
|
||||
// Get decoded video frame properties.
|
||||
int color_format = Java_MediaCodecVideoDecoder_getColorFormat(
|
||||
jni, *j_media_codec_video_decoder_);
|
||||
jni, j_media_codec_video_decoder_);
|
||||
int width =
|
||||
Java_MediaCodecVideoDecoder_getWidth(jni, *j_media_codec_video_decoder_);
|
||||
Java_MediaCodecVideoDecoder_getWidth(jni, j_media_codec_video_decoder_);
|
||||
int height =
|
||||
Java_MediaCodecVideoDecoder_getHeight(jni, *j_media_codec_video_decoder_);
|
||||
Java_MediaCodecVideoDecoder_getHeight(jni, j_media_codec_video_decoder_);
|
||||
|
||||
rtc::scoped_refptr<VideoFrameBuffer> frame_buffer;
|
||||
int64_t presentation_timestamps_ms = 0;
|
||||
@ -601,7 +606,7 @@ bool MediaCodecVideoDecoder::DeliverPendingOutputs(
|
||||
const int texture_id =
|
||||
Java_DecodedTextureBuffer_getTextureId(jni, j_decoder_output_buffer);
|
||||
if (texture_id != 0) { // |texture_id| == 0 represents a dropped frame.
|
||||
const jfloatArray j_transform_matrix =
|
||||
ScopedJavaLocalRef<jfloatArray> j_transform_matrix =
|
||||
Java_DecodedTextureBuffer_getTransformMatrix(jni,
|
||||
j_decoder_output_buffer);
|
||||
frame_delayed_ms = Java_DecodedTextureBuffer_getFrameDelayMs(
|
||||
@ -617,9 +622,9 @@ bool MediaCodecVideoDecoder::DeliverPendingOutputs(
|
||||
// Extract data from Java ByteBuffer and create output yuv420 frame -
|
||||
// for non surface decoding only.
|
||||
int stride = Java_MediaCodecVideoDecoder_getStride(
|
||||
jni, *j_media_codec_video_decoder_);
|
||||
jni, j_media_codec_video_decoder_);
|
||||
const int slice_height = Java_MediaCodecVideoDecoder_getSliceHeight(
|
||||
jni, *j_media_codec_video_decoder_);
|
||||
jni, j_media_codec_video_decoder_);
|
||||
const int output_buffer_index =
|
||||
Java_DecodedOutputBuffer_getIndex(jni, j_decoder_output_buffer);
|
||||
const int output_buffer_offset =
|
||||
@ -648,10 +653,11 @@ bool MediaCodecVideoDecoder::DeliverPendingOutputs(
|
||||
// output byte buffer, so actual stride value need to be corrected.
|
||||
stride = output_buffer_size * 2 / (height * 3);
|
||||
}
|
||||
jobjectArray output_buffers = Java_MediaCodecVideoDecoder_getOutputBuffers(
|
||||
jni, *j_media_codec_video_decoder_);
|
||||
ScopedJavaLocalRef<jobjectArray> output_buffers =
|
||||
Java_MediaCodecVideoDecoder_getOutputBuffers(
|
||||
jni, j_media_codec_video_decoder_);
|
||||
jobject output_buffer =
|
||||
jni->GetObjectArrayElement(output_buffers, output_buffer_index);
|
||||
jni->GetObjectArrayElement(output_buffers.obj(), output_buffer_index);
|
||||
uint8_t* payload = reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(
|
||||
output_buffer));
|
||||
if (CheckException(jni)) {
|
||||
@ -714,7 +720,7 @@ bool MediaCodecVideoDecoder::DeliverPendingOutputs(
|
||||
|
||||
// Return output byte buffer back to codec.
|
||||
Java_MediaCodecVideoDecoder_returnDecodedOutputBuffer(
|
||||
jni, *j_media_codec_video_decoder_, output_buffer_index);
|
||||
jni, j_media_codec_video_decoder_, output_buffer_index);
|
||||
if (CheckException(jni)) {
|
||||
ALOGE << "returnDecodedOutputBuffer error";
|
||||
return false;
|
||||
|
||||
@ -176,7 +176,7 @@ class MediaCodecVideoEncoder : public VideoEncoder {
|
||||
// frame.
|
||||
bool EncodeJavaFrame(JNIEnv* jni,
|
||||
bool key_frame,
|
||||
jobject frame,
|
||||
const JavaRef<jobject>& frame,
|
||||
int input_buffer_index);
|
||||
|
||||
// Deliver any outputs pending in the MediaCodec to our |callback_| and return
|
||||
@ -206,7 +206,7 @@ class MediaCodecVideoEncoder : public VideoEncoder {
|
||||
// State that is constant for the lifetime of this object once the ctor
|
||||
// returns.
|
||||
rtc::SequencedTaskChecker encoder_queue_checker_;
|
||||
ScopedGlobalRef<jobject> j_media_codec_video_encoder_;
|
||||
ScopedJavaGlobalRef<jobject> j_media_codec_video_encoder_;
|
||||
|
||||
// State that is valid only between InitEncode() and the next Release().
|
||||
int width_; // Frame width in pixels.
|
||||
@ -265,7 +265,7 @@ class MediaCodecVideoEncoder : public VideoEncoder {
|
||||
bool scale_;
|
||||
H264::Profile profile_;
|
||||
// Global references; must be deleted in Release().
|
||||
std::vector<ScopedGlobalRef<jobject>> input_buffers_;
|
||||
std::vector<ScopedJavaGlobalRef<jobject>> input_buffers_;
|
||||
H264BitstreamParser h264_bitstream_parser_;
|
||||
|
||||
// VP9 variables to populate codec specific structure.
|
||||
@ -521,11 +521,12 @@ int32_t MediaCodecVideoEncoder::InitEncodeInternal(int width,
|
||||
frames_received_since_last_key_ = kMinKeyFrameInterval;
|
||||
|
||||
// We enforce no extra stride/padding in the format creation step.
|
||||
jobject j_video_codec_enum =
|
||||
ScopedJavaLocalRef<jobject> j_video_codec_enum =
|
||||
Java_VideoCodecType_fromNativeIndex(jni, codec_type);
|
||||
const bool encode_status = Java_MediaCodecVideoEncoder_initEncode(
|
||||
jni, *j_media_codec_video_encoder_, j_video_codec_enum, profile_, width,
|
||||
height, kbps, fps, (use_surface ? egl_context_ : nullptr));
|
||||
jni, j_media_codec_video_encoder_, j_video_codec_enum, profile_, width,
|
||||
height, kbps, fps,
|
||||
JavaParamRef<jobject>(use_surface ? egl_context_ : nullptr));
|
||||
if (!encode_status) {
|
||||
ALOGE << "Failed to configure encoder.";
|
||||
ProcessHWError(false /* reset_if_fallback_unavailable */);
|
||||
@ -538,8 +539,9 @@ int32_t MediaCodecVideoEncoder::InitEncodeInternal(int width,
|
||||
}
|
||||
|
||||
if (!use_surface) {
|
||||
jobjectArray input_buffers = Java_MediaCodecVideoEncoder_getInputBuffers(
|
||||
jni, *j_media_codec_video_encoder_);
|
||||
ScopedJavaLocalRef<jobjectArray> input_buffers =
|
||||
Java_MediaCodecVideoEncoder_getInputBuffers(
|
||||
jni, j_media_codec_video_encoder_);
|
||||
if (CheckException(jni)) {
|
||||
ALOGE << "Exception in get input buffers.";
|
||||
ProcessHWError(false /* reset_if_fallback_unavailable */);
|
||||
@ -552,7 +554,7 @@ int32_t MediaCodecVideoEncoder::InitEncodeInternal(int width,
|
||||
}
|
||||
|
||||
switch (Java_MediaCodecVideoEncoder_getColorFormat(
|
||||
jni, *j_media_codec_video_encoder_)) {
|
||||
jni, j_media_codec_video_encoder_)) {
|
||||
case COLOR_FormatYUV420Planar:
|
||||
encoder_fourcc_ = libyuv::FOURCC_YU12;
|
||||
break;
|
||||
@ -569,12 +571,12 @@ int32_t MediaCodecVideoEncoder::InitEncodeInternal(int width,
|
||||
|
||||
RTC_CHECK(input_buffers_.empty())
|
||||
<< "Unexpected double InitEncode without Release";
|
||||
input_buffers_ = JavaToNativeVector<ScopedGlobalRef<jobject>>(
|
||||
jni, input_buffers, [](JNIEnv* env, jobject o) {
|
||||
return ScopedGlobalRef<jobject>(env, o);
|
||||
input_buffers_ = JavaToNativeVector<ScopedJavaGlobalRef<jobject>>(
|
||||
jni, input_buffers, [](JNIEnv* env, const JavaRef<jobject>& o) {
|
||||
return ScopedJavaGlobalRef<jobject>(env, o);
|
||||
});
|
||||
for (const ScopedGlobalRef<jobject>& buffer : input_buffers_) {
|
||||
int64_t yuv_buffer_capacity = jni->GetDirectBufferCapacity(*buffer);
|
||||
for (const ScopedJavaGlobalRef<jobject>& buffer : input_buffers_) {
|
||||
int64_t yuv_buffer_capacity = jni->GetDirectBufferCapacity(buffer.obj());
|
||||
if (CheckException(jni)) {
|
||||
ALOGE << "Exception in get direct buffer capacity.";
|
||||
ProcessHWError(false /* reset_if_fallback_unavailable */);
|
||||
@ -689,7 +691,7 @@ int32_t MediaCodecVideoEncoder::Encode(
|
||||
int j_input_buffer_index = -1;
|
||||
if (!use_surface_) {
|
||||
j_input_buffer_index = Java_MediaCodecVideoEncoder_dequeueInputBuffer(
|
||||
jni, *j_media_codec_video_encoder_);
|
||||
jni, j_media_codec_video_encoder_);
|
||||
if (CheckException(jni)) {
|
||||
ALOGE << "Exception in dequeu input buffer.";
|
||||
return ProcessHWErrorOnEncode();
|
||||
@ -833,7 +835,7 @@ bool MediaCodecVideoEncoder::EncodeByteBuffer(JNIEnv* jni,
|
||||
return false;
|
||||
}
|
||||
bool encode_status = Java_MediaCodecVideoEncoder_encodeBuffer(
|
||||
jni, *j_media_codec_video_encoder_, key_frame, input_buffer_index,
|
||||
jni, j_media_codec_video_encoder_, key_frame, input_buffer_index,
|
||||
yuv_size_, current_timestamp_us_);
|
||||
if (CheckException(jni)) {
|
||||
ALOGE << "Exception in encode buffer.";
|
||||
@ -851,9 +853,8 @@ bool MediaCodecVideoEncoder::FillInputBuffer(JNIEnv* jni,
|
||||
int stride_u,
|
||||
uint8_t const* buffer_v,
|
||||
int stride_v) {
|
||||
jobject j_input_buffer = *input_buffers_[input_buffer_index];
|
||||
uint8_t* yuv_buffer =
|
||||
reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(j_input_buffer));
|
||||
uint8_t* yuv_buffer = reinterpret_cast<uint8_t*>(
|
||||
jni->GetDirectBufferAddress(input_buffers_[input_buffer_index].obj()));
|
||||
if (CheckException(jni)) {
|
||||
ALOGE << "Exception in get direct buffer address.";
|
||||
ProcessHWError(true /* reset_if_fallback_unavailable */);
|
||||
@ -877,10 +878,9 @@ bool MediaCodecVideoEncoder::EncodeTexture(JNIEnv* jni,
|
||||
static_cast<AndroidTextureBuffer*>(frame.video_frame_buffer().get())
|
||||
->native_handle_impl();
|
||||
|
||||
jfloatArray sampling_matrix = handle.sampling_matrix.ToJava(jni);
|
||||
bool encode_status = Java_MediaCodecVideoEncoder_encodeTexture(
|
||||
jni, *j_media_codec_video_encoder_, key_frame, handle.oes_texture_id,
|
||||
sampling_matrix, current_timestamp_us_);
|
||||
jni, j_media_codec_video_encoder_, key_frame, handle.oes_texture_id,
|
||||
handle.sampling_matrix.ToJava(jni), current_timestamp_us_);
|
||||
if (CheckException(jni)) {
|
||||
ALOGE << "Exception in encode texture.";
|
||||
ProcessHWError(true /* reset_if_fallback_unavailable */);
|
||||
@ -891,10 +891,10 @@ bool MediaCodecVideoEncoder::EncodeTexture(JNIEnv* jni,
|
||||
|
||||
bool MediaCodecVideoEncoder::EncodeJavaFrame(JNIEnv* jni,
|
||||
bool key_frame,
|
||||
jobject frame,
|
||||
const JavaRef<jobject>& frame,
|
||||
int input_buffer_index) {
|
||||
bool encode_status = Java_MediaCodecVideoEncoder_encodeFrame(
|
||||
jni, *j_media_codec_video_encoder_, jlongFromPointer(this), key_frame,
|
||||
jni, j_media_codec_video_encoder_, jlongFromPointer(this), key_frame,
|
||||
frame, input_buffer_index);
|
||||
if (CheckException(jni)) {
|
||||
ALOGE << "Exception in encode frame.";
|
||||
@ -926,7 +926,7 @@ int32_t MediaCodecVideoEncoder::Release() {
|
||||
weak_factory_.reset(nullptr);
|
||||
ScopedLocalRefFrame local_ref_frame(jni);
|
||||
input_buffers_.clear();
|
||||
Java_MediaCodecVideoEncoder_release(jni, *j_media_codec_video_encoder_);
|
||||
Java_MediaCodecVideoEncoder_release(jni, j_media_codec_video_encoder_);
|
||||
if (CheckException(jni)) {
|
||||
ALOGE << "Exception in release.";
|
||||
ProcessHWError(false /* reset_if_fallback_unavailable */);
|
||||
@ -966,8 +966,7 @@ int32_t MediaCodecVideoEncoder::SetRateAllocation(
|
||||
last_set_fps_ = frame_rate;
|
||||
}
|
||||
bool ret = Java_MediaCodecVideoEncoder_setRates(
|
||||
jni, *j_media_codec_video_encoder_, last_set_bitrate_kbps_,
|
||||
last_set_fps_);
|
||||
jni, j_media_codec_video_encoder_, last_set_bitrate_kbps_, last_set_fps_);
|
||||
if (CheckException(jni) || !ret) {
|
||||
ProcessHWError(true /* reset_if_fallback_unavailable */);
|
||||
return sw_fallback_required_ ? WEBRTC_VIDEO_CODEC_OK
|
||||
@ -980,9 +979,9 @@ bool MediaCodecVideoEncoder::DeliverPendingOutputs(JNIEnv* jni) {
|
||||
RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_);
|
||||
|
||||
while (true) {
|
||||
jobject j_output_buffer_info =
|
||||
ScopedJavaLocalRef<jobject> j_output_buffer_info =
|
||||
Java_MediaCodecVideoEncoder_dequeueOutputBuffer(
|
||||
jni, *j_media_codec_video_encoder_);
|
||||
jni, j_media_codec_video_encoder_);
|
||||
if (CheckException(jni)) {
|
||||
ALOGE << "Exception in set dequeue output buffer.";
|
||||
ProcessHWError(true /* reset_if_fallback_unavailable */);
|
||||
@ -1000,7 +999,7 @@ bool MediaCodecVideoEncoder::DeliverPendingOutputs(JNIEnv* jni) {
|
||||
}
|
||||
|
||||
// Get key and config frame flags.
|
||||
jobject j_output_buffer =
|
||||
ScopedJavaLocalRef<jobject> j_output_buffer =
|
||||
Java_OutputBufferInfo_getBuffer(jni, j_output_buffer_info);
|
||||
bool key_frame =
|
||||
Java_OutputBufferInfo_isKeyFrame(jni, j_output_buffer_info);
|
||||
@ -1022,9 +1021,9 @@ bool MediaCodecVideoEncoder::DeliverPendingOutputs(JNIEnv* jni) {
|
||||
}
|
||||
|
||||
// Extract payload.
|
||||
size_t payload_size = jni->GetDirectBufferCapacity(j_output_buffer);
|
||||
size_t payload_size = jni->GetDirectBufferCapacity(j_output_buffer.obj());
|
||||
uint8_t* payload = reinterpret_cast<uint8_t*>(
|
||||
jni->GetDirectBufferAddress(j_output_buffer));
|
||||
jni->GetDirectBufferAddress(j_output_buffer.obj()));
|
||||
if (CheckException(jni)) {
|
||||
ALOGE << "Exception in get direct buffer address.";
|
||||
ProcessHWError(true /* reset_if_fallback_unavailable */);
|
||||
@ -1140,7 +1139,7 @@ bool MediaCodecVideoEncoder::DeliverPendingOutputs(JNIEnv* jni) {
|
||||
|
||||
// Return output buffer back to the encoder.
|
||||
bool success = Java_MediaCodecVideoEncoder_releaseOutputBuffer(
|
||||
jni, *j_media_codec_video_encoder_, output_buffer_index);
|
||||
jni, j_media_codec_video_encoder_, output_buffer_index);
|
||||
if (CheckException(jni) || !success) {
|
||||
ProcessHWError(true /* reset_if_fallback_unavailable */);
|
||||
return false;
|
||||
@ -1345,24 +1344,23 @@ void MediaCodecVideoEncoderFactory::DestroyVideoEncoder(VideoEncoder* encoder) {
|
||||
delete encoder;
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
MediaCodecVideoEncoder_fillInputBufferNative,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong native_encoder,
|
||||
jint input_buffer,
|
||||
jobject j_buffer_y,
|
||||
jint stride_y,
|
||||
jobject j_buffer_u,
|
||||
jint stride_u,
|
||||
jobject j_buffer_v,
|
||||
jint stride_v) {
|
||||
static void JNI_MediaCodecVideoEncoder_FillInputBuffer(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong native_encoder,
|
||||
jint input_buffer,
|
||||
const JavaParamRef<jobject>& j_buffer_y,
|
||||
jint stride_y,
|
||||
const JavaParamRef<jobject>& j_buffer_u,
|
||||
jint stride_u,
|
||||
const JavaParamRef<jobject>& j_buffer_v,
|
||||
jint stride_v) {
|
||||
uint8_t* buffer_y =
|
||||
static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_buffer_y));
|
||||
static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_buffer_y.obj()));
|
||||
uint8_t* buffer_u =
|
||||
static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_buffer_u));
|
||||
static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_buffer_u.obj()));
|
||||
uint8_t* buffer_v =
|
||||
static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_buffer_v));
|
||||
static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_buffer_v.obj()));
|
||||
|
||||
RTC_DCHECK(buffer_y) << "GetDirectBufferAddress returned null. Ensure that "
|
||||
"getDataY returns a direct ByteBuffer.";
|
||||
|
||||
@ -20,32 +20,29 @@
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void, Metrics_enableNative, JNIEnv* jni, jclass) {
|
||||
static void JNI_Metrics_Enable(JNIEnv* jni, const JavaParamRef<jclass>&) {
|
||||
metrics::Enable();
|
||||
}
|
||||
|
||||
// Gets and clears native histograms.
|
||||
JNI_FUNCTION_DECLARATION(jobject,
|
||||
Metrics_getAndResetNative,
|
||||
JNIEnv* jni,
|
||||
jclass) {
|
||||
jobject j_metrics = Java_Metrics_Constructor(jni);
|
||||
static ScopedJavaLocalRef<jobject> JNI_Metrics_GetAndReset(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>& jcaller) {
|
||||
ScopedJavaLocalRef<jobject> j_metrics = Java_Metrics_Constructor(jni);
|
||||
|
||||
std::map<std::string, std::unique_ptr<metrics::SampleInfo>> histograms;
|
||||
metrics::GetAndReset(&histograms);
|
||||
for (const auto& kv : histograms) {
|
||||
// Create and add samples to |HistogramInfo|.
|
||||
jobject j_info = Java_HistogramInfo_Constructor(
|
||||
ScopedJavaLocalRef<jobject> j_info = Java_HistogramInfo_Constructor(
|
||||
jni, kv.second->min, kv.second->max,
|
||||
static_cast<int>(kv.second->bucket_count));
|
||||
for (const auto& sample : kv.second->samples) {
|
||||
Java_HistogramInfo_addSample(jni, j_info, sample.first, sample.second);
|
||||
}
|
||||
// Add |HistogramInfo| to |Metrics|.
|
||||
jstring j_name = jni->NewStringUTF(kv.first.c_str());
|
||||
ScopedJavaLocalRef<jstring> j_name = NativeToJavaString(jni, kv.first);
|
||||
Java_Metrics_add(jni, j_metrics, j_name, j_info);
|
||||
jni->DeleteLocalRef(j_name);
|
||||
jni->DeleteLocalRef(j_info);
|
||||
}
|
||||
CHECK_EXCEPTION(jni);
|
||||
return j_metrics;
|
||||
|
||||
@ -14,6 +14,8 @@
|
||||
|
||||
#include "api/videosourceproxy.h"
|
||||
#include "rtc_base/logging.h"
|
||||
#include "sdk/android/generated_video_jni/jni/AndroidVideoTrackSourceObserver_jni.h"
|
||||
#include "sdk/android/generated_video_jni/jni/VideoSource_jni.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
@ -38,7 +40,7 @@ AndroidVideoTrackSource* AndroidVideoTrackSourceFromJavaProxy(jlong j_proxy) {
|
||||
AndroidVideoTrackSource::AndroidVideoTrackSource(
|
||||
rtc::Thread* signaling_thread,
|
||||
JNIEnv* jni,
|
||||
jobject j_surface_texture_helper,
|
||||
const JavaRef<jobject>& j_surface_texture_helper,
|
||||
bool is_screencast)
|
||||
: AdaptedVideoTrackSource(kRequiredResolutionAlignment),
|
||||
signaling_thread_(signaling_thread),
|
||||
@ -164,12 +166,13 @@ void AndroidVideoTrackSource::OnTextureFrameCaptured(
|
||||
rotation, translated_camera_time_us));
|
||||
}
|
||||
|
||||
void AndroidVideoTrackSource::OnFrameCaptured(JNIEnv* jni,
|
||||
int width,
|
||||
int height,
|
||||
int64_t timestamp_ns,
|
||||
VideoRotation rotation,
|
||||
jobject j_video_frame_buffer) {
|
||||
void AndroidVideoTrackSource::OnFrameCaptured(
|
||||
JNIEnv* jni,
|
||||
int width,
|
||||
int height,
|
||||
int64_t timestamp_ns,
|
||||
VideoRotation rotation,
|
||||
const JavaRef<jobject>& j_video_frame_buffer) {
|
||||
RTC_DCHECK(camera_thread_checker_.CalledOnValidThread());
|
||||
|
||||
int64_t camera_time_us = timestamp_ns / rtc::kNumNanosecsPerMicrosec;
|
||||
@ -210,13 +213,11 @@ void AndroidVideoTrackSource::OnOutputFormatRequest(int width,
|
||||
video_adapter()->OnOutputFormatRequest(format);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(
|
||||
void,
|
||||
AndroidVideoTrackSourceObserver_nativeOnByteBufferFrameCaptured,
|
||||
static void JNI_AndroidVideoTrackSourceObserver_OnByteBufferFrameCaptured(
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_source,
|
||||
jbyteArray j_frame,
|
||||
const JavaParamRef<jbyteArray>& j_frame,
|
||||
jint length,
|
||||
jint width,
|
||||
jint height,
|
||||
@ -224,22 +225,20 @@ JNI_FUNCTION_DECLARATION(
|
||||
jlong timestamp) {
|
||||
AndroidVideoTrackSource* source =
|
||||
AndroidVideoTrackSourceFromJavaProxy(j_source);
|
||||
jbyte* bytes = jni->GetByteArrayElements(j_frame, nullptr);
|
||||
jbyte* bytes = jni->GetByteArrayElements(j_frame.obj(), nullptr);
|
||||
source->OnByteBufferFrameCaptured(bytes, length, width, height,
|
||||
jintToVideoRotation(rotation), timestamp);
|
||||
jni->ReleaseByteArrayElements(j_frame, bytes, JNI_ABORT);
|
||||
jni->ReleaseByteArrayElements(j_frame.obj(), bytes, JNI_ABORT);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(
|
||||
void,
|
||||
AndroidVideoTrackSourceObserver_nativeOnTextureFrameCaptured,
|
||||
static void JNI_AndroidVideoTrackSourceObserver_OnTextureFrameCaptured(
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_source,
|
||||
jint j_width,
|
||||
jint j_height,
|
||||
jint j_oes_texture_id,
|
||||
jfloatArray j_transform_matrix,
|
||||
const JavaParamRef<jfloatArray>& j_transform_matrix,
|
||||
jint j_rotation,
|
||||
jlong j_timestamp) {
|
||||
AndroidVideoTrackSource* source =
|
||||
@ -249,16 +248,15 @@ JNI_FUNCTION_DECLARATION(
|
||||
NativeHandleImpl(jni, j_oes_texture_id, j_transform_matrix));
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
AndroidVideoTrackSourceObserver_nativeOnFrameCaptured,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_source,
|
||||
jint j_width,
|
||||
jint j_height,
|
||||
jint j_rotation,
|
||||
jlong j_timestamp_ns,
|
||||
jobject j_video_frame_buffer) {
|
||||
static void JNI_AndroidVideoTrackSourceObserver_OnFrameCaptured(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_source,
|
||||
jint j_width,
|
||||
jint j_height,
|
||||
jint j_rotation,
|
||||
jlong j_timestamp_ns,
|
||||
const JavaParamRef<jobject>& j_video_frame_buffer) {
|
||||
AndroidVideoTrackSource* source =
|
||||
AndroidVideoTrackSourceFromJavaProxy(j_source);
|
||||
source->OnFrameCaptured(jni, j_width, j_height, j_timestamp_ns,
|
||||
@ -266,12 +264,11 @@ JNI_FUNCTION_DECLARATION(void,
|
||||
j_video_frame_buffer);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
AndroidVideoTrackSourceObserver_nativeCapturerStarted,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_source,
|
||||
jboolean j_success) {
|
||||
static void JNI_AndroidVideoTrackSourceObserver_CapturerStarted(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_source,
|
||||
jboolean j_success) {
|
||||
RTC_LOG(LS_INFO) << "AndroidVideoTrackSourceObserve_nativeCapturerStarted";
|
||||
AndroidVideoTrackSource* source =
|
||||
AndroidVideoTrackSourceFromJavaProxy(j_source);
|
||||
@ -279,25 +276,22 @@ JNI_FUNCTION_DECLARATION(void,
|
||||
: AndroidVideoTrackSource::SourceState::kEnded);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
AndroidVideoTrackSourceObserver_nativeCapturerStopped,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_source) {
|
||||
static void JNI_AndroidVideoTrackSourceObserver_CapturerStopped(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_source) {
|
||||
RTC_LOG(LS_INFO) << "AndroidVideoTrackSourceObserve_nativeCapturerStopped";
|
||||
AndroidVideoTrackSource* source =
|
||||
AndroidVideoTrackSourceFromJavaProxy(j_source);
|
||||
source->SetState(AndroidVideoTrackSource::SourceState::kEnded);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
VideoSource_nativeAdaptOutputFormat,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_source,
|
||||
jint j_width,
|
||||
jint j_height,
|
||||
jint j_fps) {
|
||||
static void JNI_VideoSource_AdaptOutputFormat(JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_source,
|
||||
jint j_width,
|
||||
jint j_height,
|
||||
jint j_fps) {
|
||||
RTC_LOG(LS_INFO) << "VideoSource_nativeAdaptOutputFormat";
|
||||
AndroidVideoTrackSource* source =
|
||||
AndroidVideoTrackSourceFromJavaProxy(j_source);
|
||||
|
||||
@ -30,7 +30,7 @@ class AndroidVideoTrackSource : public rtc::AdaptedVideoTrackSource {
|
||||
public:
|
||||
AndroidVideoTrackSource(rtc::Thread* signaling_thread,
|
||||
JNIEnv* jni,
|
||||
jobject j_surface_texture_helper,
|
||||
const JavaRef<jobject>& j_surface_texture_helper,
|
||||
bool is_screencast = false);
|
||||
|
||||
bool is_screencast() const override { return is_screencast_; }
|
||||
@ -65,7 +65,7 @@ class AndroidVideoTrackSource : public rtc::AdaptedVideoTrackSource {
|
||||
int height,
|
||||
int64_t timestamp_ns,
|
||||
VideoRotation rotation,
|
||||
jobject j_video_frame_buffer);
|
||||
const JavaRef<jobject>& j_video_frame_buffer);
|
||||
|
||||
void OnOutputFormatRequest(int width, int height, int fps);
|
||||
|
||||
|
||||
@ -15,6 +15,8 @@
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
#include "sdk/android/generated_base_jni/jni/WebRtcClassLoader_jni.h"
|
||||
#include "sdk/android/src/jni/jni_helpers.h"
|
||||
#include "sdk/android/src/jni/scoped_java_ref.h"
|
||||
|
||||
// Abort the process if |jni| has a Java exception pending. This macros uses the
|
||||
// comma operator to execute ExceptionDescribe and ExceptionClear ignoring their
|
||||
@ -30,7 +32,8 @@ namespace {
|
||||
|
||||
class ClassLoader {
|
||||
public:
|
||||
explicit ClassLoader(JNIEnv* env) {
|
||||
explicit ClassLoader(JNIEnv* env)
|
||||
: class_loader_(Java_WebRtcClassLoader_getClassLoader(env)) {
|
||||
class_loader_class_ = reinterpret_cast<jclass>(
|
||||
env->NewGlobalRef(env->FindClass("java/lang/ClassLoader")));
|
||||
CHECK_EXCEPTION(env);
|
||||
@ -38,27 +41,24 @@ class ClassLoader {
|
||||
env->GetMethodID(class_loader_class_, "loadClass",
|
||||
"(Ljava/lang/String;)Ljava/lang/Class;");
|
||||
CHECK_EXCEPTION(env);
|
||||
class_loader_ =
|
||||
env->NewGlobalRef(Java_WebRtcClassLoader_getClassLoader(env));
|
||||
CHECK_EXCEPTION(env);
|
||||
}
|
||||
|
||||
jclass FindClass(JNIEnv* env, const char* c_name) {
|
||||
ScopedJavaLocalRef<jclass> FindClass(JNIEnv* env, const char* c_name) {
|
||||
// ClassLoader.loadClass expects a classname with components separated by
|
||||
// dots instead of the slashes that JNIEnv::FindClass expects.
|
||||
std::string name(c_name);
|
||||
std::replace(name.begin(), name.end(), '/', '.');
|
||||
jstring jstr = env->NewStringUTF(name.c_str());
|
||||
const jclass clazz = static_cast<jclass>(
|
||||
env->CallObjectMethod(class_loader_, load_class_method_, jstr));
|
||||
ScopedJavaLocalRef<jstring> j_name = NativeToJavaString(env, name);
|
||||
const jclass clazz = static_cast<jclass>(env->CallObjectMethod(
|
||||
class_loader_.obj(), load_class_method_, j_name.obj()));
|
||||
CHECK_EXCEPTION(env);
|
||||
return clazz;
|
||||
return ScopedJavaLocalRef<jclass>(env, clazz);
|
||||
}
|
||||
|
||||
private:
|
||||
ScopedJavaGlobalRef<jobject> class_loader_;
|
||||
jclass class_loader_class_;
|
||||
jmethodID load_class_method_;
|
||||
jobject class_loader_;
|
||||
};
|
||||
|
||||
static ClassLoader* g_class_loader = nullptr;
|
||||
@ -70,11 +70,12 @@ void InitClassLoader(JNIEnv* env) {
|
||||
g_class_loader = new ClassLoader(env);
|
||||
}
|
||||
|
||||
jclass GetClass(JNIEnv* env, const char* name) {
|
||||
ScopedJavaLocalRef<jclass> GetClass(JNIEnv* env, const char* name) {
|
||||
// The class loader will be null in the JNI code called from the ClassLoader
|
||||
// ctor when we are bootstrapping ourself.
|
||||
return (g_class_loader == nullptr) ? env->FindClass(name)
|
||||
: g_class_loader->FindClass(env, name);
|
||||
return (g_class_loader == nullptr)
|
||||
? ScopedJavaLocalRef<jclass>(env, env->FindClass(name))
|
||||
: g_class_loader->FindClass(env, name);
|
||||
}
|
||||
|
||||
} // namespace jni
|
||||
|
||||
@ -19,6 +19,8 @@
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include "sdk/android/src/jni/scoped_java_ref.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
@ -32,7 +34,7 @@ void InitClassLoader(JNIEnv* env);
|
||||
// example, the fully-qualified class name for the java.lang.String class is:
|
||||
// "java/lang/String". This function will be used from the JNI generated code
|
||||
// and should rarely be used manually.
|
||||
jclass GetClass(JNIEnv* env, const char* name);
|
||||
ScopedJavaLocalRef<jclass> GetClass(JNIEnv* env, const char* name);
|
||||
|
||||
} // namespace jni
|
||||
} // namespace webrtc
|
||||
|
||||
@ -18,22 +18,28 @@
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
jobject NativeToJavaFrameType(JNIEnv* env, FrameType frame_type) {
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaFrameType(JNIEnv* env,
|
||||
FrameType frame_type) {
|
||||
return Java_FrameType_fromNativeIndex(env, frame_type);
|
||||
}
|
||||
|
||||
jobject NativeToJavaEncodedImage(JNIEnv* jni, const EncodedImage& image) {
|
||||
jobject buffer = jni->NewDirectByteBuffer(image._buffer, image._length);
|
||||
jobject frame_type = NativeToJavaFrameType(jni, image._frameType);
|
||||
jobject qp =
|
||||
(image.qp_ == -1) ? nullptr : NativeToJavaInteger(jni, image.qp_);
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaEncodedImage(
|
||||
JNIEnv* jni,
|
||||
const EncodedImage& image) {
|
||||
ScopedJavaLocalRef<jobject> buffer =
|
||||
NewDirectByteBuffer(jni, image._buffer, image._length);
|
||||
ScopedJavaLocalRef<jobject> frame_type =
|
||||
NativeToJavaFrameType(jni, image._frameType);
|
||||
ScopedJavaLocalRef<jobject> qp;
|
||||
if (image.qp_ != -1)
|
||||
qp = NativeToJavaInteger(jni, image.qp_);
|
||||
return Java_EncodedImage_Constructor(
|
||||
jni, buffer, image._encodedWidth, image._encodedHeight,
|
||||
image.capture_time_ms_ * rtc::kNumNanosecsPerMillisec, frame_type,
|
||||
static_cast<jint>(image.rotation_), image._completeFrame, qp);
|
||||
}
|
||||
|
||||
jobjectArray NativeToJavaFrameTypeArray(
|
||||
ScopedJavaLocalRef<jobjectArray> NativeToJavaFrameTypeArray(
|
||||
JNIEnv* env,
|
||||
const std::vector<FrameType>& frame_types) {
|
||||
return NativeToJavaObjectArray(
|
||||
|
||||
@ -12,18 +12,21 @@
|
||||
#define SDK_ANDROID_SRC_JNI_ENCODEDIMAGE_H_
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include "common_types.h" // NOLINT(build/include)
|
||||
|
||||
#include "sdk/android/src/jni/scoped_java_ref.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class EncodedImage;
|
||||
|
||||
namespace jni {
|
||||
|
||||
jobject NativeToJavaFrameType(JNIEnv* env, FrameType frame_type);
|
||||
jobject NativeToJavaEncodedImage(JNIEnv* jni, const EncodedImage& image);
|
||||
jobjectArray NativeToJavaFrameTypeArray(
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaFrameType(JNIEnv* env,
|
||||
FrameType frame_type);
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaEncodedImage(JNIEnv* jni,
|
||||
const EncodedImage& image);
|
||||
ScopedJavaLocalRef<jobjectArray> NativeToJavaFrameTypeArray(
|
||||
JNIEnv* env,
|
||||
const std::vector<FrameType>& frame_types);
|
||||
|
||||
|
||||
@ -10,20 +10,18 @@
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include "media/base/codec.h"
|
||||
#include "media/base/h264_profile_level_id.h"
|
||||
#include "media/base/mediaconstants.h"
|
||||
#include "sdk/android/generated_video_jni/jni/HardwareVideoEncoderFactory_jni.h"
|
||||
#include "sdk/android/src/jni/jni_helpers.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jboolean,
|
||||
HardwareVideoEncoderFactory_isSameH264Profile,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jobject params1,
|
||||
jobject params2) {
|
||||
static jboolean JNI_HardwareVideoEncoderFactory_IsSameH264Profile(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
const JavaParamRef<jobject>& params1,
|
||||
const JavaParamRef<jobject>& params2) {
|
||||
return H264::IsSameH264Profile(JavaToStdMapStrings(jni, params1),
|
||||
JavaToStdMapStrings(jni, params2));
|
||||
}
|
||||
|
||||
@ -9,45 +9,39 @@
|
||||
*/
|
||||
|
||||
#include "rtc_base/refcount.h"
|
||||
#include "sdk/android/generated_base_jni/jni/JniCommon_jni.h"
|
||||
#include "sdk/android/src/jni/jni_helpers.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
JniCommon_nativeAddRef,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_native_ref_counted_pointer) {
|
||||
static void JNI_JniCommon_AddRef(JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_native_ref_counted_pointer) {
|
||||
reinterpret_cast<rtc::RefCountInterface*>(j_native_ref_counted_pointer)
|
||||
->AddRef();
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
JniCommon_nativeReleaseRef,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_native_ref_counted_pointer) {
|
||||
static void JNI_JniCommon_ReleaseRef(JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_native_ref_counted_pointer) {
|
||||
reinterpret_cast<rtc::RefCountInterface*>(j_native_ref_counted_pointer)
|
||||
->Release();
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jobject,
|
||||
JniCommon_allocateNativeByteBuffer,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jint size) {
|
||||
static ScopedJavaLocalRef<jobject> JNI_JniCommon_AllocateByteBuffer(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jint size) {
|
||||
void* new_data = ::operator new(size);
|
||||
jobject byte_buffer = jni->NewDirectByteBuffer(new_data, size);
|
||||
return byte_buffer;
|
||||
return NewDirectByteBuffer(jni, new_data, size);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
JniCommon_freeNativeByteBuffer,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jobject byte_buffer) {
|
||||
void* data = jni->GetDirectBufferAddress(byte_buffer);
|
||||
static void JNI_JniCommon_FreeByteBuffer(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
const JavaParamRef<jobject>& byte_buffer) {
|
||||
void* data = jni->GetDirectBufferAddress(byte_buffer.obj());
|
||||
::operator delete(data);
|
||||
}
|
||||
|
||||
|
||||
@ -28,22 +28,21 @@ jclass LazyGetClass(JNIEnv* env,
|
||||
rtc::AtomicOps::AcquireLoadPtr(atomic_class_id);
|
||||
if (value)
|
||||
return reinterpret_cast<jclass>(value);
|
||||
jclass clazz = static_cast<jclass>(
|
||||
env->NewGlobalRef(webrtc::jni::GetClass(env, class_name)));
|
||||
RTC_CHECK(clazz) << class_name;
|
||||
webrtc::jni::ScopedJavaGlobalRef<jclass> clazz(
|
||||
webrtc::jni::GetClass(env, class_name));
|
||||
RTC_CHECK(!clazz.is_null()) << class_name;
|
||||
base::subtle::AtomicWord null_aw = nullptr;
|
||||
base::subtle::AtomicWord cas_result = rtc::AtomicOps::CompareAndSwapPtr(
|
||||
atomic_class_id, null_aw,
|
||||
reinterpret_cast<base::subtle::AtomicWord>(clazz));
|
||||
reinterpret_cast<base::subtle::AtomicWord>(clazz.obj()));
|
||||
if (cas_result == null_aw) {
|
||||
// We sucessfully stored |clazz| in |atomic_class_id|, so we are
|
||||
// intentionally leaking the global ref since it's now stored there.
|
||||
return clazz;
|
||||
return clazz.Release();
|
||||
} else {
|
||||
// Some other thread came before us and stored a global pointer in
|
||||
// |atomic_class_id|. Relase our global ref and return the ref from the
|
||||
// other thread.
|
||||
env->DeleteGlobalRef(clazz);
|
||||
return reinterpret_cast<jclass>(cas_result);
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
#include <jni.h>
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
#include "sdk/android/src/jni/scoped_java_ref.h"
|
||||
|
||||
#define CHECK_CLAZZ(env, jcaller, clazz, ...) RTC_DCHECK(clazz);
|
||||
#define CHECK_NATIVE_PTR(env, jcaller, native_ptr, method_name, ...) \
|
||||
@ -56,31 +57,9 @@ typedef void* AtomicWord;
|
||||
|
||||
namespace android {
|
||||
|
||||
// Implement JavaRef and ScopedJavaLocalRef as a shallow wrapper on top of a
|
||||
// jobject/jclass, with no scoped destruction.
|
||||
// TODO(magjed): Start using Chromium's scoped Java refs.
|
||||
template <typename T>
|
||||
class JavaRef {
|
||||
public:
|
||||
JavaRef() {}
|
||||
JavaRef(JNIEnv* env, T obj) : obj_(obj) {}
|
||||
T obj() const { return obj_; }
|
||||
|
||||
// Implicit on purpose.
|
||||
JavaRef(const T& obj) : obj_(obj) {} // NOLINT(runtime/explicit)
|
||||
operator T() const { return obj_; }
|
||||
|
||||
private:
|
||||
T obj_;
|
||||
};
|
||||
|
||||
// TODO(magjed): This looks weird, but it is safe. We don't use DeleteLocalRef
|
||||
// in WebRTC, we use ScopedLocalRefFrame instead. We should probably switch to
|
||||
// using DeleteLocalRef though.
|
||||
template <typename T>
|
||||
using ScopedJavaLocalRef = JavaRef<T>;
|
||||
template <typename T>
|
||||
using JavaParamRef = JavaRef<T>;
|
||||
using webrtc::jni::JavaRef;
|
||||
using webrtc::jni::ScopedJavaLocalRef;
|
||||
using webrtc::jni::JavaParamRef;
|
||||
|
||||
// This function will initialize |atomic_class_id| to contain a global ref to
|
||||
// the given class, and will return that ref on subsequent calls. The caller is
|
||||
|
||||
@ -150,87 +150,108 @@ jlong jlongFromPointer(void* ptr) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool IsNull(JNIEnv* jni, jobject obj) {
|
||||
return jni->IsSameObject(obj, nullptr);
|
||||
bool IsNull(JNIEnv* jni, const JavaRef<jobject>& obj) {
|
||||
return jni->IsSameObject(obj.obj(), nullptr);
|
||||
}
|
||||
|
||||
ScopedJavaLocalRef<jobject> NewDirectByteBuffer(JNIEnv* env,
|
||||
void* address,
|
||||
jlong capacity) {
|
||||
ScopedJavaLocalRef<jobject> buffer(
|
||||
env, env->NewDirectByteBuffer(address, capacity));
|
||||
CHECK_EXCEPTION(env) << "error NewDirectByteBuffer";
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// Given a jstring, reinterprets it to a new native string.
|
||||
std::string JavaToStdString(JNIEnv* jni, const jstring& j_string) {
|
||||
const jbyteArray j_byte_array = Java_JniHelper_getStringBytes(jni, j_string);
|
||||
std::string JavaToStdString(JNIEnv* jni, const JavaRef<jstring>& j_string) {
|
||||
const ScopedJavaLocalRef<jbyteArray> j_byte_array =
|
||||
Java_JniHelper_getStringBytes(jni, j_string);
|
||||
|
||||
const size_t len = jni->GetArrayLength(j_byte_array);
|
||||
const size_t len = jni->GetArrayLength(j_byte_array.obj());
|
||||
CHECK_EXCEPTION(jni) << "error during GetArrayLength";
|
||||
std::string str(len, '\0');
|
||||
jni->GetByteArrayRegion(j_byte_array, 0, len,
|
||||
jni->GetByteArrayRegion(j_byte_array.obj(), 0, len,
|
||||
reinterpret_cast<jbyte*>(&str[0]));
|
||||
CHECK_EXCEPTION(jni) << "error during GetByteArrayRegion";
|
||||
return str;
|
||||
}
|
||||
|
||||
// Given a list of jstrings, reinterprets it to a new vector of native strings.
|
||||
std::vector<std::string> JavaToStdVectorStrings(JNIEnv* jni, jobject list) {
|
||||
std::vector<std::string> JavaToStdVectorStrings(JNIEnv* jni,
|
||||
const JavaRef<jobject>& list) {
|
||||
std::vector<std::string> converted_list;
|
||||
if (list != nullptr) {
|
||||
for (jobject str : Iterable(jni, list)) {
|
||||
converted_list.push_back(
|
||||
JavaToStdString(jni, reinterpret_cast<jstring>(str)));
|
||||
if (!list.is_null()) {
|
||||
for (const JavaRef<jobject>& str : Iterable(jni, list)) {
|
||||
converted_list.push_back(JavaToStdString(
|
||||
jni, JavaParamRef<jstring>(static_cast<jstring>(str.obj()))));
|
||||
}
|
||||
}
|
||||
return converted_list;
|
||||
}
|
||||
|
||||
rtc::Optional<int32_t> JavaToNativeOptionalInt(JNIEnv* jni, jobject integer) {
|
||||
rtc::Optional<int32_t> JavaToNativeOptionalInt(
|
||||
JNIEnv* jni,
|
||||
const JavaRef<jobject>& integer) {
|
||||
if (IsNull(jni, integer))
|
||||
return rtc::nullopt;
|
||||
return JNI_Integer::Java_Integer_intValue(jni, integer);
|
||||
}
|
||||
|
||||
rtc::Optional<bool> JavaToNativeOptionalBool(JNIEnv* jni, jobject boolean) {
|
||||
rtc::Optional<bool> JavaToNativeOptionalBool(JNIEnv* jni,
|
||||
const JavaRef<jobject>& boolean) {
|
||||
if (IsNull(jni, boolean))
|
||||
return rtc::nullopt;
|
||||
return JNI_Boolean::Java_Boolean_booleanValue(jni, boolean);
|
||||
}
|
||||
|
||||
int64_t JavaToNativeLong(JNIEnv* env, jobject j_long) {
|
||||
int64_t JavaToNativeLong(JNIEnv* env, const JavaRef<jobject>& j_long) {
|
||||
return JNI_Long::Java_Long_longValue(env, j_long);
|
||||
}
|
||||
|
||||
jobject NativeToJavaBoolean(JNIEnv* env, bool b) {
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaBoolean(JNIEnv* env, bool b) {
|
||||
return JNI_Boolean::Java_Boolean_ConstructorJLB_Z(env, b);
|
||||
}
|
||||
|
||||
jobject NativeToJavaInteger(JNIEnv* jni, int32_t i) {
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaInteger(JNIEnv* jni, int32_t i) {
|
||||
return JNI_Integer::Java_Integer_ConstructorJLI_I(jni, i);
|
||||
}
|
||||
|
||||
jobject NativeToJavaLong(JNIEnv* env, int64_t u) {
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaLong(JNIEnv* env, int64_t u) {
|
||||
return JNI_Long::Java_Long_ConstructorJLLO_J(env, u);
|
||||
}
|
||||
|
||||
jobject NativeToJavaDouble(JNIEnv* env, double d) {
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaDouble(JNIEnv* env, double d) {
|
||||
return JNI_Double::Java_Double_ConstructorJLD_D(env, d);
|
||||
}
|
||||
|
||||
jstring NativeToJavaString(JNIEnv* jni, const std::string& native) {
|
||||
jstring jstr = jni->NewStringUTF(native.c_str());
|
||||
CHECK_EXCEPTION(jni) << "error during NewStringUTF";
|
||||
return jstr;
|
||||
ScopedJavaLocalRef<jstring> NativeToJavaString(JNIEnv* env, const char* str) {
|
||||
jstring j_str = env->NewStringUTF(str);
|
||||
CHECK_EXCEPTION(env) << "error during NewStringUTF";
|
||||
return ScopedJavaLocalRef<jstring>(env, j_str);
|
||||
}
|
||||
|
||||
jobject NativeToJavaInteger(JNIEnv* jni,
|
||||
const rtc::Optional<int32_t>& optional_int) {
|
||||
ScopedJavaLocalRef<jstring> NativeToJavaString(JNIEnv* jni,
|
||||
const std::string& str) {
|
||||
return NativeToJavaString(jni, str.c_str());
|
||||
}
|
||||
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaInteger(
|
||||
JNIEnv* jni,
|
||||
const rtc::Optional<int32_t>& optional_int) {
|
||||
return optional_int ? NativeToJavaInteger(jni, *optional_int) : nullptr;
|
||||
}
|
||||
|
||||
std::string GetJavaEnumName(JNIEnv* jni, jobject j_enum) {
|
||||
std::string GetJavaEnumName(JNIEnv* jni, const JavaRef<jobject>& j_enum) {
|
||||
return JavaToStdString(jni, JNI_Enum::Java_Enum_name(jni, j_enum));
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> JavaToStdMapStrings(JNIEnv* jni,
|
||||
jobject j_map) {
|
||||
jobject j_entry_set = JNI_Map::Java_Map_entrySet(jni, j_map);
|
||||
std::map<std::string, std::string> JavaToStdMapStrings(
|
||||
JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_map) {
|
||||
const JavaRef<jobject>& j_entry_set = JNI_Map::Java_Map_entrySet(jni, j_map);
|
||||
std::map<std::string, std::string> result;
|
||||
for (jobject j_entry : Iterable(jni, j_entry_set)) {
|
||||
for (const JavaRef<jobject>& j_entry : Iterable(jni, j_entry_set)) {
|
||||
result.insert(std::make_pair(
|
||||
JavaToStdString(jni, Java_JniHelper_getKey(jni, j_entry)),
|
||||
JavaToStdString(jni, Java_JniHelper_getValue(jni, j_entry))));
|
||||
@ -261,13 +282,19 @@ ScopedLocalRefFrame::~ScopedLocalRefFrame() {
|
||||
jni_->PopLocalFrame(nullptr);
|
||||
}
|
||||
|
||||
Iterable::Iterable(JNIEnv* jni, const JavaRef<jobject>& iterable)
|
||||
: jni_(jni), iterable_(jni, iterable) {}
|
||||
|
||||
Iterable::~Iterable() = default;
|
||||
|
||||
// Creates an iterator representing the end of any collection.
|
||||
Iterable::Iterator::Iterator() : iterator_(nullptr) {}
|
||||
Iterable::Iterator::Iterator() = default;
|
||||
|
||||
// Creates an iterator pointing to the beginning of the specified collection.
|
||||
Iterable::Iterator::Iterator(JNIEnv* jni, jobject iterable) : jni_(jni) {
|
||||
Iterable::Iterator::Iterator(JNIEnv* jni, const JavaRef<jobject>& iterable)
|
||||
: jni_(jni) {
|
||||
iterator_ = JNI_Iterable::Java_Iterable_iterator(jni, iterable);
|
||||
RTC_CHECK(iterator_);
|
||||
RTC_CHECK(!iterator_.is_null());
|
||||
// Start at the first element in the collection.
|
||||
++(*this);
|
||||
}
|
||||
@ -280,6 +307,8 @@ Iterable::Iterator::Iterator(Iterator&& other)
|
||||
value_(std::move(other.value_)),
|
||||
thread_checker_(std::move(other.thread_checker_)){};
|
||||
|
||||
Iterable::Iterator::~Iterator() = default;
|
||||
|
||||
// Advances the iterator one step.
|
||||
Iterable::Iterator& Iterable::Iterator::operator++() {
|
||||
RTC_CHECK(thread_checker_.CalledOnValidThread());
|
||||
@ -311,7 +340,7 @@ bool Iterable::Iterator::operator==(const Iterable::Iterator& other) {
|
||||
return AtEnd() == other.AtEnd();
|
||||
}
|
||||
|
||||
jobject Iterable::Iterator::operator*() {
|
||||
ScopedJavaLocalRef<jobject>& Iterable::Iterator::operator*() {
|
||||
RTC_CHECK(!AtEnd());
|
||||
return value_;
|
||||
}
|
||||
@ -321,56 +350,63 @@ bool Iterable::Iterator::AtEnd() const {
|
||||
return jni_ == nullptr || IsNull(jni_, iterator_);
|
||||
}
|
||||
|
||||
jobjectArray NativeToJavaIntegerArray(JNIEnv* env,
|
||||
const std::vector<int32_t>& container) {
|
||||
jobject (*convert_function)(JNIEnv*, int32_t) = &NativeToJavaInteger;
|
||||
ScopedJavaLocalRef<jobjectArray> NativeToJavaIntegerArray(
|
||||
JNIEnv* env,
|
||||
const std::vector<int32_t>& container) {
|
||||
ScopedJavaLocalRef<jobject> (*convert_function)(JNIEnv*, int32_t) =
|
||||
&NativeToJavaInteger;
|
||||
return NativeToJavaObjectArray(env, container, java_lang_Integer_clazz(env),
|
||||
convert_function);
|
||||
}
|
||||
|
||||
jobjectArray NativeToJavaBooleanArray(JNIEnv* env,
|
||||
const std::vector<bool>& container) {
|
||||
ScopedJavaLocalRef<jobjectArray> NativeToJavaBooleanArray(
|
||||
JNIEnv* env,
|
||||
const std::vector<bool>& container) {
|
||||
return NativeToJavaObjectArray(env, container, java_lang_Boolean_clazz(env),
|
||||
&NativeToJavaBoolean);
|
||||
}
|
||||
|
||||
jobjectArray NativeToJavaDoubleArray(JNIEnv* env,
|
||||
const std::vector<double>& container) {
|
||||
ScopedJavaLocalRef<jobjectArray> NativeToJavaDoubleArray(
|
||||
JNIEnv* env,
|
||||
const std::vector<double>& container) {
|
||||
return NativeToJavaObjectArray(env, container, java_lang_Double_clazz(env),
|
||||
&NativeToJavaDouble);
|
||||
}
|
||||
|
||||
jobjectArray NativeToJavaLongArray(JNIEnv* env,
|
||||
const std::vector<int64_t>& container) {
|
||||
ScopedJavaLocalRef<jobjectArray> NativeToJavaLongArray(
|
||||
JNIEnv* env,
|
||||
const std::vector<int64_t>& container) {
|
||||
return NativeToJavaObjectArray(env, container, java_lang_Long_clazz(env),
|
||||
&NativeToJavaLong);
|
||||
}
|
||||
|
||||
jobjectArray NativeToJavaStringArray(
|
||||
ScopedJavaLocalRef<jobjectArray> NativeToJavaStringArray(
|
||||
JNIEnv* env,
|
||||
const std::vector<std::string>& container) {
|
||||
ScopedJavaLocalRef<jstring> (*convert)(JNIEnv*, const std::string&) =
|
||||
&NativeToJavaString;
|
||||
return NativeToJavaObjectArray(
|
||||
env, container,
|
||||
static_cast<jclass>(Java_JniHelper_getStringClass(env).obj()),
|
||||
&NativeToJavaString);
|
||||
static_cast<jclass>(Java_JniHelper_getStringClass(env).obj()), convert);
|
||||
}
|
||||
|
||||
JavaMapBuilder::JavaMapBuilder(JNIEnv* env)
|
||||
: env_(env),
|
||||
j_map_(JNI_LinkedHashMap::Java_LinkedHashMap_ConstructorJULIHM(env)) {}
|
||||
|
||||
void JavaMapBuilder::put(jobject key, jobject value) {
|
||||
JNI_Map::Java_Map_put(env_, j_map_, key, value);
|
||||
}
|
||||
JavaMapBuilder::~JavaMapBuilder() = default;
|
||||
|
||||
jobject JavaMapBuilder::GetJavaMap() {
|
||||
return j_map_;
|
||||
void JavaMapBuilder::put(const JavaRef<jobject>& key,
|
||||
const JavaRef<jobject>& value) {
|
||||
JNI_Map::Java_Map_put(env_, j_map_, key, value);
|
||||
}
|
||||
|
||||
JavaListBuilder::JavaListBuilder(JNIEnv* env)
|
||||
: env_(env), j_list_(JNI_ArrayList::Java_ArrayList_ConstructorJUALI(env)) {}
|
||||
|
||||
void JavaListBuilder::add(jobject element) {
|
||||
JavaListBuilder::~JavaListBuilder() = default;
|
||||
|
||||
void JavaListBuilder::add(const JavaRef<jobject>& element) {
|
||||
JNI_ArrayList::Java_ArrayList_addZ_JUE(env_, j_list_, element);
|
||||
}
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include "rtc_base/constructormagic.h"
|
||||
#include "rtc_base/refcount.h"
|
||||
#include "rtc_base/thread_checker.h"
|
||||
#include "sdk/android/src/jni/scoped_java_ref.h"
|
||||
|
||||
// Abort the process if |jni| has a Java exception pending.
|
||||
// This macros uses the comma operator to execute ExceptionDescribe
|
||||
@ -57,34 +58,54 @@ JNIEnv* AttachCurrentThreadIfNeeded();
|
||||
jlong jlongFromPointer(void* ptr);
|
||||
|
||||
// Returns true if |obj| == null in Java.
|
||||
bool IsNull(JNIEnv* jni, jobject obj);
|
||||
bool IsNull(JNIEnv* jni, const JavaRef<jobject>& obj);
|
||||
|
||||
ScopedJavaLocalRef<jobject> NewDirectByteBuffer(JNIEnv* env,
|
||||
void* address,
|
||||
jlong capacity);
|
||||
// Given a (UTF-16) jstring return a new UTF-8 native string.
|
||||
std::string JavaToStdString(JNIEnv* jni, const jstring& j_string);
|
||||
std::string JavaToStdString(JNIEnv* jni, const JavaRef<jstring>& j_string);
|
||||
|
||||
// Deprecated. Use scoped jobjects instead.
|
||||
inline std::string JavaToStdString(JNIEnv* jni, jstring j_string) {
|
||||
return JavaToStdString(jni, JavaParamRef<jstring>(j_string));
|
||||
}
|
||||
|
||||
// Given a List of (UTF-16) jstrings
|
||||
// return a new vector of UTF-8 native strings.
|
||||
std::vector<std::string> JavaToStdVectorStrings(JNIEnv* jni, jobject list);
|
||||
std::vector<std::string> JavaToStdVectorStrings(JNIEnv* jni,
|
||||
const JavaRef<jobject>& list);
|
||||
|
||||
rtc::Optional<int32_t> JavaToNativeOptionalInt(JNIEnv* jni, jobject integer);
|
||||
rtc::Optional<bool> JavaToNativeOptionalBool(JNIEnv* jni, jobject boolean);
|
||||
int64_t JavaToNativeLong(JNIEnv* env, jobject j_long);
|
||||
rtc::Optional<int32_t> JavaToNativeOptionalInt(JNIEnv* jni,
|
||||
const JavaRef<jobject>& integer);
|
||||
rtc::Optional<bool> JavaToNativeOptionalBool(JNIEnv* jni,
|
||||
const JavaRef<jobject>& boolean);
|
||||
int64_t JavaToNativeLong(JNIEnv* env, const JavaRef<jobject>& j_long);
|
||||
|
||||
jobject NativeToJavaBoolean(JNIEnv* env, bool b);
|
||||
jobject NativeToJavaInteger(JNIEnv* jni, int32_t i);
|
||||
jobject NativeToJavaLong(JNIEnv* env, int64_t u);
|
||||
jobject NativeToJavaDouble(JNIEnv* env, double d);
|
||||
// Given a UTF-8 encoded |native| string return a new (UTF-16) jstring.
|
||||
jstring NativeToJavaString(JNIEnv* jni, const std::string& native);
|
||||
jobject NativeToJavaInteger(JNIEnv* jni,
|
||||
const rtc::Optional<int32_t>& optional_int);
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaBoolean(JNIEnv* env, bool b);
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaInteger(JNIEnv* jni, int32_t i);
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaLong(JNIEnv* env, int64_t u);
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaDouble(JNIEnv* env, double d);
|
||||
ScopedJavaLocalRef<jstring> NativeToJavaString(JNIEnv* jni, const char* str);
|
||||
ScopedJavaLocalRef<jstring> NativeToJavaString(JNIEnv* jni,
|
||||
const std::string& str);
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaInteger(
|
||||
JNIEnv* jni,
|
||||
const rtc::Optional<int32_t>& optional_int);
|
||||
|
||||
// Parses Map<String, String> to std::map<std::string, std::string>.
|
||||
std::map<std::string, std::string> JavaToStdMapStrings(JNIEnv* jni,
|
||||
jobject j_map);
|
||||
std::map<std::string, std::string> JavaToStdMapStrings(
|
||||
JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_map);
|
||||
|
||||
// Deprecated. Use scoped jobjects instead.
|
||||
inline std::map<std::string, std::string> JavaToStdMapStrings(JNIEnv* jni,
|
||||
jobject j_map) {
|
||||
return JavaToStdMapStrings(jni, JavaParamRef<jobject>(j_map));
|
||||
}
|
||||
|
||||
// Returns the name of a Java enum.
|
||||
std::string GetJavaEnumName(JNIEnv* jni, jobject j_enum);
|
||||
std::string GetJavaEnumName(JNIEnv* jni, const JavaRef<jobject>& j_enum);
|
||||
|
||||
jobject NewGlobalRef(JNIEnv* jni, jobject o);
|
||||
|
||||
@ -102,30 +123,6 @@ class ScopedLocalRefFrame {
|
||||
JNIEnv* jni_;
|
||||
};
|
||||
|
||||
// Scoped holder for global Java refs.
|
||||
template<class T> // T is jclass, jobject, jintArray, etc.
|
||||
class ScopedGlobalRef {
|
||||
public:
|
||||
ScopedGlobalRef(JNIEnv* jni, T obj)
|
||||
: obj_(static_cast<T>(jni->NewGlobalRef(obj))) {}
|
||||
|
||||
ScopedGlobalRef(ScopedGlobalRef&& other) : obj_(other.obj_) {
|
||||
other.obj_ = nullptr;
|
||||
}
|
||||
|
||||
~ScopedGlobalRef() {
|
||||
if (obj_) {
|
||||
DeleteGlobalRef(AttachCurrentThreadIfNeeded(), obj_);
|
||||
}
|
||||
}
|
||||
T operator*() const {
|
||||
return obj_;
|
||||
}
|
||||
private:
|
||||
T obj_;
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(ScopedGlobalRef);
|
||||
};
|
||||
|
||||
// Provides a convenient way to iterate over a Java Iterable using the
|
||||
// C++ range-for loop.
|
||||
// E.g. for (jobject value : Iterable(jni, j_iterable)) { ... }
|
||||
@ -134,7 +131,8 @@ class ScopedGlobalRef {
|
||||
// Java iterator.
|
||||
class Iterable {
|
||||
public:
|
||||
Iterable(JNIEnv* jni, jobject iterable) : jni_(jni), iterable_(iterable) {}
|
||||
Iterable(JNIEnv* jni, const JavaRef<jobject>& iterable);
|
||||
~Iterable();
|
||||
|
||||
class Iterator {
|
||||
public:
|
||||
@ -142,12 +140,14 @@ class Iterable {
|
||||
Iterator();
|
||||
// Creates an iterator pointing to the beginning of the specified
|
||||
// collection.
|
||||
Iterator(JNIEnv* jni, jobject iterable);
|
||||
Iterator(JNIEnv* jni, const JavaRef<jobject>& iterable);
|
||||
|
||||
// Move constructor - necessary to be able to return iterator types from
|
||||
// functions.
|
||||
Iterator(Iterator&& other);
|
||||
|
||||
~Iterator();
|
||||
|
||||
// Move assignment should not be used.
|
||||
Iterator& operator=(Iterator&&) = delete;
|
||||
|
||||
@ -164,14 +164,14 @@ class Iterable {
|
||||
// iterators.
|
||||
bool operator==(const Iterator& other);
|
||||
bool operator!=(const Iterator& other) { return !(*this == other); }
|
||||
jobject operator*();
|
||||
ScopedJavaLocalRef<jobject>& operator*();
|
||||
|
||||
private:
|
||||
bool AtEnd() const;
|
||||
|
||||
JNIEnv* jni_ = nullptr;
|
||||
jobject iterator_ = nullptr;
|
||||
jobject value_ = nullptr;
|
||||
ScopedJavaLocalRef<jobject> iterator_;
|
||||
ScopedJavaLocalRef<jobject> value_;
|
||||
rtc::ThreadChecker thread_checker_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(Iterator);
|
||||
@ -182,52 +182,56 @@ class Iterable {
|
||||
|
||||
private:
|
||||
JNIEnv* jni_;
|
||||
jobject iterable_;
|
||||
ScopedJavaLocalRef<jobject> iterable_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(Iterable);
|
||||
};
|
||||
|
||||
// Helper function for converting std::vector<T> into a Java array.
|
||||
template <typename T, typename Convert>
|
||||
jobjectArray NativeToJavaObjectArray(JNIEnv* env,
|
||||
const std::vector<T>& container,
|
||||
jclass clazz,
|
||||
Convert convert) {
|
||||
jobjectArray j_container =
|
||||
env->NewObjectArray(container.size(), clazz, nullptr);
|
||||
ScopedJavaLocalRef<jobjectArray> NativeToJavaObjectArray(
|
||||
JNIEnv* env,
|
||||
const std::vector<T>& container,
|
||||
jclass clazz,
|
||||
Convert convert) {
|
||||
ScopedJavaLocalRef<jobjectArray> j_container(
|
||||
env, env->NewObjectArray(container.size(), clazz, nullptr));
|
||||
int i = 0;
|
||||
for (const T& element : container) {
|
||||
jobject j_element = convert(env, element);
|
||||
env->SetObjectArrayElement(j_container, i, j_element);
|
||||
// Delete local ref immediately since we might create a lot of local
|
||||
// references in this loop.
|
||||
env->DeleteLocalRef(j_element);
|
||||
env->SetObjectArrayElement(j_container.obj(), i,
|
||||
convert(env, element).obj());
|
||||
++i;
|
||||
}
|
||||
return j_container;
|
||||
}
|
||||
|
||||
jobjectArray NativeToJavaIntegerArray(JNIEnv* env,
|
||||
const std::vector<int32_t>& container);
|
||||
jobjectArray NativeToJavaBooleanArray(JNIEnv* env,
|
||||
const std::vector<bool>& container);
|
||||
jobjectArray NativeToJavaLongArray(JNIEnv* env,
|
||||
const std::vector<int64_t>& container);
|
||||
jobjectArray NativeToJavaDoubleArray(JNIEnv* env,
|
||||
const std::vector<double>& container);
|
||||
jobjectArray NativeToJavaStringArray(JNIEnv* env,
|
||||
const std::vector<std::string>& container);
|
||||
ScopedJavaLocalRef<jobjectArray> NativeToJavaIntegerArray(
|
||||
JNIEnv* env,
|
||||
const std::vector<int32_t>& container);
|
||||
ScopedJavaLocalRef<jobjectArray> NativeToJavaBooleanArray(
|
||||
JNIEnv* env,
|
||||
const std::vector<bool>& container);
|
||||
ScopedJavaLocalRef<jobjectArray> NativeToJavaLongArray(
|
||||
JNIEnv* env,
|
||||
const std::vector<int64_t>& container);
|
||||
ScopedJavaLocalRef<jobjectArray> NativeToJavaDoubleArray(
|
||||
JNIEnv* env,
|
||||
const std::vector<double>& container);
|
||||
ScopedJavaLocalRef<jobjectArray> NativeToJavaStringArray(
|
||||
JNIEnv* env,
|
||||
const std::vector<std::string>& container);
|
||||
|
||||
template <typename T, typename Convert>
|
||||
std::vector<T> JavaToNativeVector(JNIEnv* env,
|
||||
jobjectArray j_container,
|
||||
const JavaRef<jobjectArray>& j_container,
|
||||
Convert convert) {
|
||||
std::vector<T> container;
|
||||
const size_t size = env->GetArrayLength(j_container);
|
||||
const size_t size = env->GetArrayLength(j_container.obj());
|
||||
container.reserve(size);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
container.emplace_back(
|
||||
convert(env, env->GetObjectArrayElement(j_container, i)));
|
||||
container.emplace_back(convert(
|
||||
env, ScopedJavaLocalRef<jobject>(
|
||||
env, env->GetObjectArrayElement(j_container.obj(), i))));
|
||||
}
|
||||
CHECK_EXCEPTION(env) << "Error during JavaToNativeVector";
|
||||
return container;
|
||||
@ -238,16 +242,19 @@ std::vector<T> JavaToNativeVector(JNIEnv* env,
|
||||
class JavaListBuilder {
|
||||
public:
|
||||
explicit JavaListBuilder(JNIEnv* env);
|
||||
void add(jobject element);
|
||||
jobject java_list() { return j_list_; }
|
||||
~JavaListBuilder();
|
||||
void add(const JavaRef<jobject>& element);
|
||||
ScopedJavaLocalRef<jobject> java_list() { return j_list_; }
|
||||
|
||||
private:
|
||||
JNIEnv* env_;
|
||||
jobject j_list_;
|
||||
ScopedJavaLocalRef<jobject> j_list_;
|
||||
};
|
||||
|
||||
template <typename C, typename Convert>
|
||||
jobject NativeToJavaList(JNIEnv* env, const C& container, Convert convert) {
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaList(JNIEnv* env,
|
||||
const C& container,
|
||||
Convert convert) {
|
||||
JavaListBuilder builder(env);
|
||||
for (const auto& e : container)
|
||||
builder.add(convert(env, e));
|
||||
@ -259,16 +266,19 @@ jobject NativeToJavaList(JNIEnv* env, const C& container, Convert convert) {
|
||||
class JavaMapBuilder {
|
||||
public:
|
||||
explicit JavaMapBuilder(JNIEnv* env);
|
||||
void put(jobject key, jobject value);
|
||||
jobject GetJavaMap();
|
||||
~JavaMapBuilder();
|
||||
void put(const JavaRef<jobject>& key, const JavaRef<jobject>& value);
|
||||
ScopedJavaLocalRef<jobject> GetJavaMap() { return j_map_; }
|
||||
|
||||
private:
|
||||
JNIEnv* env_;
|
||||
jobject j_map_;
|
||||
ScopedJavaLocalRef<jobject> j_map_;
|
||||
};
|
||||
|
||||
template <typename C, typename Convert>
|
||||
jobject NativeToJavaMap(JNIEnv* env, const C& container, Convert convert) {
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaMap(JNIEnv* env,
|
||||
const C& container,
|
||||
Convert convert) {
|
||||
JavaMapBuilder builder(env);
|
||||
for (const auto& e : container) {
|
||||
ScopedLocalRefFrame local_ref_frame(env);
|
||||
|
||||
@ -15,30 +15,30 @@
|
||||
#include "third_party/libyuv/include/libyuv/scale.h"
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
#include "sdk/android/generated_video_jni/jni/NV12Buffer_jni.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_org_webrtc_NV12Buffer_nativeCropAndScale(JNIEnv* jni,
|
||||
jclass,
|
||||
jint crop_x,
|
||||
jint crop_y,
|
||||
jint crop_width,
|
||||
jint crop_height,
|
||||
jint scale_width,
|
||||
jint scale_height,
|
||||
jobject j_src,
|
||||
jint src_width,
|
||||
jint src_height,
|
||||
jint src_stride,
|
||||
jint src_slice_height,
|
||||
jobject j_dst_y,
|
||||
jint dst_stride_y,
|
||||
jobject j_dst_u,
|
||||
jint dst_stride_u,
|
||||
jobject j_dst_v,
|
||||
jint dst_stride_v) {
|
||||
static void JNI_NV12Buffer_CropAndScale(JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jint crop_x,
|
||||
jint crop_y,
|
||||
jint crop_width,
|
||||
jint crop_height,
|
||||
jint scale_width,
|
||||
jint scale_height,
|
||||
const JavaParamRef<jobject>& j_src,
|
||||
jint src_width,
|
||||
jint src_height,
|
||||
jint src_stride,
|
||||
jint src_slice_height,
|
||||
const JavaParamRef<jobject>& j_dst_y,
|
||||
jint dst_stride_y,
|
||||
const JavaParamRef<jobject>& j_dst_u,
|
||||
jint dst_stride_u,
|
||||
const JavaParamRef<jobject>& j_dst_v,
|
||||
jint dst_stride_v) {
|
||||
const int src_stride_y = src_stride;
|
||||
const int src_stride_uv = src_stride;
|
||||
const int crop_chroma_x = crop_x / 2;
|
||||
@ -50,12 +50,15 @@ Java_org_webrtc_NV12Buffer_nativeCropAndScale(JNIEnv* jni,
|
||||
const int tmp_size = crop_chroma_height * (tmp_stride_u + tmp_stride_v);
|
||||
|
||||
uint8_t const* src_y =
|
||||
static_cast<uint8_t const*>(jni->GetDirectBufferAddress(j_src));
|
||||
static_cast<uint8_t const*>(jni->GetDirectBufferAddress(j_src.obj()));
|
||||
uint8_t const* src_uv = src_y + src_slice_height * src_stride_y;
|
||||
|
||||
uint8_t* dst_y = static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_dst_y));
|
||||
uint8_t* dst_u = static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_dst_u));
|
||||
uint8_t* dst_v = static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_dst_v));
|
||||
uint8_t* dst_y =
|
||||
static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_dst_y.obj()));
|
||||
uint8_t* dst_u =
|
||||
static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_dst_u.obj()));
|
||||
uint8_t* dst_v =
|
||||
static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_dst_v.obj()));
|
||||
|
||||
// Crop using pointer arithmetic.
|
||||
src_y += crop_x + crop_y * src_stride_y;
|
||||
|
||||
@ -16,28 +16,28 @@
|
||||
|
||||
#include "common_video/libyuv/include/webrtc_libyuv.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "sdk/android/generated_video_jni/jni/NV21Buffer_jni.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_org_webrtc_NV21Buffer_nativeCropAndScale(JNIEnv* jni,
|
||||
jclass,
|
||||
jint crop_x,
|
||||
jint crop_y,
|
||||
jint crop_width,
|
||||
jint crop_height,
|
||||
jint scale_width,
|
||||
jint scale_height,
|
||||
jbyteArray j_src,
|
||||
jint src_width,
|
||||
jint src_height,
|
||||
jobject j_dst_y,
|
||||
jint dst_stride_y,
|
||||
jobject j_dst_u,
|
||||
jint dst_stride_u,
|
||||
jobject j_dst_v,
|
||||
jint dst_stride_v) {
|
||||
static void JNI_NV21Buffer_CropAndScale(JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jint crop_x,
|
||||
jint crop_y,
|
||||
jint crop_width,
|
||||
jint crop_height,
|
||||
jint scale_width,
|
||||
jint scale_height,
|
||||
const JavaParamRef<jbyteArray>& j_src,
|
||||
jint src_width,
|
||||
jint src_height,
|
||||
const JavaParamRef<jobject>& j_dst_y,
|
||||
jint dst_stride_y,
|
||||
const JavaParamRef<jobject>& j_dst_u,
|
||||
jint dst_stride_u,
|
||||
const JavaParamRef<jobject>& j_dst_v,
|
||||
jint dst_stride_v) {
|
||||
const int src_stride_y = src_width;
|
||||
const int src_stride_uv = src_width;
|
||||
const int crop_chroma_x = crop_x / 2;
|
||||
@ -49,14 +49,17 @@ Java_org_webrtc_NV21Buffer_nativeCropAndScale(JNIEnv* jni,
|
||||
const int tmp_size = crop_chroma_height * (tmp_stride_u + tmp_stride_v);
|
||||
|
||||
jboolean was_copy;
|
||||
jbyte* src_bytes = jni->GetByteArrayElements(j_src, &was_copy);
|
||||
jbyte* src_bytes = jni->GetByteArrayElements(j_src.obj(), &was_copy);
|
||||
RTC_DCHECK(!was_copy);
|
||||
uint8_t const* src_y = reinterpret_cast<uint8_t const*>(src_bytes);
|
||||
uint8_t const* src_uv = src_y + src_height * src_stride_y;
|
||||
|
||||
uint8_t* dst_y = static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_dst_y));
|
||||
uint8_t* dst_u = static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_dst_u));
|
||||
uint8_t* dst_v = static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_dst_v));
|
||||
uint8_t* dst_y =
|
||||
static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_dst_y.obj()));
|
||||
uint8_t* dst_u =
|
||||
static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_dst_u.obj()));
|
||||
uint8_t* dst_v =
|
||||
static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_dst_v.obj()));
|
||||
|
||||
// Crop using pointer arithmetic.
|
||||
src_y += crop_x + crop_y * src_stride_y;
|
||||
@ -68,7 +71,7 @@ Java_org_webrtc_NV21Buffer_nativeCropAndScale(JNIEnv* jni,
|
||||
crop_height, dst_y, dst_stride_y, dst_v, dst_stride_v,
|
||||
dst_u, dst_stride_u, scale_width, scale_height);
|
||||
|
||||
jni->ReleaseByteArrayElements(j_src, src_bytes, JNI_ABORT);
|
||||
jni->ReleaseByteArrayElements(j_src.obj(), src_bytes, JNI_ABORT);
|
||||
}
|
||||
|
||||
} // namespace jni
|
||||
|
||||
@ -29,7 +29,9 @@ enum AndroidSdkVersion {
|
||||
SDK_VERSION_MARSHMALLOW = 23
|
||||
};
|
||||
|
||||
static NetworkType GetNetworkTypeFromJava(JNIEnv* jni, jobject j_network_type) {
|
||||
static NetworkType GetNetworkTypeFromJava(
|
||||
JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_network_type) {
|
||||
std::string enum_name = GetJavaEnumName(jni, j_network_type);
|
||||
if (enum_name == "CONNECTION_UNKNOWN") {
|
||||
return NetworkType::NETWORK_UNKNOWN;
|
||||
@ -85,29 +87,32 @@ static rtc::AdapterType AdapterTypeFromNetworkType(NetworkType network_type) {
|
||||
}
|
||||
}
|
||||
|
||||
static rtc::IPAddress JavaToNativeIpAddress(JNIEnv* jni, jobject j_ip_address) {
|
||||
jbyteArray j_addresses = Java_IPAddress_getAddress(jni, j_ip_address);
|
||||
size_t address_length = jni->GetArrayLength(j_addresses);
|
||||
jbyte* addr_array = jni->GetByteArrayElements(j_addresses, nullptr);
|
||||
static rtc::IPAddress JavaToNativeIpAddress(
|
||||
JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_ip_address) {
|
||||
ScopedJavaLocalRef<jbyteArray> j_addresses =
|
||||
Java_IPAddress_getAddress(jni, j_ip_address);
|
||||
size_t address_length = jni->GetArrayLength(j_addresses.obj());
|
||||
jbyte* addr_array = jni->GetByteArrayElements(j_addresses.obj(), nullptr);
|
||||
CHECK_EXCEPTION(jni) << "Error during JavaToNativeIpAddress";
|
||||
if (address_length == 4) {
|
||||
// IP4
|
||||
struct in_addr ip4_addr;
|
||||
memcpy(&ip4_addr.s_addr, addr_array, 4);
|
||||
jni->ReleaseByteArrayElements(j_addresses, addr_array, JNI_ABORT);
|
||||
jni->ReleaseByteArrayElements(j_addresses.obj(), addr_array, JNI_ABORT);
|
||||
return rtc::IPAddress(ip4_addr);
|
||||
}
|
||||
// IP6
|
||||
RTC_CHECK(address_length == 16);
|
||||
struct in6_addr ip6_addr;
|
||||
memcpy(ip6_addr.s6_addr, addr_array, address_length);
|
||||
jni->ReleaseByteArrayElements(j_addresses, addr_array, JNI_ABORT);
|
||||
jni->ReleaseByteArrayElements(j_addresses.obj(), addr_array, JNI_ABORT);
|
||||
return rtc::IPAddress(ip6_addr);
|
||||
}
|
||||
|
||||
static NetworkInformation GetNetworkInformationFromJava(
|
||||
JNIEnv* jni,
|
||||
jobject j_network_info) {
|
||||
const JavaRef<jobject>& j_network_info) {
|
||||
NetworkInformation network_info;
|
||||
network_info.interface_name = JavaToStdString(
|
||||
jni, Java_NetworkInformation_getName(jni, j_network_info));
|
||||
@ -115,7 +120,7 @@ static NetworkInformation GetNetworkInformationFromJava(
|
||||
Java_NetworkInformation_getHandle(jni, j_network_info));
|
||||
network_info.type = GetNetworkTypeFromJava(
|
||||
jni, Java_NetworkInformation_getConnectionType(jni, j_network_info));
|
||||
jobjectArray j_ip_addresses =
|
||||
ScopedJavaLocalRef<jobjectArray> j_ip_addresses =
|
||||
Java_NetworkInformation_getIpAddresses(jni, j_network_info);
|
||||
network_info.ip_addresses = JavaToNativeVector<rtc::IPAddress>(
|
||||
jni, j_ip_addresses, &JavaToNativeIpAddress);
|
||||
@ -150,7 +155,7 @@ void AndroidNetworkMonitor::Start() {
|
||||
worker_thread()->socketserver()->set_network_binder(this);
|
||||
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
Java_NetworkMonitor_startMonitoring(env, *j_network_monitor_,
|
||||
Java_NetworkMonitor_startMonitoring(env, j_network_monitor_,
|
||||
jlongFromPointer(this));
|
||||
}
|
||||
|
||||
@ -168,7 +173,7 @@ void AndroidNetworkMonitor::Stop() {
|
||||
}
|
||||
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
Java_NetworkMonitor_stopMonitoring(env, *j_network_monitor_,
|
||||
Java_NetworkMonitor_stopMonitoring(env, j_network_monitor_,
|
||||
jlongFromPointer(this));
|
||||
|
||||
network_handle_by_address_.clear();
|
||||
@ -186,7 +191,7 @@ rtc::NetworkBindingResult AndroidNetworkMonitor::BindSocketToNetwork(
|
||||
// networks. This may also occur if there is no connectivity manager service.
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
const bool network_binding_supported =
|
||||
Java_NetworkMonitor_networkBindingSupported(env, *j_network_monitor_);
|
||||
Java_NetworkMonitor_networkBindingSupported(env, j_network_monitor_);
|
||||
if (!network_binding_supported) {
|
||||
RTC_LOG(LS_WARNING)
|
||||
<< "BindSocketToNetwork is not supported on this platform "
|
||||
@ -341,32 +346,35 @@ AndroidNetworkMonitorFactory::CreateNetworkMonitor() {
|
||||
return new AndroidNetworkMonitor(AttachCurrentThreadIfNeeded());
|
||||
}
|
||||
|
||||
void AndroidNetworkMonitor::NotifyConnectionTypeChanged(JNIEnv* env,
|
||||
jobject j_caller) {
|
||||
void AndroidNetworkMonitor::NotifyConnectionTypeChanged(
|
||||
JNIEnv* env,
|
||||
const JavaRef<jobject>& j_caller) {
|
||||
OnNetworksChanged();
|
||||
}
|
||||
|
||||
void AndroidNetworkMonitor::NotifyOfActiveNetworkList(
|
||||
JNIEnv* env,
|
||||
jobject j_caller,
|
||||
jobjectArray j_network_infos) {
|
||||
const JavaRef<jobject>& j_caller,
|
||||
const JavaRef<jobjectArray>& j_network_infos) {
|
||||
std::vector<NetworkInformation> network_infos =
|
||||
JavaToNativeVector<NetworkInformation>(env, j_network_infos,
|
||||
&GetNetworkInformationFromJava);
|
||||
SetNetworkInfos(network_infos);
|
||||
}
|
||||
|
||||
void AndroidNetworkMonitor::NotifyOfNetworkConnect(JNIEnv* env,
|
||||
jobject j_caller,
|
||||
jobject j_network_info) {
|
||||
void AndroidNetworkMonitor::NotifyOfNetworkConnect(
|
||||
JNIEnv* env,
|
||||
const JavaRef<jobject>& j_caller,
|
||||
const JavaRef<jobject>& j_network_info) {
|
||||
NetworkInformation network_info =
|
||||
GetNetworkInformationFromJava(env, j_network_info);
|
||||
OnNetworkConnected(network_info);
|
||||
}
|
||||
|
||||
void AndroidNetworkMonitor::NotifyOfNetworkDisconnect(JNIEnv* env,
|
||||
jobject j_caller,
|
||||
jlong network_handle) {
|
||||
void AndroidNetworkMonitor::NotifyOfNetworkDisconnect(
|
||||
JNIEnv* env,
|
||||
const JavaRef<jobject>& j_caller,
|
||||
jlong network_handle) {
|
||||
OnNetworkDisconnected(static_cast<NetworkHandle>(network_handle));
|
||||
}
|
||||
|
||||
|
||||
@ -69,23 +69,24 @@ class AndroidNetworkMonitor : public rtc::NetworkMonitorBase,
|
||||
// Always expected to be called on the network thread.
|
||||
void SetNetworkInfos(const std::vector<NetworkInformation>& network_infos);
|
||||
|
||||
void NotifyConnectionTypeChanged(JNIEnv* env, jobject j_caller);
|
||||
void NotifyConnectionTypeChanged(JNIEnv* env,
|
||||
const JavaRef<jobject>& j_caller);
|
||||
void NotifyOfNetworkConnect(JNIEnv* env,
|
||||
jobject j_caller,
|
||||
jobject j_network_info);
|
||||
const JavaRef<jobject>& j_caller,
|
||||
const JavaRef<jobject>& j_network_info);
|
||||
void NotifyOfNetworkDisconnect(JNIEnv* env,
|
||||
jobject j_caller,
|
||||
const JavaRef<jobject>& j_caller,
|
||||
jlong network_handle);
|
||||
void NotifyOfActiveNetworkList(JNIEnv* env,
|
||||
jobject j_caller,
|
||||
jobjectArray j_network_infos);
|
||||
const JavaRef<jobject>& j_caller,
|
||||
const JavaRef<jobjectArray>& j_network_infos);
|
||||
|
||||
private:
|
||||
void OnNetworkConnected_w(const NetworkInformation& network_info);
|
||||
void OnNetworkDisconnected_w(NetworkHandle network_handle);
|
||||
|
||||
const int android_sdk_int_;
|
||||
ScopedGlobalRef<jobject> j_network_monitor_;
|
||||
ScopedJavaGlobalRef<jobject> j_network_monitor_;
|
||||
rtc::ThreadChecker thread_checker_;
|
||||
bool started_ = false;
|
||||
std::map<std::string, rtc::AdapterType> adapter_type_by_name_;
|
||||
|
||||
@ -9,17 +9,15 @@
|
||||
*/
|
||||
|
||||
#include "api/mediastreaminterface.h"
|
||||
#include "sdk/android/src/jni/jni_helpers.h"
|
||||
#include "sdk/android/generated_peerconnection_jni/jni/AudioTrack_jni.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
AudioTrack_nativeSetVolume,
|
||||
JNIEnv*,
|
||||
jclass,
|
||||
jlong j_p,
|
||||
jdouble volume) {
|
||||
static void JNI_AudioTrack_SetVolume(JNIEnv*,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_p,
|
||||
jdouble volume) {
|
||||
rtc::scoped_refptr<AudioSourceInterface> source(
|
||||
reinterpret_cast<AudioTrackInterface*>(j_p)->GetSource());
|
||||
source->SetVolume(volume);
|
||||
|
||||
@ -9,18 +9,18 @@
|
||||
*/
|
||||
|
||||
#include "rtc_base/logsinks.h"
|
||||
#include "sdk/android/generated_peerconnection_jni/jni/CallSessionFileRotatingLogSink_jni.h"
|
||||
#include "sdk/android/src/jni/jni_helpers.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jlong,
|
||||
CallSessionFileRotatingLogSink_nativeAddSink,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jstring j_dirPath,
|
||||
jint j_maxFileSize,
|
||||
jint j_severity) {
|
||||
static jlong JNI_CallSessionFileRotatingLogSink_AddSink(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
const JavaParamRef<jstring>& j_dirPath,
|
||||
jint j_maxFileSize,
|
||||
jint j_severity) {
|
||||
std::string dir_path = JavaToStdString(jni, j_dirPath);
|
||||
rtc::CallSessionFileRotatingLogSink* sink =
|
||||
new rtc::CallSessionFileRotatingLogSink(dir_path, j_maxFileSize);
|
||||
@ -33,46 +33,46 @@ JNI_FUNCTION_DECLARATION(jlong,
|
||||
}
|
||||
rtc::LogMessage::AddLogToStream(
|
||||
sink, static_cast<rtc::LoggingSeverity>(j_severity));
|
||||
return (jlong)sink;
|
||||
return jlongFromPointer(sink);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
CallSessionFileRotatingLogSink_nativeDeleteSink,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_sink) {
|
||||
static void JNI_CallSessionFileRotatingLogSink_DeleteSink(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_sink) {
|
||||
rtc::CallSessionFileRotatingLogSink* sink =
|
||||
reinterpret_cast<rtc::CallSessionFileRotatingLogSink*>(j_sink);
|
||||
rtc::LogMessage::RemoveLogToStream(sink);
|
||||
delete sink;
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jbyteArray,
|
||||
CallSessionFileRotatingLogSink_nativeGetLogData,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jstring j_dirPath) {
|
||||
static ScopedJavaLocalRef<jbyteArray>
|
||||
JNI_CallSessionFileRotatingLogSink_GetLogData(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
const JavaParamRef<jstring>& j_dirPath) {
|
||||
std::string dir_path = JavaToStdString(jni, j_dirPath);
|
||||
std::unique_ptr<rtc::CallSessionFileRotatingStream> stream(
|
||||
new rtc::CallSessionFileRotatingStream(dir_path));
|
||||
if (!stream->Open()) {
|
||||
RTC_LOG_V(rtc::LoggingSeverity::LS_WARNING)
|
||||
<< "Failed to open CallSessionFileRotatingStream for path " << dir_path;
|
||||
return jni->NewByteArray(0);
|
||||
return ScopedJavaLocalRef<jbyteArray>(jni, jni->NewByteArray(0));
|
||||
}
|
||||
size_t log_size = 0;
|
||||
if (!stream->GetSize(&log_size) || log_size == 0) {
|
||||
RTC_LOG_V(rtc::LoggingSeverity::LS_WARNING)
|
||||
<< "CallSessionFileRotatingStream returns 0 size for path " << dir_path;
|
||||
return jni->NewByteArray(0);
|
||||
return ScopedJavaLocalRef<jbyteArray>(jni, jni->NewByteArray(0));
|
||||
}
|
||||
|
||||
size_t read = 0;
|
||||
std::unique_ptr<jbyte> buffer(static_cast<jbyte*>(malloc(log_size)));
|
||||
stream->ReadAll(buffer.get(), log_size, &read, nullptr);
|
||||
|
||||
jbyteArray result = jni->NewByteArray(read);
|
||||
jni->SetByteArrayRegion(result, 0, read, buffer.get());
|
||||
ScopedJavaLocalRef<jbyteArray> result =
|
||||
ScopedJavaLocalRef<jbyteArray>(jni, jni->NewByteArray(read));
|
||||
jni->SetByteArrayRegion(result.obj(), 0, read, buffer.get());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ namespace {
|
||||
// and dispatching the callback from C++ back to Java.
|
||||
class DataChannelObserverJni : public DataChannelObserver {
|
||||
public:
|
||||
DataChannelObserverJni(JNIEnv* jni, jobject j_observer);
|
||||
DataChannelObserverJni(JNIEnv* jni, const JavaRef<jobject>& j_observer);
|
||||
virtual ~DataChannelObserverJni() {}
|
||||
|
||||
void OnBufferedAmountChange(uint64_t previous_amount) override;
|
||||
@ -35,40 +35,44 @@ class DataChannelObserverJni : public DataChannelObserver {
|
||||
void OnMessage(const DataBuffer& buffer) override;
|
||||
|
||||
private:
|
||||
const ScopedGlobalRef<jobject> j_observer_global_;
|
||||
const ScopedJavaGlobalRef<jobject> j_observer_global_;
|
||||
};
|
||||
|
||||
DataChannelObserverJni::DataChannelObserverJni(JNIEnv* jni, jobject j_observer)
|
||||
DataChannelObserverJni::DataChannelObserverJni(
|
||||
JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_observer)
|
||||
: j_observer_global_(jni, j_observer) {}
|
||||
|
||||
void DataChannelObserverJni::OnBufferedAmountChange(uint64_t previous_amount) {
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
Java_Observer_onBufferedAmountChange(env, *j_observer_global_,
|
||||
Java_Observer_onBufferedAmountChange(env, j_observer_global_,
|
||||
previous_amount);
|
||||
}
|
||||
|
||||
void DataChannelObserverJni::OnStateChange() {
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
Java_Observer_onStateChange(env, *j_observer_global_);
|
||||
Java_Observer_onStateChange(env, j_observer_global_);
|
||||
}
|
||||
|
||||
void DataChannelObserverJni::OnMessage(const DataBuffer& buffer) {
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(env);
|
||||
jobject byte_buffer = env->NewDirectByteBuffer(
|
||||
const_cast<char*>(buffer.data.data<char>()), buffer.data.size());
|
||||
jobject j_buffer = Java_Buffer_Constructor(env, byte_buffer, buffer.binary);
|
||||
Java_Observer_onMessage(env, *j_observer_global_, j_buffer);
|
||||
ScopedJavaLocalRef<jobject> byte_buffer = NewDirectByteBuffer(
|
||||
env, const_cast<char*>(buffer.data.data<char>()), buffer.data.size());
|
||||
ScopedJavaLocalRef<jobject> j_buffer =
|
||||
Java_Buffer_Constructor(env, byte_buffer, buffer.binary);
|
||||
Java_Observer_onMessage(env, j_observer_global_, j_buffer);
|
||||
}
|
||||
|
||||
DataChannelInterface* ExtractNativeDC(JNIEnv* jni, jobject j_dc) {
|
||||
jlong j_d = Java_DataChannel_getNativeDataChannel(jni, j_dc);
|
||||
return reinterpret_cast<DataChannelInterface*>(j_d);
|
||||
DataChannelInterface* ExtractNativeDC(JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_dc) {
|
||||
return reinterpret_cast<DataChannelInterface*>(
|
||||
Java_DataChannel_getNativeDataChannel(jni, j_dc));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
DataChannelInit JavaToNativeDataChannelInit(JNIEnv* env, jobject j_init) {
|
||||
DataChannelInit JavaToNativeDataChannelInit(JNIEnv* env,
|
||||
const JavaRef<jobject>& j_init) {
|
||||
DataChannelInit init;
|
||||
init.ordered = Java_Init_getOrdered(env, j_init);
|
||||
init.maxRetransmitTime = Java_Init_getMaxRetransmitTimeMs(env, j_init);
|
||||
@ -79,79 +83,72 @@ DataChannelInit JavaToNativeDataChannelInit(JNIEnv* env, jobject j_init) {
|
||||
return init;
|
||||
}
|
||||
|
||||
jobject WrapNativeDataChannel(
|
||||
ScopedJavaLocalRef<jobject> WrapNativeDataChannel(
|
||||
JNIEnv* env,
|
||||
rtc::scoped_refptr<DataChannelInterface> channel) {
|
||||
if (!channel)
|
||||
return nullptr;
|
||||
// Channel is now owned by Java object, and will be freed from there.
|
||||
return channel ? Java_DataChannel_Constructor(
|
||||
env, jlongFromPointer(channel.release()))
|
||||
: nullptr;
|
||||
return Java_DataChannel_Constructor(env, jlongFromPointer(channel.release()));
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jlong,
|
||||
DataChannel_registerObserverNative,
|
||||
JNIEnv* jni,
|
||||
jobject j_dc,
|
||||
jobject j_observer) {
|
||||
static jlong JNI_DataChannel_RegisterObserver(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_dc,
|
||||
const JavaParamRef<jobject>& j_observer) {
|
||||
auto observer = rtc::MakeUnique<DataChannelObserverJni>(jni, j_observer);
|
||||
ExtractNativeDC(jni, j_dc)->RegisterObserver(observer.get());
|
||||
return jlongFromPointer(observer.release());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
DataChannel_unregisterObserverNative,
|
||||
JNIEnv* jni,
|
||||
jobject j_dc,
|
||||
jlong native_observer) {
|
||||
static void JNI_DataChannel_UnregisterObserver(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_dc,
|
||||
jlong native_observer) {
|
||||
ExtractNativeDC(jni, j_dc)->UnregisterObserver();
|
||||
delete reinterpret_cast<DataChannelObserverJni*>(native_observer);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jstring,
|
||||
DataChannel_label,
|
||||
JNIEnv* jni,
|
||||
jobject j_dc) {
|
||||
static ScopedJavaLocalRef<jstring> JNI_DataChannel_Label(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_dc) {
|
||||
return NativeToJavaString(jni, ExtractNativeDC(jni, j_dc)->label());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jint, DataChannel_id, JNIEnv* jni, jobject j_dc) {
|
||||
static jint JNI_DataChannel_Id(JNIEnv* jni, const JavaParamRef<jobject>& j_dc) {
|
||||
int id = ExtractNativeDC(jni, j_dc)->id();
|
||||
RTC_CHECK_LE(id, std::numeric_limits<int32_t>::max())
|
||||
<< "id overflowed jint!";
|
||||
return static_cast<jint>(id);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jobject,
|
||||
DataChannel_state,
|
||||
JNIEnv* jni,
|
||||
jobject j_dc) {
|
||||
static ScopedJavaLocalRef<jobject> JNI_DataChannel_State(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_dc) {
|
||||
return Java_State_fromNativeIndex(jni, ExtractNativeDC(jni, j_dc)->state());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jlong,
|
||||
DataChannel_bufferedAmount,
|
||||
JNIEnv* jni,
|
||||
jobject j_dc) {
|
||||
static jlong JNI_DataChannel_BufferedAmount(JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_dc) {
|
||||
uint64_t buffered_amount = ExtractNativeDC(jni, j_dc)->buffered_amount();
|
||||
RTC_CHECK_LE(buffered_amount, std::numeric_limits<int64_t>::max())
|
||||
<< "buffered_amount overflowed jlong!";
|
||||
return static_cast<jlong>(buffered_amount);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void, DataChannel_close, JNIEnv* jni, jobject j_dc) {
|
||||
static void JNI_DataChannel_Close(JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_dc) {
|
||||
ExtractNativeDC(jni, j_dc)->Close();
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jboolean,
|
||||
DataChannel_sendNative,
|
||||
JNIEnv* jni,
|
||||
jobject j_dc,
|
||||
jbyteArray data,
|
||||
jboolean binary) {
|
||||
jbyte* bytes = jni->GetByteArrayElements(data, nullptr);
|
||||
static jboolean JNI_DataChannel_Send(JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_dc,
|
||||
const JavaParamRef<jbyteArray>& data,
|
||||
jboolean binary) {
|
||||
jbyte* bytes = jni->GetByteArrayElements(data.obj(), nullptr);
|
||||
bool ret = ExtractNativeDC(jni, j_dc)->Send(DataBuffer(
|
||||
rtc::CopyOnWriteBuffer(bytes, jni->GetArrayLength(data)), binary));
|
||||
jni->ReleaseByteArrayElements(data, bytes, JNI_ABORT);
|
||||
rtc::CopyOnWriteBuffer(bytes, jni->GetArrayLength(data.obj())), binary));
|
||||
jni->ReleaseByteArrayElements(data.obj(), bytes, JNI_ABORT);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -14,10 +14,12 @@
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
DataChannelInit JavaToNativeDataChannelInit(JNIEnv* env, jobject j_init);
|
||||
DataChannelInit JavaToNativeDataChannelInit(JNIEnv* env,
|
||||
const JavaRef<jobject>& j_init);
|
||||
|
||||
jobject WrapNativeDataChannel(JNIEnv* env,
|
||||
rtc::scoped_refptr<DataChannelInterface> channel);
|
||||
ScopedJavaLocalRef<jobject> WrapNativeDataChannel(
|
||||
JNIEnv* env,
|
||||
rtc::scoped_refptr<DataChannelInterface> channel);
|
||||
|
||||
} // namespace jni
|
||||
} // namespace webrtc
|
||||
|
||||
@ -12,16 +12,15 @@
|
||||
|
||||
#include "modules/audio_processing/include/audio_processing.h"
|
||||
#include "rtc_base/scoped_ref_ptr.h"
|
||||
#include "sdk/android/generated_audio_jni/jni/DefaultAudioProcessingFactory_jni.h"
|
||||
#include "sdk/android/src/jni/jni_helpers.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
JNI_FUNCTION_DECLARATION(
|
||||
jlong,
|
||||
DefaultAudioProcessingFactory_nativeCreateAudioProcessing,
|
||||
static jlong JNI_DefaultAudioProcessingFactory_CreateAudioProcessing(
|
||||
JNIEnv*,
|
||||
jclass,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong native_post_processor) {
|
||||
std::unique_ptr<PostProcessing> post_processor(
|
||||
reinterpret_cast<PostProcessing*>(native_post_processor));
|
||||
|
||||
@ -9,56 +9,48 @@
|
||||
*/
|
||||
|
||||
#include "api/dtmfsenderinterface.h"
|
||||
#include "sdk/android/generated_peerconnection_jni/jni/DtmfSender_jni.h"
|
||||
#include "sdk/android/src/jni/jni_helpers.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jboolean,
|
||||
DtmfSender_nativeCanInsertDtmf,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_dtmf_sender_pointer) {
|
||||
static jboolean JNI_DtmfSender_CanInsertDtmf(JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_dtmf_sender_pointer) {
|
||||
return reinterpret_cast<DtmfSenderInterface*>(j_dtmf_sender_pointer)
|
||||
->CanInsertDtmf();
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jboolean,
|
||||
DtmfSender_nativeInsertDtmf,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_dtmf_sender_pointer,
|
||||
jstring tones,
|
||||
jint duration,
|
||||
jint inter_tone_gap) {
|
||||
static jboolean JNI_DtmfSender_InsertDtmf(JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_dtmf_sender_pointer,
|
||||
const JavaParamRef<jstring>& tones,
|
||||
jint duration,
|
||||
jint inter_tone_gap) {
|
||||
return reinterpret_cast<DtmfSenderInterface*>(j_dtmf_sender_pointer)
|
||||
->InsertDtmf(JavaToStdString(jni, tones), duration, inter_tone_gap);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jstring,
|
||||
DtmfSender_nativeTones,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_dtmf_sender_pointer) {
|
||||
static ScopedJavaLocalRef<jstring> JNI_DtmfSender_Tones(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_dtmf_sender_pointer) {
|
||||
return NativeToJavaString(
|
||||
jni,
|
||||
reinterpret_cast<DtmfSenderInterface*>(j_dtmf_sender_pointer)->tones());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jint,
|
||||
DtmfSender_nativeDuration,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_dtmf_sender_pointer) {
|
||||
static jint JNI_DtmfSender_Duration(JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_dtmf_sender_pointer) {
|
||||
return reinterpret_cast<DtmfSenderInterface*>(j_dtmf_sender_pointer)
|
||||
->duration();
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jint,
|
||||
DtmfSender_nativeInterToneGap,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_dtmf_sender_pointer) {
|
||||
static jint JNI_DtmfSender_InterToneGap(JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_dtmf_sender_pointer) {
|
||||
return reinterpret_cast<DtmfSenderInterface*>(j_dtmf_sender_pointer)
|
||||
->inter_tone_gap();
|
||||
}
|
||||
|
||||
@ -21,11 +21,12 @@ namespace jni {
|
||||
|
||||
namespace {
|
||||
|
||||
jobject CreateJavaIceCandidate(JNIEnv* env,
|
||||
const std::string& sdp_mid,
|
||||
int sdp_mline_index,
|
||||
const std::string& sdp,
|
||||
const std::string server_url) {
|
||||
ScopedJavaLocalRef<jobject> CreateJavaIceCandidate(
|
||||
JNIEnv* env,
|
||||
const std::string& sdp_mid,
|
||||
int sdp_mline_index,
|
||||
const std::string& sdp,
|
||||
const std::string server_url) {
|
||||
return Java_IceCandidate_Constructor(
|
||||
env, NativeToJavaString(env, sdp_mid), sdp_mline_index,
|
||||
NativeToJavaString(env, sdp), NativeToJavaString(env, server_url));
|
||||
@ -33,7 +34,8 @@ jobject CreateJavaIceCandidate(JNIEnv* env,
|
||||
|
||||
} // namespace
|
||||
|
||||
cricket::Candidate JavaToNativeCandidate(JNIEnv* jni, jobject j_candidate) {
|
||||
cricket::Candidate JavaToNativeCandidate(JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_candidate) {
|
||||
std::string sdp_mid =
|
||||
JavaToStdString(jni, Java_IceCandidate_getSdpMid(jni, j_candidate));
|
||||
std::string sdp =
|
||||
@ -45,8 +47,9 @@ cricket::Candidate JavaToNativeCandidate(JNIEnv* jni, jobject j_candidate) {
|
||||
return candidate;
|
||||
}
|
||||
|
||||
jobject NativeToJavaCandidate(JNIEnv* env,
|
||||
const cricket::Candidate& candidate) {
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaCandidate(
|
||||
JNIEnv* env,
|
||||
const cricket::Candidate& candidate) {
|
||||
std::string sdp = SdpSerializeCandidate(candidate);
|
||||
RTC_CHECK(!sdp.empty()) << "got an empty ICE candidate";
|
||||
// sdp_mline_index is not used, pass an invalid value -1.
|
||||
@ -55,8 +58,9 @@ jobject NativeToJavaCandidate(JNIEnv* env,
|
||||
"" /* server_url */);
|
||||
}
|
||||
|
||||
jobject NativeToJavaIceCandidate(JNIEnv* env,
|
||||
const IceCandidateInterface& candidate) {
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaIceCandidate(
|
||||
JNIEnv* env,
|
||||
const IceCandidateInterface& candidate) {
|
||||
std::string sdp;
|
||||
RTC_CHECK(candidate.ToString(&sdp)) << "got so far: " << sdp;
|
||||
return CreateJavaIceCandidate(env, candidate.sdp_mid(),
|
||||
@ -64,7 +68,7 @@ jobject NativeToJavaIceCandidate(JNIEnv* env,
|
||||
candidate.candidate().url());
|
||||
}
|
||||
|
||||
jobjectArray NativeToJavaCandidateArray(
|
||||
ScopedJavaLocalRef<jobjectArray> NativeToJavaCandidateArray(
|
||||
JNIEnv* jni,
|
||||
const std::vector<cricket::Candidate>& candidates) {
|
||||
return NativeToJavaObjectArray(jni, candidates,
|
||||
@ -74,7 +78,7 @@ jobjectArray NativeToJavaCandidateArray(
|
||||
|
||||
PeerConnectionInterface::IceTransportsType JavaToNativeIceTransportsType(
|
||||
JNIEnv* jni,
|
||||
jobject j_ice_transports_type) {
|
||||
const JavaRef<jobject>& j_ice_transports_type) {
|
||||
std::string enum_name = GetJavaEnumName(jni, j_ice_transports_type);
|
||||
|
||||
if (enum_name == "ALL")
|
||||
@ -95,7 +99,7 @@ PeerConnectionInterface::IceTransportsType JavaToNativeIceTransportsType(
|
||||
|
||||
PeerConnectionInterface::BundlePolicy JavaToNativeBundlePolicy(
|
||||
JNIEnv* jni,
|
||||
jobject j_bundle_policy) {
|
||||
const JavaRef<jobject>& j_bundle_policy) {
|
||||
std::string enum_name = GetJavaEnumName(jni, j_bundle_policy);
|
||||
|
||||
if (enum_name == "BALANCED")
|
||||
@ -113,7 +117,7 @@ PeerConnectionInterface::BundlePolicy JavaToNativeBundlePolicy(
|
||||
|
||||
PeerConnectionInterface::RtcpMuxPolicy JavaToNativeRtcpMuxPolicy(
|
||||
JNIEnv* jni,
|
||||
jobject j_rtcp_mux_policy) {
|
||||
const JavaRef<jobject>& j_rtcp_mux_policy) {
|
||||
std::string enum_name = GetJavaEnumName(jni, j_rtcp_mux_policy);
|
||||
|
||||
if (enum_name == "NEGOTIATE")
|
||||
@ -128,7 +132,7 @@ PeerConnectionInterface::RtcpMuxPolicy JavaToNativeRtcpMuxPolicy(
|
||||
|
||||
PeerConnectionInterface::TcpCandidatePolicy JavaToNativeTcpCandidatePolicy(
|
||||
JNIEnv* jni,
|
||||
jobject j_tcp_candidate_policy) {
|
||||
const JavaRef<jobject>& j_tcp_candidate_policy) {
|
||||
std::string enum_name = GetJavaEnumName(jni, j_tcp_candidate_policy);
|
||||
|
||||
if (enum_name == "ENABLED")
|
||||
@ -142,8 +146,9 @@ PeerConnectionInterface::TcpCandidatePolicy JavaToNativeTcpCandidatePolicy(
|
||||
}
|
||||
|
||||
PeerConnectionInterface::CandidateNetworkPolicy
|
||||
JavaToNativeCandidateNetworkPolicy(JNIEnv* jni,
|
||||
jobject j_candidate_network_policy) {
|
||||
JavaToNativeCandidateNetworkPolicy(
|
||||
JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_candidate_network_policy) {
|
||||
std::string enum_name = GetJavaEnumName(jni, j_candidate_network_policy);
|
||||
|
||||
if (enum_name == "ALL")
|
||||
@ -157,7 +162,8 @@ JavaToNativeCandidateNetworkPolicy(JNIEnv* jni,
|
||||
return PeerConnectionInterface::kCandidateNetworkPolicyAll;
|
||||
}
|
||||
|
||||
rtc::KeyType JavaToNativeKeyType(JNIEnv* jni, jobject j_key_type) {
|
||||
rtc::KeyType JavaToNativeKeyType(JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_key_type) {
|
||||
std::string enum_name = GetJavaEnumName(jni, j_key_type);
|
||||
|
||||
if (enum_name == "RSA")
|
||||
@ -170,7 +176,9 @@ rtc::KeyType JavaToNativeKeyType(JNIEnv* jni, jobject j_key_type) {
|
||||
}
|
||||
|
||||
PeerConnectionInterface::ContinualGatheringPolicy
|
||||
JavaToNativeContinualGatheringPolicy(JNIEnv* jni, jobject j_gathering_policy) {
|
||||
JavaToNativeContinualGatheringPolicy(
|
||||
JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_gathering_policy) {
|
||||
std::string enum_name = GetJavaEnumName(jni, j_gathering_policy);
|
||||
if (enum_name == "GATHER_ONCE")
|
||||
return PeerConnectionInterface::GATHER_ONCE;
|
||||
@ -185,7 +193,7 @@ JavaToNativeContinualGatheringPolicy(JNIEnv* jni, jobject j_gathering_policy) {
|
||||
|
||||
PeerConnectionInterface::TlsCertPolicy JavaToNativeTlsCertPolicy(
|
||||
JNIEnv* jni,
|
||||
jobject j_ice_server_tls_cert_policy) {
|
||||
const JavaRef<jobject>& j_ice_server_tls_cert_policy) {
|
||||
std::string enum_name = GetJavaEnumName(jni, j_ice_server_tls_cert_policy);
|
||||
|
||||
if (enum_name == "TLS_CERT_POLICY_SECURE")
|
||||
|
||||
@ -24,14 +24,18 @@
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
cricket::Candidate JavaToNativeCandidate(JNIEnv* jni, jobject j_candidate);
|
||||
cricket::Candidate JavaToNativeCandidate(JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_candidate);
|
||||
|
||||
jobject NativeToJavaCandidate(JNIEnv* env, const cricket::Candidate& candidate);
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaCandidate(
|
||||
JNIEnv* env,
|
||||
const cricket::Candidate& candidate);
|
||||
|
||||
jobject NativeToJavaIceCandidate(JNIEnv* env,
|
||||
const IceCandidateInterface& candidate);
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaIceCandidate(
|
||||
JNIEnv* env,
|
||||
const IceCandidateInterface& candidate);
|
||||
|
||||
jobjectArray NativeToJavaCandidateArray(
|
||||
ScopedJavaLocalRef<jobjectArray> NativeToJavaCandidateArray(
|
||||
JNIEnv* jni,
|
||||
const std::vector<cricket::Candidate>& candidates);
|
||||
|
||||
@ -40,32 +44,36 @@ jobjectArray NativeToJavaCandidateArray(
|
||||
*****************************************************/
|
||||
PeerConnectionInterface::IceTransportsType JavaToNativeIceTransportsType(
|
||||
JNIEnv* jni,
|
||||
jobject j_ice_transports_type);
|
||||
const JavaRef<jobject>& j_ice_transports_type);
|
||||
|
||||
PeerConnectionInterface::BundlePolicy JavaToNativeBundlePolicy(
|
||||
JNIEnv* jni,
|
||||
jobject j_bundle_policy);
|
||||
const JavaRef<jobject>& j_bundle_policy);
|
||||
|
||||
PeerConnectionInterface::RtcpMuxPolicy JavaToNativeRtcpMuxPolicy(
|
||||
JNIEnv* jni,
|
||||
jobject j_rtcp_mux_policy);
|
||||
const JavaRef<jobject>& j_rtcp_mux_policy);
|
||||
|
||||
PeerConnectionInterface::TcpCandidatePolicy JavaToNativeTcpCandidatePolicy(
|
||||
JNIEnv* jni,
|
||||
jobject j_tcp_candidate_policy);
|
||||
const JavaRef<jobject>& j_tcp_candidate_policy);
|
||||
|
||||
PeerConnectionInterface::CandidateNetworkPolicy
|
||||
JavaToNativeCandidateNetworkPolicy(JNIEnv* jni,
|
||||
jobject j_candidate_network_policy);
|
||||
JavaToNativeCandidateNetworkPolicy(
|
||||
JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_candidate_network_policy);
|
||||
|
||||
rtc::KeyType JavaToNativeKeyType(JNIEnv* jni, jobject j_key_type);
|
||||
rtc::KeyType JavaToNativeKeyType(JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_key_type);
|
||||
|
||||
PeerConnectionInterface::ContinualGatheringPolicy
|
||||
JavaToNativeContinualGatheringPolicy(JNIEnv* jni, jobject j_gathering_policy);
|
||||
JavaToNativeContinualGatheringPolicy(
|
||||
JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_gathering_policy);
|
||||
|
||||
PeerConnectionInterface::TlsCertPolicy JavaToNativeTlsCertPolicy(
|
||||
JNIEnv* jni,
|
||||
jobject j_ice_server_tls_cert_policy);
|
||||
const JavaRef<jobject>& j_ice_server_tls_cert_policy);
|
||||
|
||||
} // namespace jni
|
||||
} // namespace webrtc
|
||||
|
||||
@ -48,8 +48,8 @@ JNI_FUNCTION_DECLARATION(void,
|
||||
jint j_severity,
|
||||
jstring j_tag,
|
||||
jstring j_message) {
|
||||
std::string message = JavaToStdString(jni, j_message);
|
||||
std::string tag = JavaToStdString(jni, j_tag);
|
||||
std::string message = JavaToStdString(jni, JavaParamRef<jstring>(j_message));
|
||||
std::string tag = JavaToStdString(jni, JavaParamRef<jstring>(j_tag));
|
||||
RTC_LOG_TAG(static_cast<rtc::LoggingSeverity>(j_severity), tag) << message;
|
||||
}
|
||||
|
||||
|
||||
@ -22,13 +22,12 @@ namespace {
|
||||
// Helper for translating a List<Pair<String, String>> to a Constraints.
|
||||
MediaConstraintsInterface::Constraints PopulateConstraintsFromJavaPairList(
|
||||
JNIEnv* env,
|
||||
jobject j_list) {
|
||||
const JavaRef<jobject>& j_list) {
|
||||
MediaConstraintsInterface::Constraints constraints;
|
||||
for (jobject entry : Iterable(env, j_list)) {
|
||||
jstring j_key = Java_KeyValuePair_getKey(env, entry);
|
||||
jstring j_value = Java_KeyValuePair_getValue(env, entry);
|
||||
constraints.emplace_back(JavaToStdString(env, j_key),
|
||||
JavaToStdString(env, j_value));
|
||||
for (const JavaRef<jobject>& entry : Iterable(env, j_list)) {
|
||||
constraints.emplace_back(
|
||||
JavaToStdString(env, Java_KeyValuePair_getKey(env, entry)),
|
||||
JavaToStdString(env, Java_KeyValuePair_getValue(env, entry)));
|
||||
}
|
||||
return constraints;
|
||||
}
|
||||
@ -37,7 +36,7 @@ MediaConstraintsInterface::Constraints PopulateConstraintsFromJavaPairList(
|
||||
// the constructor returns the Java object is no longer needed.
|
||||
class MediaConstraintsJni : public MediaConstraintsInterface {
|
||||
public:
|
||||
MediaConstraintsJni(JNIEnv* env, jobject j_constraints)
|
||||
MediaConstraintsJni(JNIEnv* env, const JavaRef<jobject>& j_constraints)
|
||||
: mandatory_(PopulateConstraintsFromJavaPairList(
|
||||
env,
|
||||
Java_MediaConstraints_getMandatory(env, j_constraints))),
|
||||
@ -59,7 +58,7 @@ class MediaConstraintsJni : public MediaConstraintsInterface {
|
||||
|
||||
std::unique_ptr<MediaConstraintsInterface> JavaToNativeMediaConstraints(
|
||||
JNIEnv* env,
|
||||
jobject j_constraints) {
|
||||
const JavaRef<jobject>& j_constraints) {
|
||||
return rtc::MakeUnique<MediaConstraintsJni>(env, j_constraints);
|
||||
}
|
||||
|
||||
|
||||
@ -15,13 +15,14 @@
|
||||
#include <memory>
|
||||
|
||||
#include "api/mediaconstraintsinterface.h"
|
||||
#include "sdk/android/src/jni/scoped_java_ref.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
std::unique_ptr<MediaConstraintsInterface> JavaToNativeMediaConstraints(
|
||||
JNIEnv* env,
|
||||
jobject j_constraints);
|
||||
const JavaRef<jobject>& j_constraints);
|
||||
|
||||
} // namespace jni
|
||||
} // namespace webrtc
|
||||
|
||||
@ -10,16 +10,12 @@
|
||||
|
||||
#include "api/mediastreaminterface.h"
|
||||
#include "sdk/android/generated_peerconnection_jni/jni/MediaSource_jni.h"
|
||||
#include "sdk/android/src/jni/jni_helpers.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jobject,
|
||||
MediaSource_getNativeState,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_p) {
|
||||
static ScopedJavaLocalRef<jobject>
|
||||
JNI_MediaSource_GetState(JNIEnv* jni, const JavaParamRef<jclass>&, jlong j_p) {
|
||||
return Java_State_fromNativeIndex(
|
||||
jni, reinterpret_cast<MediaSourceInterface*>(j_p)->state());
|
||||
}
|
||||
|
||||
@ -27,12 +27,12 @@ JavaMediaStream::JavaMediaStream(
|
||||
observer_(rtc::MakeUnique<MediaStreamObserver>(media_stream)) {
|
||||
for (rtc::scoped_refptr<AudioTrackInterface> track :
|
||||
media_stream->GetAudioTracks()) {
|
||||
Java_MediaStream_addNativeAudioTrack(env, *j_media_stream_,
|
||||
Java_MediaStream_addNativeAudioTrack(env, j_media_stream_,
|
||||
jlongFromPointer(track.release()));
|
||||
}
|
||||
for (rtc::scoped_refptr<VideoTrackInterface> track :
|
||||
media_stream->GetVideoTracks()) {
|
||||
Java_MediaStream_addNativeVideoTrack(env, *j_media_stream_,
|
||||
Java_MediaStream_addNativeVideoTrack(env, j_media_stream_,
|
||||
jlongFromPointer(track.release()));
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ JavaMediaStream::~JavaMediaStream() {
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
// Remove the observer first, so it doesn't react to events during deletion.
|
||||
observer_ = nullptr;
|
||||
Java_MediaStream_dispose(env, *j_media_stream_);
|
||||
Java_MediaStream_dispose(env, j_media_stream_);
|
||||
}
|
||||
|
||||
void JavaMediaStream::OnAudioTrackAddedToStream(AudioTrackInterface* track,
|
||||
@ -64,7 +64,7 @@ void JavaMediaStream::OnAudioTrackAddedToStream(AudioTrackInterface* track,
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(env);
|
||||
track->AddRef();
|
||||
Java_MediaStream_addNativeAudioTrack(env, *j_media_stream_,
|
||||
Java_MediaStream_addNativeAudioTrack(env, j_media_stream_,
|
||||
jlongFromPointer(track));
|
||||
}
|
||||
|
||||
@ -73,7 +73,7 @@ void JavaMediaStream::OnVideoTrackAddedToStream(VideoTrackInterface* track,
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(env);
|
||||
track->AddRef();
|
||||
Java_MediaStream_addNativeVideoTrack(env, *j_media_stream_,
|
||||
Java_MediaStream_addNativeVideoTrack(env, j_media_stream_,
|
||||
jlongFromPointer(track));
|
||||
}
|
||||
|
||||
@ -82,7 +82,7 @@ void JavaMediaStream::OnAudioTrackRemovedFromStream(
|
||||
MediaStreamInterface* stream) {
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(env);
|
||||
Java_MediaStream_removeAudioTrack(env, *j_media_stream_,
|
||||
Java_MediaStream_removeAudioTrack(env, j_media_stream_,
|
||||
jlongFromPointer(track));
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ void JavaMediaStream::OnVideoTrackRemovedFromStream(
|
||||
MediaStreamInterface* stream) {
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(env);
|
||||
Java_MediaStream_removeVideoTrack(env, *j_media_stream_,
|
||||
Java_MediaStream_removeVideoTrack(env, j_media_stream_,
|
||||
jlongFromPointer(track));
|
||||
}
|
||||
|
||||
@ -99,51 +99,42 @@ jclass GetMediaStreamClass(JNIEnv* env) {
|
||||
return org_webrtc_MediaStream_clazz(env);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jboolean,
|
||||
MediaStream_addAudioTrackToNativeStream,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong pointer,
|
||||
jlong j_audio_track_pointer) {
|
||||
static jboolean JNI_MediaStream_AddAudioTrackToNativeStream(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong pointer,
|
||||
jlong j_audio_track_pointer) {
|
||||
return reinterpret_cast<MediaStreamInterface*>(pointer)->AddTrack(
|
||||
reinterpret_cast<AudioTrackInterface*>(j_audio_track_pointer));
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jboolean,
|
||||
MediaStream_addVideoTrackToNativeStream,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong pointer,
|
||||
jlong j_video_track_pointer) {
|
||||
static jboolean JNI_MediaStream_AddVideoTrackToNativeStream(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong pointer,
|
||||
jlong j_video_track_pointer) {
|
||||
return reinterpret_cast<MediaStreamInterface*>(pointer)->AddTrack(
|
||||
reinterpret_cast<VideoTrackInterface*>(j_video_track_pointer));
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jboolean,
|
||||
MediaStream_removeNativeAudioTrack,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong pointer,
|
||||
jlong j_audio_track_pointer) {
|
||||
static jboolean JNI_MediaStream_RemoveAudioTrack(JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong pointer,
|
||||
jlong j_audio_track_pointer) {
|
||||
return reinterpret_cast<MediaStreamInterface*>(pointer)->RemoveTrack(
|
||||
reinterpret_cast<AudioTrackInterface*>(j_audio_track_pointer));
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jboolean,
|
||||
MediaStream_removeNativeVideoTrack,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong pointer,
|
||||
jlong j_video_track_pointer) {
|
||||
static jboolean JNI_MediaStream_RemoveVideoTrack(JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong pointer,
|
||||
jlong j_video_track_pointer) {
|
||||
return reinterpret_cast<MediaStreamInterface*>(pointer)->RemoveTrack(
|
||||
reinterpret_cast<VideoTrackInterface*>(j_video_track_pointer));
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jstring,
|
||||
MediaStream_getNativeLabel,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_p) {
|
||||
static ScopedJavaLocalRef<jstring>
|
||||
JNI_MediaStream_GetLabel(JNIEnv* jni, const JavaParamRef<jclass>&, jlong j_p) {
|
||||
return NativeToJavaString(
|
||||
jni, reinterpret_cast<MediaStreamInterface*>(j_p)->label());
|
||||
}
|
||||
|
||||
@ -28,7 +28,9 @@ class JavaMediaStream : public sigslot::has_slots<> {
|
||||
rtc::scoped_refptr<MediaStreamInterface> media_stream);
|
||||
~JavaMediaStream();
|
||||
|
||||
jobject j_media_stream() { return *j_media_stream_; }
|
||||
const ScopedJavaGlobalRef<jobject>& j_media_stream() {
|
||||
return j_media_stream_;
|
||||
}
|
||||
|
||||
private:
|
||||
void OnAudioTrackAddedToStream(AudioTrackInterface* track,
|
||||
@ -40,7 +42,7 @@ class JavaMediaStream : public sigslot::has_slots<> {
|
||||
void OnVideoTrackRemovedFromStream(VideoTrackInterface* track,
|
||||
MediaStreamInterface* stream);
|
||||
|
||||
ScopedGlobalRef<jobject> j_media_stream_;
|
||||
ScopedJavaGlobalRef<jobject> j_media_stream_;
|
||||
std::unique_ptr<MediaStreamObserver> observer_;
|
||||
};
|
||||
|
||||
|
||||
@ -17,56 +17,52 @@
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
jobject NativeToJavaMediaType(JNIEnv* jni, cricket::MediaType media_type) {
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaMediaType(
|
||||
JNIEnv* jni,
|
||||
cricket::MediaType media_type) {
|
||||
return Java_MediaType_fromNativeIndex(jni, media_type);
|
||||
}
|
||||
|
||||
cricket::MediaType JavaToNativeMediaType(JNIEnv* jni, jobject j_media_type) {
|
||||
cricket::MediaType JavaToNativeMediaType(JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_media_type) {
|
||||
return static_cast<cricket::MediaType>(
|
||||
Java_MediaType_getNative(jni, j_media_type));
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jstring,
|
||||
MediaStreamTrack_getNativeId,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_p) {
|
||||
static ScopedJavaLocalRef<jstring> JNI_MediaStreamTrack_GetId(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_p) {
|
||||
return NativeToJavaString(
|
||||
jni, reinterpret_cast<MediaStreamTrackInterface*>(j_p)->id());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jstring,
|
||||
MediaStreamTrack_getNativeKind,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_p) {
|
||||
static ScopedJavaLocalRef<jstring> JNI_MediaStreamTrack_GetKind(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_p) {
|
||||
return NativeToJavaString(
|
||||
jni, reinterpret_cast<MediaStreamTrackInterface*>(j_p)->kind());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jboolean,
|
||||
MediaStreamTrack_getNativeEnabled,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_p) {
|
||||
static jboolean JNI_MediaStreamTrack_GetEnabled(JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_p) {
|
||||
return reinterpret_cast<MediaStreamTrackInterface*>(j_p)->enabled();
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jobject,
|
||||
MediaStreamTrack_getNativeState,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_p) {
|
||||
static ScopedJavaLocalRef<jobject> JNI_MediaStreamTrack_GetState(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_p) {
|
||||
return Java_State_fromNativeIndex(
|
||||
jni, reinterpret_cast<MediaStreamTrackInterface*>(j_p)->state());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jboolean,
|
||||
MediaStreamTrack_setNativeEnabled,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_p,
|
||||
jboolean enabled) {
|
||||
static jboolean JNI_MediaStreamTrack_SetEnabled(JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_p,
|
||||
jboolean enabled) {
|
||||
return reinterpret_cast<MediaStreamTrackInterface*>(j_p)->set_enabled(
|
||||
enabled);
|
||||
}
|
||||
|
||||
@ -14,12 +14,16 @@
|
||||
#include <jni.h>
|
||||
|
||||
#include "api/mediatypes.h"
|
||||
#include "sdk/android/src/jni/scoped_java_ref.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
jobject NativeToJavaMediaType(JNIEnv* jni, cricket::MediaType media_type);
|
||||
cricket::MediaType JavaToNativeMediaType(JNIEnv* jni, jobject j_media_type);
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaMediaType(
|
||||
JNIEnv* jni,
|
||||
cricket::MediaType media_type);
|
||||
cricket::MediaType JavaToNativeMediaType(JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_media_type);
|
||||
|
||||
} // namespace jni
|
||||
} // namespace webrtc
|
||||
|
||||
@ -13,13 +13,30 @@
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
VideoEncoderFactory* CreateVideoEncoderFactory(JNIEnv* jni,
|
||||
jobject j_encoder_factory) {
|
||||
VideoEncoderFactory* CreateVideoEncoderFactory(
|
||||
JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_encoder_factory) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
VideoDecoderFactory* CreateVideoDecoderFactory(JNIEnv* jni,
|
||||
jobject j_decoder_factory) {
|
||||
VideoDecoderFactory* CreateVideoDecoderFactory(
|
||||
JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_decoder_factory) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SetEglContext(JNIEnv* env,
|
||||
cricket::WebRtcVideoEncoderFactory* encoder_factory,
|
||||
const JavaRef<jobject>& egl_context) {}
|
||||
void SetEglContext(JNIEnv* env,
|
||||
cricket::WebRtcVideoDecoderFactory* decoder_factory,
|
||||
const JavaRef<jobject>& egl_context) {}
|
||||
|
||||
void* CreateVideoSource(JNIEnv* env,
|
||||
rtc::Thread* signaling_thread,
|
||||
rtc::Thread* worker_thread,
|
||||
const JavaParamRef<jobject>& j_surface_texture_helper,
|
||||
jboolean is_screencast) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@ -56,27 +56,32 @@ namespace jni {
|
||||
|
||||
namespace {
|
||||
|
||||
PeerConnectionInterface* ExtractNativePC(JNIEnv* jni, jobject j_pc) {
|
||||
PeerConnectionInterface* ExtractNativePC(JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_pc) {
|
||||
return reinterpret_cast<PeerConnectionInterface*>(
|
||||
Java_PeerConnection_getNativePeerConnection(jni, j_pc));
|
||||
}
|
||||
|
||||
PeerConnectionInterface::IceServers JavaToNativeIceServers(
|
||||
JNIEnv* jni,
|
||||
jobject j_ice_servers) {
|
||||
const JavaRef<jobject>& j_ice_servers) {
|
||||
PeerConnectionInterface::IceServers ice_servers;
|
||||
for (jobject j_ice_server : Iterable(jni, j_ice_servers)) {
|
||||
jobject j_ice_server_tls_cert_policy =
|
||||
for (const JavaRef<jobject>& j_ice_server : Iterable(jni, j_ice_servers)) {
|
||||
ScopedJavaLocalRef<jobject> j_ice_server_tls_cert_policy =
|
||||
Java_IceServer_getTlsCertPolicy(jni, j_ice_server);
|
||||
jobject urls = Java_IceServer_getUrls(jni, j_ice_server);
|
||||
jstring username = Java_IceServer_getUsername(jni, j_ice_server);
|
||||
jstring password = Java_IceServer_getPassword(jni, j_ice_server);
|
||||
ScopedJavaLocalRef<jobject> urls =
|
||||
Java_IceServer_getUrls(jni, j_ice_server);
|
||||
ScopedJavaLocalRef<jstring> username =
|
||||
Java_IceServer_getUsername(jni, j_ice_server);
|
||||
ScopedJavaLocalRef<jstring> password =
|
||||
Java_IceServer_getPassword(jni, j_ice_server);
|
||||
PeerConnectionInterface::TlsCertPolicy tls_cert_policy =
|
||||
JavaToNativeTlsCertPolicy(jni, j_ice_server_tls_cert_policy);
|
||||
jstring hostname = Java_IceServer_getHostname(jni, j_ice_server);
|
||||
jobject tls_alpn_protocols =
|
||||
ScopedJavaLocalRef<jstring> hostname =
|
||||
Java_IceServer_getHostname(jni, j_ice_server);
|
||||
ScopedJavaLocalRef<jobject> tls_alpn_protocols =
|
||||
Java_IceServer_getTlsAlpnProtocols(jni, j_ice_server);
|
||||
jobject tls_elliptic_curves =
|
||||
ScopedJavaLocalRef<jobject> tls_elliptic_curves =
|
||||
Java_IceServer_getTlsEllipticCurves(jni, j_ice_server);
|
||||
PeerConnectionInterface::IceServer server;
|
||||
server.urls = JavaToStdVectorStrings(jni, urls);
|
||||
@ -96,23 +101,23 @@ PeerConnectionInterface::IceServers JavaToNativeIceServers(
|
||||
|
||||
void JavaToNativeRTCConfiguration(
|
||||
JNIEnv* jni,
|
||||
jobject j_rtc_config,
|
||||
const JavaRef<jobject>& j_rtc_config,
|
||||
PeerConnectionInterface::RTCConfiguration* rtc_config) {
|
||||
jobject j_ice_transports_type =
|
||||
ScopedJavaLocalRef<jobject> j_ice_transports_type =
|
||||
Java_RTCConfiguration_getIceTransportsType(jni, j_rtc_config);
|
||||
jobject j_bundle_policy =
|
||||
ScopedJavaLocalRef<jobject> j_bundle_policy =
|
||||
Java_RTCConfiguration_getBundlePolicy(jni, j_rtc_config);
|
||||
jobject j_rtcp_mux_policy =
|
||||
ScopedJavaLocalRef<jobject> j_rtcp_mux_policy =
|
||||
Java_RTCConfiguration_getRtcpMuxPolicy(jni, j_rtc_config);
|
||||
jobject j_tcp_candidate_policy =
|
||||
ScopedJavaLocalRef<jobject> j_tcp_candidate_policy =
|
||||
Java_RTCConfiguration_getTcpCandidatePolicy(jni, j_rtc_config);
|
||||
jobject j_candidate_network_policy =
|
||||
ScopedJavaLocalRef<jobject> j_candidate_network_policy =
|
||||
Java_RTCConfiguration_getCandidateNetworkPolicy(jni, j_rtc_config);
|
||||
jobject j_ice_servers =
|
||||
ScopedJavaLocalRef<jobject> j_ice_servers =
|
||||
Java_RTCConfiguration_getIceServers(jni, j_rtc_config);
|
||||
jobject j_continual_gathering_policy =
|
||||
ScopedJavaLocalRef<jobject> j_continual_gathering_policy =
|
||||
Java_RTCConfiguration_getContinualGatheringPolicy(jni, j_rtc_config);
|
||||
jobject j_turn_customizer =
|
||||
ScopedJavaLocalRef<jobject> j_turn_customizer =
|
||||
Java_RTCConfiguration_getTurnCustomizer(jni, j_rtc_config);
|
||||
|
||||
rtc_config->type = JavaToNativeIceTransportsType(jni, j_ice_transports_type);
|
||||
@ -143,7 +148,7 @@ void JavaToNativeRTCConfiguration(
|
||||
rtc_config->presume_writable_when_fully_relayed =
|
||||
Java_RTCConfiguration_getPresumeWritableWhenFullyRelayed(jni,
|
||||
j_rtc_config);
|
||||
jobject j_ice_check_min_interval =
|
||||
ScopedJavaLocalRef<jobject> j_ice_check_min_interval =
|
||||
Java_RTCConfiguration_getIceCheckMinInterval(jni, j_rtc_config);
|
||||
rtc_config->ice_check_min_interval =
|
||||
JavaToNativeOptionalInt(jni, j_ice_check_min_interval);
|
||||
@ -151,7 +156,7 @@ void JavaToNativeRTCConfiguration(
|
||||
Java_RTCConfiguration_getDisableIPv6OnWifi(jni, j_rtc_config);
|
||||
rtc_config->max_ipv6_networks =
|
||||
Java_RTCConfiguration_getMaxIPv6Networks(jni, j_rtc_config);
|
||||
jobject j_ice_regather_interval_range =
|
||||
ScopedJavaLocalRef<jobject> j_ice_regather_interval_range =
|
||||
Java_RTCConfiguration_getIceRegatherIntervalRange(jni, j_rtc_config);
|
||||
if (!IsNull(jni, j_ice_regather_interval_range)) {
|
||||
int min = Java_IntervalRange_getMin(jni, j_ice_regather_interval_range);
|
||||
@ -179,13 +184,15 @@ void JavaToNativeRTCConfiguration(
|
||||
jni, Java_RTCConfiguration_getEnableDtlsSrtp(jni, j_rtc_config));
|
||||
}
|
||||
|
||||
rtc::KeyType GetRtcConfigKeyType(JNIEnv* env, jobject j_rtc_config) {
|
||||
rtc::KeyType GetRtcConfigKeyType(JNIEnv* env,
|
||||
const JavaRef<jobject>& j_rtc_config) {
|
||||
return JavaToNativeKeyType(
|
||||
env, Java_RTCConfiguration_getKeyType(env, j_rtc_config));
|
||||
}
|
||||
|
||||
PeerConnectionObserverJni::PeerConnectionObserverJni(JNIEnv* jni,
|
||||
jobject j_observer)
|
||||
PeerConnectionObserverJni::PeerConnectionObserverJni(
|
||||
JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_observer)
|
||||
: j_observer_global_(jni, j_observer) {}
|
||||
|
||||
PeerConnectionObserverJni::~PeerConnectionObserverJni() = default;
|
||||
@ -193,70 +200,62 @@ PeerConnectionObserverJni::~PeerConnectionObserverJni() = default;
|
||||
void PeerConnectionObserverJni::OnIceCandidate(
|
||||
const IceCandidateInterface* candidate) {
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(env);
|
||||
Java_Observer_onIceCandidate(env, *j_observer_global_,
|
||||
Java_Observer_onIceCandidate(env, j_observer_global_,
|
||||
NativeToJavaIceCandidate(env, *candidate));
|
||||
}
|
||||
|
||||
void PeerConnectionObserverJni::OnIceCandidatesRemoved(
|
||||
const std::vector<cricket::Candidate>& candidates) {
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(env);
|
||||
Java_Observer_onIceCandidatesRemoved(
|
||||
env, *j_observer_global_, NativeToJavaCandidateArray(env, candidates));
|
||||
env, j_observer_global_, NativeToJavaCandidateArray(env, candidates));
|
||||
}
|
||||
|
||||
void PeerConnectionObserverJni::OnSignalingChange(
|
||||
PeerConnectionInterface::SignalingState new_state) {
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(env);
|
||||
Java_Observer_onSignalingChange(
|
||||
env, *j_observer_global_,
|
||||
env, j_observer_global_,
|
||||
Java_SignalingState_fromNativeIndex(env, new_state));
|
||||
}
|
||||
|
||||
void PeerConnectionObserverJni::OnIceConnectionChange(
|
||||
PeerConnectionInterface::IceConnectionState new_state) {
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(env);
|
||||
Java_Observer_onIceConnectionChange(
|
||||
env, *j_observer_global_,
|
||||
env, j_observer_global_,
|
||||
Java_IceConnectionState_fromNativeIndex(env, new_state));
|
||||
}
|
||||
|
||||
void PeerConnectionObserverJni::OnIceConnectionReceivingChange(bool receiving) {
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(env);
|
||||
Java_Observer_onIceConnectionReceivingChange(env, *j_observer_global_,
|
||||
Java_Observer_onIceConnectionReceivingChange(env, j_observer_global_,
|
||||
receiving);
|
||||
}
|
||||
|
||||
void PeerConnectionObserverJni::OnIceGatheringChange(
|
||||
PeerConnectionInterface::IceGatheringState new_state) {
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(env);
|
||||
Java_Observer_onIceGatheringChange(
|
||||
env, *j_observer_global_,
|
||||
env, j_observer_global_,
|
||||
Java_IceGatheringState_fromNativeIndex(env, new_state));
|
||||
}
|
||||
|
||||
void PeerConnectionObserverJni::OnAddStream(
|
||||
rtc::scoped_refptr<MediaStreamInterface> stream) {
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(env);
|
||||
jobject j_stream = GetOrCreateJavaStream(env, stream).j_media_stream();
|
||||
Java_Observer_onAddStream(env, *j_observer_global_, j_stream);
|
||||
|
||||
Java_Observer_onAddStream(
|
||||
env, j_observer_global_,
|
||||
GetOrCreateJavaStream(env, stream).j_media_stream());
|
||||
}
|
||||
|
||||
void PeerConnectionObserverJni::OnRemoveStream(
|
||||
rtc::scoped_refptr<MediaStreamInterface> stream) {
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(env);
|
||||
NativeToJavaStreamsMap::iterator it = remote_streams_.find(stream);
|
||||
RTC_CHECK(it != remote_streams_.end())
|
||||
<< "unexpected stream: " << std::hex << stream;
|
||||
Java_Observer_onRemoveStream(env, *j_observer_global_,
|
||||
Java_Observer_onRemoveStream(env, j_observer_global_,
|
||||
it->second.j_media_stream());
|
||||
remote_streams_.erase(it);
|
||||
}
|
||||
@ -264,26 +263,24 @@ void PeerConnectionObserverJni::OnRemoveStream(
|
||||
void PeerConnectionObserverJni::OnDataChannel(
|
||||
rtc::scoped_refptr<DataChannelInterface> channel) {
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(env);
|
||||
Java_Observer_onDataChannel(env, *j_observer_global_,
|
||||
Java_Observer_onDataChannel(env, j_observer_global_,
|
||||
WrapNativeDataChannel(env, channel));
|
||||
}
|
||||
|
||||
void PeerConnectionObserverJni::OnRenegotiationNeeded() {
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(env);
|
||||
Java_Observer_onRenegotiationNeeded(env, *j_observer_global_);
|
||||
Java_Observer_onRenegotiationNeeded(env, j_observer_global_);
|
||||
}
|
||||
|
||||
void PeerConnectionObserverJni::OnAddTrack(
|
||||
rtc::scoped_refptr<RtpReceiverInterface> receiver,
|
||||
const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(env);
|
||||
jobject j_rtp_receiver = NativeToJavaRtpReceiver(env, receiver);
|
||||
ScopedJavaLocalRef<jobject> j_rtp_receiver =
|
||||
NativeToJavaRtpReceiver(env, receiver);
|
||||
rtp_receivers_.emplace_back(env, j_rtp_receiver);
|
||||
|
||||
Java_Observer_onAddTrack(env, *j_observer_global_, j_rtp_receiver,
|
||||
Java_Observer_onAddTrack(env, j_observer_global_, j_rtp_receiver,
|
||||
NativeToJavaMediaStreamArray(env, streams));
|
||||
}
|
||||
|
||||
@ -309,61 +306,55 @@ JavaMediaStream& PeerConnectionObserverJni::GetOrCreateJavaStream(
|
||||
return it->second;
|
||||
}
|
||||
|
||||
jobjectArray PeerConnectionObserverJni::NativeToJavaMediaStreamArray(
|
||||
ScopedJavaLocalRef<jobjectArray>
|
||||
PeerConnectionObserverJni::NativeToJavaMediaStreamArray(
|
||||
JNIEnv* jni,
|
||||
const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
|
||||
jobjectArray java_streams =
|
||||
jni->NewObjectArray(streams.size(), GetMediaStreamClass(jni), nullptr);
|
||||
CHECK_EXCEPTION(jni) << "error during NewObjectArray";
|
||||
for (size_t i = 0; i < streams.size(); ++i) {
|
||||
jobject j_stream = GetOrCreateJavaStream(jni, streams[i]).j_media_stream();
|
||||
jni->SetObjectArrayElement(java_streams, i, j_stream);
|
||||
}
|
||||
return java_streams;
|
||||
return NativeToJavaObjectArray(
|
||||
jni, streams, GetMediaStreamClass(jni),
|
||||
[this](JNIEnv* env, rtc::scoped_refptr<MediaStreamInterface> stream)
|
||||
-> const ScopedJavaGlobalRef<jobject>& {
|
||||
return GetOrCreateJavaStream(env, stream).j_media_stream();
|
||||
});
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jlong,
|
||||
PeerConnection_createNativePeerConnectionObserver,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jobject j_observer) {
|
||||
static jlong JNI_PeerConnection_CreatePeerConnectionObserver(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
const JavaParamRef<jobject>& j_observer) {
|
||||
return jlongFromPointer(new PeerConnectionObserverJni(jni, j_observer));
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
PeerConnection_freeNativePeerConnectionObserver,
|
||||
JNIEnv*,
|
||||
jclass,
|
||||
jlong j_p) {
|
||||
static void JNI_PeerConnection_FreePeerConnectionObserver(
|
||||
JNIEnv*,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_p) {
|
||||
PeerConnectionObserverJni* p =
|
||||
reinterpret_cast<PeerConnectionObserverJni*>(j_p);
|
||||
delete p;
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jobject,
|
||||
PeerConnection_getLocalDescription,
|
||||
JNIEnv* jni,
|
||||
jobject j_pc) {
|
||||
static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetLocalDescription(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_pc) {
|
||||
const SessionDescriptionInterface* sdp =
|
||||
ExtractNativePC(jni, j_pc)->local_description();
|
||||
return sdp ? NativeToJavaSessionDescription(jni, sdp) : nullptr;
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jobject,
|
||||
PeerConnection_getRemoteDescription,
|
||||
JNIEnv* jni,
|
||||
jobject j_pc) {
|
||||
static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetRemoteDescription(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_pc) {
|
||||
const SessionDescriptionInterface* sdp =
|
||||
ExtractNativePC(jni, j_pc)->remote_description();
|
||||
return sdp ? NativeToJavaSessionDescription(jni, sdp) : nullptr;
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jobject,
|
||||
PeerConnection_createDataChannel,
|
||||
JNIEnv* jni,
|
||||
jobject j_pc,
|
||||
jstring j_label,
|
||||
jobject j_init) {
|
||||
static ScopedJavaLocalRef<jobject> JNI_PeerConnection_CreateDataChannel(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_pc,
|
||||
const JavaParamRef<jstring>& j_label,
|
||||
const JavaParamRef<jobject>& j_init) {
|
||||
DataChannelInit init = JavaToNativeDataChannelInit(jni, j_init);
|
||||
rtc::scoped_refptr<DataChannelInterface> channel(
|
||||
ExtractNativePC(jni, j_pc)->CreateDataChannel(
|
||||
@ -371,12 +362,11 @@ JNI_FUNCTION_DECLARATION(jobject,
|
||||
return WrapNativeDataChannel(jni, channel);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
PeerConnection_createOffer,
|
||||
JNIEnv* jni,
|
||||
jobject j_pc,
|
||||
jobject j_observer,
|
||||
jobject j_constraints) {
|
||||
static void JNI_PeerConnection_CreateOffer(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_pc,
|
||||
const JavaParamRef<jobject>& j_observer,
|
||||
const JavaParamRef<jobject>& j_constraints) {
|
||||
std::unique_ptr<MediaConstraintsInterface> constraints =
|
||||
JavaToNativeMediaConstraints(jni, j_constraints);
|
||||
rtc::scoped_refptr<CreateSdpObserverJni> observer(
|
||||
@ -385,12 +375,11 @@ JNI_FUNCTION_DECLARATION(void,
|
||||
ExtractNativePC(jni, j_pc)->CreateOffer(observer, observer->constraints());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
PeerConnection_createAnswer,
|
||||
JNIEnv* jni,
|
||||
jobject j_pc,
|
||||
jobject j_observer,
|
||||
jobject j_constraints) {
|
||||
static void JNI_PeerConnection_CreateAnswer(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_pc,
|
||||
const JavaParamRef<jobject>& j_observer,
|
||||
const JavaParamRef<jobject>& j_constraints) {
|
||||
std::unique_ptr<MediaConstraintsInterface> constraints =
|
||||
JavaToNativeMediaConstraints(jni, j_constraints);
|
||||
rtc::scoped_refptr<CreateSdpObserverJni> observer(
|
||||
@ -399,52 +388,47 @@ JNI_FUNCTION_DECLARATION(void,
|
||||
ExtractNativePC(jni, j_pc)->CreateAnswer(observer, observer->constraints());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
PeerConnection_setLocalDescription,
|
||||
JNIEnv* jni,
|
||||
jobject j_pc,
|
||||
jobject j_observer,
|
||||
jobject j_sdp) {
|
||||
static void JNI_PeerConnection_SetLocalDescription(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_pc,
|
||||
const JavaParamRef<jobject>& j_observer,
|
||||
const JavaParamRef<jobject>& j_sdp) {
|
||||
rtc::scoped_refptr<SetSdpObserverJni> observer(
|
||||
new rtc::RefCountedObject<SetSdpObserverJni>(jni, j_observer, nullptr));
|
||||
ExtractNativePC(jni, j_pc)->SetLocalDescription(
|
||||
observer, JavaToNativeSessionDescription(jni, j_sdp).release());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
PeerConnection_setRemoteDescription,
|
||||
JNIEnv* jni,
|
||||
jobject j_pc,
|
||||
jobject j_observer,
|
||||
jobject j_sdp) {
|
||||
static void JNI_PeerConnection_SetRemoteDescription(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_pc,
|
||||
const JavaParamRef<jobject>& j_observer,
|
||||
const JavaParamRef<jobject>& j_sdp) {
|
||||
rtc::scoped_refptr<SetSdpObserverJni> observer(
|
||||
new rtc::RefCountedObject<SetSdpObserverJni>(jni, j_observer, nullptr));
|
||||
ExtractNativePC(jni, j_pc)->SetRemoteDescription(
|
||||
observer, JavaToNativeSessionDescription(jni, j_sdp).release());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
PeerConnection_setAudioPlayout,
|
||||
JNIEnv* jni,
|
||||
jobject j_pc,
|
||||
jboolean playout) {
|
||||
static void JNI_PeerConnection_SetAudioPlayout(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_pc,
|
||||
jboolean playout) {
|
||||
ExtractNativePC(jni, j_pc)->SetAudioPlayout(playout);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
PeerConnection_setAudioRecording,
|
||||
JNIEnv* jni,
|
||||
jobject j_pc,
|
||||
jboolean recording) {
|
||||
static void JNI_PeerConnection_SetAudioRecording(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_pc,
|
||||
jboolean recording) {
|
||||
ExtractNativePC(jni, j_pc)->SetAudioRecording(recording);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jboolean,
|
||||
PeerConnection_setNativeConfiguration,
|
||||
JNIEnv* jni,
|
||||
jobject j_pc,
|
||||
jobject j_rtc_config,
|
||||
jlong native_observer) {
|
||||
static jboolean JNI_PeerConnection_SetConfiguration(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_pc,
|
||||
const JavaParamRef<jobject>& j_rtc_config,
|
||||
jlong native_observer) {
|
||||
// Need to merge constraints into RTCConfiguration again, which are stored
|
||||
// in the observer object.
|
||||
PeerConnectionObserverJni* observer =
|
||||
@ -458,13 +442,12 @@ JNI_FUNCTION_DECLARATION(jboolean,
|
||||
return ExtractNativePC(jni, j_pc)->SetConfiguration(rtc_config);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jboolean,
|
||||
PeerConnection_addNativeIceCandidate,
|
||||
JNIEnv* jni,
|
||||
jobject j_pc,
|
||||
jstring j_sdp_mid,
|
||||
jint j_sdp_mline_index,
|
||||
jstring j_candidate_sdp) {
|
||||
static jboolean JNI_PeerConnection_AddIceCandidate(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_pc,
|
||||
const JavaParamRef<jstring>& j_sdp_mid,
|
||||
jint j_sdp_mline_index,
|
||||
const JavaParamRef<jstring>& j_candidate_sdp) {
|
||||
std::string sdp_mid = JavaToStdString(jni, j_sdp_mid);
|
||||
std::string sdp = JavaToStdString(jni, j_candidate_sdp);
|
||||
std::unique_ptr<IceCandidateInterface> candidate(
|
||||
@ -472,41 +455,37 @@ JNI_FUNCTION_DECLARATION(jboolean,
|
||||
return ExtractNativePC(jni, j_pc)->AddIceCandidate(candidate.get());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jboolean,
|
||||
PeerConnection_removeNativeIceCandidates,
|
||||
JNIEnv* jni,
|
||||
jobject j_pc,
|
||||
jobjectArray j_candidates) {
|
||||
static jboolean JNI_PeerConnection_RemoveIceCandidates(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_pc,
|
||||
const JavaParamRef<jobjectArray>& j_candidates) {
|
||||
std::vector<cricket::Candidate> candidates =
|
||||
JavaToNativeVector<cricket::Candidate>(jni, j_candidates,
|
||||
&JavaToNativeCandidate);
|
||||
return ExtractNativePC(jni, j_pc)->RemoveIceCandidates(candidates);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jboolean,
|
||||
PeerConnection_addNativeLocalStream,
|
||||
JNIEnv* jni,
|
||||
jobject j_pc,
|
||||
jlong native_stream) {
|
||||
static jboolean JNI_PeerConnection_AddLocalStream(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_pc,
|
||||
jlong native_stream) {
|
||||
return ExtractNativePC(jni, j_pc)->AddStream(
|
||||
reinterpret_cast<MediaStreamInterface*>(native_stream));
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
PeerConnection_removeNativeLocalStream,
|
||||
JNIEnv* jni,
|
||||
jobject j_pc,
|
||||
jlong native_stream) {
|
||||
static void JNI_PeerConnection_RemoveLocalStream(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_pc,
|
||||
jlong native_stream) {
|
||||
ExtractNativePC(jni, j_pc)->RemoveStream(
|
||||
reinterpret_cast<MediaStreamInterface*>(native_stream));
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jobject,
|
||||
PeerConnection_createNativeSender,
|
||||
JNIEnv* jni,
|
||||
jobject j_pc,
|
||||
jstring j_kind,
|
||||
jstring j_stream_id) {
|
||||
static ScopedJavaLocalRef<jobject> JNI_PeerConnection_CreateSender(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_pc,
|
||||
const JavaParamRef<jstring>& j_kind,
|
||||
const JavaParamRef<jstring>& j_stream_id) {
|
||||
std::string kind = JavaToStdString(jni, j_kind);
|
||||
std::string stream_id = JavaToStdString(jni, j_stream_id);
|
||||
rtc::scoped_refptr<RtpSenderInterface> sender =
|
||||
@ -514,28 +493,25 @@ JNI_FUNCTION_DECLARATION(jobject,
|
||||
return NativeToJavaRtpSender(jni, sender);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jobject,
|
||||
PeerConnection_getNativeSenders,
|
||||
JNIEnv* jni,
|
||||
jobject j_pc) {
|
||||
static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetSenders(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_pc) {
|
||||
return NativeToJavaList(jni, ExtractNativePC(jni, j_pc)->GetSenders(),
|
||||
&NativeToJavaRtpSender);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jobject,
|
||||
PeerConnection_getNativeReceivers,
|
||||
JNIEnv* jni,
|
||||
jobject j_pc) {
|
||||
static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetReceivers(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_pc) {
|
||||
return NativeToJavaList(jni, ExtractNativePC(jni, j_pc)->GetReceivers(),
|
||||
&NativeToJavaRtpReceiver);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(bool,
|
||||
PeerConnection_oldGetNativeStats,
|
||||
JNIEnv* jni,
|
||||
jobject j_pc,
|
||||
jobject j_observer,
|
||||
jlong native_track) {
|
||||
static jboolean JNI_PeerConnection_OldGetStats(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_pc,
|
||||
const JavaParamRef<jobject>& j_observer,
|
||||
jlong native_track) {
|
||||
rtc::scoped_refptr<StatsObserverJni> observer(
|
||||
new rtc::RefCountedObject<StatsObserverJni>(jni, j_observer));
|
||||
return ExtractNativePC(jni, j_pc)->GetStats(
|
||||
@ -543,24 +519,22 @@ JNI_FUNCTION_DECLARATION(bool,
|
||||
PeerConnectionInterface::kStatsOutputLevelStandard);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
PeerConnection_newGetNativeStats,
|
||||
JNIEnv* jni,
|
||||
jobject j_pc,
|
||||
jobject j_callback) {
|
||||
static void JNI_PeerConnection_NewGetStats(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_pc,
|
||||
const JavaParamRef<jobject>& j_callback) {
|
||||
rtc::scoped_refptr<RTCStatsCollectorCallbackWrapper> callback(
|
||||
new rtc::RefCountedObject<RTCStatsCollectorCallbackWrapper>(jni,
|
||||
j_callback));
|
||||
ExtractNativePC(jni, j_pc)->GetStats(callback);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jboolean,
|
||||
PeerConnection_setBitrate,
|
||||
JNIEnv* jni,
|
||||
jobject j_pc,
|
||||
jobject j_min,
|
||||
jobject j_current,
|
||||
jobject j_max) {
|
||||
static jboolean JNI_PeerConnection_SetBitrate(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_pc,
|
||||
const JavaParamRef<jobject>& j_min,
|
||||
const JavaParamRef<jobject>& j_current,
|
||||
const JavaParamRef<jobject>& j_max) {
|
||||
PeerConnectionInterface::BitrateParameters params;
|
||||
params.min_bitrate_bps = JavaToNativeOptionalInt(jni, j_min);
|
||||
params.current_bitrate_bps = JavaToNativeOptionalInt(jni, j_current);
|
||||
@ -568,51 +542,44 @@ JNI_FUNCTION_DECLARATION(jboolean,
|
||||
return ExtractNativePC(jni, j_pc)->SetBitrate(params).ok();
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(bool,
|
||||
PeerConnection_startNativeRtcEventLog,
|
||||
JNIEnv* jni,
|
||||
jobject j_pc,
|
||||
int file_descriptor,
|
||||
int max_size_bytes) {
|
||||
static jboolean JNI_PeerConnection_StartRtcEventLog(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_pc,
|
||||
int file_descriptor,
|
||||
int max_size_bytes) {
|
||||
return ExtractNativePC(jni, j_pc)->StartRtcEventLog(file_descriptor,
|
||||
max_size_bytes);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
PeerConnection_stopNativeRtcEventLog,
|
||||
JNIEnv* jni,
|
||||
jobject j_pc) {
|
||||
static void JNI_PeerConnection_StopRtcEventLog(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_pc) {
|
||||
ExtractNativePC(jni, j_pc)->StopRtcEventLog();
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jobject,
|
||||
PeerConnection_signalingState,
|
||||
JNIEnv* env,
|
||||
jobject j_pc) {
|
||||
static ScopedJavaLocalRef<jobject> JNI_PeerConnection_SignalingState(
|
||||
JNIEnv* env,
|
||||
const JavaParamRef<jobject>& j_pc) {
|
||||
return Java_SignalingState_fromNativeIndex(
|
||||
env, ExtractNativePC(env, j_pc)->signaling_state());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jobject,
|
||||
PeerConnection_iceConnectionState,
|
||||
JNIEnv* env,
|
||||
jobject j_pc) {
|
||||
static ScopedJavaLocalRef<jobject> JNI_PeerConnection_IceConnectionState(
|
||||
JNIEnv* env,
|
||||
const JavaParamRef<jobject>& j_pc) {
|
||||
return Java_IceConnectionState_fromNativeIndex(
|
||||
env, ExtractNativePC(env, j_pc)->ice_connection_state());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jobject,
|
||||
PeerConnection_iceGatheringState,
|
||||
JNIEnv* env,
|
||||
jobject j_pc) {
|
||||
static ScopedJavaLocalRef<jobject> JNI_PeerConnection_IceGatheringState(
|
||||
JNIEnv* env,
|
||||
const JavaParamRef<jobject>& j_pc) {
|
||||
return Java_IceGatheringState_fromNativeIndex(
|
||||
env, ExtractNativePC(env, j_pc)->ice_gathering_state());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
PeerConnection_close,
|
||||
JNIEnv* jni,
|
||||
jobject j_pc) {
|
||||
static void JNI_PeerConnection_Close(JNIEnv* jni,
|
||||
const JavaParamRef<jobject>& j_pc) {
|
||||
ExtractNativePC(jni, j_pc)->Close();
|
||||
}
|
||||
|
||||
|
||||
@ -27,17 +27,18 @@ namespace jni {
|
||||
|
||||
void JavaToNativeRTCConfiguration(
|
||||
JNIEnv* jni,
|
||||
jobject j_rtc_config,
|
||||
const JavaRef<jobject>& j_rtc_config,
|
||||
PeerConnectionInterface::RTCConfiguration* rtc_config);
|
||||
|
||||
rtc::KeyType GetRtcConfigKeyType(JNIEnv* env, jobject j_rtc_config);
|
||||
rtc::KeyType GetRtcConfigKeyType(JNIEnv* env,
|
||||
const JavaRef<jobject>& j_rtc_config);
|
||||
|
||||
// Adapter between the C++ PeerConnectionObserver interface and the Java
|
||||
// PeerConnection.Observer interface. Wraps an instance of the Java interface
|
||||
// and dispatches C++ callbacks to Java.
|
||||
class PeerConnectionObserverJni : public PeerConnectionObserver {
|
||||
public:
|
||||
PeerConnectionObserverJni(JNIEnv* jni, jobject j_observer);
|
||||
PeerConnectionObserverJni(JNIEnv* jni, const JavaRef<jobject>& j_observer);
|
||||
virtual ~PeerConnectionObserverJni();
|
||||
|
||||
// Implementation of PeerConnectionObserver interface, which propagates
|
||||
@ -76,11 +77,11 @@ class PeerConnectionObserverJni : public PeerConnectionObserver {
|
||||
const rtc::scoped_refptr<MediaStreamInterface>& stream);
|
||||
|
||||
// Converts array of streams, creating or re-using Java streams as necessary.
|
||||
jobjectArray NativeToJavaMediaStreamArray(
|
||||
ScopedJavaLocalRef<jobjectArray> NativeToJavaMediaStreamArray(
|
||||
JNIEnv* jni,
|
||||
const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams);
|
||||
|
||||
const ScopedGlobalRef<jobject> j_observer_global_;
|
||||
const ScopedJavaGlobalRef<jobject> j_observer_global_;
|
||||
|
||||
// C++ -> Java remote streams.
|
||||
NativeToJavaStreamsMap remote_streams_;
|
||||
|
||||
@ -45,7 +45,8 @@ namespace jni {
|
||||
|
||||
namespace {
|
||||
PeerConnectionFactoryInterface::Options
|
||||
JavaToNativePeerConnectionFactoryOptions(JNIEnv* jni, jobject options) {
|
||||
JavaToNativePeerConnectionFactoryOptions(JNIEnv* jni,
|
||||
const JavaRef<jobject>& options) {
|
||||
int network_ignore_mask = Java_Options_getNetworkIgnoreMask(jni, options);
|
||||
bool disable_encryption = Java_Options_getDisableEncryption(jni, options);
|
||||
bool disable_network_monitor =
|
||||
@ -93,12 +94,11 @@ void PeerConnectionFactorySignalingThreadReady() {
|
||||
Java_PeerConnectionFactory_onSignalingThreadReady(env);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
PeerConnectionFactory_initializeNativeAndroidGlobals,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jobject context,
|
||||
jboolean video_hw_acceleration) {
|
||||
static void JNI_PeerConnectionFactory_InitializeAndroidGlobals(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
const JavaParamRef<jobject>& context,
|
||||
jboolean video_hw_acceleration) {
|
||||
video_hw_acceleration_enabled = video_hw_acceleration;
|
||||
if (!factory_static_initialized) {
|
||||
JVM::Initialize(GetJVM());
|
||||
@ -106,75 +106,71 @@ JNI_FUNCTION_DECLARATION(void,
|
||||
}
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
PeerConnectionFactory_initializeFieldTrials,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jstring j_trials_init_string) {
|
||||
static void JNI_PeerConnectionFactory_InitializeFieldTrials(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
const JavaParamRef<jstring>& j_trials_init_string) {
|
||||
field_trials_init_string = NULL;
|
||||
if (j_trials_init_string != NULL) {
|
||||
if (!j_trials_init_string.is_null()) {
|
||||
const char* init_string =
|
||||
jni->GetStringUTFChars(j_trials_init_string, NULL);
|
||||
int init_string_length = jni->GetStringUTFLength(j_trials_init_string);
|
||||
jni->GetStringUTFChars(j_trials_init_string.obj(), NULL);
|
||||
int init_string_length =
|
||||
jni->GetStringUTFLength(j_trials_init_string.obj());
|
||||
field_trials_init_string = new char[init_string_length + 1];
|
||||
rtc::strcpyn(field_trials_init_string, init_string_length + 1, init_string);
|
||||
jni->ReleaseStringUTFChars(j_trials_init_string, init_string);
|
||||
jni->ReleaseStringUTFChars(j_trials_init_string.obj(), init_string);
|
||||
RTC_LOG(LS_INFO) << "initializeFieldTrials: " << field_trials_init_string;
|
||||
}
|
||||
field_trial::InitFieldTrialsFromString(field_trials_init_string);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
PeerConnectionFactory_initializeNativeInternalTracer,
|
||||
JNIEnv* jni,
|
||||
jclass) {
|
||||
static void JNI_PeerConnectionFactory_InitializeInternalTracer(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&) {
|
||||
rtc::tracing::SetupInternalTracer();
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jstring,
|
||||
PeerConnectionFactory_findNativeFieldTrialsFullName,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jstring j_name) {
|
||||
static ScopedJavaLocalRef<jstring>
|
||||
JNI_PeerConnectionFactory_FindFieldTrialsFullName(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
const JavaParamRef<jstring>& j_name) {
|
||||
return NativeToJavaString(
|
||||
jni, field_trial::FindFullName(JavaToStdString(jni, j_name)));
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jboolean,
|
||||
PeerConnectionFactory_startInternalTracingCapture,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jstring j_event_tracing_filename) {
|
||||
if (!j_event_tracing_filename)
|
||||
static jboolean JNI_PeerConnectionFactory_StartInternalTracingCapture(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
const JavaParamRef<jstring>& j_event_tracing_filename) {
|
||||
if (j_event_tracing_filename.is_null())
|
||||
return false;
|
||||
|
||||
const char* init_string =
|
||||
jni->GetStringUTFChars(j_event_tracing_filename, NULL);
|
||||
jni->GetStringUTFChars(j_event_tracing_filename.obj(), NULL);
|
||||
RTC_LOG(LS_INFO) << "Starting internal tracing to: " << init_string;
|
||||
bool ret = rtc::tracing::StartInternalCapture(init_string);
|
||||
jni->ReleaseStringUTFChars(j_event_tracing_filename, init_string);
|
||||
jni->ReleaseStringUTFChars(j_event_tracing_filename.obj(), init_string);
|
||||
return ret;
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
PeerConnectionFactory_stopInternalTracingCapture,
|
||||
JNIEnv* jni,
|
||||
jclass) {
|
||||
static void JNI_PeerConnectionFactory_StopInternalTracingCapture(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&) {
|
||||
rtc::tracing::StopInternalCapture();
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
PeerConnectionFactory_shutdownNativeInternalTracer,
|
||||
JNIEnv* jni,
|
||||
jclass) {
|
||||
static void JNI_PeerConnectionFactory_ShutdownInternalTracer(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&) {
|
||||
rtc::tracing::ShutdownInternalTracer();
|
||||
}
|
||||
|
||||
jlong CreatePeerConnectionFactoryForJava(
|
||||
JNIEnv* jni,
|
||||
jobject joptions,
|
||||
jobject jencoder_factory,
|
||||
jobject jdecoder_factory,
|
||||
const JavaParamRef<jobject>& joptions,
|
||||
const JavaParamRef<jobject>& jencoder_factory,
|
||||
const JavaParamRef<jobject>& jdecoder_factory,
|
||||
rtc::scoped_refptr<AudioProcessing> audio_processor) {
|
||||
// talk/ assumes pretty widely that the current Thread is ThreadManager'd, but
|
||||
// ThreadManager only WrapCurrentThread()s the thread where it is first
|
||||
@ -201,7 +197,7 @@ jlong CreatePeerConnectionFactoryForJava(
|
||||
auto audio_decoder_factory = CreateAudioDecoderFactory();
|
||||
|
||||
PeerConnectionFactoryInterface::Options options;
|
||||
bool has_options = joptions != NULL;
|
||||
bool has_options = !joptions.is_null();
|
||||
if (has_options) {
|
||||
options = JavaToNativePeerConnectionFactoryOptions(jni, joptions);
|
||||
}
|
||||
@ -222,7 +218,7 @@ jlong CreatePeerConnectionFactoryForJava(
|
||||
cricket::WebRtcVideoEncoderFactory* legacy_video_encoder_factory = nullptr;
|
||||
cricket::WebRtcVideoDecoderFactory* legacy_video_decoder_factory = nullptr;
|
||||
std::unique_ptr<cricket::MediaEngineInterface> media_engine;
|
||||
if (jencoder_factory == nullptr && jdecoder_factory == nullptr) {
|
||||
if (jencoder_factory.is_null() && jdecoder_factory.is_null()) {
|
||||
// This uses the legacy API, which automatically uses the internal SW
|
||||
// codecs in WebRTC.
|
||||
if (video_hw_acceleration_enabled) {
|
||||
@ -236,7 +232,7 @@ jlong CreatePeerConnectionFactoryForJava(
|
||||
} else {
|
||||
// This uses the new API, does not automatically include software codecs.
|
||||
std::unique_ptr<VideoEncoderFactory> video_encoder_factory = nullptr;
|
||||
if (jencoder_factory == nullptr) {
|
||||
if (jencoder_factory.is_null()) {
|
||||
legacy_video_encoder_factory = CreateLegacyVideoEncoderFactory();
|
||||
video_encoder_factory = std::unique_ptr<VideoEncoderFactory>(
|
||||
WrapLegacyVideoEncoderFactory(legacy_video_encoder_factory));
|
||||
@ -246,7 +242,7 @@ jlong CreatePeerConnectionFactoryForJava(
|
||||
}
|
||||
|
||||
std::unique_ptr<VideoDecoderFactory> video_decoder_factory = nullptr;
|
||||
if (jdecoder_factory == nullptr) {
|
||||
if (jdecoder_factory.is_null()) {
|
||||
legacy_video_decoder_factory = CreateLegacyVideoDecoderFactory();
|
||||
video_decoder_factory = std::unique_ptr<VideoDecoderFactory>(
|
||||
WrapLegacyVideoDecoderFactory(legacy_video_decoder_factory));
|
||||
@ -282,27 +278,24 @@ jlong CreatePeerConnectionFactoryForJava(
|
||||
return jlongFromPointer(owned_factory);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(
|
||||
jlong,
|
||||
PeerConnectionFactory_createNativePeerConnectionFactory,
|
||||
static jlong JNI_PeerConnectionFactory_CreatePeerConnectionFactory(
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jobject joptions,
|
||||
jobject jencoder_factory,
|
||||
jobject jdecoder_factory) {
|
||||
const JavaParamRef<jclass>&,
|
||||
const JavaParamRef<jobject>& joptions,
|
||||
const JavaParamRef<jobject>& jencoder_factory,
|
||||
const JavaParamRef<jobject>& jdecoder_factory) {
|
||||
return CreatePeerConnectionFactoryForJava(jni, joptions, jencoder_factory,
|
||||
jdecoder_factory,
|
||||
CreateAudioProcessing());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(
|
||||
jlong,
|
||||
PeerConnectionFactory_createNativePeerConnectionFactoryWithAudioProcessing,
|
||||
static jlong
|
||||
JNI_PeerConnectionFactory_CreatePeerConnectionFactoryWithAudioProcessing(
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jobject joptions,
|
||||
jobject jencoder_factory,
|
||||
jobject jdecoder_factory,
|
||||
const JavaParamRef<jclass>&,
|
||||
const JavaParamRef<jobject>& joptions,
|
||||
const JavaParamRef<jobject>& jencoder_factory,
|
||||
const JavaParamRef<jobject>& jdecoder_factory,
|
||||
jlong native_audio_processor) {
|
||||
rtc::scoped_refptr<AudioProcessing> audio_processor =
|
||||
reinterpret_cast<AudioProcessing*>(native_audio_processor);
|
||||
@ -311,11 +304,9 @@ JNI_FUNCTION_DECLARATION(
|
||||
jdecoder_factory, audio_processor);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
PeerConnectionFactory_freeNativeFactory,
|
||||
JNIEnv*,
|
||||
jclass,
|
||||
jlong j_p) {
|
||||
static void JNI_PeerConnectionFactory_FreeFactory(JNIEnv*,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_p) {
|
||||
delete reinterpret_cast<OwnedFactoryAndThreads*>(j_p);
|
||||
if (field_trials_init_string) {
|
||||
field_trial::InitFieldTrialsFromString(NULL);
|
||||
@ -324,35 +315,32 @@ JNI_FUNCTION_DECLARATION(void,
|
||||
}
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
PeerConnectionFactory_invokeNativeThreadsCallbacks,
|
||||
JNIEnv*,
|
||||
jclass,
|
||||
jlong j_p) {
|
||||
static void JNI_PeerConnectionFactory_InvokeThreadsCallbacks(
|
||||
JNIEnv*,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_p) {
|
||||
OwnedFactoryAndThreads* factory =
|
||||
reinterpret_cast<OwnedFactoryAndThreads*>(j_p);
|
||||
factory->InvokeJavaCallbacksOnFactoryThreads();
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jlong,
|
||||
PeerConnectionFactory_createNativeLocalMediaStream,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong native_factory,
|
||||
jstring label) {
|
||||
static jlong JNI_PeerConnectionFactory_CreateLocalMediaStream(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong native_factory,
|
||||
const JavaParamRef<jstring>& label) {
|
||||
rtc::scoped_refptr<PeerConnectionFactoryInterface> factory(
|
||||
factoryFromJava(native_factory));
|
||||
rtc::scoped_refptr<MediaStreamInterface> stream(
|
||||
factory->CreateLocalMediaStream(JavaToStdString(jni, label)));
|
||||
return (jlong)stream.release();
|
||||
return jlongFromPointer(stream.release());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jlong,
|
||||
PeerConnectionFactory_createNativeAudioSource,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong native_factory,
|
||||
jobject j_constraints) {
|
||||
static jlong JNI_PeerConnectionFactory_CreateAudioSource(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong native_factory,
|
||||
const JavaParamRef<jobject>& j_constraints) {
|
||||
std::unique_ptr<MediaConstraintsInterface> constraints =
|
||||
JavaToNativeMediaConstraints(jni, j_constraints);
|
||||
rtc::scoped_refptr<PeerConnectionFactoryInterface> factory(
|
||||
@ -361,52 +349,47 @@ JNI_FUNCTION_DECLARATION(jlong,
|
||||
CopyConstraintsIntoAudioOptions(constraints.get(), &options);
|
||||
rtc::scoped_refptr<AudioSourceInterface> source(
|
||||
factory->CreateAudioSource(options));
|
||||
return (jlong)source.release();
|
||||
return jlongFromPointer(source.release());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jlong,
|
||||
PeerConnectionFactory_createNativeAudioTrack,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong native_factory,
|
||||
jstring id,
|
||||
jlong native_source) {
|
||||
jlong JNI_PeerConnectionFactory_CreateAudioTrack(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong native_factory,
|
||||
const JavaParamRef<jstring>& id,
|
||||
jlong native_source) {
|
||||
rtc::scoped_refptr<PeerConnectionFactoryInterface> factory(
|
||||
factoryFromJava(native_factory));
|
||||
rtc::scoped_refptr<AudioTrackInterface> track(factory->CreateAudioTrack(
|
||||
JavaToStdString(jni, id),
|
||||
reinterpret_cast<AudioSourceInterface*>(native_source)));
|
||||
return (jlong)track.release();
|
||||
return jlongFromPointer(track.release());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jboolean,
|
||||
PeerConnectionFactory_startNativeAecDump,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong native_factory,
|
||||
jint file,
|
||||
jint filesize_limit_bytes) {
|
||||
static jboolean JNI_PeerConnectionFactory_StartAecDump(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong native_factory,
|
||||
jint file,
|
||||
jint filesize_limit_bytes) {
|
||||
rtc::scoped_refptr<PeerConnectionFactoryInterface> factory(
|
||||
factoryFromJava(native_factory));
|
||||
return factory->StartAecDump(file, filesize_limit_bytes);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
PeerConnectionFactory_stopNativeAecDump,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong native_factory) {
|
||||
static void JNI_PeerConnectionFactory_StopAecDump(JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong native_factory) {
|
||||
rtc::scoped_refptr<PeerConnectionFactoryInterface> factory(
|
||||
factoryFromJava(native_factory));
|
||||
factory->StopAecDump();
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
PeerConnectionFactory_setNativeOptions,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong native_factory,
|
||||
jobject options) {
|
||||
static void JNI_PeerConnectionFactory_SetOptions(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jobject>&,
|
||||
jlong native_factory,
|
||||
const JavaParamRef<jobject>& options) {
|
||||
rtc::scoped_refptr<PeerConnectionFactoryInterface> factory(
|
||||
factoryFromJava(native_factory));
|
||||
PeerConnectionFactoryInterface::Options options_to_set =
|
||||
@ -424,14 +407,13 @@ JNI_FUNCTION_DECLARATION(void,
|
||||
}
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jlong,
|
||||
PeerConnectionFactory_createNativePeerConnection,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong factory,
|
||||
jobject j_rtc_config,
|
||||
jobject j_constraints,
|
||||
jlong observer_p) {
|
||||
static jlong JNI_PeerConnectionFactory_CreatePeerConnection(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong factory,
|
||||
const JavaParamRef<jobject>& j_rtc_config,
|
||||
const JavaParamRef<jobject>& j_constraints,
|
||||
jlong observer_p) {
|
||||
rtc::scoped_refptr<PeerConnectionFactoryInterface> f(
|
||||
reinterpret_cast<PeerConnectionFactoryInterface*>(
|
||||
factoryFromJava(factory)));
|
||||
@ -456,7 +438,7 @@ JNI_FUNCTION_DECLARATION(jlong,
|
||||
|
||||
PeerConnectionObserverJni* observer =
|
||||
reinterpret_cast<PeerConnectionObserverJni*>(observer_p);
|
||||
if (j_constraints != nullptr) {
|
||||
if (!j_constraints.is_null()) {
|
||||
observer->SetConstraints(JavaToNativeMediaConstraints(jni, j_constraints));
|
||||
CopyConstraintsIntoRtcConfiguration(observer->constraints(), &rtc_config);
|
||||
}
|
||||
@ -465,13 +447,12 @@ JNI_FUNCTION_DECLARATION(jlong,
|
||||
return jlongFromPointer(pc.release());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jlong,
|
||||
PeerConnectionFactory_createNativeVideoSource,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong native_factory,
|
||||
jobject j_surface_texture_helper,
|
||||
jboolean is_screencast) {
|
||||
static jlong JNI_PeerConnectionFactory_CreateVideoSource(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong native_factory,
|
||||
const JavaParamRef<jobject>& j_surface_texture_helper,
|
||||
jboolean is_screencast) {
|
||||
OwnedFactoryAndThreads* factory =
|
||||
reinterpret_cast<OwnedFactoryAndThreads*>(native_factory);
|
||||
return jlongFromPointer(CreateVideoSource(
|
||||
@ -479,13 +460,12 @@ JNI_FUNCTION_DECLARATION(jlong,
|
||||
j_surface_texture_helper, is_screencast));
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jlong,
|
||||
PeerConnectionFactory_createNativeVideoTrack,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong native_factory,
|
||||
jstring id,
|
||||
jlong native_source) {
|
||||
static jlong JNI_PeerConnectionFactory_CreateVideoTrack(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong native_factory,
|
||||
const JavaParamRef<jstring>& id,
|
||||
jlong native_source) {
|
||||
rtc::scoped_refptr<PeerConnectionFactoryInterface> factory(
|
||||
factoryFromJava(native_factory));
|
||||
rtc::scoped_refptr<VideoTrackInterface> track(factory->CreateVideoTrack(
|
||||
@ -494,14 +474,12 @@ JNI_FUNCTION_DECLARATION(jlong,
|
||||
return jlongFromPointer(track.release());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(
|
||||
void,
|
||||
PeerConnectionFactory_setNativeVideoHwAccelerationOptions,
|
||||
static void JNI_PeerConnectionFactory_SetVideoHwAccelerationOptions(
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong native_factory,
|
||||
jobject local_egl_context,
|
||||
jobject remote_egl_context) {
|
||||
const JavaParamRef<jobject>& local_egl_context,
|
||||
const JavaParamRef<jobject>& remote_egl_context) {
|
||||
OwnedFactoryAndThreads* owned_factory =
|
||||
reinterpret_cast<OwnedFactoryAndThreads*>(native_factory);
|
||||
SetEglContext(jni, owned_factory->legacy_encoder_factory(),
|
||||
|
||||
@ -24,19 +24,21 @@ namespace jni {
|
||||
|
||||
namespace {
|
||||
|
||||
jobject NativeToJavaBigInteger(JNIEnv* env, uint64_t u) {
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaBigInteger(JNIEnv* env, uint64_t u) {
|
||||
return JNI_BigInteger::Java_BigInteger_ConstructorJMBI_JLS(
|
||||
env, NativeToJavaString(env, rtc::ToString(u)));
|
||||
}
|
||||
|
||||
jobjectArray NativeToJavaBigIntegerArray(
|
||||
ScopedJavaLocalRef<jobjectArray> NativeToJavaBigIntegerArray(
|
||||
JNIEnv* env,
|
||||
const std::vector<uint64_t>& container) {
|
||||
return NativeToJavaObjectArray(
|
||||
env, container, java_math_BigInteger_clazz(env), &NativeToJavaBigInteger);
|
||||
}
|
||||
|
||||
jobject MemberToJava(JNIEnv* env, const RTCStatsMemberInterface& member) {
|
||||
ScopedJavaLocalRef<jobject> MemberToJava(
|
||||
JNIEnv* env,
|
||||
const RTCStatsMemberInterface& member) {
|
||||
switch (member.type()) {
|
||||
case RTCStatsMemberInterface::kBool:
|
||||
return NativeToJavaBoolean(env, *member.cast_to<RTCStatsMember<bool>>());
|
||||
@ -96,12 +98,12 @@ jobject MemberToJava(JNIEnv* env, const RTCStatsMemberInterface& member) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
jobject NativeToJavaRtcStats(JNIEnv* env, const RTCStats& stats) {
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaRtcStats(JNIEnv* env,
|
||||
const RTCStats& stats) {
|
||||
JavaMapBuilder builder(env);
|
||||
for (const auto& member : stats.Members()) {
|
||||
if (!member->is_defined())
|
||||
continue;
|
||||
ScopedLocalRefFrame local_ref_frame(env);
|
||||
builder.put(NativeToJavaString(env, member->name()),
|
||||
MemberToJava(env, *member));
|
||||
}
|
||||
@ -110,10 +112,10 @@ jobject NativeToJavaRtcStats(JNIEnv* env, const RTCStats& stats) {
|
||||
NativeToJavaString(env, stats.id()), builder.GetJavaMap());
|
||||
}
|
||||
|
||||
jobject NativeToJavaRtcStatsReport(
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaRtcStatsReport(
|
||||
JNIEnv* env,
|
||||
const rtc::scoped_refptr<const RTCStatsReport>& report) {
|
||||
jobject j_stats_map =
|
||||
ScopedJavaLocalRef<jobject> j_stats_map =
|
||||
NativeToJavaMap(env, *report, [](JNIEnv* env, const RTCStats& stats) {
|
||||
return std::make_pair(NativeToJavaString(env, stats.id()),
|
||||
NativeToJavaRtcStats(env, stats));
|
||||
@ -125,16 +127,14 @@ jobject NativeToJavaRtcStatsReport(
|
||||
|
||||
RTCStatsCollectorCallbackWrapper::RTCStatsCollectorCallbackWrapper(
|
||||
JNIEnv* jni,
|
||||
jobject j_callback)
|
||||
const JavaRef<jobject>& j_callback)
|
||||
: j_callback_global_(jni, j_callback) {}
|
||||
|
||||
void RTCStatsCollectorCallbackWrapper::OnStatsDelivered(
|
||||
const rtc::scoped_refptr<const RTCStatsReport>& report) {
|
||||
JNIEnv* jni = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(jni);
|
||||
jobject j_report = NativeToJavaRtcStatsReport(jni, report);
|
||||
Java_RTCStatsCollectorCallback_onStatsDelivered(jni, *j_callback_global_,
|
||||
j_report);
|
||||
Java_RTCStatsCollectorCallback_onStatsDelivered(
|
||||
jni, j_callback_global_, NativeToJavaRtcStatsReport(jni, report));
|
||||
}
|
||||
|
||||
} // namespace jni
|
||||
|
||||
@ -24,13 +24,14 @@ namespace jni {
|
||||
// Java.
|
||||
class RTCStatsCollectorCallbackWrapper : public RTCStatsCollectorCallback {
|
||||
public:
|
||||
RTCStatsCollectorCallbackWrapper(JNIEnv* jni, jobject j_callback);
|
||||
RTCStatsCollectorCallbackWrapper(JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_callback);
|
||||
|
||||
void OnStatsDelivered(
|
||||
const rtc::scoped_refptr<const RTCStatsReport>& report) override;
|
||||
|
||||
private:
|
||||
const ScopedGlobalRef<jobject> j_callback_global_;
|
||||
const ScopedJavaGlobalRef<jobject> j_callback_global_;
|
||||
};
|
||||
|
||||
} // namespace jni
|
||||
|
||||
@ -19,7 +19,7 @@ namespace jni {
|
||||
|
||||
namespace {
|
||||
|
||||
jobject NativeToJavaRtpEncodingParameter(
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaRtpEncodingParameter(
|
||||
JNIEnv* env,
|
||||
const RtpEncodingParameters& encoding) {
|
||||
return Java_Encoding_Constructor(
|
||||
@ -27,8 +27,9 @@ jobject NativeToJavaRtpEncodingParameter(
|
||||
encoding.ssrc ? NativeToJavaLong(env, *encoding.ssrc) : nullptr);
|
||||
}
|
||||
|
||||
jobject NativeToJavaRtpCodecParameter(JNIEnv* env,
|
||||
const RtpCodecParameters& codec) {
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaRtpCodecParameter(
|
||||
JNIEnv* env,
|
||||
const RtpCodecParameters& codec) {
|
||||
return Java_Codec_Constructor(env, codec.payload_type,
|
||||
NativeToJavaString(env, codec.name),
|
||||
NativeToJavaMediaType(env, codec.kind),
|
||||
@ -38,26 +39,31 @@ jobject NativeToJavaRtpCodecParameter(JNIEnv* env,
|
||||
|
||||
} // namespace
|
||||
|
||||
RtpParameters JavaToNativeRtpParameters(JNIEnv* jni, jobject j_parameters) {
|
||||
RtpParameters JavaToNativeRtpParameters(JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_parameters) {
|
||||
RtpParameters parameters;
|
||||
|
||||
// Convert encodings.
|
||||
jobject j_encodings = Java_RtpParameters_getEncodings(jni, j_parameters);
|
||||
for (jobject j_encoding_parameters : Iterable(jni, j_encodings)) {
|
||||
ScopedJavaLocalRef<jobject> j_encodings =
|
||||
Java_RtpParameters_getEncodings(jni, j_parameters);
|
||||
for (const JavaRef<jobject>& j_encoding_parameters :
|
||||
Iterable(jni, j_encodings)) {
|
||||
RtpEncodingParameters encoding;
|
||||
encoding.active = Java_Encoding_getActive(jni, j_encoding_parameters);
|
||||
jobject j_bitrate =
|
||||
ScopedJavaLocalRef<jobject> j_bitrate =
|
||||
Java_Encoding_getMaxBitrateBps(jni, j_encoding_parameters);
|
||||
encoding.max_bitrate_bps = JavaToNativeOptionalInt(jni, j_bitrate);
|
||||
jobject j_ssrc = Java_Encoding_getSsrc(jni, j_encoding_parameters);
|
||||
ScopedJavaLocalRef<jobject> j_ssrc =
|
||||
Java_Encoding_getSsrc(jni, j_encoding_parameters);
|
||||
if (!IsNull(jni, j_ssrc))
|
||||
encoding.ssrc = JavaToNativeLong(jni, j_ssrc);
|
||||
parameters.encodings.push_back(encoding);
|
||||
}
|
||||
|
||||
// Convert codecs.
|
||||
jobject j_codecs = Java_RtpParameters_getCodecs(jni, j_parameters);
|
||||
for (jobject j_codec : Iterable(jni, j_codecs)) {
|
||||
ScopedJavaLocalRef<jobject> j_codecs =
|
||||
Java_RtpParameters_getCodecs(jni, j_parameters);
|
||||
for (const JavaRef<jobject>& j_codec : Iterable(jni, j_codecs)) {
|
||||
RtpCodecParameters codec;
|
||||
codec.payload_type = Java_Codec_getPayloadType(jni, j_codec);
|
||||
codec.name = JavaToStdString(jni, Java_Codec_getName(jni, j_codec));
|
||||
@ -71,8 +77,9 @@ RtpParameters JavaToNativeRtpParameters(JNIEnv* jni, jobject j_parameters) {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
jobject NativeToJavaRtpParameters(JNIEnv* env,
|
||||
const RtpParameters& parameters) {
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaRtpParameters(
|
||||
JNIEnv* env,
|
||||
const RtpParameters& parameters) {
|
||||
return Java_RtpParameters_Constructor(
|
||||
env,
|
||||
NativeToJavaList(env, parameters.encodings,
|
||||
|
||||
@ -14,12 +14,16 @@
|
||||
#include <jni.h>
|
||||
|
||||
#include "api/rtpparameters.h"
|
||||
#include "sdk/android/src/jni/scoped_java_ref.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
RtpParameters JavaToNativeRtpParameters(JNIEnv* jni, jobject j_parameters);
|
||||
jobject NativeToJavaRtpParameters(JNIEnv* jni, const RtpParameters& parameters);
|
||||
RtpParameters JavaToNativeRtpParameters(JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_parameters);
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaRtpParameters(
|
||||
JNIEnv* jni,
|
||||
const RtpParameters& parameters);
|
||||
|
||||
} // namespace jni
|
||||
} // namespace webrtc
|
||||
|
||||
@ -25,24 +25,24 @@ namespace {
|
||||
// dispatches C++ callbacks to Java.
|
||||
class RtpReceiverObserverJni : public RtpReceiverObserverInterface {
|
||||
public:
|
||||
RtpReceiverObserverJni(JNIEnv* env, jobject j_observer)
|
||||
RtpReceiverObserverJni(JNIEnv* env, const JavaRef<jobject>& j_observer)
|
||||
: j_observer_global_(env, j_observer) {}
|
||||
|
||||
~RtpReceiverObserverJni() override = default;
|
||||
|
||||
void OnFirstPacketReceived(cricket::MediaType media_type) override {
|
||||
JNIEnv* const env = AttachCurrentThreadIfNeeded();
|
||||
Java_Observer_onFirstPacketReceived(env, *j_observer_global_,
|
||||
Java_Observer_onFirstPacketReceived(env, j_observer_global_,
|
||||
NativeToJavaMediaType(env, media_type));
|
||||
}
|
||||
|
||||
private:
|
||||
const ScopedGlobalRef<jobject> j_observer_global_;
|
||||
const ScopedJavaGlobalRef<jobject> j_observer_global_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
jobject NativeToJavaRtpReceiver(
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaRtpReceiver(
|
||||
JNIEnv* env,
|
||||
rtc::scoped_refptr<RtpReceiverInterface> receiver) {
|
||||
// Receiver is now owned by Java object, and will be freed from there.
|
||||
@ -50,68 +50,62 @@ jobject NativeToJavaRtpReceiver(
|
||||
jlongFromPointer(receiver.release()));
|
||||
}
|
||||
|
||||
JavaRtpReceiverGlobalOwner::JavaRtpReceiverGlobalOwner(JNIEnv* env,
|
||||
jobject j_receiver)
|
||||
JavaRtpReceiverGlobalOwner::JavaRtpReceiverGlobalOwner(
|
||||
JNIEnv* env,
|
||||
const JavaRef<jobject>& j_receiver)
|
||||
: j_receiver_(env, j_receiver) {}
|
||||
|
||||
JavaRtpReceiverGlobalOwner::JavaRtpReceiverGlobalOwner(
|
||||
JavaRtpReceiverGlobalOwner&& other) = default;
|
||||
|
||||
JavaRtpReceiverGlobalOwner::~JavaRtpReceiverGlobalOwner() {
|
||||
if (*j_receiver_)
|
||||
Java_RtpReceiver_dispose(AttachCurrentThreadIfNeeded(), *j_receiver_);
|
||||
if (j_receiver_.obj())
|
||||
Java_RtpReceiver_dispose(AttachCurrentThreadIfNeeded(), j_receiver_);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jlong,
|
||||
RtpReceiver_getNativeTrack,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_rtp_receiver_pointer,
|
||||
jlong j_track_pointer) {
|
||||
static jlong JNI_RtpReceiver_GetTrack(JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_rtp_receiver_pointer) {
|
||||
return jlongFromPointer(
|
||||
reinterpret_cast<RtpReceiverInterface*>(j_rtp_receiver_pointer)
|
||||
->track()
|
||||
.release());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jboolean,
|
||||
RtpReceiver_setNativeParameters,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_rtp_receiver_pointer,
|
||||
jobject j_parameters) {
|
||||
static jboolean JNI_RtpReceiver_SetParameters(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_rtp_receiver_pointer,
|
||||
const JavaParamRef<jobject>& j_parameters) {
|
||||
RtpParameters parameters = JavaToNativeRtpParameters(jni, j_parameters);
|
||||
return reinterpret_cast<RtpReceiverInterface*>(j_rtp_receiver_pointer)
|
||||
->SetParameters(parameters);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jobject,
|
||||
RtpReceiver_getNativeParameters,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_rtp_receiver_pointer) {
|
||||
static ScopedJavaLocalRef<jobject> JNI_RtpReceiver_GetParameters(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_rtp_receiver_pointer) {
|
||||
RtpParameters parameters =
|
||||
reinterpret_cast<RtpReceiverInterface*>(j_rtp_receiver_pointer)
|
||||
->GetParameters();
|
||||
return NativeToJavaRtpParameters(jni, parameters);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jstring,
|
||||
RtpReceiver_getNativeId,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_rtp_receiver_pointer) {
|
||||
static ScopedJavaLocalRef<jstring> JNI_RtpReceiver_GetId(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_rtp_receiver_pointer) {
|
||||
return NativeToJavaString(
|
||||
jni,
|
||||
reinterpret_cast<RtpReceiverInterface*>(j_rtp_receiver_pointer)->id());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jlong,
|
||||
RtpReceiver_setNativeObserver,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_rtp_receiver_pointer,
|
||||
jobject j_observer) {
|
||||
static jlong JNI_RtpReceiver_SetObserver(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_rtp_receiver_pointer,
|
||||
const JavaParamRef<jobject>& j_observer) {
|
||||
RtpReceiverObserverJni* rtpReceiverObserver =
|
||||
new RtpReceiverObserverJni(jni, j_observer);
|
||||
reinterpret_cast<RtpReceiverInterface*>(j_rtp_receiver_pointer)
|
||||
@ -119,12 +113,10 @@ JNI_FUNCTION_DECLARATION(jlong,
|
||||
return jlongFromPointer(rtpReceiverObserver);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
RtpReceiver_unsetNativeObserver,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_rtp_receiver_pointer,
|
||||
jlong j_observer_pointer) {
|
||||
static void JNI_RtpReceiver_UnsetObserver(JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_rtp_receiver_pointer,
|
||||
jlong j_observer_pointer) {
|
||||
reinterpret_cast<RtpReceiverInterface*>(j_rtp_receiver_pointer)
|
||||
->SetObserver(nullptr);
|
||||
RtpReceiverObserverJni* observer =
|
||||
|
||||
@ -14,12 +14,12 @@
|
||||
#include <jni.h>
|
||||
|
||||
#include "api/rtpreceiverinterface.h"
|
||||
#include "sdk/android/src/jni/jni_helpers.h"
|
||||
#include "sdk/android/src/jni/scoped_java_ref.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
jobject NativeToJavaRtpReceiver(
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaRtpReceiver(
|
||||
JNIEnv* env,
|
||||
rtc::scoped_refptr<RtpReceiverInterface> receiver);
|
||||
|
||||
@ -27,12 +27,12 @@ jobject NativeToJavaRtpReceiver(
|
||||
// reference. Will call dispose() in the dtor.
|
||||
class JavaRtpReceiverGlobalOwner {
|
||||
public:
|
||||
JavaRtpReceiverGlobalOwner(JNIEnv* env, jobject j_receiver);
|
||||
JavaRtpReceiverGlobalOwner(JNIEnv* env, const JavaRef<jobject>& j_receiver);
|
||||
JavaRtpReceiverGlobalOwner(JavaRtpReceiverGlobalOwner&& other);
|
||||
~JavaRtpReceiverGlobalOwner();
|
||||
|
||||
private:
|
||||
ScopedGlobalRef<jobject> j_receiver_;
|
||||
ScopedJavaGlobalRef<jobject> j_receiver_;
|
||||
};
|
||||
|
||||
} // namespace jni
|
||||
|
||||
@ -17,8 +17,9 @@
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
jobject NativeToJavaRtpSender(JNIEnv* env,
|
||||
rtc::scoped_refptr<RtpSenderInterface> sender) {
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaRtpSender(
|
||||
JNIEnv* env,
|
||||
rtc::scoped_refptr<RtpSenderInterface> sender) {
|
||||
if (!sender)
|
||||
return nullptr;
|
||||
// Sender is now owned by the Java object, and will be freed from
|
||||
@ -26,44 +27,37 @@ jobject NativeToJavaRtpSender(JNIEnv* env,
|
||||
return Java_RtpSender_Constructor(env, jlongFromPointer(sender.release()));
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jboolean,
|
||||
RtpSender_setNativeTrack,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_rtp_sender_pointer,
|
||||
jlong j_track_pointer) {
|
||||
static jboolean JNI_RtpSender_SetTrack(JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_rtp_sender_pointer,
|
||||
jlong j_track_pointer) {
|
||||
return reinterpret_cast<RtpSenderInterface*>(j_rtp_sender_pointer)
|
||||
->SetTrack(reinterpret_cast<MediaStreamTrackInterface*>(j_track_pointer));
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jlong,
|
||||
RtpSender_getNativeTrack,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_rtp_sender_pointer) {
|
||||
jlong JNI_RtpSender_GetTrack(JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_rtp_sender_pointer) {
|
||||
return jlongFromPointer(
|
||||
reinterpret_cast<RtpSenderInterface*>(j_rtp_sender_pointer)
|
||||
->track()
|
||||
.release());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jlong,
|
||||
RtpSender_getNativeDtmfSender,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_rtp_sender_pointer) {
|
||||
jlong JNI_RtpSender_GetDtmfSender(JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_rtp_sender_pointer) {
|
||||
return jlongFromPointer(
|
||||
reinterpret_cast<RtpSenderInterface*>(j_rtp_sender_pointer)
|
||||
->GetDtmfSender()
|
||||
.release());
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jboolean,
|
||||
RtpSender_setNativeParameters,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_rtp_sender_pointer,
|
||||
jobject j_parameters) {
|
||||
jboolean JNI_RtpSender_SetParameters(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_rtp_sender_pointer,
|
||||
const JavaParamRef<jobject>& j_parameters) {
|
||||
if (IsNull(jni, j_parameters)) {
|
||||
return false;
|
||||
}
|
||||
@ -72,22 +66,19 @@ JNI_FUNCTION_DECLARATION(jboolean,
|
||||
->SetParameters(parameters);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jobject,
|
||||
RtpSender_getNativeParameters,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_rtp_sender_pointer) {
|
||||
ScopedJavaLocalRef<jobject> JNI_RtpSender_GetParameters(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_rtp_sender_pointer) {
|
||||
RtpParameters parameters =
|
||||
reinterpret_cast<RtpSenderInterface*>(j_rtp_sender_pointer)
|
||||
->GetParameters();
|
||||
return NativeToJavaRtpParameters(jni, parameters);
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(jstring,
|
||||
RtpSender_getNativeId,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_rtp_sender_pointer) {
|
||||
ScopedJavaLocalRef<jstring> JNI_RtpSender_GetId(JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_rtp_sender_pointer) {
|
||||
return NativeToJavaString(
|
||||
jni, reinterpret_cast<RtpSenderInterface*>(j_rtp_sender_pointer)->id());
|
||||
}
|
||||
|
||||
@ -14,12 +14,14 @@
|
||||
#include <jni.h>
|
||||
|
||||
#include "api/rtpsenderinterface.h"
|
||||
#include "sdk/android/src/jni/scoped_java_ref.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
jobject NativeToJavaRtpSender(JNIEnv* env,
|
||||
rtc::scoped_refptr<RtpSenderInterface> sender);
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaRtpSender(
|
||||
JNIEnv* env,
|
||||
rtc::scoped_refptr<RtpSenderInterface> sender);
|
||||
|
||||
} // namespace jni
|
||||
} // namespace webrtc
|
||||
|
||||
@ -21,15 +21,14 @@ namespace jni {
|
||||
|
||||
CreateSdpObserverJni::CreateSdpObserverJni(
|
||||
JNIEnv* env,
|
||||
jobject j_observer,
|
||||
const JavaRef<jobject>& j_observer,
|
||||
std::unique_ptr<MediaConstraintsInterface> constraints)
|
||||
: j_observer_global_(env, j_observer),
|
||||
constraints_(std::move(constraints)) {}
|
||||
|
||||
void CreateSdpObserverJni::OnSuccess(SessionDescriptionInterface* desc) {
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(env);
|
||||
Java_SdpObserver_onCreateSuccess(env, *j_observer_global_,
|
||||
Java_SdpObserver_onCreateSuccess(env, j_observer_global_,
|
||||
NativeToJavaSessionDescription(env, desc));
|
||||
// OnSuccess transfers ownership of the description (there's a TODO to make
|
||||
// it use unique_ptr...).
|
||||
@ -38,25 +37,25 @@ void CreateSdpObserverJni::OnSuccess(SessionDescriptionInterface* desc) {
|
||||
|
||||
void CreateSdpObserverJni::OnFailure(const std::string& error) {
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
Java_SdpObserver_onCreateFailure(env, *j_observer_global_,
|
||||
Java_SdpObserver_onCreateFailure(env, j_observer_global_,
|
||||
NativeToJavaString(env, error));
|
||||
}
|
||||
|
||||
SetSdpObserverJni::SetSdpObserverJni(
|
||||
JNIEnv* env,
|
||||
jobject j_observer,
|
||||
const JavaRef<jobject>& j_observer,
|
||||
std::unique_ptr<MediaConstraintsInterface> constraints)
|
||||
: j_observer_global_(env, j_observer),
|
||||
constraints_(std::move(constraints)) {}
|
||||
|
||||
void SetSdpObserverJni::OnSuccess() {
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
Java_SdpObserver_onSetSuccess(env, *j_observer_global_);
|
||||
Java_SdpObserver_onSetSuccess(env, j_observer_global_);
|
||||
}
|
||||
|
||||
void SetSdpObserverJni::OnFailure(const std::string& error) {
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
Java_SdpObserver_onSetFailure(env, *j_observer_global_,
|
||||
Java_SdpObserver_onSetFailure(env, j_observer_global_,
|
||||
NativeToJavaString(env, error));
|
||||
}
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@ namespace jni {
|
||||
class CreateSdpObserverJni : public CreateSessionDescriptionObserver {
|
||||
public:
|
||||
CreateSdpObserverJni(JNIEnv* env,
|
||||
jobject j_observer,
|
||||
const JavaRef<jobject>& j_observer,
|
||||
std::unique_ptr<MediaConstraintsInterface> constraints);
|
||||
|
||||
MediaConstraintsInterface* constraints() { return constraints_.get(); }
|
||||
@ -33,14 +33,14 @@ class CreateSdpObserverJni : public CreateSessionDescriptionObserver {
|
||||
void OnFailure(const std::string& error) override;
|
||||
|
||||
private:
|
||||
const ScopedGlobalRef<jobject> j_observer_global_;
|
||||
const ScopedJavaGlobalRef<jobject> j_observer_global_;
|
||||
std::unique_ptr<MediaConstraintsInterface> constraints_;
|
||||
};
|
||||
|
||||
class SetSdpObserverJni : public SetSessionDescriptionObserver {
|
||||
public:
|
||||
SetSdpObserverJni(JNIEnv* env,
|
||||
jobject j_observer,
|
||||
const JavaRef<jobject>& j_observer,
|
||||
std::unique_ptr<MediaConstraintsInterface> constraints);
|
||||
|
||||
MediaConstraintsInterface* constraints() { return constraints_.get(); }
|
||||
@ -49,7 +49,7 @@ class SetSdpObserverJni : public SetSessionDescriptionObserver {
|
||||
void OnFailure(const std::string& error) override;
|
||||
|
||||
private:
|
||||
const ScopedGlobalRef<jobject> j_observer_global_;
|
||||
const ScopedJavaGlobalRef<jobject> j_observer_global_;
|
||||
std::unique_ptr<MediaConstraintsInterface> constraints_;
|
||||
};
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ namespace jni {
|
||||
|
||||
std::unique_ptr<SessionDescriptionInterface> JavaToNativeSessionDescription(
|
||||
JNIEnv* jni,
|
||||
jobject j_sdp) {
|
||||
const JavaRef<jobject>& j_sdp) {
|
||||
std::string std_type = JavaToStdString(
|
||||
jni, Java_SessionDescription_getTypeInCanonicalForm(jni, j_sdp));
|
||||
std::string std_description =
|
||||
@ -34,18 +34,15 @@ std::unique_ptr<SessionDescriptionInterface> JavaToNativeSessionDescription(
|
||||
return CreateSessionDescription(*sdp_type_maybe, std_description);
|
||||
}
|
||||
|
||||
jobject NativeToJavaSessionDescription(
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaSessionDescription(
|
||||
JNIEnv* jni,
|
||||
const SessionDescriptionInterface* desc) {
|
||||
std::string sdp;
|
||||
RTC_CHECK(desc->ToString(&sdp)) << "got so far: " << sdp;
|
||||
jstring j_description = NativeToJavaString(jni, sdp);
|
||||
jobject j_type =
|
||||
Java_Type_fromCanonicalForm(jni, NativeToJavaString(jni, desc->type()));
|
||||
jobject j_sdp =
|
||||
Java_SessionDescription_Constructor(jni, j_type, j_description);
|
||||
CHECK_EXCEPTION(jni) << "error during NewObject";
|
||||
return j_sdp;
|
||||
return Java_SessionDescription_Constructor(
|
||||
jni,
|
||||
Java_Type_fromCanonicalForm(jni, NativeToJavaString(jni, desc->type())),
|
||||
NativeToJavaString(jni, sdp));
|
||||
}
|
||||
|
||||
} // namespace jni
|
||||
|
||||
@ -15,16 +15,18 @@
|
||||
#include <memory>
|
||||
|
||||
#include "api/jsep.h"
|
||||
#include "sdk/android/src/jni/scoped_java_ref.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
std::unique_ptr<SessionDescriptionInterface> JavaToNativeSessionDescription(
|
||||
JNIEnv* jni,
|
||||
jobject j_sdp);
|
||||
const JavaRef<jobject>& j_sdp);
|
||||
|
||||
jobject NativeToJavaSessionDescription(JNIEnv* jni,
|
||||
const SessionDescriptionInterface* desc);
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaSessionDescription(
|
||||
JNIEnv* jni,
|
||||
const SessionDescriptionInterface* desc);
|
||||
|
||||
} // namespace jni
|
||||
} // namespace webrtc
|
||||
|
||||
@ -21,20 +21,17 @@ namespace jni {
|
||||
|
||||
namespace {
|
||||
|
||||
jobject NativeToJavaStatsReportValue(
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaStatsReportValue(
|
||||
JNIEnv* env,
|
||||
const rtc::scoped_refptr<StatsReport::Value>& value_ptr) {
|
||||
// Should we use the '.name' enum value here instead of converting the
|
||||
// name to a string?
|
||||
jstring j_name = NativeToJavaString(env, value_ptr->display_name());
|
||||
jstring j_value = NativeToJavaString(env, value_ptr->ToString());
|
||||
jobject ret = Java_Value_Constructor(env, j_name, j_value);
|
||||
env->DeleteLocalRef(j_name);
|
||||
env->DeleteLocalRef(j_value);
|
||||
return ret;
|
||||
return Java_Value_Constructor(
|
||||
env, NativeToJavaString(env, value_ptr->display_name()),
|
||||
NativeToJavaString(env, value_ptr->ToString()));
|
||||
}
|
||||
|
||||
jobjectArray NativeToJavaStatsReportValueArray(
|
||||
ScopedJavaLocalRef<jobjectArray> NativeToJavaStatsReportValueArray(
|
||||
JNIEnv* env,
|
||||
const StatsReport::Values& value_map) {
|
||||
// Ignore the keys and make an array out of the values.
|
||||
@ -46,33 +43,28 @@ jobjectArray NativeToJavaStatsReportValueArray(
|
||||
&NativeToJavaStatsReportValue);
|
||||
}
|
||||
|
||||
jobject NativeToJavaStatsReport(JNIEnv* env, const StatsReport& report) {
|
||||
jstring j_id = NativeToJavaString(env, report.id()->ToString());
|
||||
jstring j_type = NativeToJavaString(env, report.TypeToString());
|
||||
jobjectArray j_values =
|
||||
NativeToJavaStatsReportValueArray(env, report.values());
|
||||
jobject ret = Java_StatsReport_Constructor(env, j_id, j_type,
|
||||
report.timestamp(), j_values);
|
||||
env->DeleteLocalRef(j_values);
|
||||
env->DeleteLocalRef(j_type);
|
||||
env->DeleteLocalRef(j_id);
|
||||
return ret;
|
||||
ScopedJavaLocalRef<jobject> NativeToJavaStatsReport(JNIEnv* env,
|
||||
const StatsReport& report) {
|
||||
return Java_StatsReport_Constructor(
|
||||
env, NativeToJavaString(env, report.id()->ToString()),
|
||||
NativeToJavaString(env, report.TypeToString()), report.timestamp(),
|
||||
NativeToJavaStatsReportValueArray(env, report.values()));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
StatsObserverJni::StatsObserverJni(JNIEnv* jni, jobject j_observer)
|
||||
StatsObserverJni::StatsObserverJni(JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_observer)
|
||||
: j_observer_global_(jni, j_observer) {}
|
||||
|
||||
void StatsObserverJni::OnComplete(const StatsReports& reports) {
|
||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
||||
jobjectArray j_reports =
|
||||
ScopedJavaLocalRef<jobjectArray> j_reports =
|
||||
NativeToJavaObjectArray(env, reports, org_webrtc_StatsReport_clazz(env),
|
||||
[](JNIEnv* env, const StatsReport* report) {
|
||||
return NativeToJavaStatsReport(env, *report);
|
||||
});
|
||||
Java_StatsObserver_onComplete(env, *j_observer_global_, j_reports);
|
||||
env->DeleteLocalRef(j_reports);
|
||||
Java_StatsObserver_onComplete(env, j_observer_global_, j_reports);
|
||||
}
|
||||
|
||||
} // namespace jni
|
||||
|
||||
@ -21,12 +21,12 @@ namespace jni {
|
||||
// dispatching the callback from C++ back to Java.
|
||||
class StatsObserverJni : public StatsObserver {
|
||||
public:
|
||||
StatsObserverJni(JNIEnv* jni, jobject j_observer);
|
||||
StatsObserverJni(JNIEnv* jni, const JavaRef<jobject>& j_observer);
|
||||
|
||||
void OnComplete(const StatsReports& reports) override;
|
||||
|
||||
private:
|
||||
const ScopedGlobalRef<jobject> j_observer_global_;
|
||||
const ScopedJavaGlobalRef<jobject> j_observer_global_;
|
||||
};
|
||||
|
||||
} // namespace jni
|
||||
|
||||
@ -15,19 +15,19 @@
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
TurnCustomizer* GetNativeTurnCustomizer(JNIEnv* env,
|
||||
jobject j_turn_customizer) {
|
||||
TurnCustomizer* GetNativeTurnCustomizer(
|
||||
JNIEnv* env,
|
||||
const JavaRef<jobject>& j_turn_customizer) {
|
||||
if (IsNull(env, j_turn_customizer))
|
||||
return nullptr;
|
||||
return reinterpret_cast<webrtc::TurnCustomizer*>(
|
||||
Java_TurnCustomizer_getNativeTurnCustomizer(env, j_turn_customizer));
|
||||
}
|
||||
|
||||
JNI_FUNCTION_DECLARATION(void,
|
||||
TurnCustomizer_freeNativeTurnCustomizer,
|
||||
JNIEnv* jni,
|
||||
jclass,
|
||||
jlong j_turn_customizer_pointer) {
|
||||
static void JNI_TurnCustomizer_FreeTurnCustomizer(
|
||||
JNIEnv* jni,
|
||||
const JavaParamRef<jclass>&,
|
||||
jlong j_turn_customizer_pointer) {
|
||||
delete reinterpret_cast<TurnCustomizer*>(j_turn_customizer_pointer);
|
||||
}
|
||||
|
||||
|
||||
@ -12,11 +12,14 @@
|
||||
#define SDK_ANDROID_SRC_JNI_PC_TURNCUSTOMIZER_H_
|
||||
|
||||
#include "api/turncustomizer.h"
|
||||
#include "sdk/android/src/jni/scoped_java_ref.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
TurnCustomizer* GetNativeTurnCustomizer(JNIEnv* env, jobject j_turn_customizer);
|
||||
TurnCustomizer* GetNativeTurnCustomizer(
|
||||
JNIEnv* env,
|
||||
const JavaRef<jobject>& j_turn_customizer);
|
||||
|
||||
} // namespace jni
|
||||
} // namespace webrtc
|
||||
|
||||
@ -32,38 +32,40 @@
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
VideoEncoderFactory* CreateVideoEncoderFactory(JNIEnv* jni,
|
||||
jobject j_encoder_factory) {
|
||||
VideoEncoderFactory* CreateVideoEncoderFactory(
|
||||
JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_encoder_factory) {
|
||||
return new VideoEncoderFactoryWrapper(jni, j_encoder_factory);
|
||||
}
|
||||
|
||||
VideoDecoderFactory* CreateVideoDecoderFactory(JNIEnv* jni,
|
||||
jobject j_decoder_factory) {
|
||||
VideoDecoderFactory* CreateVideoDecoderFactory(
|
||||
JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_decoder_factory) {
|
||||
return new VideoDecoderFactoryWrapper(jni, j_decoder_factory);
|
||||
}
|
||||
|
||||
void SetEglContext(JNIEnv* env,
|
||||
cricket::WebRtcVideoEncoderFactory* encoder_factory,
|
||||
jobject egl_context) {
|
||||
const JavaRef<jobject>& egl_context) {
|
||||
if (encoder_factory) {
|
||||
MediaCodecVideoEncoderFactory* media_codec_factory =
|
||||
static_cast<MediaCodecVideoEncoderFactory*>(encoder_factory);
|
||||
if (media_codec_factory && Java_Context_isEgl14Context(env, egl_context)) {
|
||||
RTC_LOG(LS_INFO) << "Set EGL context for HW encoding.";
|
||||
media_codec_factory->SetEGLContext(env, egl_context);
|
||||
media_codec_factory->SetEGLContext(env, egl_context.obj());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetEglContext(JNIEnv* env,
|
||||
cricket::WebRtcVideoDecoderFactory* decoder_factory,
|
||||
jobject egl_context) {
|
||||
const JavaRef<jobject>& egl_context) {
|
||||
if (decoder_factory) {
|
||||
MediaCodecVideoDecoderFactory* media_codec_factory =
|
||||
static_cast<MediaCodecVideoDecoderFactory*>(decoder_factory);
|
||||
if (media_codec_factory) {
|
||||
RTC_LOG(LS_INFO) << "Set EGL context for HW decoding.";
|
||||
media_codec_factory->SetEGLContext(env, egl_context);
|
||||
media_codec_factory->SetEGLContext(env, egl_context.obj());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -71,7 +73,7 @@ void SetEglContext(JNIEnv* env,
|
||||
void* CreateVideoSource(JNIEnv* env,
|
||||
rtc::Thread* signaling_thread,
|
||||
rtc::Thread* worker_thread,
|
||||
jobject j_surface_texture_helper,
|
||||
const JavaParamRef<jobject>& j_surface_texture_helper,
|
||||
jboolean is_screencast) {
|
||||
rtc::scoped_refptr<AndroidVideoTrackSource> source(
|
||||
new rtc::RefCountedObject<AndroidVideoTrackSource>(
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
|
||||
#include "rtc_base/scoped_ref_ptr.h"
|
||||
#include "rtc_base/thread.h"
|
||||
#include "sdk/android/src/jni/scoped_java_ref.h"
|
||||
|
||||
namespace cricket {
|
||||
class WebRtcVideoEncoderFactory;
|
||||
@ -31,23 +32,25 @@ namespace jni {
|
||||
|
||||
class SurfaceTextureHelper;
|
||||
|
||||
VideoEncoderFactory* CreateVideoEncoderFactory(JNIEnv* jni,
|
||||
jobject j_encoder_factory);
|
||||
VideoEncoderFactory* CreateVideoEncoderFactory(
|
||||
JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_encoder_factory);
|
||||
|
||||
VideoDecoderFactory* CreateVideoDecoderFactory(JNIEnv* jni,
|
||||
jobject j_decoder_factory);
|
||||
VideoDecoderFactory* CreateVideoDecoderFactory(
|
||||
JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_decoder_factory);
|
||||
|
||||
void SetEglContext(JNIEnv* env,
|
||||
cricket::WebRtcVideoEncoderFactory* encoder_factory,
|
||||
jobject egl_context);
|
||||
const JavaRef<jobject>& egl_context);
|
||||
void SetEglContext(JNIEnv* env,
|
||||
cricket::WebRtcVideoDecoderFactory* decoder_factory,
|
||||
jobject egl_context);
|
||||
const JavaRef<jobject>& egl_context);
|
||||
|
||||
void* CreateVideoSource(JNIEnv* env,
|
||||
rtc::Thread* signaling_thread,
|
||||
rtc::Thread* worker_thread,
|
||||
jobject j_surface_texture_helper,
|
||||
const JavaParamRef<jobject>& j_surface_texture_helper,
|
||||
jboolean is_screencast);
|
||||
|
||||
cricket::WebRtcVideoEncoderFactory* CreateLegacyVideoEncoderFactory();
|
||||
|
||||
205
sdk/android/src/jni/scoped_java_ref.h
Normal file
205
sdk/android/src/jni/scoped_java_ref.h
Normal file
@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright 2017 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.
|
||||
*/
|
||||
|
||||
// Originally these classes are from Chromium.
|
||||
// https://cs.chromium.org/chromium/src/base/android/scoped_java_ref.h.
|
||||
|
||||
#ifndef SDK_ANDROID_SRC_JNI_SCOPED_JAVA_REF_H_
|
||||
#define SDK_ANDROID_SRC_JNI_SCOPED_JAVA_REF_H_
|
||||
|
||||
#include <jni.h>
|
||||
#include <utility>
|
||||
|
||||
#include "rtc_base/constructormagic.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace jni {
|
||||
|
||||
JNIEnv* AttachCurrentThreadIfNeeded();
|
||||
|
||||
// Generic base class for ScopedJavaLocalRef and ScopedJavaGlobalRef. Useful
|
||||
// for allowing functions to accept a reference without having to mandate
|
||||
// whether it is a local or global type.
|
||||
template <typename T>
|
||||
class JavaRef;
|
||||
|
||||
// Template specialization of JavaRef, which acts as the base class for all
|
||||
// other JavaRef<> template types. This allows you to e.g. pass JavaRef<jstring>
|
||||
// into a function taking const JavaRef<jobject>&.
|
||||
template <>
|
||||
class JavaRef<jobject> {
|
||||
public:
|
||||
jobject obj() const { return obj_; }
|
||||
bool is_null() const {
|
||||
// This is not valid for weak references. For weak references you need to
|
||||
// use env->IsSameObject(objc_, nullptr), but that should be avoided anyway
|
||||
// since it does not prevent the object from being freed immediately
|
||||
// thereafter. Consequently, programmers should not use this check on weak
|
||||
// references anyway and should first make a ScopedJavaLocalRef or
|
||||
// ScopedJavaGlobalRef before checking if it is null.
|
||||
return obj_ == nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
JavaRef() : obj_(nullptr) {}
|
||||
explicit JavaRef(jobject obj) : obj_(obj) {}
|
||||
jobject obj_;
|
||||
|
||||
private:
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(JavaRef);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class JavaRef : public JavaRef<jobject> {
|
||||
public:
|
||||
T obj() const { return static_cast<T>(obj_); }
|
||||
|
||||
protected:
|
||||
JavaRef() : JavaRef<jobject>(nullptr) {}
|
||||
explicit JavaRef(T obj) : JavaRef<jobject>(obj) {}
|
||||
|
||||
private:
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(JavaRef);
|
||||
};
|
||||
|
||||
// Holds a local reference to a JNI method parameter.
|
||||
// Method parameters should not be deleted, and so this class exists purely to
|
||||
// wrap them as a JavaRef<T> in the JNI binding generator. Do not create
|
||||
// instances manually.
|
||||
template <typename T>
|
||||
class JavaParamRef : public JavaRef<T> {
|
||||
public:
|
||||
// Assumes that |obj| is a parameter passed to a JNI method from Java.
|
||||
// Does not assume ownership as parameters should not be deleted.
|
||||
explicit JavaParamRef(T obj) : JavaRef<T>(obj) {}
|
||||
JavaParamRef(JNIEnv*, T obj) : JavaRef<T>(obj) {}
|
||||
|
||||
private:
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(JavaParamRef);
|
||||
};
|
||||
|
||||
// Holds a local reference to a Java object. The local reference is scoped
|
||||
// to the lifetime of this object.
|
||||
// Instances of this class may hold onto any JNIEnv passed into it until
|
||||
// destroyed. Therefore, since a JNIEnv is only suitable for use on a single
|
||||
// thread, objects of this class must be created, used, and destroyed, on a
|
||||
// single thread.
|
||||
// Therefore, this class should only be used as a stack-based object and from a
|
||||
// single thread. If you wish to have the reference outlive the current
|
||||
// callstack (e.g. as a class member) or you wish to pass it across threads,
|
||||
// use a ScopedJavaGlobalRef instead.
|
||||
template <typename T>
|
||||
class ScopedJavaLocalRef : public JavaRef<T> {
|
||||
public:
|
||||
ScopedJavaLocalRef() = default;
|
||||
ScopedJavaLocalRef(std::nullptr_t) {} // NOLINT(runtime/explicit)
|
||||
|
||||
ScopedJavaLocalRef(JNIEnv* env, const JavaRef<T>& other) : env_(env) {
|
||||
Reset(other.obj(), OwnershipPolicy::RETAIN);
|
||||
}
|
||||
// Allow constructing e.g. ScopedJavaLocalRef<jobject> from
|
||||
// ScopedJavaLocalRef<jstring>.
|
||||
template <typename G>
|
||||
ScopedJavaLocalRef(ScopedJavaLocalRef<G>&& other) : env_(other.env()) {
|
||||
Reset(other.Release(), OwnershipPolicy::ADOPT);
|
||||
}
|
||||
ScopedJavaLocalRef(const ScopedJavaLocalRef& other) : env_(other.env_) {
|
||||
Reset(other.obj(), OwnershipPolicy::RETAIN);
|
||||
}
|
||||
|
||||
// Assumes that |obj| is a reference to a Java object and takes
|
||||
// ownership of this reference. This should preferably not be used
|
||||
// outside of JNI helper functions.
|
||||
ScopedJavaLocalRef(JNIEnv* env, T obj) : JavaRef<T>(obj), env_(env) {}
|
||||
|
||||
~ScopedJavaLocalRef() {
|
||||
if (obj_ != nullptr)
|
||||
env_->DeleteLocalRef(obj_);
|
||||
}
|
||||
|
||||
void operator=(const ScopedJavaLocalRef& other) {
|
||||
Reset(other.obj(), OwnershipPolicy::RETAIN);
|
||||
}
|
||||
void operator=(ScopedJavaLocalRef&& other) {
|
||||
Reset(other.Release(), OwnershipPolicy::ADOPT);
|
||||
}
|
||||
|
||||
// Releases the reference to the caller. The caller *must* delete the
|
||||
// reference when it is done with it. Note that calling a Java method
|
||||
// is *not* a transfer of ownership and Release() should not be used.
|
||||
T Release() {
|
||||
T obj = static_cast<T>(obj_);
|
||||
obj_ = nullptr;
|
||||
return obj;
|
||||
}
|
||||
|
||||
JNIEnv* env() const { return env_; }
|
||||
|
||||
private:
|
||||
using JavaRef<T>::obj_;
|
||||
|
||||
enum OwnershipPolicy {
|
||||
// The scoped object takes ownership of an object by taking over an existing
|
||||
// ownership claim.
|
||||
ADOPT,
|
||||
// The scoped object will retain the the object and any initial ownership is
|
||||
// not changed.
|
||||
RETAIN
|
||||
};
|
||||
|
||||
void Reset(T obj, OwnershipPolicy policy) {
|
||||
if (obj_ != nullptr)
|
||||
env_->DeleteLocalRef(obj_);
|
||||
obj_ = (obj != nullptr && policy == OwnershipPolicy::RETAIN)
|
||||
? env_->NewLocalRef(obj)
|
||||
: obj;
|
||||
}
|
||||
|
||||
JNIEnv* const env_ = AttachCurrentThreadIfNeeded();
|
||||
};
|
||||
|
||||
// Holds a global reference to a Java object. The global reference is scoped
|
||||
// to the lifetime of this object. This class does not hold onto any JNIEnv*
|
||||
// passed to it, hence it is safe to use across threads (within the constraints
|
||||
// imposed by the underlying Java object that it references).
|
||||
template <typename T>
|
||||
class ScopedJavaGlobalRef : public JavaRef<T> {
|
||||
public:
|
||||
using JavaRef<T>::obj_;
|
||||
|
||||
ScopedJavaGlobalRef(JNIEnv* env, const JavaRef<T>& other)
|
||||
: JavaRef<T>(static_cast<T>(env->NewGlobalRef(other.obj()))) {}
|
||||
explicit ScopedJavaGlobalRef(const ScopedJavaLocalRef<T>& other)
|
||||
: ScopedJavaGlobalRef(other.env(), other) {}
|
||||
ScopedJavaGlobalRef(ScopedJavaGlobalRef&& other)
|
||||
: JavaRef<T>(other.Release()) {}
|
||||
|
||||
~ScopedJavaGlobalRef() {
|
||||
if (obj_ != nullptr)
|
||||
AttachCurrentThreadIfNeeded()->DeleteGlobalRef(obj_);
|
||||
}
|
||||
|
||||
// Releases the reference to the caller. The caller *must* delete the
|
||||
// reference when it is done with it. Note that calling a Java method
|
||||
// is *not* a transfer of ownership and Release() should not be used.
|
||||
T Release() {
|
||||
T obj = static_cast<T>(obj_);
|
||||
obj_ = nullptr;
|
||||
return obj;
|
||||
}
|
||||
|
||||
private:
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(ScopedJavaGlobalRef);
|
||||
};
|
||||
|
||||
} // namespace jni
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // SDK_ANDROID_SRC_JNI_SCOPED_JAVA_REF_H_
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user